Skip to content

Commit

Permalink
Merge branch 'states'
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremiah-sypult committed Oct 28, 2014
2 parents ed530d1 + 3e6151c commit 9767e46
Show file tree
Hide file tree
Showing 45 changed files with 1,254 additions and 87 deletions.
6 changes: 6 additions & 0 deletions ReleaseNotes.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
v2.1.0 - October 27, 2014
- Added support for saving and loading Intellivision game states.
- Refactored code for multi-platform support.
See https://github.com/jeremiah-sypult/BlissEmu and
https://github.com/OpenEmu/OpenEmu

v2.0.5 - May 25, 2005
- Added support for the Classic Game Controller (CGC).
See http://www.shiny-technologies.com/cgc.php for details on this device.
Expand Down
3 changes: 2 additions & 1 deletion ToDo.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
- offer the ability to display the overlays somehow, maybe as a toggle display for the
lower left and right sides of the screen
- input
- move Classic Game Controller (CGC) support code out of core (Windows)
- bug where I can't add bindings to the ECS keyboard default bindings; have to clear the
binding first because it's getting confused somehow
- allow the user to custom-bind different controls to different games
- saving and loading
- saving and loading game state
- saving and loading atari 5200 game state
- saving screenshots
- record/playback (save the inputs and play them back)
- record audio
Expand Down
53 changes: 28 additions & 25 deletions core/Emulator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,52 +58,56 @@ void Emulator::UsePeripheral(UINT32 i, BOOL b)

UINT32 Emulator::GetVideoWidth()
{
return videoWidth;
return videoWidth;
}

UINT32 Emulator::GetVideoHeight()
{
return videoHeight;
return videoHeight;
}

void Emulator::InitVideo(VideoBus* video, UINT32 width, UINT32 height)
{
if ( video != NULL ) {
videoBus = video;
}
if ( video != NULL ) {
videoBus = video;
}

videoBus->init(width, height);
}

void Emulator::ReleaseVideo()
{
videoBus->release();
videoBus = NULL;
if (videoBus) {
videoBus->release();
videoBus = NULL;
}
}

void Emulator::InitAudio(AudioMixer* audio, UINT32 sampleRate)
{
if (audio != NULL) {
audioMixer = audio;
}
if (audio != NULL) {
audioMixer = audio;
}

// TODO: check for an existing audioMixer processor and release it
for (UINT16 i = 0; i < GetProcessorCount(); i++) {
Processor* p = GetProcessor(i);
if (p == audio) {
RemoveProcessor(audio);
}
}
// TODO: check for an existing audioMixer processor and release it
for (UINT16 i = 0; i < GetProcessorCount(); i++) {
Processor* p = GetProcessor(i);
if (p == audio) {
RemoveProcessor(audio);
}
}

AddProcessor(audioMixer);
audioMixer->init(sampleRate);
AddProcessor(audioMixer);
audioMixer->init(sampleRate);
}

void Emulator::ReleaseAudio()
{
audioMixer->release();
RemoveProcessor(audioMixer);
audioMixer = NULL;
if (audioMixer) {
audioMixer->release();
RemoveProcessor(audioMixer);
audioMixer = NULL;
}
}

void Emulator::Reset()
Expand Down Expand Up @@ -141,7 +145,7 @@ void Emulator::SetRip(Rip* rip)

