Skip to content

Commit 6807635

Browse files
initial cross-platform support
windows-specific code has mostly been isolated, excepting input. os x support is not checked in, but working-in-progress.
1 parent b2fca1e commit 6807635

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+905
-617
lines changed

core/Emulator.cpp

100644100755
Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@ Emulator::Emulator(const char* name)
3333
{
3434
memset(peripherals, 0, sizeof(peripherals));
3535
memset(usePeripheralIndicators, FALSE, sizeof(usePeripheralIndicators));
36-
37-
AddProcessor(&audioMixer);
3836
}
3937

4038
void Emulator::AddPeripheral(Peripheral* p)
@@ -58,24 +56,54 @@ void Emulator::UsePeripheral(UINT32 i, BOOL b)
5856
usePeripheralIndicators[i] = b;
5957
}
6058

61-
void Emulator::InitVideo(IDirect3DDevice9* direct3DDevice)
59+
UINT32 Emulator::GetVideoWidth()
60+
{
61+
return videoWidth;
62+
}
63+
64+
UINT32 Emulator::GetVideoHeight()
65+
{
66+
return videoHeight;
67+
}
68+
69+
void Emulator::InitVideo(VideoBus* video, UINT32 width, UINT32 height)
6270
{
63-
videoBus.init(direct3DDevice);
71+
if ( video != NULL ) {
72+
videoBus = video;
73+
}
74+
75+
videoBus->init(width, height);
6476
}
6577

6678
void Emulator::ReleaseVideo()
6779
{
68-
videoBus.release();
80+
videoBus->release();
81+
videoBus = NULL;
6982
}
7083

71-
void Emulator::InitAudio(IDirectSoundBuffer8* directSoundBuffer)
84+
void Emulator::InitAudio(AudioMixer* audio, UINT32 sampleRate)
7285
{
73-
audioMixer.init(directSoundBuffer);
86+
if (audio != NULL) {
87+
audioMixer = audio;
88+
}
89+
90+
// TODO: check for an existing audioMixer processor and release it
91+
for (UINT16 i = 0; i < GetProcessorCount(); i++) {
92+
Processor* p = GetProcessor(i);
93+
if (p == audio) {
94+
RemoveProcessor(audio);
95+
}
96+
}
97+
98+
AddProcessor(audioMixer);
99+
audioMixer->init(sampleRate);
74100
}
75101

76102
void Emulator::ReleaseAudio()
77103
{
78-
audioMixer.release();
104+
audioMixer->release();
105+
RemoveProcessor(audioMixer);
106+
audioMixer = NULL;
79107
}
80108

81109
void Emulator::Reset()
@@ -89,8 +117,8 @@ void Emulator::SetRip(Rip* rip)
89117
if (this->currentRip != NULL) {
90118
processorBus.removeAll();
91119
memoryBus.removeAll();
92-
videoBus.removeAll();
93-
audioMixer.removeAll();
120+
videoBus->removeAll();
121+
audioMixer->removeAll();
94122
inputConsumerBus.removeAll();
95123
}
96124

@@ -136,12 +164,12 @@ void Emulator::InsertPeripheral(Peripheral* p)
136164
//video producers
137165
count = p->GetVideoProducerCount();
138166
for (i = 0; i < count; i++)
139-
videoBus.addVideoProducer(p->GetVideoProducer(i));
167+
videoBus->addVideoProducer(p->GetVideoProducer(i));
140168

141169
//audio producers
142170
count = p->GetAudioProducerCount();
143171
for (i = 0; i < count; i++)
144-
audioMixer.addAudioProducer(p->GetAudioProducer(i));
172+
audioMixer->addAudioProducer(p->GetAudioProducer(i));
145173

146174
//input consumers
147175
count = p->GetInputConsumerCount();
@@ -171,12 +199,12 @@ void Emulator::RemovePeripheral(Peripheral* p)
171199
//video producers
172200
count = p->GetVideoProducerCount();
173201
for (i = 0; i < count; i++)
174-
videoBus.removeVideoProducer(p->GetVideoProducer(i));
202+
videoBus->removeVideoProducer(p->GetVideoProducer(i));
175203

176204
//audio producers
177205
count = p->GetAudioProducerCount();
178206
for (i = 0; i < count; i++)
179-
audioMixer.removeAudioProducer(p->GetAudioProducer(i));
207+
audioMixer->removeAudioProducer(p->GetAudioProducer(i));
180208

181209
//input consumers
182210
count = p->GetInputConsumerCount();
@@ -192,12 +220,12 @@ void Emulator::Run()
192220

193221
void Emulator::Render()
194222
{
195-
videoBus.render();
223+
videoBus->render();
196224
}
197225

