⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 directdrawwindow16bpp.cpp

📁 VIGASOCO (VIdeo GAmes SOurce COde) Windows port (v0.01)
💻 CPP
字号:
// DirectDrawWindow16bpp.cpp
//
/////////////////////////////////////////////////////////////////////////////

//#include "Bitmap.h"
#include <cassert>
#include "DirectDrawWindow16bpp.h"
#include "IPalette.h"

/////////////////////////////////////////////////////////////////////////////
// initialization and cleanup
/////////////////////////////////////////////////////////////////////////////

DirectDrawWindow16bpp::DirectDrawWindow16bpp(Win32Settings *settings) : DirectDrawWindow(settings)
{
	_hardware = true;
	_originalPalette = 0;
	_palette = 0;
}

DirectDrawWindow16bpp::~DirectDrawWindow16bpp()
{
}

/////////////////////////////////////////////////////////////////////////////
// Direct Draw initialization and cleanup
/////////////////////////////////////////////////////////////////////////////

bool DirectDrawWindow16bpp::init(const VideoInfo *vi, IPalette *pal)
{
	// default DirectDraw initialization in Windowed mode
	if (!DirectDrawWindow::init(vi, pal)){
		return false;
	}

	// check bpp to see if this plugin can work
	if ((_bpp != 16) && (_bpp != 15)){
		_errorMsg = "DirectDrawWindow32bpp ERROR: desktop is not in 16bpp mode";
		return false;
	}

	// creates the auxiliary surface
	if (!DirectDrawWindow::createAuxiliarySurface((_hardware) ? 1 : _scale, _scale)){
		return false;
	}

	// checks that the visible area width is divisible by 2
	if (!((_visAreaWidth % 2) == 0)){
		_errorMsg = "DirectDrawWindow16bpp ERROR: visible area width is not divisible by 2";
		return false;
	}

	// creates a 16bpp palette from the original one and suscribe for changes
	_originalPalette = pal;
	_palette = new UINT16[pal->getTotalColors()];
	pal->attach(this);
	updateFullPalette(pal);

	_isInitialized = true;

	return true;
}

void DirectDrawWindow16bpp::end()
{
	_isInitialized = false;

	if (_palette){
		delete[] _palette;
		_palette = 0;

		_originalPalette->detach(this);
	}

	DirectDrawWindow::end();
}

/////////////////////////////////////////////////////////////////////////////
// Palette changes
/////////////////////////////////////////////////////////////////////////////

void DirectDrawWindow16bpp::updateFullPalette(IPalette *palette)
{
	for (int i = 0; i < palette->getTotalColors(); i++){
		UINT8 r, g, b;

		palette->getColor(i, r, g, b);
		_palette[i] = DirectDrawPlugin::convertColorTo16bpp(&_palConv, r, g, b);
	}
}

void DirectDrawWindow16bpp::update(IPalette *palette, int data)
{
	if (data != -1){
		// single color update
		UINT8 r, g, b;

		palette->getColor(data, r, g, b);
		_palette[data] = DirectDrawPlugin::convertColorTo16bpp(&_palConv, r, g, b);
	} else {
		// full palette update
		updateFullPalette(palette);	
	}
}

/////////////////////////////////////////////////////////////////////////////
// Render
/////////////////////////////////////////////////////////////////////////////