void Emulator::InsertPeripheral(Peripheral* p)
{
UINT16 i;
UINT16 i;

//processors
UINT16 count = p->GetProcessorCount();
Expand Down Expand Up @@ -179,7 +183,7 @@ void Emulator::InsertPeripheral(Peripheral* p)

void Emulator::RemovePeripheral(Peripheral* p)
{
UINT16 i;
UINT16 i;

//processors
UINT16 count = p->GetProcessorCount();
Expand Down Expand Up @@ -240,4 +244,3 @@ Emulator* Emulator::emus[] = {
&atari5200,
&inty,
};

36 changes: 31 additions & 5 deletions core/Emulator.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,30 @@
#include "core/memory/MemoryBus.h"
#include "core/memory/Memory.h"

typedef struct _StateHeader
{
UINT32 emu;
UINT32 state;
UINT32 emuID;
UINT32 version;
UINT32 sys;
UINT32 sysID;
UINT32 cart;
UINT32 cartID;
} StateHeader;

typedef struct _StateChunk
{
UINT32 id;
UINT32 size;
} StateChunk;

#if defined(DEBUG)
#define EMU_STATE_VERSION ('dev\0')
#else
#define EMU_STATE_VERSION (0x02010000)
#endif

class Intellivision;
class Atari5200;

Expand Down Expand Up @@ -49,6 +73,9 @@ class Emulator : public Peripheral
void FlushAudio();
void Render();

virtual BOOL SaveState(const CHAR* filename) = 0;
virtual BOOL LoadState(const CHAR* filename) = 0;

static UINT32 GetEmulatorCount();
static Emulator* GetEmulator(UINT32 i);
static Emulator* GetEmulatorByID(UINT32 targetSystemID);
Expand All @@ -58,8 +85,10 @@ class Emulator : public Peripheral

MemoryBus memoryBus;

UINT32 videoWidth;
UINT32 videoHeight;
Rip* currentRip;

UINT32 videoWidth;
UINT32 videoHeight;

private:
ProcessorBus processorBus;
Expand All @@ -70,8 +99,6 @@ class Emulator : public Peripheral
void InsertPeripheral(Peripheral* p);
void RemovePeripheral(Peripheral* p);

Rip* currentRip;

Peripheral* peripherals[MAX_PERIPHERALS];
BOOL usePeripheralIndicators[MAX_PERIPHERALS];
INT32 peripheralCount;
Expand All @@ -84,4 +111,3 @@ class Emulator : public Peripheral
};

#endif

67 changes: 67 additions & 0 deletions core/audio/AY38914.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,3 +221,70 @@ INT32 AY38914::tick(INT32 minimum)
return totalTicks;
}

AY38914State AY38914::getState()
{
AY38914State state = {0};

this->registers.getMemory(state.registers, 0, this->registers.getMemoryByteSize());

state.clockDivisor = this->clockDivisor;

state.channel0 = this->channel0.getState();
state.channel1 = this->channel1.getState();
state.channel2 = this->channel2.getState();

state.cachedTotalOutputIsDirty = this->cachedTotalOutputIsDirty;
state.cachedTotalOutput = this->cachedTotalOutput;

state.envelopeIdle = this->envelopeIdle;
state.envelopePeriod = this->envelopePeriod;
state.envelopePeriodValue = this->envelopePeriodValue;
state.envelopeCounter = this->envelopeCounter;
state.envelopeVolume = this->envelopeVolume;
state.envelopeHold = this->envelopeHold;
state.envelopeAltr = this->envelopeAltr;
state.envelopeAtak = this->envelopeAtak;
state.envelopeCont = this->envelopeCont;

state.noiseIdle = this->noiseIdle;
state.noisePeriod = this->noisePeriod;
state.noisePeriodValue = this->noisePeriodValue;
state.noiseCounter = this->noiseCounter;

state.random = this->random;
state.noise = this->noise;

return state;
}

void AY38914::setState(AY38914State state)
{
this->registers.setMemory(state.registers, 0, this->registers.getMemoryByteSize());

this->clockDivisor = state.clockDivisor;

this->channel0.setState(state.channel0);
this->channel1.setState(state.channel1);
this->channel2.setState(state.channel2);

this->cachedTotalOutputIsDirty = state.cachedTotalOutputIsDirty;
this->cachedTotalOutput = state.cachedTotalOutput;

this->envelopeIdle = state.envelopeIdle;
this->envelopePeriod = state.envelopePeriod;
this->envelopePeriodValue = state.envelopePeriodValue;
this->envelopeCounter = state.envelopeCounter;
this->envelopeVolume = state.envelopeVolume;
this->envelopeHold = state.envelopeHold;
this->envelopeAltr = state.envelopeAltr;
this->envelopeAtak = state.envelopeAtak;
this->envelopeCont = state.envelopeCont;

this->noiseIdle = state.noiseIdle;
this->noisePeriod = state.noisePeriod;
this->noisePeriodValue = state.noisePeriodValue;
this->noiseCounter = state.noiseCounter;

this->random = state.random;
this->noise = state.noise;
}
31 changes: 29 additions & 2 deletions core/audio/AY38914.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,32 @@

