Commits

spencercw committed 1df981b

Add a simple menu so ROMs can be loaded on-demand.

Comments (0)

Files changed (19)

gb_emulator/include/gb_emulator/gb.hpp

 	 */
 	void run();
 
+	//! Resets the emulator.
+	/**
+	 * Path to the new ROM to load; may be empty, in which case no ROM is loaded.
+	 */
+	void reset(const boost::filesystem::path &rom = boost::filesystem::path());
+
 	//! Saves the current state of the emulator.
 	/**
 	 * The file is saved with the same name as the ROM file with the extension replaced with ".sav".

gb_emulator/include/gb_emulator/gb_comms_serial.h

 	GbCommsSerial(Gb &gb, int &cycles, boost::asio::io_service &ioService, const std::string &host,
 		uint16_t port);
 
+	//! Resets the serial comms emulator to its default state.
+	void reset();
+
 	//! Handles events that occur after a period of time.
 	/**
 	 * This should be called when the \c cycles parameter passed to the constructor reaches zero.

gb_emulator/include/gb_emulator/gb_cpu.hpp

 	 */
 	GbCpu(GbMemory &memory);
 
+	//! Resets the CPU emulator to its default state.
+	void reset();
+
 	//! Executes a number of instructions.
 	/**
 	 * \param cycles The number of cycles to execute.

gb_emulator/include/gb_emulator/gb_memory.hpp

 	{
 	}
 
+	//! Resets the memory manager to its default state.
+	virtual void reset() = 0;
+
 	////////////////////////////////////////////////////////////////////////////////////////////////
 	// General accessor functions
 
 	//! Destructor.
 	~GbMemoryImpl();
 
+	//! Resets the memory manager to its default state.
+	void reset();
+
 	////////////////////////////////////////////////////////////////////////////////////////////////
 	// General accessor functions
 

gb_emulator/include/gb_emulator/gb_sound.hpp

 	//! Destructor.
 	virtual ~GbSound();
 
+	//! Resets the sound emulator to its default state.
+	void reset();
+
 	//! Generates a single sample.
 	/**
 	 * The base class implementation does nothing except return the number of CPU cycles that should

gb_emulator/include/gb_emulator/gb_timers.hpp

 	//! Constructor; sets the associated emulator container.
 	GbTimers(Gb &gb);
 
+	//! Resets the timers emulator to its default state.
+	void reset();
+
 	//! Updates the timers.
 	/**
 	 * \return The number of cycles that should be executed before this is next called.

gb_emulator/include/gb_emulator/gb_video.hpp

 	//! Destructor.
 	virtual ~GbVideo();
 
+	//! Resets the video emulator to its default state.
+	void reset();
+
 	//! Renders a line.
 	/**
 	 * \return The number of cycles that should be executed before this is next called.

gb_emulator/src/gb.cpp

 {
 }
 
+void Gb::reset(const fs::path &romPath)
+{
+	frames_ = 0;
+	gbc_ = true;
+
+	cpu_->reset();
+	sound_->reset();
+	video_->reset();
+	mem_->reset();
+	serial_->reset();
+	timers_.reset();
+
+	loadRom(romPath);
+}
+
 void Gb::loadRom(const fs::path &romPath)
 {
 	fs::path path = fs::absolute(romPath);

gb_emulator/src/gb_comms_serial.cpp

 GbCommsSerial::GbCommsSerial(Gb &gb, int &cycles, io::io_service &ioService, uint16_t port):
 gb_(gb),
 cycles_(cycles),
-state_(STATE_IDLE),
 connected_(false),
 server_(true),
-lineState_(true),
-net_(new TcpServer(ioService, port)),
-sequence_(0)
+net_(new TcpServer(ioService, port))
 {
+	reset();
 	connectNetworkSignals();
 }
 
 	uint16_t port):
 gb_(gb),
 cycles_(cycles),
-state_(STATE_IDLE),
 connected_(false),
 server_(false),
-lineState_(true),
-net_(new TcpClient(ioService, host, port)),
-sequence_(0),
-data_(0)
+net_(new TcpClient(ioService, host, port))
 {
+	reset();
 	connectNetworkSignals();
 }
 
+void GbCommsSerial::reset()
+{
+	state_ = STATE_IDLE;
+	intDelay_.reset();
+	lineState_ = true;
+	sequence_ = 0;
+	data_ = 0;
+}
+
 void GbCommsSerial::poll()
 {
 	switch (state_)

gb_emulator/src/gb_cpu.cpp

 mem_(memory),
 debugger_(NULL)
 {
+	reset();
+}
+
+void GbCpu::reset()
+{
 	// Set register values
 	r.r8[A]      = 0x11;
 	r.r8[F]      = 0xb0;

gb_emulator/src/gb_memory.cpp

 GbMemoryImpl::GbMemoryImpl(Gb &gb):
 gb_(gb)
 {
+	reset();
+}
+
+GbMemoryImpl::~GbMemoryImpl()
+{
+}
+
+void GbMemoryImpl::reset()
+{
 	cart_ = ROM_ONLY;
 
 	// Clear memory
 	vramBank_ = 0;
 }
 
-GbMemoryImpl::~GbMemoryImpl()
-{
-}
-
 uint8_t GbMemoryImpl::read(uint16_t ptr) const
 {
 	if (ptr == IE)

gb_emulator/src/gb_sound.cpp

 static const double BASE_VOLUME = 1. / 64;
 
 GbSound::GbSound(Gb &gb):
-	gb_(gb),
-	sampleRate_(0),
-	sampleCycles_(0),
-	gbFrequency1_(0),
-	gbFrequency2_(0),
-	gbFrequency3_(0),
-	actFrequency1_(0),
-	actFrequency2_(0),
-	actFrequency3_(0),
-	actFrequency4_(0),
-	hi1_(false),
-	hi2_(false),
-	duration1_(0),
-	duration2_(0),
-	duration3_(0),
-	duration4_(0),
-	duty1_(1),
-	duty2_(1),
-	countdown1_(0),
-	countdown2_(0),
-	countdown3_(0),
-	countdown4_(0),
-	sweepEnabled1_(false),
-	sweepNextFrequency1_(0),
-	sweepShifts1_(0),
-	sweepType1_(0),
-	sweepStep1_(0),
-	sweepCountdown1_(0),
-	envelope1_(0),
-	envelope2_(0),
-	envelope4_(0),
-	envelopeDirection1_(false),
-	envelopeDirection2_(false),
-	envelopeDirection4_(false),
-	envelopeStep1_(0),
-	envelopeStep2_(0),
-	envelopeStep4_(0),
-	envelopeCountdown1_(0),
-	envelopeCountdown2_(0),
-	envelopeCountdown4_(0),
-	waveIndex3_(0),
-	outLevel3_(0),
-	counterData4_(lfsr15),
-	counterDataSize4_(32768),
-	counterIndex4_(0)
+gb_(gb)
 {
-	memset(wavePattern3_, 0, 0x10);
-	memset(savedRegisters, 0xff, 5);
+	reset();
 }
 
 GbSound::~GbSound()
 {
 }
 
+void GbSound::reset()
+{
+	gbFrequency1_ = 0;
+	gbFrequency2_ = 0;
+	gbFrequency3_ = 0;
+	actFrequency1_ = 0;
+	actFrequency2_ = 0;
+	actFrequency3_ = 0;
+	actFrequency4_ = 0;
+	hi1_ = false;
+	hi2_ = false;
+	duration1_ = 0;
+	duration2_ = 0;
+	duration3_ = 0;
+	duration4_ = 0;
+	duty1_ = 1;
+	duty2_ = 1;
+	countdown1_ = 0;
+	countdown2_ = 0;
+	countdown3_ = 0;
+	countdown4_ = 0;
+	sweepEnabled1_ = false;
+	sweepNextFrequency1_ = 0;
+	sweepShifts1_ = 0;
+	sweepType1_ = 0;
+	sweepStep1_ = 0;
+	sweepCountdown1_ = 0;
+	envelope1_ = 0;
+	envelope2_ = 0;
+	envelope4_ = 0;
+	envelopeDirection1_ = false;
+	envelopeDirection2_ = false;
+	envelopeDirection4_ = false;
+	envelopeStep1_ = 0;
+	envelopeStep2_ = 0;
+	envelopeStep4_ = 0;
+	envelopeCountdown1_ = 0;
+	envelopeCountdown2_ = 0;
+	envelopeCountdown4_ = 0;
+	waveIndex3_ = 0;
+	outLevel3_ = 0;
+	counterData4_ = lfsr15;
+	counterDataSize4_ = 32768;
+	counterIndex4_ = 0;
+
+	memset(wavePattern3_, 0, 0x10);
+	memset(savedRegisters, 0xff, 5);
+}
+
 double GbSound::poll()
 {
 	return sampleCycles_;

gb_emulator/src/gb_timers.cpp

 using std::min;
 
 GbTimers::GbTimers(Gb &gb):
-gb_(gb),
-rtc_(44236800),  // 512 days. This will set the overflow flag.
-dividerCountdown_(0),
-timerCountdown_(0),
-rtcCountdown_(0)
+gb_(gb)
 {
+	reset();
+}
+
+void GbTimers::reset()
+{
+	rtc_ = 44236800;  // 512 days. This will set the overflow flag.
+	dividerCountdown_ = 0;
+	timerCountdown_ = 0;
+	rtcCountdown_ = 0;
 }
 
 int GbTimers::poll()

gb_emulator/src/gb_video.cpp

 gb_(gb),
 pixelBuffer_(new uint16_t[WIDTH * HEIGHT])
 {
+	reset();
+
+	// Initialise hqx
+	hqxInit();
+}
+
+GbVideo::~GbVideo()
+{
+}
+
+void GbVideo::reset()
+{
 	#ifdef DEBUG
 	drawBackground = true;
 	drawWindow = true;
 	// Fill GBC background palette with white
 	memset(gbcBgPalette,     0xff, GBC_PALETTE_SIZE);
 	memset(gbcSpritePalette, 0xff, GBC_PALETTE_SIZE);
-
-	// Initialise hqx
-	hqxInit();
-}
-
-GbVideo::~GbVideo()
-{
 }
 
 int GbVideo::poll()

gb_emulator/src/gb_video_d3d11.cpp

 
 #include <Cg/cgD3D11.h>
 
+#include <CommDlg.h>
 #include <D3D11.h>
 
 #include <gb_emulator/gb.hpp>
 	windowClass.hIcon = NULL;
 	windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
 	windowClass.hbrBackground = NULL;
-	windowClass.lpszMenuName = NULL;
+	windowClass.lpszMenuName = MAKEINTRESOURCEW(101);
 	windowClass.lpszClassName = L"WindowClass";
 	windowClass.hIconSm = NULL;
 
 		}
 		break;
 
+	case WM_COMMAND:
+		switch (wParam & 0xffff)
+		{
+		case 57601:  // Open
+			{
+				wchar_t fileName[32768];
+				fileName[0] = L'\0';
+
+				OPENFILENAMEW ofn;
+				memset(&ofn, 0, sizeof(ofn));
+				ofn.lStructSize = sizeof(ofn);
+				ofn.hwndOwner = hwnd;
+				ofn.lpstrFilter = L"Game Boy ROMs (*.gb, *.gbc)\0*.gb;*.gbc\0";
+				ofn.lpstrFile = fileName;
+				ofn.nMaxFile = sizeof(fileName)/sizeof(fileName[0]);
+				ofn.lpstrTitle = L"Open ROM";
+				ofn.Flags = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST | OFN_NONETWORKBUTTON |
+					OFN_PATHMUSTEXIST;
+
+				if (GetOpenFileNameW(&ofn))
+				{
+					gD3D11->gb_.reset(ofn.lpstrFile);
+				}
+			}
+			break;
+
+		case 57603:  // Save
+			gD3D11->gb_.save();
+			break;
+
+		case 40004:  // Load
+			gD3D11->gb_.load();
+			break;
+
+		case 40001:  // Exit
+			exit(0);
+			break;
+		}
+		break;
+
 	default:
 		return DefWindowProc(hwnd, uMsg, wParam, lParam);
 	}

gb_emulator_main/gb_emulator.rc

Binary file added.

gb_emulator_main/gb_emulator_main.vcxproj

   <ItemGroup>
     <ClCompile Include="main.cpp" />
   </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="gb_emulator.rc" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="resource.h" />
+  </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>

gb_emulator_main/gb_emulator_main.vcxproj.filters

       <Filter>Source Files</Filter>
     </ClCompile>
   </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="gb_emulator.rc">
+      <Filter>Resource Files</Filter>
+    </ResourceCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="resource.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
 </Project>

gb_emulator_main/resource.h

Binary file added.