Commits

spencercw committed 873d8ab

Move the video SDL code into a separate class.

Comments (0)

Files changed (7)

gb_emulator/gb_emulator.vcxproj

     <ClInclude Include="include\gb_emulator\gb_sound_wasapi_renderer.h" />
     <ClInclude Include="include\gb_emulator\gb_timers.hpp" />
     <ClInclude Include="include\gb_emulator\gb_video.hpp" />
+    <ClInclude Include="include\gb_emulator\gb_video_sdl.h" />
     <ClInclude Include="src\gb_sound_tables.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="src\gb_sound_wasapi_renderer.cpp" />
     <ClCompile Include="src\gb_timers.cpp" />
     <ClCompile Include="src\gb_video.cpp" />
+    <ClCompile Include="src\gb_video_sdl.cpp" />
   </ItemGroup>
   <ItemGroup>
     <CustomBuild Include="gb.proto">

gb_emulator/gb_emulator.vcxproj.filters

     <ClInclude Include="include\gb_emulator\gb_sound_wasapi_renderer.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="include\gb_emulator\gb_video_sdl.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="gb.pb.cc">
     <ClCompile Include="src\gb_sound_wasapi_renderer.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="src\gb_video_sdl.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <CustomBuild Include="gb.proto">

gb_emulator/include/gb_emulator/gb.hpp

 #include <gb_emulator/gb_input.hpp>
 #include <gb_emulator/gb_memory.hpp>
 #include <gb_emulator/gb_timers.hpp>
-#include <gb_emulator/gb_video.hpp>
+#include <gb_emulator/gb_video_sdl.h>
 #ifdef _WIN32
 #include <gb_emulator/gb_sound_wasapi.h>
 #else
 #else
 	GbSoundSdl sound_;
 #endif
-	GbVideo video_;
+	GbVideoSdl video_;
 	GbMemory mem_;
 	GbDebugger debugger_;
 	bool gbc_;

gb_emulator/include/gb_emulator/gb_video.hpp

 class Gb;
 class GbCpu;
 class GbVideoData;
-struct SDL_Surface;
 
 //! GameBoy video output emulator.
 class GbVideo
 	//! Constructor; sets the associated emulator container.
 	GbVideo(Gb &gb);
 