class Intellivision;

TYPEDEF_STRUCT_PACK( _AY38914State
{
UINT16 registers[0x0E];
AY38914_ChannelState channel0;
AY38914_ChannelState channel1;
AY38914_ChannelState channel2;
INT32 clockDivisor;
INT32 cachedTotalOutput;
INT32 envelopePeriod;
INT32 envelopePeriodValue;
INT32 envelopeCounter;
INT32 envelopeVolume;
INT32 noisePeriod;
INT32 noisePeriodValue;
INT32 noiseCounter;
INT32 random;
INT8 cachedTotalOutputIsDirty;
INT8 envelopeIdle;
INT8 envelopeHold;
INT8 envelopeAltr;
INT8 envelopeAtak;
INT8 envelopeCont;
INT8 noiseIdle;
INT8 noise;
} AY38914State; )

/**
* The AY-3-8914 chip in the Intellivision, also known as the Programmable
* Sound Generator (PSG).
Expand All @@ -35,6 +61,9 @@ class AY38914 : public Processor, public AudioProducer
void setClockDivisor(INT32 clockDivisor);
INT32 getClockDivisor();

AY38914State getState();
void setState(AY38914State state);

//registers
AY38914_Registers registers;

Expand Down Expand Up @@ -77,8 +106,6 @@ class AY38914 : public Processor, public AudioProducer

//output amplitudes for a single channel
static const INT32 amplitudes16Bit[16];

};

#endif

30 changes: 30 additions & 0 deletions core/audio/AY38914_Channel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,33 @@ void AY38914_Channel::reset() {
isDirty = TRUE;
cachedSample = 0;
}

AY38914_ChannelState AY38914_Channel::getState()
{
AY38914_ChannelState state = {0};

state.period = this->period;
state.periodValue = this->periodValue;
state.volume = this->volume;
state.toneCounter = this->toneCounter;
state.tone = this->tone;
state.envelope = this->envelope;
state.toneDisabled = this->toneDisabled;
state.noiseDisabled = this->noiseDisabled;

return state;
}

void AY38914_Channel::setState(AY38914_ChannelState state)
{
this->period = state.period;
this->periodValue = state.periodValue;
this->volume = state.volume;
this->toneCounter = state.toneCounter;
this->tone = state.tone;
this->envelope = state.envelope;
this->toneDisabled = state.toneDisabled;
this->noiseDisabled = state.noiseDisabled;

this->isDirty = TRUE;
}
17 changes: 15 additions & 2 deletions core/audio/AY38914_Channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,27 @@
class AY38914;
class AY38914_Registers;

TYPEDEF_STRUCT_PACK( _AY38914_ChannelState
{
INT32 period;
INT32 periodValue;
INT32 volume;
INT32 toneCounter;
INT8 tone;
INT8 envelope;
INT8 toneDisabled;
INT8 noiseDisabled;
} AY38914_ChannelState; )

class AY38914_Channel
{

friend class AY38914;
friend class AY38914_Registers;

AY38914_ChannelState getState();
void setState(AY38914_ChannelState state);

private:
void reset();

Expand All @@ -26,8 +41,6 @@ class AY38914_Channel
BOOL noiseDisabled;
BOOL isDirty;
INT32 cachedSample;

};

#endif

Loading

0 comments on commit 9767e46

Please sign in to comment.