Source

gb_emulator / gb_emulator / include / gb_emulator / gb_video.hpp

/*  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_HPP_74CA38E0_8A0E_11E0_A824_0002A5D5C51B
#define GB_VIDEO_HPP_74CA38E0_8A0E_11E0_A824_0002A5D5C51B

#include <stdint.h>

#include <boost/scoped_array.hpp>

#include <Windows.h>

#include <gb_emulator/constants.hpp>

class Gb;
class GbCpu;
class GbVideoData;

//! GameBoy video output emulator.
class GbVideo
{
public:
	//! Pixel priority map.
	uint8_t priorityMap[160];
	//! GameBoy Color background color palette.
	uint8_t gbcBgPalette[GBC_PALETTE_SIZE];
	//! GameBoy Color sprite color palette.
	uint8_t gbcSpritePalette[GBC_PALETTE_SIZE];

	#ifdef DEBUG
	//! Flag specifying whether the background should be drawn.
	bool drawBackground;
	//! Flag specifying whether the window should be drawn.
	bool drawWindow;
	//! Flag specifying whether sprites should be drawn.
	bool drawSprites;
	#endif

	//! Constructor; sets the associated emulator container.
	GbVideo(Gb &gb);

	//! Destructor.
	virtual ~GbVideo();

	//! Indicates whether the video driver is available.
	/**
	 * This function does a runtime check to see whether the video driver can be used.
	 * \return Whether the video driver is available and may be used.
	 */
	virtual bool isAvailable() = 0;

	//! Performs any initialisation that needs to be carried out before processing can start.
	virtual void initialise() = 0;

	//! 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.
	 */
	int poll();

#ifdef DEBUG
	//! Dumps the sprites currently in memory to files.
	void dumpGraphics();
#endif

	//! Saves the current state of the video emulator into the given message.
	void save(GbVideoData &data) const;

	//! Loads the video emulator state from the given message.
	void load(const GbVideoData &data);

protected:
	Gb &gb_;

	// Dimensions of the output display
	static const unsigned WIDTH  = 160;
	static const unsigned HEIGHT = 144;
	
	static const unsigned SCALED_WIDTH  = 4 * WIDTH;
	static const unsigned SCALED_HEIGHT = 4 * HEIGHT;

	//! Redraws the display.
	/**
	 * \param pixelBuffer The screen buffer of pixels to draw. This buffer is \c WIDTH * \c HEIGHT
	 * pixels in size. Each value contains either a 15-bit Game Boy Color RGB colour value or a DMG
	 * palette and index value depending on the value of \c gbc. If it is a DMG value the lower
	 * 8-bits contain the palette and bits 8-9 contain the palette index.
	 * \param gbc Whether the emulator is running in GBC of DMG mode. This specifies the format of
	 * \c pixelBuffer.
	 */
	virtual void draw(uint16_t *pixelBuffer, bool gbc) = 0;

	//! Performs post-processing in software.
	/**
	 * This is designed to be used in conjunction with draw(). It will convert the pixels into the
	 * RGB colour space and upscale the image.
	 * \param pixelBuffer The pixel buffer passed to draw().
	 * \param gbc The \c gbc flag passed to draw().
	 * \param unscaledBuffer The buffer to fill with the processed but unscaled image. This must be
	 * \c WIDTH * \c HEIGHT in size.
	 * \param scaledBuffer The buffer to fill with the processed and upscaled image. This must be
	 * \c SCALED_WIDTH * \c SCALED_HEIGHT in size.
	 */
	static void postProcess(const uint16_t *pixelBuffer, bool gbc, uint32_t *unscaledBuffer,
		uint32_t *scaledBuffer);

private:
	enum DrawType
	{
		DRAW_BACKGROUND,
		DRAW_WINDOW
	};

	// Pixel buffer containing Game Boy format pixels. See draw() for details.
	boost::scoped_array<uint16_t> pixelBuffer_;

	void drawBgWndw(DrawType type);

#ifdef DEBUG
	void dumpTile(int bank, int map, int index);
#endif

	// Disabled operations
	GbVideo(const GbVideo &);
	GbVideo & operator=(const GbVideo &);
};

#endif