+	//! Destructor.
+	virtual ~GbVideo();
+
 	//! Renders a line.
 	/**
 	 * \return The number of cycles that should be executed before this is next called.
 	//! Loads the video emulator state from the given message.
 	void load(const GbVideoData &data);
 
+protected:
+	uint32_t pixelBuffer[160 * 144];
+
+	// Redraws the display
+	virtual void draw() = 0;
+
 private:
 	enum DrawType
 	{
 	};
 
 	Gb &gb_;
-	SDL_Surface *surface_;
-	uint32_t pixelBuffer[160 * 144];
 
 	void drawBgWndw(DrawType type);
 

gb_emulator/include/gb_emulator/gb_video_sdl.h

+/*  Copyright © 2011 Chris Spencer <spencercw@gmail.com>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef GB_VIDEO_SDL_H_75A9CC80_1B63_11E1_B757_0002A5D5C51B
+#define GB_VIDEO_SDL_H_75A9CC80_1B63_11E1_B757_0002A5D5C51B
+
+#include <gb_emulator/gb_video.hpp>
+
+struct SDL_Surface;
+
+//! SDL video driver.
+class GbVideoSdl: public GbVideo
+{
+public:
+	//! Constructor; opens the display.
+	GbVideoSdl(Gb &gb);
+
+private:
+	SDL_Surface *surface_;
+
+	// Redraws the display
+	void draw();
+};
+
+#endif

gb_emulator/src/gb_video.cpp

 #pragma warning(push, 0)
 #endif
 
-#include <SDL/SDL.h>
-
 #include "gb.pb.h"
 
 #ifdef _MSC_VER
 using std::runtime_error;
 using std::string;
 
-class SdlVideoLock
-{
-public:
-	SdlVideoLock(SDL_Surface *surface):
-	surface_(surface)
-	{
-		if (SDL_MUSTLOCK(surface_))
-		{
-			if (!SDL_LockSurface(surface_))
-			{
-				throw runtime_error(string("failed to lock video surface: ") + SDL_GetError());
-			}
-			locked_ = true;
-		}
-		else
-		{
-			locked_ = false;
-		}
-	}
-
-	~SdlVideoLock()
-	{
-		if (locked_)
-		{
-			SDL_UnlockSurface(surface_);
-		}
-	}
-
-private:
-	SDL_Surface *surface_;
-	bool locked_;
-};
-
 GbVideo::GbVideo(Gb &gb):
 	gb_(gb)
 {
 	drawSprites = true;
 	#endif
 
-	// Create display
-	if (!SDL_WasInit(SDL_INIT_VIDEO))
-	{
-		SDL_InitSubSystem(SDL_INIT_VIDEO);
-	}
-
-	surface_ = SDL_SetVideoMode(160 * 3, 144 * 3, 32, SDL_SWSURFACE);
-	if (!surface_)
-	{
-		throw runtime_error(string("failed to create video surface: ") + SDL_GetError());
-	}
 	memset(priorityMap, 0, sizeof(priorityMap));
 
 	// Fill GBC background palette with white
 	hqxInit();
 }
 
+GbVideo::~GbVideo()
+{
+}
+
 int GbVideo::poll()
 {
 	if (!(gb_.mem_.ioPorts[LCDC] & LCDC_OPERATIONAL))
 	}
 	else if (gb_.mem_.ioPorts[LCDC_Y] == VBLANK_START)
 	{
-		// Scale the image and redraw the display
-		{
-			SdlVideoLock lock(surface_);
-			hq3x_32(pixelBuffer, static_cast<uint32_t *>(surface_->pixels), 160, 144);
-			SDL_UpdateRect(surface_, 0, 0, 0, 0);
-		}
+		// Redraw the display
+		draw();
 
 		// Flag the VBLANK interrupt
 		gb_.mem_.ioPorts[IF] |= VBLANK_INTR;

gb_emulator/src/gb_video_sdl.cpp

+/*  Copyright © 2011 Chris Spencer <spencercw@gmail.com>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <gb_emulator/gb_video_sdl.h>
+
+#include <stdexcept>
+#include <string>
+
+#ifdef _MSC_VER
+#pragma warning(push, 0)
+#endif
+
+#include <SDL/SDL.h>
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <hqx.h>
+
+using std::runtime_error;
+using std::string;
+
+class SdlVideoLock
+{
+public:
+	SdlVideoLock(SDL_Surface *surface):
+	surface_(surface)
+	{
+		if (SDL_MUSTLOCK(surface_))
+		{
+			if (!SDL_LockSurface(surface_))
+			{
+				throw runtime_error(string("failed to lock video surface: ") + SDL_GetError());
+			}
+			locked_ = true;
+		}
+		else
+		{
+			locked_ = false;
+		}
+	}
+
+	~SdlVideoLock()
+	{
+		if (locked_)
+		{
+			SDL_UnlockSurface(surface_);
+		}
+	}
+
+private:
+	SDL_Surface *surface_;
+	bool locked_;
+};
+
+GbVideoSdl::GbVideoSdl(Gb &gb):
+GbVideo(gb)
+{
+	// Create the display
+	if (!SDL_WasInit(SDL_INIT_VIDEO))
+	{
+		SDL_InitSubSystem(SDL_INIT_VIDEO);
+	}
+
+	surface_ = SDL_SetVideoMode(160 * 3, 144 * 3, 32, SDL_SWSURFACE);
+	if (!surface_)
+	{
+		throw runtime_error(string("failed to create video surface: ") + SDL_GetError());
+	}
+}
+
+void GbVideoSdl::draw()
+{
+	SdlVideoLock lock(surface_);
+	hq3x_32(pixelBuffer, static_cast<uint32_t *>(surface_->pixels), 160, 144);
+	SDL_UpdateRect(surface_, 0, 0, 0, 0);
+}