diff --git a/Chip8/Apu.cpp b/Chip8/Apu.cpp new file mode 100644 index 0000000..d91d9b8 --- /dev/null +++ b/Chip8/Apu.cpp @@ -0,0 +1,22 @@ +#include "Apu.h" + +Apu::Apu() +{ + mutex = Mutex::Create(); +} + +Apu::~Apu() +{ + delete mutex; +} + +void Apu::SetAudioDriver(IAudioDriver *audioDriver) +{ +} + +void Apu::SetBeeping(bool beeping) +{ + mutex->Lock(); + this->beeping = beeping; + mutex->Unlock(); +} diff --git a/Chip8/Apu.h b/Chip8/Apu.h new file mode 100644 index 0000000..47fe503 --- /dev/null +++ b/Chip8/Apu.h @@ -0,0 +1,24 @@ +#ifndef __CHIP8_APU_H__ +#define __CHIP8_APU_H__ + +#include "../Common.h" + +#include "../IAudioDriver.h" + +class Apu +{ +public: + Apu(); + ~Apu(); + + void SetAudioDriver(IAudioDriver *audioDriver); + + void SetBeeping(bool beeping); + +private: + IAudioDriver *audioDriver; + Mutex *mutex; + bool beeping; +}; + +#endif diff --git a/Chip8/Chip8.cpp b/Chip8/Chip8.cpp index a7b952c..5ad75e9 100644 --- a/Chip8/Chip8.cpp +++ b/Chip8/Chip8.cpp @@ -27,7 +27,6 @@ Chip8::Chip8() rom = 0; romSize = 0; stack = new Stack(16); - gpu = new Gpu(); speed = 20; Reset(); } @@ -37,7 +36,6 @@ Chip8::~Chip8() delete [] ram; if (rom) delete rom; delete stack; - delete gpu; } void Chip8::Reset() @@ -50,8 +48,8 @@ void Chip8::Reset() for (int i = 0; i < 4096; i++) ram[i] = random.GetNextInt(256); for (int i = 0; i < 16 * 5; i++) ram[i] = charMem[i]; for (int i = 0; i < 16; i++) inputs[i] = false; - gpu->Clear(); - //apu.SetBeeping(false); + gpu.Clear(); + apu.SetBeeping(false); running = false; waitingForKeypress = false; } @@ -69,7 +67,7 @@ void Chip8::Update() if (timerSound > 0) { timerSound--; - //apu.SetBeeping(timerSound > 0); + apu.SetBeeping(timerSound > 0); } int keyPressReg = 0; @@ -110,7 +108,7 @@ void Chip8::Update() else if(opcode == 0x00e0) { // CLS - gpu->Clear(); + gpu.Clear(); } else if (opcode == 0x00ee) { @@ -244,7 +242,7 @@ void Chip8::Update() case 0xd: // DRW Vx, Vy, nibble - regs[15] = gpu->DrawSprite(regs[x], regs[y], ram + iReg, n); + regs[15] = gpu.DrawSprite(regs[x], regs[y], ram + iReg, n); break; case 0xe: @@ -340,8 +338,7 @@ void Chip8::Update() running = false; } - gpu->Update(); - //apu.Update(); + gpu.Update(); } int Chip8::GetOutputWidth() const @@ -356,7 +353,12 @@ int Chip8::GetOutputHeight() const void Chip8::SetVideoDriver(IVideoDriver *videoDriver) { - gpu->SetVideoDriver(videoDriver); + gpu.SetVideoDriver(videoDriver); +} + +void Chip8::SetAudioDriver(IAudioDriver *audioDriver) +{ + apu.SetAudioDriver(audioDriver); } void Chip8::LoadRom(const List& input) @@ -409,26 +411,6 @@ int Chip8::GetSpeed() const return speed; } -void Chip8::SetAudioEnabled(bool enabled) -{ - //apu.SetEnabled(enabled); -} - -bool Chip8::GetAudioEnabled() const -{ - return false;//apu.GetEnabled(); -} - -void Chip8::SetAudioLatencyMs(int latencyMs) -{ - //apu.SetLatencyMs(latencyMs); -} - -int Chip8::GetAudioLatencyMs() const -{ - return 0;//apu.GetLatencyMs(); -} - void Chip8::invalidOpcode() { throw FSL_EXCEPTION("Invalid opcode"); diff --git a/Chip8/Chip8.h b/Chip8/Chip8.h index 9677c1a..f2b6a4c 100644 --- a/Chip8/Chip8.h +++ b/Chip8/Chip8.h @@ -3,6 +3,9 @@ #include "../Common.h" #include "Gpu.h" +#include "Apu.h" + +#include "../IAudioDriver.h" class Chip8 : public IEmulator { @@ -10,13 +13,14 @@ class Chip8 : public IEmulator Chip8(); ~Chip8(); - void Reset(); - void Update(); + virtual void Reset(); + virtual void Update(); - int GetOutputWidth() const; - int GetOutputHeight() const; + virtual int GetOutputWidth() const; + virtual int GetOutputHeight() const; - void SetVideoDriver(IVideoDriver *videoDriver); + virtual void SetVideoDriver(IVideoDriver *videoDriver); + virtual void SetAudioDriver(IAudioDriver *audioDriver); void LoadRom(const List& input); bool HasRom() const; @@ -27,10 +31,6 @@ class Chip8 : public IEmulator void SetSpeed(int speed); int GetSpeed() const; - void SetAudioEnabled(bool enabled); - bool GetAudioEnabled() const; - void SetAudioLatencyMs(int latencyMs); - int GetAudioLatencyMs() const; private: static void invalidOpcode(); @@ -48,8 +48,8 @@ class Chip8 : public IEmulator Stack *stack; bool inputs[16]; - Gpu *gpu; - //Apu apu; + Gpu gpu; + Apu apu; bool running; bool waitingForKeypress; diff --git a/GLVideoDriver.cpp b/GLVideoDriver.cpp index 09ba996..fef8093 100644 --- a/GLVideoDriver.cpp +++ b/GLVideoDriver.cpp @@ -35,7 +35,6 @@ void GLVideoDriver::SetOutput(int width, int height, const unsigned int *data) wglMakeCurrent(dc, rc); glViewport(0, 0, viewport->GetWidth(), viewport->GetHeight()); - glClear(GL_COLOR_BUFFER_BIT); glBindTexture(GL_TEXTURE_2D, textureHandle); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, data); diff --git a/Main.cpp b/Main.cpp index a036098..45a6461 100644 --- a/Main.cpp +++ b/Main.cpp @@ -117,7 +117,34 @@ int Main(const List& arguments) systemVideoMenu->AddChild(systemVideoZoomMenu); systemMenu->AddChild(systemVideoMenu); + auto systemSpeedMenu = Menu::Create("Speed"); + const int numSpeeds = 10; + const int speeds[] = { 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000 }; + int speedIndex = 4; + List systemSpeedItems; + auto reflectSpeedIndex = [&] + { + auto speed = speeds[speedIndex]; + chip8.SetSpeed(speed); + for (int i = 0; i < systemSpeedItems.Count(); i++) systemSpeedItems[i]->SetChecked(i == speedIndex); + }; + for (int i = 0; i < numSpeeds; i++) + { + auto speed = speeds[i]; + auto item = MenuItem::Create(String(speed) + " instruction" + (speed > 1 ? "s" : "") + "/frame"); + item->Click += [&, i] + { + speedIndex = i; + reflectSpeedIndex(); + }; + systemSpeedMenu->AddChild(item); + systemSpeedItems.Add(item); + } + reflectSpeedIndex(); + systemMenu->AddChild(systemSpeedMenu); + menu->AddChild(systemMenu); + auto helpMenu = Menu::Create("Help"); auto helpAbout = MenuItem::Create("About..."); helpAbout->Click += [&] { MessageWindow::Info(window, "Vip8 - A Chip-8 emulator"); }; @@ -157,6 +184,9 @@ int Main(const List& arguments) delete systemVideoZoomMenu; for (int i = 0; i < systemVideoZoomItems.Count(); i++) delete systemVideoZoomItems[i]; + delete systemSpeedMenu; + for (int i = 0; i < systemSpeedItems.Count(); i++) delete systemSpeedItems[i]; + delete helpMenu; delete helpAbout; delete viewport; diff --git a/Vip8.vcxproj b/Vip8.vcxproj index 38bd02b..ad9e1b3 100644 --- a/Vip8.vcxproj +++ b/Vip8.vcxproj @@ -78,6 +78,7 @@ + @@ -86,6 +87,7 @@ + diff --git a/Vip8.vcxproj.filters b/Vip8.vcxproj.filters index efcfe87..ffab181 100644 --- a/Vip8.vcxproj.filters +++ b/Vip8.vcxproj.filters @@ -16,6 +16,9 @@ + + Chip8 + @@ -28,5 +31,8 @@ + + Chip8 + \ No newline at end of file