From 2376ffcbc12a641813625c26dc5d23edcf454810 Mon Sep 17 00:00:00 2001 From: oz Date: Fri, 13 Nov 2020 19:04:58 +0300 Subject: [PATCH] gdrv v2, ready. --- Doc/FuncStats.xlsx | Bin 31455 -> 31437 bytes SpaceCadetPinball/SpaceCadetPinball.cpp | 1 + SpaceCadetPinball/gdrv.cpp | 331 ++++++++++++++++++++---- SpaceCadetPinball/gdrv.h | 103 +++----- SpaceCadetPinball/winmain.cpp | 23 +- 5 files changed, 345 insertions(+), 113 deletions(-) diff --git a/Doc/FuncStats.xlsx b/Doc/FuncStats.xlsx index bfd49e47d4211c1ff309854b4e306c175f1494e3..b5acbe9b58aa9f8f9b17a00317313f1ba98bd377 100644 GIT binary patch delta 22085 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 delta 22049 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 + auto dib = static_cast(GlobalLock(buf)); if (!dib) return nullptr; - dib->BufferSize = sizeBytes; - dib->Width = width; - dib->PaletteOffset = 40; - dib->Height = height; - dib->Unknown3_1 = 1; - dib->Bpp = bpp; - dib->Unknown4 = 0; - dib->Unknown6 = 0; - dib->Unknown7 = 0; - dib->NumberOfColors = 0; - dib->Unknown9 = 0; + dib->bmiHeader.biSizeImage = sizeBytes; + dib->bmiHeader.biWidth = width; + dib->bmiHeader.biSize = 40; + dib->bmiHeader.biHeight = height; + dib->bmiHeader.biPlanes = 1; + dib->bmiHeader.biBitCount = bpp; + dib->bmiHeader.biCompression = 0; + dib->bmiHeader.biXPelsPerMeter = 0; + dib->bmiHeader.biYPelsPerMeter = 0; + dib->bmiHeader.biClrUsed = 0; + dib->bmiHeader.biClrImportant = 0; if (bpp == 4) { - dib->NumberOfColors = 16; + dib->bmiHeader.biClrUsed = 16; } else if (bpp == 8) { - dib->NumberOfColors = 256; + dib->bmiHeader.biClrUsed = 256; } - auto pltPtr = &dib->Palette0; - for (auto index = 0; index < dib->NumberOfColors / 16; ++index, pltPtr++) + int index = 0; + for (auto i = (int*)dib->bmiColors; index < static_cast(dib->bmiHeader.biClrUsed) / 16; ++index) { - *pltPtr = gdrv_dib_palette{ - {0}, - {0x800000}, - {0x8000}, - {8421376}, - {128}, - {8388736}, - {32896}, - {12632256}, - {8421504}, - {16711680}, - {65280}, - {16776960}, - {255}, - {16711935}, - {0xFFFF}, - {0xFFFFFF}, - }; + *i++ = 0; + *i++ = 0x800000; + *i++ = 0x8000; + *i++ = 8421376; + *i++ = 128; + *i++ = 8388736; + *i++ = 32896; + *i++ = 12632256; + *i++ = 8421504; + *i++ = 16711680; + *i++ = 65280; + *i++ = 16776960; + *i++ = 255; + *i++ = 16711935; + *i++ = 0xFFFF; + *i++ = 0xFFFFFF; } 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] @@ -71,18 +93,18 @@ void gdrv::DibSetUsage(gdrv_dib* dib, HPALETTE hpal, int someFlag) hpal = static_cast(GetStockObject(DEFAULT_PALETTE)); if (!dib) return; - int numOfColors = dib->NumberOfColors; + int numOfColors = dib->bmiHeader.biClrUsed; if (!numOfColors) { - auto bpp = dib->Bpp; + auto bpp = dib->bmiHeader.biBitCount; if (bpp <= 8u) numOfColors = 1 << bpp; } - if (numOfColors > 0 && (dib->Unknown4 != 3 || numOfColors == 3)) + if (numOfColors > 0 && (dib->bmiHeader.biCompression != 3 || numOfColors == 3)) { 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) { *pltPtr++ = i; @@ -91,7 +113,7 @@ void gdrv::DibSetUsage(gdrv_dib* dib, HPALETTE hpal, int someFlag) else { assertm(false, "Entered bad code"); - char* dibPtr = (char*)dib + dib->PaletteOffset; + char* dibPtr = (char*)dib + dib->bmiHeader.biSize; if (numOfColors >= 256) numOfColors = 256; 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) { char* bmpBufPtr; // ecx - gdrv_dib* dib = DibCreate(8, width, height); + auto dib = DibCreate(8, width, height); DibSetUsage(dib, palette_handle, 1); bmp->Dib = dib; @@ -123,14 +145,14 @@ int gdrv::create_bitmap_dib(gdrv_bitmap8* bmp, int width, int height) bmp->Stride = width; if (width % 4) bmp->Stride = 4 - width % 4 + width; - gdrv_dib* dib2 = bmp->Dib; - bmp->Height = height; - bmp->SomeByte = 2; - if (dib2->Unknown4 == 3) - bmpBufPtr = (char*)&dib2->Unknown3_1 + dib2->PaletteOffset; + bmp->Height = height; + bmp->BitmapType = BitmapType::DibBitmap; + + if (dib->bmiHeader.biCompression == 3) + bmpBufPtr = (char*)&dib->bmiHeader.biPlanes + dib->bmiHeader.biSize; 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->BmpBufPtr2 = bmpBufPtr; 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; unsigned int sizeInBytes = height * bmp->Stride; bmp->Height = height; - bmp->SomeByte = 1; + bmp->BitmapType = BitmapType::RawBitmap; char* buf = memory::allocate(sizeInBytes); bmp->BmpBufPtr1 = buf; if (!buf) @@ -158,3 +180,212 @@ int gdrv::create_raw_bitmap(gdrv_bitmap8* bmp, int width, int height, int flag) bmp->BmpBufPtr2 = buf; return 0; } + + +int gdrv::display_palette(PALETTEENTRY* plt) +{ + if (palette_handle) + DeleteObject(palette_handle); + palette_handle = CreatePalette((LOGPALETTE*)¤t_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 = ¤t_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; + } +} diff --git a/SpaceCadetPinball/gdrv.h b/SpaceCadetPinball/gdrv.h index 10312aa..697e84e 100644 --- a/SpaceCadetPinball/gdrv.h +++ b/SpaceCadetPinball/gdrv.h @@ -1,93 +1,74 @@ #pragma once -union tagPALETTEENTRY2 +enum class BitmapType : char { - unsigned __int32 PltInt; - tagPALETTEENTRY Plt; + None = 0, + 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) struct __declspec(align(1)) gdrv_bitmap8 { - gdrv_dib* Dib; + BITMAPINFO* Dib; char* BmpBufPtr2; char* BmpBufPtr1; int Width; int Height; int Stride; - char SomeByte; + BitmapType BitmapType; int Color6; int XPosition; int YPosition; }; #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"); -static_assert(sizeof(gdrv_dib) == (10 * 4) + sizeof(gdrv_dib_palette) * 16 + 4, "Wrong size of gdrv_dib"); + +struct LOGPALETTEx256 +{ + WORD palVersion; + WORD palNumEntries; + PALETTEENTRY palPalEntry[256]; + + LOGPALETTEx256() : palVersion(0x300), palNumEntries(256), palPalEntry{} + { + } +}; + static_assert(sizeof(gdrv_bitmap8) == 37, "Wrong size of gdrv_bitmap8"); class gdrv { public: 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 gdrv_dib* DibCreate(__int16 bpp, int width, int height); - static void DibSetUsage(gdrv_dib* dib, HPALETTE hpal, int someFlag); + static BITMAPINFO* DibCreate(__int16 bpp, int width, int height); + 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(gdrv_bitmap8* bmp, int width, int height); 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: }; diff --git a/SpaceCadetPinball/winmain.cpp b/SpaceCadetPinball/winmain.cpp index f83ecef..13aec7b 100644 --- a/SpaceCadetPinball/winmain.cpp +++ b/SpaceCadetPinball/winmain.cpp @@ -160,6 +160,25 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi 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) break; Sleep(8); @@ -205,8 +224,8 @@ int winmain::ProcessWindowMessages() void winmain::memalloc_failure() { /*midi_music_stop(); - Sound_Close(); - gdrv_uninit();*/ + Sound_Close();*/ + gdrv::uninit(); char* caption = pinball::get_rc_string(170, 0); char* text = pinball::get_rc_string(179, 0); MessageBoxA(nullptr, text, caption, 0x2030u);