// renders the screen bitmap to the window
void DirectDrawWindow16bpp::render(bool throttle)
{
	// if any surface was lost, restore it
	if (_auxBuf->IsLost() == DDERR_SURFACELOST){
		_auxBuf->Restore();
	}

	if (_screenBuf->IsLost() == DDERR_SURFACELOST){
		_screenBuf->Restore();
	}

	DDSURFACEDESC ddsd;
	memset(&ddsd, 0, sizeof(ddsd));
	ddsd.dwSize = sizeof(ddsd);

	// waits for exclusive acces to the auxiliary buffer
	DWORD attr = throttle ? DDLOCK_SURFACEMEMORYPTR | DDLOCK_WRITEONLY | DDLOCK_WAIT : DDLOCK_SURFACEMEMORYPTR | DDLOCK_WRITEONLY;
	HRESULT result = _auxBuf->Lock(0, &ddsd, attr, 0);
	if (result != DD_OK) return;

	UINT16 *pIni = (UINT16 *)_actualBitmap->getData();

	// copy visible area to the auxiliary surface
	if (_hardware){
		UINT32 *pSurf = (UINT32 *) ddsd.lpSurface;

		// if we can't get a pointer to the surface, exit
		if (!pSurf){
			return;
		}

		// we can blit 2 pixels in each iteration
		UINT32 *pBuf = (UINT32 *) &pIni[(_visAreaOffsY*_gameWidth) + _visAreaOffsX];
		int pitch = (ddsd.lPitch) >> 2;

		for (int j = 0; j < _visAreaHeight; j++){
			for (int i = 0; i < (_visAreaWidth >> 1); i++){
				pSurf[i] = pBuf[i];
			}
			pSurf += pitch;
			pBuf += _gameWidth >> 1;
		}
	} else {
		UINT16 *pSurf = (UINT16 *) ddsd.lpSurface;

		// if we can't get a pointer to the surface, exit
		if (!pSurf){
			return;
		}

		// we can blit only a pixel in each iteration
		UINT16 *pBuf = (UINT16 *) &pIni[(_visAreaOffsY*_gameWidth) + _visAreaOffsX];
		int pitch = (ddsd.lPitch) >> 1;

		for (int j = 0; j < _visAreaHeight; j++){
			for (int k = 0; k < _scale; k++){
				for (int i = 0; i < _visAreaWidth; i++){
					for (int l = 0; l < _scale; l++){
						*pSurf = pBuf[i];
						pSurf++;
					}
				}
			}
			pSurf += pitch - _visAreaWidth*_scale;
			pBuf += _gameWidth;
		}
	}

	// unlock auxiliary buffer
	_auxBuf->Unlock(0);

	// convert client coordinates to screen coordinates
	RECT rect;
	POINT corner = { 0, 0 };
	GetClientRect(_settings->getHWnd(), &rect);
	ClientToScreen(_settings->getHWnd(), &corner);
	rect.left += corner.x; rect.right += corner.x;
	rect.top += corner.y; rect.bottom += corner.y;

	// copy auxiliary buffer to the primary buffer
	_screenBuf->Blt(&rect, _auxBuf, 0, DDBLT_WAIT, 0);
}

/////////////////////////////////////////////////////////////////////////////
// Draw methods
/////////////////////////////////////////////////////////////////////////////

void DirectDrawWindow16bpp::setPixel(int x, int y, int color)
{
	assert((color >= 0) && (color < _gameColors));

	_actualBitmap->setPixel<UINT16, 16>(x, y, _palette[color]);
}

void DirectDrawWindow16bpp::drawGfx(GfxElement *gfx, int code, int color, int x, int y, int attr)
{
	_actualBitmap->drawGfx<UINT16, 16>(gfx, _palette, code, color, x, y, attr);
}

void DirectDrawWindow16bpp::drawGfxClip(GfxElement *gfx, int code, int color, int x, int y, int attr, Rect *clip)
{
	_actualBitmap->drawGfxClip<UINT16, 16>(gfx, _palette, code, color, x, y, attr, clip);
}

void DirectDrawWindow16bpp::drawGfxTrans(GfxElement *gfx, int code, int color, int x, int y, int attr, int transData)
{
	_actualBitmap->drawGfxTrans<UINT16, 16>(gfx, _palette, code, color, x, y, attr, transData);
}

void DirectDrawWindow16bpp::drawGfxClipTrans(GfxElement *gfx, int code, int color, int x, int y, int attr, Rect *clip, int transData)
{
	_actualBitmap->drawGfxClipTrans<UINT16, 16>(gfx, _palette, code, color, x, y, attr, clip, transData);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -