1
0
mirror of https://github.com/k4zmu2a/SpaceCadetPinball.git synced 2024-11-07 03:12:58 +01:00

gdrv v2, ready.

This commit is contained in:
oz 2020-11-13 19:04:58 +03:00
parent 989ba6cdb2
commit 2376ffcbc1
5 changed files with 345 additions and 113 deletions

Binary file not shown.

View File

@ -22,6 +22,7 @@ int main()
char cmdLine[1]{}; char cmdLine[1]{};
//WinMain(pinball::hinst, 0, cmdLine, 10); //WinMain(pinball::hinst, 0, cmdLine, 10);
gdrv::init(0, 0);
auto dib = gdrv::DibCreate(8, 1, 1); auto dib = gdrv::DibCreate(8, 1, 1);
gdrv::DibSetUsage(dib, 0, 1); gdrv::DibSetUsage(dib, 0, 1);

View File

@ -1,69 +1,91 @@
#include "pch.h" #include "pch.h"
#include "gdrv.h" #include "gdrv.h"
#include "memory.h" #include "memory.h"
#include "winmain.h"
HPALETTE gdrv::palette_handle=0; HPALETTE gdrv::palette_handle = nullptr;
HINSTANCE gdrv::hinst;
HWND gdrv::hwnd;
LOGPALETTEx256 gdrv::current_palette{};
int gdrv::sequence_handle;
HDC gdrv::sequence_hdc;
int gdrv::use_wing = 0;
int gdrv::init(HINSTANCE hInst, HWND hWnd)
{
hinst = hInst;
hwnd = hWnd;
if (!palette_handle)
palette_handle = CreatePalette((LOGPALETTE*)&current_palette);
return 0;
}
int gdrv::uninit()
{
if (palette_handle)
DeleteObject(palette_handle);
return 0;
}
void gdrv::get_focus() void gdrv::get_focus()
{ {
} }
gdrv_dib* gdrv::DibCreate(__int16 bpp, int width, int height) BITMAPINFO* gdrv::DibCreate(__int16 bpp, int width, int height)
{ {
auto sizeBytes = height * ((width * bpp / 8 + 3) & 0xFFFFFFFC); auto sizeBytes = height * ((width * bpp / 8 + 3) & 0xFFFFFFFC);
auto buf = GlobalAlloc(0x42u, sizeBytes + 1064); auto buf = GlobalAlloc(0x42u, sizeBytes + 1064);
auto dib = static_cast<gdrv_dib*>(GlobalLock(buf)); auto dib = static_cast<BITMAPINFO*>(GlobalLock(buf));
if (!dib) if (!dib)
return nullptr; return nullptr;
dib->BufferSize = sizeBytes; dib->bmiHeader.biSizeImage = sizeBytes;
dib->Width = width; dib->bmiHeader.biWidth = width;
dib->PaletteOffset = 40; dib->bmiHeader.biSize = 40;
dib->Height = height; dib->bmiHeader.biHeight = height;
dib->Unknown3_1 = 1; dib->bmiHeader.biPlanes = 1;
dib->Bpp = bpp; dib->bmiHeader.biBitCount = bpp;
dib->Unknown4 = 0; dib->bmiHeader.biCompression = 0;
dib->Unknown6 = 0; dib->bmiHeader.biXPelsPerMeter = 0;
dib->Unknown7 = 0; dib->bmiHeader.biYPelsPerMeter = 0;
dib->NumberOfColors = 0; dib->bmiHeader.biClrUsed = 0;
dib->Unknown9 = 0; dib->bmiHeader.biClrImportant = 0;
if (bpp == 4) if (bpp == 4)
{ {
dib->NumberOfColors = 16; dib->bmiHeader.biClrUsed = 16;
} }
else if (bpp == 8) else if (bpp == 8)
{ {
dib->NumberOfColors = 256; dib->bmiHeader.biClrUsed = 256;
} }
auto pltPtr = &dib->Palette0; int index = 0;
for (auto index = 0; index < dib->NumberOfColors / 16; ++index, pltPtr++) for (auto i = (int*)dib->bmiColors; index < static_cast<signed int>(dib->bmiHeader.biClrUsed) / 16; ++index)
{ {
*pltPtr = gdrv_dib_palette{ *i++ = 0;
{0}, *i++ = 0x800000;
{0x800000}, *i++ = 0x8000;
{0x8000}, *i++ = 8421376;
{8421376}, *i++ = 128;
{128}, *i++ = 8388736;
{8388736}, *i++ = 32896;
{32896}, *i++ = 12632256;
{12632256}, *i++ = 8421504;
{8421504}, *i++ = 16711680;
{16711680}, *i++ = 65280;
{65280}, *i++ = 16776960;
{16776960}, *i++ = 255;
{255}, *i++ = 16711935;
{16711935}, *i++ = 0xFFFF;
{0xFFFF}, *i++ = 0xFFFFFF;
{0xFFFFFF},
};
} }
return dib; return dib;
} }
void gdrv::DibSetUsage(gdrv_dib* dib, HPALETTE hpal, int someFlag) void gdrv::DibSetUsage(BITMAPINFO* dib, HPALETTE hpal, int someFlag)
{ {
tagPALETTEENTRY pPalEntries[256]; // [esp+4h] [ebp-400h] tagPALETTEENTRY pPalEntries[256]; // [esp+4h] [ebp-400h]
@ -71,18 +93,18 @@ void gdrv::DibSetUsage(gdrv_dib* dib, HPALETTE hpal, int someFlag)
hpal = static_cast<HPALETTE>(GetStockObject(DEFAULT_PALETTE)); hpal = static_cast<HPALETTE>(GetStockObject(DEFAULT_PALETTE));
if (!dib) if (!dib)
return; return;
int numOfColors = dib->NumberOfColors; int numOfColors = dib->bmiHeader.biClrUsed;
if (!numOfColors) if (!numOfColors)
{ {
auto bpp = dib->Bpp; auto bpp = dib->bmiHeader.biBitCount;
if (bpp <= 8u) if (bpp <= 8u)
numOfColors = 1 << bpp; numOfColors = 1 << bpp;
} }
if (numOfColors > 0 && (dib->Unknown4 != 3 || numOfColors == 3)) if (numOfColors > 0 && (dib->bmiHeader.biCompression != 3 || numOfColors == 3))
{ {
if (someFlag && someFlag <= 2) if (someFlag && someFlag <= 2)
{ {
auto pltPtr = (short*)((char*)dib + dib->PaletteOffset); auto pltPtr = (short*)((char*)dib + dib->bmiHeader.biSize);
for (int i = 0; i < numOfColors; ++i) for (int i = 0; i < numOfColors; ++i)
{ {
*pltPtr++ = i; *pltPtr++ = i;
@ -91,7 +113,7 @@ void gdrv::DibSetUsage(gdrv_dib* dib, HPALETTE hpal, int someFlag)
else else
{ {
assertm(false, "Entered bad code"); assertm(false, "Entered bad code");
char* dibPtr = (char*)dib + dib->PaletteOffset; char* dibPtr = (char*)dib + dib->bmiHeader.biSize;
if (numOfColors >= 256) if (numOfColors >= 256)
numOfColors = 256; numOfColors = 256;
GetPaletteEntries(hpal, 0, numOfColors, pPalEntries); GetPaletteEntries(hpal, 0, numOfColors, pPalEntries);
@ -115,7 +137,7 @@ void gdrv::DibSetUsage(gdrv_dib* dib, HPALETTE hpal, int someFlag)
int gdrv::create_bitmap_dib(gdrv_bitmap8* bmp, int width, int height) int gdrv::create_bitmap_dib(gdrv_bitmap8* bmp, int width, int height)
{ {
char* bmpBufPtr; // ecx char* bmpBufPtr; // ecx
gdrv_dib* dib = DibCreate(8, width, height); auto dib = DibCreate(8, width, height);
DibSetUsage(dib, palette_handle, 1); DibSetUsage(dib, palette_handle, 1);
bmp->Dib = dib; bmp->Dib = dib;
@ -123,14 +145,14 @@ int gdrv::create_bitmap_dib(gdrv_bitmap8* bmp, int width, int height)
bmp->Stride = width; bmp->Stride = width;
if (width % 4) if (width % 4)
bmp->Stride = 4 - width % 4 + width; bmp->Stride = 4 - width % 4 + width;
gdrv_dib* dib2 = bmp->Dib;
bmp->Height = height;
bmp->SomeByte = 2;
if (dib2->Unknown4 == 3) bmp->Height = height;
bmpBufPtr = (char*)&dib2->Unknown3_1 + dib2->PaletteOffset; bmp->BitmapType = BitmapType::DibBitmap;
if (dib->bmiHeader.biCompression == 3)
bmpBufPtr = (char*)&dib->bmiHeader.biPlanes + dib->bmiHeader.biSize;
else else
bmpBufPtr = (char*)&dib2->PaletteOffset + 4 * dib2->NumberOfColors + dib2->PaletteOffset; bmpBufPtr = (char*)&dib->bmiHeader.biSize + 4 * dib->bmiHeader.biClrUsed + dib->bmiHeader.biSize;
bmp->BmpBufPtr1 = bmpBufPtr; bmp->BmpBufPtr1 = bmpBufPtr;
bmp->BmpBufPtr2 = bmpBufPtr; bmp->BmpBufPtr2 = bmpBufPtr;
return 0; return 0;
@ -150,7 +172,7 @@ int gdrv::create_raw_bitmap(gdrv_bitmap8* bmp, int width, int height, int flag)
bmp->Stride = width - width % 4 + 4; bmp->Stride = width - width % 4 + 4;
unsigned int sizeInBytes = height * bmp->Stride; unsigned int sizeInBytes = height * bmp->Stride;
bmp->Height = height; bmp->Height = height;
bmp->SomeByte = 1; bmp->BitmapType = BitmapType::RawBitmap;
char* buf = memory::allocate(sizeInBytes); char* buf = memory::allocate(sizeInBytes);
bmp->BmpBufPtr1 = buf; bmp->BmpBufPtr1 = buf;
if (!buf) if (!buf)
@ -158,3 +180,212 @@ int gdrv::create_raw_bitmap(gdrv_bitmap8* bmp, int width, int height, int flag)
bmp->BmpBufPtr2 = buf; bmp->BmpBufPtr2 = buf;
return 0; return 0;
} }
int gdrv::display_palette(PALETTEENTRY* plt)
{
if (palette_handle)
DeleteObject(palette_handle);
palette_handle = CreatePalette((LOGPALETTE*)&current_palette);
auto windowHandle = GetDesktopWindow();
auto dc = winmain::_GetDC(windowHandle);
SetSystemPaletteUse(dc, 2u);
SetSystemPaletteUse(dc, 1u);
auto pltHandle = SelectPalette(dc, palette_handle, 0);
RealizePalette(dc);
SelectPalette(dc, pltHandle, 0);
GetSystemPaletteEntries(dc, 0, 0x100u, current_palette.palPalEntry);
for (int i = 0; i < 256; i++)
{
current_palette.palPalEntry[i].peFlags = 0;
}
auto pltSrc = &plt[10];
auto pltDst = &current_palette.palPalEntry[10];
for (int index = 236; index > 0; --index)
{
if (plt)
{
pltDst->peRed = pltSrc->peRed;
pltDst->peGreen = pltSrc->peGreen;
pltDst->peBlue = pltSrc->peBlue;
}
pltDst->peFlags = 4;
pltSrc++;
pltDst++;
}
if (!(GetDeviceCaps(dc, 38) & 0x100))
{
current_palette.palPalEntry[255].peBlue = -1;
current_palette.palPalEntry[255].peGreen = -1;
current_palette.palPalEntry[255].peRed = -1;
}
ResizePalette(palette_handle, 0x100u);
SetPaletteEntries(palette_handle, 0, 0x100u, current_palette.palPalEntry);
windowHandle = GetDesktopWindow();
ReleaseDC(windowHandle, dc);
return 0;
}
int gdrv::destroy_bitmap(gdrv_bitmap8* bmp)
{
if (!bmp)
return -1;
if (bmp->BitmapType == BitmapType::RawBitmap)
{
memory::free(bmp->BmpBufPtr1);
}
else if (bmp->BitmapType == BitmapType::DibBitmap)
{
GlobalUnlock(GlobalHandle(bmp->Dib));
GlobalFree(GlobalHandle(bmp->Dib));
}
memset(bmp, 0, sizeof(gdrv_bitmap8));
return 0;
}
UINT gdrv::start_blit_sequence()
{
HDC dc = winmain::_GetDC(hwnd);
sequence_handle = 0;
sequence_hdc = dc;
SelectPalette(dc, palette_handle, 0);
return RealizePalette(sequence_hdc);
}
void gdrv::blit_sequence(gdrv_bitmap8* bmp, int xSrc, int ySrcOff, int xDest, int yDest, int DestWidth, int DestHeight)
{
if (!use_wing)
StretchDIBits(
sequence_hdc,
xDest,
yDest,
DestWidth,
DestHeight,
xSrc,
bmp->Height - ySrcOff - DestHeight,
DestWidth,
DestHeight,
bmp->BmpBufPtr1,
bmp->Dib,
1u,
SRCCOPY);
}
void gdrv::end_blit_sequence()
{
ReleaseDC(hwnd, sequence_hdc);
}
void gdrv::blit(gdrv_bitmap8* bmp, int xSrc, int ySrcOff, int xDest, int yDest, int DestWidth, int DestHeight)
{
HDC dc = winmain::_GetDC(hwnd);
if (dc)
{
SelectPalette(dc, palette_handle, 0);
RealizePalette(dc);
if (!use_wing)
StretchDIBits(
dc,
xDest,
yDest,
DestWidth,
DestHeight,
xSrc,
bmp->Height - ySrcOff - DestHeight,
DestWidth,
DestHeight,
bmp->BmpBufPtr1,
bmp->Dib,
1u,
SRCCOPY);
ReleaseDC(hwnd, dc);
}
}
void gdrv::blat(gdrv_bitmap8* bmp, int xDest, int yDest)
{
HDC dc = winmain::_GetDC(hwnd);
SelectPalette(dc, palette_handle, 0);
RealizePalette(dc);
if (!use_wing)
StretchDIBits(
dc,
xDest,
yDest,
bmp->Width,
bmp->Height,
0,
0,
bmp->Width,
bmp->Height,
bmp->BmpBufPtr1,
bmp->Dib,
1u,
SRCCOPY);
ReleaseDC(hwnd, dc);
}
void gdrv::fill_bitmap(gdrv_bitmap8* bmp, int width, int height, int xOff, int yOff, char fillChar)
{
int bmpHeight = bmp->Height;
if (bmpHeight < 0)
bmpHeight = -bmpHeight;
char* bmpPtr = &bmp->BmpBufPtr1[bmp->Width * (bmpHeight - height - yOff) + xOff];
if (height > 0)
{
do
{
if (width > 0)
memset(bmpPtr, fillChar, width);
bmpPtr += bmp->Stride;
--height;
}
while (height);
}
}
void gdrv::copy_bitmap(gdrv_bitmap8* dstBmp, int width, int height, int xOff, int yOff, gdrv_bitmap8* srcBmp,
int srcXOff, int srcYOff)
{
int dstHeight = abs(dstBmp->Height);
int srcHeight = abs(srcBmp->Height);
char* srcPtr = &srcBmp->BmpBufPtr1[srcBmp->Stride * (srcHeight - height - srcYOff) + srcXOff];
char* dstPtr = &dstBmp->BmpBufPtr1[dstBmp->Stride * (dstHeight - height - yOff) + xOff];
for (int y = height; y > 0; --y)
{
for (int x = width; x > 0; --x)
*dstPtr++ = *srcPtr++;
srcPtr += srcBmp->Stride - width;
dstPtr += dstBmp->Stride - width;
}
}
void gdrv::copy_bitmap_w_transparency(gdrv_bitmap8* dstBmp, int width, int height, int xOff, int yOff,
gdrv_bitmap8* srcBmp, int srcXOff, int srcYOff)
{
int dstHeight = abs(dstBmp->Height);
int srcHeight = abs(srcBmp->Height);
char* srcPtr = &srcBmp->BmpBufPtr1[srcBmp->Stride * (srcHeight - height - srcYOff) + srcXOff];
char* dstPtr = &dstBmp->BmpBufPtr1[dstBmp->Stride * (dstHeight - height - yOff) + xOff];
for (int y = height; y > 0; --y)
{
for (int x = width; x > 0; --x)
{
if (*srcPtr)
*dstPtr = *srcPtr;
++srcPtr;
++dstPtr;
}
srcPtr += srcBmp->Stride - width;
dstPtr += dstBmp->Stride - width;
}
}

View File

@ -1,93 +1,74 @@
#pragma once #pragma once
union tagPALETTEENTRY2 enum class BitmapType : char
{ {
unsigned __int32 PltInt; None = 0,
tagPALETTEENTRY Plt; RawBitmap = 1,
DibBitmap=2,
}; };
struct gdrv_dib_palette
{
tagPALETTEENTRY2 Color0;
tagPALETTEENTRY2 Color1;
tagPALETTEENTRY2 Color2;
tagPALETTEENTRY2 Color3;
tagPALETTEENTRY2 Color4;
tagPALETTEENTRY2 Color5;
tagPALETTEENTRY2 Color6;
tagPALETTEENTRY2 Color7;
tagPALETTEENTRY2 Color8;
tagPALETTEENTRY2 Color9;
tagPALETTEENTRY2 Color10;
tagPALETTEENTRY2 Color11;
tagPALETTEENTRY2 Color12;
tagPALETTEENTRY2 Color13;
tagPALETTEENTRY2 Color14;
tagPALETTEENTRY2 Color15;
};
struct __declspec(align(4)) gdrv_dib
{
int PaletteOffset;
int Width;
int Height;
__int16 Unknown3_1;
unsigned __int16 Bpp;
int Unknown4;
int BufferSize;
int Unknown6;
int Unknown7;
int NumberOfColors;
int Unknown9;
gdrv_dib_palette Palette0;
gdrv_dib_palette Palette1;
gdrv_dib_palette Palette2;
gdrv_dib_palette Palette3;
gdrv_dib_palette Palette4;
gdrv_dib_palette Palette5;
gdrv_dib_palette Palette6;
gdrv_dib_palette Palette7;
gdrv_dib_palette Palette8;
gdrv_dib_palette Palette9;
gdrv_dib_palette Palette10;
gdrv_dib_palette Palette11;
gdrv_dib_palette Palette12;
gdrv_dib_palette Palette13;
gdrv_dib_palette Palette14;
gdrv_dib_palette Palette15;
char BmpBuffer[1];
};
#pragma pack(push, 1) #pragma pack(push, 1)
struct __declspec(align(1)) gdrv_bitmap8 struct __declspec(align(1)) gdrv_bitmap8
{ {
gdrv_dib* Dib; BITMAPINFO* Dib;
char* BmpBufPtr2; char* BmpBufPtr2;
char* BmpBufPtr1; char* BmpBufPtr1;
int Width; int Width;
int Height; int Height;
int Stride; int Stride;
char SomeByte; BitmapType BitmapType;
int Color6; int Color6;
int XPosition; int XPosition;
int YPosition; int YPosition;
}; };
#pragma pack(pop) #pragma pack(pop)
static_assert(sizeof(tagPALETTEENTRY2) == 4, "Wrong size of tagPALETTEENTRY2");
static_assert(sizeof(gdrv_dib_palette) == 4 * 16, "Wrong size of gdrv_dib_palette"); struct LOGPALETTEx256
static_assert(sizeof(gdrv_dib) == (10 * 4) + sizeof(gdrv_dib_palette) * 16 + 4, "Wrong size of gdrv_dib"); {
WORD palVersion;
WORD palNumEntries;
PALETTEENTRY palPalEntry[256];
LOGPALETTEx256() : palVersion(0x300), palNumEntries(256), palPalEntry{}
{
}
};
static_assert(sizeof(gdrv_bitmap8) == 37, "Wrong size of gdrv_bitmap8"); static_assert(sizeof(gdrv_bitmap8) == 37, "Wrong size of gdrv_bitmap8");
class gdrv class gdrv
{ {
public: public:
static HPALETTE palette_handle; static HPALETTE palette_handle;
static HINSTANCE hinst;
static HWND hwnd;
static LOGPALETTEx256 current_palette;
static int sequence_handle;
static HDC sequence_hdc;
static int use_wing;
static int init(HINSTANCE hInst, HWND hWnd);
static int uninit();
static void get_focus(); static void get_focus();
static gdrv_dib* DibCreate(__int16 bpp, int width, int height); static BITMAPINFO* DibCreate(__int16 bpp, int width, int height);
static void DibSetUsage(gdrv_dib* dib, HPALETTE hpal, int someFlag); static void DibSetUsage(BITMAPINFO* dib, HPALETTE hpal, int someFlag);
static int create_bitmap_dib(gdrv_bitmap8* bmp, int width, int height); static int create_bitmap_dib(gdrv_bitmap8* bmp, int width, int height);
static int create_bitmap(gdrv_bitmap8* bmp, int width, int height); static int create_bitmap(gdrv_bitmap8* bmp, int width, int height);
static int create_raw_bitmap(gdrv_bitmap8* bmp, int width, int height, int flag); static int create_raw_bitmap(gdrv_bitmap8* bmp, int width, int height, int flag);
static int destroy_bitmap(gdrv_bitmap8* bmp);
static int display_palette(PALETTEENTRY* plt);
static UINT start_blit_sequence();
static void blit_sequence(gdrv_bitmap8* bmp, int xSrc, int ySrcOff, int xDest, int yDest, int DestWidth,
int DestHeight);
static void end_blit_sequence();
static void blit(gdrv_bitmap8* bmp, int xSrc, int ySrcOff, int xDest, int yDest, int DestWidth, int DestHeight);
static void blat(gdrv_bitmap8* bmp, int xDest, int yDest);
static void fill_bitmap(gdrv_bitmap8* bmp, int width, int height, int xOff, int yOff, char fillChar);
static void copy_bitmap(gdrv_bitmap8* dstBmp, int width, int height, int xOff, int yOff, gdrv_bitmap8* srcBmp,
int srcXOff, int srcYOff);
static void copy_bitmap_w_transparency(gdrv_bitmap8* dstBmp, int width, int height, int xOff, int yOff,
gdrv_bitmap8* srcBmp, int srcXOff, int srcYOff);
private: private:
}; };

View File

@ -160,6 +160,25 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
while (true) while (true)
{ {
if(false)
{
auto plt = (PALETTEENTRY*)malloc(1024u);
auto gg = sizeof(LOGPALETTEx256);
auto pltPtr = &plt[10];
for (int i1 = 0, i2 = 0; i1 < 256 - 10; ++i1, i2 += 8)
{
unsigned char blue = i2, redGreen = i2;
if (i2 > 255)
{
blue = 255;
redGreen = i1;
}
*pltPtr++ = { redGreen, redGreen, blue };
}
gdrv::display_palette(plt);
}
if (!ProcessWindowMessages() || bQuit) if (!ProcessWindowMessages() || bQuit)
break; break;
Sleep(8); Sleep(8);
@ -205,8 +224,8 @@ int winmain::ProcessWindowMessages()
void winmain::memalloc_failure() void winmain::memalloc_failure()
{ {
/*midi_music_stop(); /*midi_music_stop();
Sound_Close(); Sound_Close();*/
gdrv_uninit();*/ gdrv::uninit();
char* caption = pinball::get_rc_string(170, 0); char* caption = pinball::get_rc_string(170, 0);
char* text = pinball::get_rc_string(179, 0); char* text = pinball::get_rc_string(179, 0);
MessageBoxA(nullptr, text, caption, 0x2030u); MessageBoxA(nullptr, text, caption, 0x2030u);