198226
void Emulator::FlushAudio()
199227
{
200-
audioMixer.flushAudio();
228+
audioMixer->flushAudio();
201229
}
202230

203231
UINT32 Emulator::systemIDs[NUM_EMULATORS] = {

core/Emulator.h

100644100755
Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,6 @@
22
#ifndef EMULATOR_H
33
#define EMULATOR_H
44

5-
#include <d3d9.h>
6-
#include <mmreg.h>
7-
#include <dsound.h>
8-
95
#include "Peripheral.h"
106
#include "core/types.h"
117
#include "core/rip/Rip.h"
@@ -36,14 +32,17 @@ class Emulator : public Peripheral
3632
UINT32 GetPeripheralCount();
3733
Peripheral* GetPeripheral(UINT32);
3834

35+
UINT32 GetVideoWidth();
36+
UINT32 GetVideoHeight();
37+
3938
void UsePeripheral(UINT32, BOOL);
4039

4140
void SetRip(Rip* rip);
4241

43-
void InitVideo(IDirect3DDevice9* direct3DDevice);
44-
void ReleaseVideo();
45-
void InitAudio(IDirectSoundBuffer8* directSoundBuffer);
46-
void ReleaseAudio();
42+
void InitVideo(VideoBus* video, UINT32 width, UINT32 height);
43+
void ReleaseVideo();
44+
void InitAudio(AudioMixer* audio, UINT32 sampleRate);
45+
void ReleaseAudio();
4746

4847
void Reset();
4948
void Run();
@@ -59,10 +58,13 @@ class Emulator : public Peripheral
5958

6059
MemoryBus memoryBus;
6160

61+
UINT32 videoWidth;
62+
UINT32 videoHeight;
63+
6264
private:
6365
ProcessorBus processorBus;
64-
AudioMixer audioMixer;
65-
VideoBus videoBus;
66+
AudioMixer *audioMixer;
67+
VideoBus *videoBus;
6668
InputConsumerBus inputConsumerBus;
6769

6870
void InsertPeripheral(Peripheral* p);

core/Peripheral.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,18 @@ void Peripheral::AddProcessor(Processor* p)
88
processorCount++;
99
}
1010

11+
void Peripheral::RemoveProcessor(Processor* p)
12+
{
13+
for (UINT32 i = 0; i < processorCount; i++) {
14+
if (processors[i] == p) {
15+
for (UINT32 j = i; j < (processorCount-1); j++)
16+
processors[j] = processors[j+1];
17+
processorCount--;
18+
return;
19+
}
20+
}
21+
}
22+
1123
UINT16 Peripheral::GetProcessorCount()
1224
{
1325
return processorCount;

core/Peripheral.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@ class Peripheral
4141
*/
4242
void AddProcessor(Processor* processor);
4343

44+
/**
45+
* Removes a processor from this peripheral.
46+
*
47+
* @param processor the processor to remove
48+
*/
49+
void RemoveProcessor(Processor* processor);
50+
4451
/**
4552
* Gets the number of processors in this peripheral.
4653
*

core/audio/AudioMixer.cpp

100644100755
Lines changed: 39 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11

2-
#include "gui/stdafx.h"
3-
#include "gui/BlissApp.h"
4-
52
#include <stdio.h>
63
#include <string.h>
74
#include "AudioMixer.h"
@@ -10,15 +7,13 @@
107
extern UINT64 lcm(UINT64, UINT64);
118

129
AudioMixer::AudioMixer()
13-
: Processor("Audio Mixer"),
14-
outputBuffer(NULL),
15-
audioProducerCount(0),
16-
commonClocksPerTick(0),
17-
sampleBuffer(NULL),
18-
sampleBufferLength(0),
19-
sampleCount(0),
20-
outputBufferWritePosition(0),
21-
outputBufferSize(0)
10+
: Processor("Audio Mixer"),
11+
audioProducerCount(0),
12+
commonClocksPerTick(0),
13+
sampleBuffer(NULL),
14+
sampleBufferSize(0),
15+
sampleCount(0),
16+
sampleSize(0)
2217
{
2318
memset(&audioProducers, 0, sizeof(audioProducers));
2419
}
@@ -61,11 +56,12 @@ void AudioMixer::removeAll()
6156
void AudioMixer::resetProcessor()
6257
{
6358
//reset instance data
64-
outputBufferWritePosition = 0;
6559
commonClocksPerTick = 0;
6660
sampleCount = 0;
67-
if (sampleBuffer)
68-
memset(sampleBuffer, 0, sampleBufferLength);
61+
62+
if (sampleBuffer) {
63+
memset(sampleBuffer, 0, sampleBufferSize);
64+
}
6965

7066
//iterate through my audio output lines to determine the common output clock
7167
UINT64 totalClockSpeed = getClockSpeed();
@@ -82,45 +78,42 @@ void AudioMixer::resetProcessor()
8278
}
8379
}
8480

85-
void AudioMixer::init(IDirectSoundBuffer8* buffer)
81+
void AudioMixer::init(UINT32 sampleRate)
8682
{
87-
this->outputBuffer = buffer;
88-
DSBCAPS caps;
89-
ZeroMemory(&caps, sizeof(DSBCAPS));
90-
caps.dwSize = sizeof(DSBCAPS);
91-
buffer->GetCaps(&caps);
92-
outputBufferSize = caps.dwBufferBytes;
93-
WAVEFORMATEX wfx;
94-
ZeroMemory(&wfx, sizeof(WAVEFORMATEX));
95-
buffer->GetFormat(&wfx, sizeof(WAVEFORMATEX), NULL);
96-
sampleBufferLength = wfx.nAvgBytesPerSec/10;
97-
sampleBuffer = new UINT8[sampleBufferLength];
98-
memset(sampleBuffer, 0, sampleBufferLength);
99-
sampleCount = 0;
83+
// TODO: assert if sampleRate/clockSpeed is 0
84+
85+
AudioMixer::release();
86+
87+
clockSpeed = sampleRate;
88+
sampleSize = ( clockSpeed / 60.0 );
89+
sampleBufferSize = sampleSize * sizeof(INT16);
90+
sampleBuffer = new INT16[sampleSize];
91+
92+
if (sampleBuffer) {
93+
memset(sampleBuffer, 0, sampleBufferSize);
94+
}
10095
}
10196

10297
void AudioMixer::release()
10398
{
104-
if (outputBuffer) {
105-
this->outputBuffer = NULL;
106-
}
10799
if (sampleBuffer) {
100+
sampleBufferSize = 0;
101+
sampleSize = 0;
102+
sampleCount = 0;
108103
delete[] sampleBuffer;
109104
sampleBuffer = NULL;
110-
sampleBufferLength = 0;
111-
sampleCount = 0;
112105
}
113106
}
114107

115108
INT32 AudioMixer::getClockSpeed()
116109
{
117-
DWORD freq;
118-
outputBuffer->GetFrequency(&freq);
119-
return freq;
110+
return clockSpeed;
120111
}
121112

122113
INT32 AudioMixer::tick(INT32 minimum)
123114
{
115+
// TODO: assert if sampleCount >= sampleSize
116+
124117
for (int totalTicks = 0; totalTicks < minimum; totalTicks++) {
125118
//mix and flush the sample buffers
126119
INT64 totalSample = 0;
@@ -148,39 +141,23 @@ INT32 AudioMixer::tick(INT32 minimum)
148141
nextLine->commonClockCounter = -missingClocks;
149142
}
150143

151-
if (audioProducerCount > 0)
144+
if (audioProducerCount > 1) {
152145
totalSample = totalSample / audioProducerCount;
153-
sampleBuffer[sampleCount++] = (UINT8)(totalSample & 0xFF);
154-
sampleBuffer[sampleCount++] = (UINT8)((totalSample & 0xFF00)>>8);
155-
156-
if (sampleCount == sampleBufferLength)
146+
}
147+
148+
sampleBuffer[sampleCount++] = clipSample(totalSample);
149+
150+
if (sampleCount == sampleSize) {
157151
flushAudio();
152+
}
158153
}
159154

160155
return minimum;
161156
}
162157

163158
void AudioMixer::flushAudio()
164159
{
165-
DWORD currentPos;
166-
UINT32 end = (outputBufferWritePosition + sampleCount) % outputBufferSize;
167-
if (end < outputBufferWritePosition) {
168-
do {
169-
outputBuffer->GetCurrentPosition(&currentPos, NULL);
170-
} while (currentPos >= outputBufferWritePosition || currentPos < end);
171-
}
172-
else {
173-
do {
174-
outputBuffer->GetCurrentPosition(&currentPos, NULL);
175-
} while (currentPos >= outputBufferWritePosition && currentPos < end);
176-
}
177-
DWORD bufSize1, bufSize2;
178-
void* buf1; void* buf2;
179-
outputBuffer->Lock(outputBufferWritePosition, sampleCount, &buf1, &bufSize1, &buf2, &bufSize2, 0);
180-
memcpy(buf1, sampleBuffer, bufSize1);
181-
memcpy(buf2, sampleBuffer+bufSize1, bufSize2);
182-
outputBuffer->Unlock(buf1, bufSize1, buf2, bufSize2);
183-
outputBufferWritePosition = end;
184-
160+
//the platform subclass must copy the sampleBuffer to the device
161+
//before calling here (which discards the contents of sampleBuffer)
185162
sampleCount = 0;
186163
}

0 commit comments

Comments
 (0)