gdrv: simplified bitmap, fixed blit, improved SDL present.

Removed some Windows dependencies.
This commit is contained in:
Muzychenko Andrey 2021-09-01 11:02:57 +03:00
parent a09ea75d80
commit 9a10d72e1f
20 changed files with 254 additions and 493 deletions

View File

@ -15,19 +15,19 @@
#include "TTextBox.h" #include "TTextBox.h"
#include "winmain.h" #include "winmain.h"
int main() int main(int argc, char* argv[])
{ {
{ {
// Testing with UI // Testing with UI
char cmdLine[1]{}; std::string cmdLine;
WinMain(GetModuleHandleA(nullptr), nullptr, cmdLine, 10); for (int i = 0; i < argc; i++)
cmdLine += argv[i];
winmain::WinMain(cmdLine.c_str());
return 0; return 0;
} }
std::cout << "Hello World!\n"; std::cout << "Hello World!\n";
gdrv::init(nullptr,0,0); gdrv::init(0,0);
auto dib = gdrv::DibCreate(8, 1, 1);
gdrv::DibSetUsage(dib, nullptr, 1);
auto d = objlist_class<void>(2, 4); auto d = objlist_class<void>(2, 4);
for (size_t i = 0; i < 100; i++) for (size_t i = 0; i < 100; i++)
@ -39,7 +39,7 @@ int main()
auto xx = sizeof(datFileHeader); auto xx = sizeof(datFileHeader);
lstrcpyA(winmain::DatFileName, "PINBALL.DAT"); lstrcpyA(winmain::DatFileName, "PINBALL.DAT");
pb::init(nullptr); pb::init();
auto datFile = pb::record_table; auto datFile = pb::record_table;
assert(partman::field_size_nth(datFile, 0, datFieldTypes::String, 0) == 43); assert(partman::field_size_nth(datFile, 0, datFieldTypes::String, 0) == 43);

View File

@ -440,22 +440,22 @@ void fullscrn::window_size_changed()
return; return;
} }
RECT client{}; int width, height;
GetClientRect(hWnd, &client); SDL_GetWindowSize(winmain::MainWindow, &width, &height);
auto res = &resolution_array[resolution]; auto res = &resolution_array[resolution];
ScaleX = static_cast<float>(client.right) / res->TableWidth; ScaleX = static_cast<float>(width) / res->TableWidth;
ScaleY = static_cast<float>(client.bottom) / res->TableHeight; ScaleY = static_cast<float>(height) / res->TableHeight;
OffsetX = OffsetY = 0; OffsetX = OffsetY = 0;
if (options::Options.UniformScaling) if (options::Options.UniformScaling)
{ {
ScaleY = ScaleX = min(ScaleX, ScaleY); ScaleY = ScaleX = min(ScaleX, ScaleY);
OffsetX = floor((client.right - res->TableWidth * ScaleX) / 2); OffsetX = floor((width - res->TableWidth * ScaleX) / 2);
OffsetY = floor((client.bottom - res->TableHeight * ScaleY) / 2); OffsetY = floor((height - res->TableHeight * ScaleY) / 2);
auto dc = GetDC(hWnd); auto dc = GetDC(hWnd);
if (dc) if (dc)
{ {
BitBlt(dc, 0, 0, client.right, client.bottom, dc, 0, 0, BLACKNESS); BitBlt(dc, 0, 0, width, height, dc, 0, 0, BLACKNESS);
ReleaseDC(hWnd, dc); ReleaseDC(hWnd, dc);
} }
} }

View File

@ -1,50 +1,36 @@
#include "pch.h" #include "pch.h"
#include "gdrv.h" #include "gdrv.h"
#include "fullscrn.h"
#include "memory.h" #include "memory.h"
#include "pinball.h" #include "render.h"
#include "winmain.h" #include "winmain.h"
HPALETTE gdrv::palette_handle = nullptr; SDL_Texture* gdrv::vScreenTex = nullptr;
SDL_Renderer* gdrv::renderer; char* gdrv::vScreenPixels = nullptr;
int gdrv::sequence_handle; int gdrv::vScreenWidth, gdrv::vScreenHeight;
HDC gdrv::sequence_hdc; ColorRgba gdrv::current_palette[256]{};
int gdrv::use_wing = 0;
int gdrv::grtext_blue = 0;
int gdrv::grtext_green = 0;
int gdrv::grtext_red = -1;
HWND hwnd = 0; int gdrv::init(int width, int height)
SDL_Texture* vScreenTex = nullptr;
char* pixels = nullptr;
int Width, Height;
LOGPALETTEx256 current_palette{};
int gdrv::init(SDL_Renderer* render, int width, int height)
{ {
renderer = render; SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
vScreenTex = SDL_CreateTexture vScreenTex = SDL_CreateTexture
( (
renderer, winmain::Renderer,
SDL_PIXELFORMAT_ARGB8888, SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STREAMING, SDL_TEXTUREACCESS_STREAMING,
width, height width, height
); );
pixels = memory::allocate(width * height * 4); vScreenPixels = memory::allocate(width * height * 4);
Width = width; vScreenWidth = width;
Height = height; vScreenHeight = height;
if (!palette_handle)
palette_handle = CreatePalette(&current_palette);
return 0; return 0;
} }
int gdrv::uninit() int gdrv::uninit()
{ {
if (palette_handle) SDL_DestroyTexture(vScreenTex);
DeleteObject(palette_handle); memory::free(vScreenPixels);
memory::free(pixels);
return 0; return 0;
} }
@ -52,97 +38,8 @@ void gdrv::get_focus()
{ {
} }
int gdrv::create_bitmap(gdrv_bitmap8* bmp, int width, int height)
BITMAPINFO* gdrv::DibCreate(int16_t bpp, int width, int height)
{ {
auto sizeBytes = height * (width * bpp / 8 + 3 & (~3));
auto dib = memory::allocate<BITMAPINFO>(1, (256 - 1) * sizeof(RGBQUAD) + sizeBytes);
if (!dib)
return nullptr;
dib->bmiHeader.biSizeImage = sizeBytes;
dib->bmiHeader.biWidth = width;
dib->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
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->bmiHeader.biClrUsed = 16;
}
else if (bpp == 8)
{
dib->bmiHeader.biClrUsed = 256;
}
uint32_t paletteColors[]
{
0, 0x800000, 0x8000, 8421376, 128, 8388736, 32896, 12632256,
8421504, 16711680, 65280, 16776960, 255, 16711935, 0xFFFF, 0xFFFFFF,
};
for (auto index = 0u; index < dib->bmiHeader.biClrUsed; index += 16)
{
memcpy(&dib->bmiColors[index], paletteColors, sizeof paletteColors);
}
return dib;
}
void gdrv::DibSetUsage(BITMAPINFO* dib, HPALETTE hpal, int someFlag)
{
tagPALETTEENTRY pPalEntries[256];
if (!hpal)
hpal = static_cast<HPALETTE>(GetStockObject(DEFAULT_PALETTE));
if (!dib)
return;
int numOfColors = dib->bmiHeader.biClrUsed;
if (!numOfColors)
{
auto bpp = dib->bmiHeader.biBitCount;
if (bpp <= 8u)
numOfColors = 1 << bpp;
}
if (numOfColors > 0 && (dib->bmiHeader.biCompression != 3 || numOfColors == 3))
{
if (someFlag && someFlag <= 2)
{
auto pltPtr = reinterpret_cast<short*>(dib->bmiColors);
for (auto i = 0; i < numOfColors; ++i)
{
*pltPtr++ = i;
}
}
else
{
if (numOfColors >= 256)
numOfColors = 256;
GetPaletteEntries(hpal, 0, numOfColors, pPalEntries);
for (auto index = 0; index < numOfColors; index++)
{
dib->bmiColors[index].rgbRed = pPalEntries[index].peRed;
dib->bmiColors[index].rgbGreen = pPalEntries[index].peGreen;
dib->bmiColors[index].rgbBlue = pPalEntries[index].peBlue;
dib->bmiColors[index].rgbReserved = 0;
}
}
}
}
int gdrv::create_bitmap_dib(gdrv_bitmap8* bmp, int width, int height)
{
char* bmpBufPtr;
auto dib = DibCreate(8, width, height);
DibSetUsage(dib, palette_handle, 1);
bmp->Dib = dib;
bmp->Width = width; bmp->Width = width;
bmp->Stride = width; bmp->Stride = width;
if (width % 4) if (width % 4)
@ -150,24 +47,12 @@ int gdrv::create_bitmap_dib(gdrv_bitmap8* bmp, int width, int height)
bmp->Height = height; bmp->Height = height;
bmp->BitmapType = BitmapType::DibBitmap; bmp->BitmapType = BitmapType::DibBitmap;
bmp->BmpBufPtr1 = memory::allocate(bmp->Height * bmp->Stride);
if (dib->bmiHeader.biCompression == 3)
bmpBufPtr = (char*)&dib->bmiHeader.biPlanes + dib->bmiHeader.biSize;
else
bmpBufPtr = reinterpret_cast<char*>(&dib->bmiColors[dib->bmiHeader.biClrUsed]);
bmp->BmpBufPtr1 = bmpBufPtr;
bmp->BmpBufPtr2 = bmpBufPtr;
return 0; return 0;
} }
int gdrv::create_bitmap(gdrv_bitmap8* bmp, int width, int height)
{
return create_bitmap_dib(bmp, width, height);
}
int gdrv::create_raw_bitmap(gdrv_bitmap8* bmp, int width, int height, int flag) int gdrv::create_raw_bitmap(gdrv_bitmap8* bmp, int width, int height, int flag)
{ {
bmp->Dib = nullptr;
bmp->Width = width; bmp->Width = width;
bmp->Stride = width; bmp->Stride = width;
if (flag && width % 4) if (flag && width % 4)
@ -179,13 +64,11 @@ int gdrv::create_raw_bitmap(gdrv_bitmap8* bmp, int width, int height, int flag)
bmp->BmpBufPtr1 = buf; bmp->BmpBufPtr1 = buf;
if (!buf) if (!buf)
return -1; return -1;
bmp->BmpBufPtr2 = buf;
return 0; return 0;
} }
int gdrv::create_spliced_bitmap(gdrv_bitmap8* bmp, int width, int height, int size) int gdrv::create_spliced_bitmap(gdrv_bitmap8* bmp, int width, int height, int size)
{ {
bmp->Dib = nullptr;
bmp->Width = width; bmp->Width = width;
bmp->Stride = width; bmp->Stride = width;
bmp->BitmapType = BitmapType::Spliced; bmp->BitmapType = BitmapType::Spliced;
@ -194,54 +77,51 @@ int gdrv::create_spliced_bitmap(gdrv_bitmap8* bmp, int width, int height, int si
bmp->BmpBufPtr1 = buf; bmp->BmpBufPtr1 = buf;
if (!buf) if (!buf)
return -1; return -1;
bmp->BmpBufPtr2 = bmp->BmpBufPtr1;
return 0; return 0;
} }
int gdrv::display_palette(PALETTEENTRY* plt) int gdrv::display_palette(ColorRgba* plt)
{ {
if (palette_handle) const uint32_t sysPaletteColors[]
DeleteObject(palette_handle); {
palette_handle = CreatePalette(&current_palette); 0x00000000,
auto windowHandle = GetDesktopWindow(); 0x00000080,
auto dc = winmain::_GetDC(windowHandle); 0x00008000,
SetSystemPaletteUse(dc, 2u); 0x00008080,
SetSystemPaletteUse(dc, 1u); 0x00800000,
auto originalPalette = SelectPalette(dc, palette_handle, 0); 0x00800080,
RealizePalette(dc); 0x00808000,
SelectPalette(dc, originalPalette, 0); 0x00C0C0C0,
GetSystemPaletteEntries(dc, 0, 256, current_palette.palPalEntry); 0x00C0DCC0,
0x00F0CAA6
};
memcpy(current_palette, sysPaletteColors, sizeof sysPaletteColors);
for (int i = 0; i < 256; i++) for (int i = 0; i < 256; i++)
{ {
current_palette.palPalEntry[i].peFlags = 0; current_palette[i].rgba.peFlags = 0;
} }
auto pltSrc = &plt[10]; auto pltSrc = &plt[10];
auto pltDst = &current_palette.palPalEntry[10]; auto pltDst = &current_palette[10];
for (int index = 236; index > 0; --index) for (int index = 236; index > 0; --index)
{ {
if (plt) if (plt)
{ {
pltDst->peRed = pltSrc->peRed; pltDst->rgba.peRed = pltSrc->rgba.peRed;
pltDst->peGreen = pltSrc->peGreen; pltDst->rgba.peGreen = pltSrc->rgba.peGreen;
pltDst->peBlue = pltSrc->peBlue; pltDst->rgba.peBlue = pltSrc->rgba.peBlue;
} }
pltDst->peFlags = 4; pltDst->rgba.peFlags = 4;
pltSrc++; pltSrc++;
pltDst++; pltDst++;
} }
if (!(GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE)) current_palette[255].rgba.peBlue = -1;
{ current_palette[255].rgba.peGreen = -1;
current_palette.palPalEntry[255].peBlue = -1; current_palette[255].rgba.peRed = -1;
current_palette.palPalEntry[255].peGreen = -1;
current_palette.palPalEntry[255].peRed = -1;
}
ResizePalette(palette_handle, 256);
SetPaletteEntries(palette_handle, 0, 256, current_palette.palPalEntry);
windowHandle = GetDesktopWindow();
ReleaseDC(windowHandle, dc);
return 0; return 0;
} }
@ -250,102 +130,47 @@ int gdrv::destroy_bitmap(gdrv_bitmap8* bmp)
{ {
if (!bmp) if (!bmp)
return -1; return -1;
if (bmp->BitmapType == BitmapType::RawBitmap || bmp->BitmapType == BitmapType::Spliced)
if (bmp->BitmapType != BitmapType::None)
{ {
memory::free(bmp->BmpBufPtr1); memory::free(bmp->BmpBufPtr1);
} }
else if (bmp->BitmapType == BitmapType::DibBitmap)
{
memory::free(bmp->Dib);
}
memset(bmp, 0, sizeof(gdrv_bitmap8)); memset(bmp, 0, sizeof(gdrv_bitmap8));
return 0; return 0;
} }
void gdrv::start_blit_sequence() void gdrv::start_blit_sequence()
{ {
HDC dc = winmain::_GetDC(hwnd);
sequence_handle = 0;
sequence_hdc = dc;
SelectPalette(dc, palette_handle, 0);
RealizePalette(sequence_hdc);
SetStretchBltMode(dc, stretchMode);
} }
void gdrv::blit_sequence(gdrv_bitmap8* bmp, int xSrc, int ySrcOff, int xDest, int yDest, int DestWidth, int DestHeight)
{
if (!use_wing)
StretchDIBitsScaled(
sequence_hdc,
xDest,
yDest,
DestWidth,
DestHeight,
xSrc,
bmp->Height - ySrcOff - DestHeight,
DestWidth,
DestHeight,
bmp,
DIB_PAL_COLORS,
SRCCOPY
);
}
void gdrv::end_blit_sequence() 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) void gdrv::blit(gdrv_bitmap8* bmp, int xSrc, int ySrc, int xDest, int yDest, int width, int height)
{ {
HDC dc = winmain::_GetDC(hwnd); StretchDIBitsScaled(
SetStretchBltMode(dc, stretchMode); xSrc,
if (dc) ySrc ,
{ xDest,
SelectPalette(dc, palette_handle, 0); yDest,
RealizePalette(dc); width,
if (!use_wing) height,
StretchDIBitsScaled( bmp
dc, );
xDest,
yDest,
DestWidth,
DestHeight,
xSrc,
bmp->Height - ySrcOff - DestHeight,
DestWidth,
DestHeight,
bmp,
DIB_PAL_COLORS,
SRCCOPY
);
ReleaseDC(hwnd, dc);
}
} }
void gdrv::blat(gdrv_bitmap8* bmp, int xDest, int yDest) void gdrv::blat(gdrv_bitmap8* bmp, int xDest, int yDest)
{ {
HDC dc = winmain::_GetDC(hwnd); StretchDIBitsScaled(
SelectPalette(dc, palette_handle, 0); 0,
RealizePalette(dc); 0,
SetStretchBltMode(dc, stretchMode); xDest,
if (!use_wing) yDest,
StretchDIBitsScaled( bmp->Width,
dc, bmp->Height,
xDest, bmp
yDest, );
bmp->Width,
bmp->Height,
0,
0,
bmp->Width,
bmp->Height,
bmp,
DIB_PAL_COLORS,
SRCCOPY
);
ReleaseDC(hwnd, dc);
} }
void gdrv::fill_bitmap(gdrv_bitmap8* bmp, int width, int height, int xOff, int yOff, char fillChar) void gdrv::fill_bitmap(gdrv_bitmap8* bmp, int width, int height, int xOff, int yOff, char fillChar)
@ -405,106 +230,63 @@ void gdrv::copy_bitmap_w_transparency(gdrv_bitmap8* dstBmp, int width, int heigh
void gdrv::grtext_draw_ttext_in_box(LPCSTR text, int xOff, int yOff, int width, int height, int a6) void gdrv::grtext_draw_ttext_in_box(LPCSTR text, int xOff, int yOff, int width, int height, int a6)
{ {
tagRECT rc{};
HDC dc = GetDC(hwnd);
rc.left = xOff;
rc.right = width + xOff;
rc.top = yOff;
rc.bottom = height + yOff;
if (grtext_red < 0)
{
grtext_blue = 255;
grtext_green = 255;
grtext_red = 255;
const char* fontColor = pinball::get_rc_string(189, 0);
if (fontColor)
sscanf_s(fontColor, "%d %d %d", &grtext_red, &grtext_green, &grtext_blue);
}
int prevMode = SetBkMode(dc, 1);
COLORREF color = SetTextColor(dc, grtext_red | grtext_green << 8 | grtext_blue << 16);
DrawTextA(dc, text, lstrlenA(text), &rc, 0x810u);
SetBkMode(dc, prevMode);
SetTextColor(dc, color);
ReleaseDC(hwnd, dc);
} }
int gdrv::StretchDIBitsScaled(HDC hdc, int xDest, int yDest, int DestWidth, int DestHeight, int xSrc, int ySrc, int gdrv::StretchDIBitsScaled(int xSrc, int ySrc, int xDst, int yDst,
int SrcWidth, int SrcHeight, gdrv_bitmap8* bmp, UINT iUsage, int width, int height, gdrv_bitmap8* bmp)
DWORD rop)
{ {
/*Scaled partial updates may leave 1px border artifacts around update area. // Y is inverted, X normal left to right
* Pad update area to compensate.*/ ySrc = max(0, min(bmp->Height - height, bmp->Height)) - ySrc;
/*const int pad = 1, padX2 = pad * 2; yDst = max(0, min(vScreenHeight - height, vScreenHeight)) - yDst;
if (fullscrn::ScaleX > 1 && xSrc > pad && xSrc + pad < bmp->Width)
{ // Negative dst == positive src offset
xSrc -= pad; if (xDst < 0)
xDest -= pad; {
SrcWidth += padX2; xSrc -= xDst;
DestWidth += padX2; xDst = 0;
} }
if (yDst < 0)
if (fullscrn::ScaleY > 1 && ySrc > pad && ySrc + pad < bmp->Height)
{ {
ySrc -= pad; ySrc -= yDst;
yDest -= pad; yDst = 0;
SrcHeight += padX2;
DestHeight += padX2;
} }
StretchDIBits(
hdc,
static_cast<int>(round(xDest * fullscrn::ScaleX + fullscrn::OffsetX)),
static_cast<int>(round(yDest * fullscrn::ScaleY + fullscrn::OffsetY)),
static_cast<int>(round(DestWidth * fullscrn::ScaleX)),
static_cast<int>(round(DestHeight * fullscrn::ScaleY)),
xSrc,
ySrc,
SrcWidth,
SrcHeight,
bmp->BmpBufPtr1,
bmp->Dib,
iUsage,
rop);*/
//auto srcPtr = reinterpret_cast<uint8_t*>(bmp->BmpBufPtr1);
//auto dstPtr = reinterpret_cast<uint32_t*>(pixels);
//for (int y = Height; y > 0; --y)
//{
// for (int x = Width; x > 0; --x)
// *dstPtr++ = *(uint32_t*)&current_palette.palPalEntry[*srcPtr++];
// //srcPtr += srcBmp->Stride - width;
// //dstPtr += dstBmp->Stride - width;
//}
// Clamp out of bounds rectangles // Clamp out of bounds rectangles
xSrc = max(0, min(xSrc, bmp->Width));
ySrc = max(0, min(ySrc, bmp->Height)); ySrc = max(0, min(ySrc, bmp->Height));
xSrc = max(0, min(xSrc, bmp->Height)); if (xSrc + width > bmp->Width)
if (ySrc + SrcHeight > Height) width = bmp->Width - xSrc;
SrcHeight = Height - ySrc; if (ySrc + height > bmp->Height)
if (xSrc + SrcWidth > Width) height = bmp->Height - ySrc;
SrcWidth = Width - xSrc;
auto srcPtr = reinterpret_cast<uint8_t*>(&bmp->BmpBufPtr1[bmp->Stride * (ySrc)+xSrc]); xDst = max(0, min(xDst, vScreenWidth));
auto dstPtr = &reinterpret_cast<uint32_t*>(pixels)[Width * (ySrc)+xSrc]; yDst = max(0, min(yDst, vScreenHeight));
for (int y = SrcHeight; y > 0; --y) if (xDst + width > vScreenWidth)
width = vScreenWidth - xDst;
if (yDst + height > vScreenHeight)
height = vScreenHeight - yDst;
auto srcPtr = reinterpret_cast<uint8_t*>(&bmp->BmpBufPtr1[bmp->Stride * ySrc + xSrc]);
auto dstPtr = &reinterpret_cast<uint32_t*>(vScreenPixels)[vScreenWidth * yDst + xDst];
for (int y = height; y > 0; --y)
{ {
for (int x = SrcWidth; x > 0; --x) for (int x = width; x > 0; --x)
{ {
if ((char*)dstPtr >= (pixels + Width * Height * 4) || (char*)srcPtr >= (bmp->BmpBufPtr1 + bmp->Stride * bmp->Width))
{
dstPtr = dstPtr;
}
*dstPtr++ = *(uint32_t*)&current_palette.palPalEntry[*srcPtr++]; *dstPtr++ = current_palette[*srcPtr++].Color;
} }
srcPtr += bmp->Stride - SrcWidth; srcPtr += bmp->Stride - width;
dstPtr += Width - SrcWidth; dstPtr += vScreenWidth - width;
} }
return 0;
}
void gdrv::BlitScreen()
{
auto bmp = &render::vscreen;
unsigned char* lockedPixels = nullptr; unsigned char* lockedPixels = nullptr;
int pitch = 0; int pitch = 0;
SDL_LockTexture SDL_LockTexture
@ -514,12 +296,7 @@ int gdrv::StretchDIBitsScaled(HDC hdc, int xDest, int yDest, int DestWidth, int
reinterpret_cast<void**>(&lockedPixels), reinterpret_cast<void**>(&lockedPixels),
&pitch &pitch
); );
std::memcpy(lockedPixels, pixels, Width * Height * 4); std::memcpy(lockedPixels, vScreenPixels, vScreenWidth * vScreenHeight * 4);
SDL_UnlockTexture(vScreenTex); SDL_UnlockTexture(vScreenTex);
SDL_RenderCopyEx(winmain::Renderer, vScreenTex, nullptr, nullptr, 0, nullptr, SDL_FLIP_VERTICAL);
SDL_Rect dstRect
{ xDest,yDest,Width,Height };
SDL_RenderCopyEx(renderer, vScreenTex, nullptr, nullptr, 0, 0, SDL_FLIP_VERTICAL);
return 0;
} }

View File

@ -10,8 +10,6 @@ enum class BitmapType : char
struct gdrv_bitmap8 struct gdrv_bitmap8
{ {
BITMAPINFO* Dib;
char* BmpBufPtr2;
char* BmpBufPtr1; char* BmpBufPtr1;
int Width; int Width;
int Height; int Height;
@ -22,6 +20,20 @@ struct gdrv_bitmap8
int YPosition; int YPosition;
}; };
struct Rgba
{
uint8_t peRed;
uint8_t peGreen;
uint8_t peBlue;
uint8_t peFlags;
};
union ColorRgba
{
uint32_t Color;
Rgba rgba;
};
static_assert(sizeof(ColorRgba) == 4, "Wrong size of RGBA color");
struct LOGPALETTEx256 : LOGPALETTE struct LOGPALETTEx256 : LOGPALETTE
{ {
PALETTEENTRY palPalEntry2[256 - 1]; PALETTEENTRY palPalEntry2[256 - 1];
@ -37,27 +49,17 @@ struct LOGPALETTEx256 : LOGPALETTE
class gdrv class gdrv
{ {
public: public:
static HPALETTE palette_handle; static int init(int width, int height);
static int sequence_handle;
static HDC sequence_hdc;
static int use_wing;
static int init(SDL_Renderer* renderer, int width, int height);
static int uninit(); static int uninit();
static void get_focus(); static void get_focus();
static BITMAPINFO* DibCreate(int16_t 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_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 create_spliced_bitmap(gdrv_bitmap8* bmp, int width, int height, int size); static int create_spliced_bitmap(gdrv_bitmap8* bmp, int width, int height, int size);
static int destroy_bitmap(gdrv_bitmap8* bmp); static int destroy_bitmap(gdrv_bitmap8* bmp);
static int display_palette(PALETTEENTRY* plt); static int display_palette(ColorRgba* plt);
static void start_blit_sequence(); static void 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 end_blit_sequence();
static void blit(gdrv_bitmap8* bmp, int xSrc, int ySrcOff, int xDest, int yDest, int DestWidth, int DestHeight); static void blit(gdrv_bitmap8* bmp, int xSrc, int ySrc, int xDest, int yDest, int width, int height);
static void blat(gdrv_bitmap8* bmp, int xDest, int yDest); 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 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, static void copy_bitmap(gdrv_bitmap8* dstBmp, int width, int height, int xOff, int yOff, gdrv_bitmap8* srcBmp,
@ -65,15 +67,13 @@ public:
static void copy_bitmap_w_transparency(gdrv_bitmap8* dstBmp, int width, int height, int xOff, int yOff, static void copy_bitmap_w_transparency(gdrv_bitmap8* dstBmp, int width, int height, int xOff, int yOff,
gdrv_bitmap8* srcBmp, int srcXOff, int srcYOff); gdrv_bitmap8* srcBmp, int srcXOff, int srcYOff);
static void grtext_draw_ttext_in_box(LPCSTR text, int xOff, int yOff, int width, int height, int a6); static void grtext_draw_ttext_in_box(LPCSTR text, int xOff, int yOff, int width, int height, int a6);
static void BlitScreen();
private: private:
/*COLORONCOLOR or HALFTONE*/ static SDL_Texture* vScreenTex;
static const int stretchMode = COLORONCOLOR; static char* vScreenPixels;
static SDL_Renderer* renderer; static int vScreenWidth, vScreenHeight;
static int grtext_blue; static ColorRgba current_palette[256];
static int grtext_green;
static int grtext_red;
static int StretchDIBitsScaled(HDC hdc, int xDest, int yDest, int DestWidth, int DestHeight, int xSrc, int ySrc, static int StretchDIBitsScaled(int xSrc, int ySrc, int xDst, int yDst,
int SrcWidth, int SrcHeight, gdrv_bitmap8* bmp, UINT iUsage, int width, int height, gdrv_bitmap8* bmp);
DWORD rop);
}; };

View File

@ -167,7 +167,7 @@ void high_score::show_high_score_dialog(high_score_struct* table)
dlg_enter_name = 0; dlg_enter_name = 0;
dlg_score = 0; dlg_score = 0;
dlg_hst = table; dlg_hst = table;
DialogBoxParamA(winmain::hinst, "dlg_highscores", winmain::hwnd_frame, HighScore, 0); DialogBoxParamA(nullptr, "dlg_highscores", nullptr, HighScore, 0);
} }
void high_score::show_and_set_high_score_dialog(high_score_struct* table, int score, int pos, LPCSTR defaultName) void high_score::show_and_set_high_score_dialog(high_score_struct* table, int score, int pos, LPCSTR defaultName)

View File

@ -151,9 +151,13 @@ int loader::get_sound_id(int groupIndex)
sprintf_s(fileName2, pb::FullTiltMode ? "SOUND\\%s" : "%s", fileName); sprintf_s(fileName2, pb::FullTiltMode ? "SOUND\\%s" : "%s", fileName);
pinball::make_path_name(filePath, fileName2); pinball::make_path_name(filePath, fileName2);
HFILE hFile = _lopen(filePath, 0); FILE* file;
_lread(hFile, &wavHeader, sizeof wavHeader); if (!fopen_s(&file, filePath, "rb"))
_lclose(hFile); {
fread(&wavHeader, 1, sizeof wavHeader, file);
fclose(file);
}
auto sampleCount = wavHeader.data_size / (wavHeader.channels * (wavHeader.bits_per_sample / 8.0)); auto sampleCount = wavHeader.data_size / (wavHeader.channels * (wavHeader.bits_per_sample / 8.0));
sound_list[soundIndex].Duration = static_cast<float>(sampleCount / wavHeader.sample_rate); sound_list[soundIndex].Duration = static_cast<float>(sampleCount / wavHeader.sample_rate);
sound_list[soundIndex].WavePtr = Sound::LoadWaveFile(filePath); sound_list[soundIndex].WavePtr = Sound::LoadWaveFile(filePath);

View File

@ -32,11 +32,11 @@ MCIERROR midi::music_stop()
return Mix_HaltMusic(); return Mix_HaltMusic();
} }
int midi::music_init(HWND hwnd) int midi::music_init()
{ {
if (pb::FullTiltMode) if (pb::FullTiltMode)
{ {
return music_init_ft(hwnd); return music_init_ft();
} }
currentMidi = Mix_LoadMUS(pinball::get_rc_string(156, 0)); currentMidi = Mix_LoadMUS(pinball::get_rc_string(156, 0));
@ -74,7 +74,7 @@ objlist_class<midi_struct>* midi::TrackList;
midi_struct *midi::track1, *midi::track2, *midi::track3, *midi::active_track, *midi::active_track2; midi_struct *midi::track1, *midi::track2, *midi::track3, *midi::active_track, *midi::active_track2;
int midi::some_flag1; int midi::some_flag1;
int midi::music_init_ft(HWND hwnd) int midi::music_init_ft()
{ {
active_track = nullptr; active_track = nullptr;
TrackList = new objlist_class<midi_struct>(0, 1); TrackList = new objlist_class<midi_struct>(0, 1);

View File

@ -54,7 +54,7 @@ class midi
public: public:
static MCIERROR play_pb_theme(int flag); static MCIERROR play_pb_theme(int flag);
static MCIERROR music_stop(); static MCIERROR music_stop();
static int music_init(HWND hwnd); static int music_init();
static MCIERROR restart_midi_seq(LPARAM param); static MCIERROR restart_midi_seq(LPARAM param);
static void music_shutdown(); static void music_shutdown();
private: private:
@ -63,7 +63,7 @@ private:
static objlist_class<midi_struct>* TrackList; static objlist_class<midi_struct>* TrackList;
static midi_struct *track1, *track2, *track3, *active_track, *active_track2; static midi_struct *track1, *track2, *track3, *active_track, *active_track2;
static int some_flag1; static int some_flag1;
static int music_init_ft(HWND hwnd); static int music_init_ft();
static void music_shutdown_ft(); static void music_shutdown_ft();
static midi_struct* load_track(LPCSTR fileName); static midi_struct* load_track(LPCSTR fileName);
static int load_file(midi_struct** midi_res, void* filePtrOrPath, int fileSizeP, int flags); static int load_file(midi_struct** midi_res, void* filePtrOrPath, int fileSizeP, int flags);

View File

@ -80,7 +80,7 @@ void options::init(HMENU menuHandle)
Options.RightFlipperKeyDft = SDLK_SLASH; Options.RightFlipperKeyDft = SDLK_SLASH;
Options.PlungerKeyDft = SDLK_SPACE; Options.PlungerKeyDft = SDLK_SPACE;
Options.LeftTableBumpKeyDft = SDLK_x; Options.LeftTableBumpKeyDft = SDLK_x;
Options.RightTableBumpKeyDft = SDLK_GREATER; Options.RightTableBumpKeyDft = SDLK_PERIOD;
Options.BottomTableBumpKeyDft = SDLK_UP; Options.BottomTableBumpKeyDft = SDLK_UP;
/*pinball::get_rc_int(159, &Options.LeftFlipperKeyDft); /*pinball::get_rc_int(159, &Options.LeftFlipperKeyDft);
pinball::get_rc_int(160, &Options.RightFlipperKeyDft); pinball::get_rc_int(160, &Options.RightFlipperKeyDft);
@ -126,7 +126,7 @@ void options::init(HMENU menuHandle)
if (MenuHandle) if (MenuHandle)
{ {
DeleteMenu(MenuHandle, Menu1_Select_Table, 0); DeleteMenu(MenuHandle, Menu1_Select_Table, 0);
DrawMenuBar(winmain::hwnd_frame); DrawMenuBar(nullptr);
} }
} }
memory::free(tmpBuf); memory::free(tmpBuf);
@ -387,7 +387,7 @@ void options::init_resolution()
void options::keyboard() void options::keyboard()
{ {
DialogBoxParamA(winmain::hinst, "KEYMAPPER", winmain::hwnd_frame, KeyMapDlgProc, 0); DialogBoxParamA(nullptr, "KEYMAPPER", nullptr, KeyMapDlgProc, 0);
} }
INT_PTR _stdcall options::KeyMapDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) INT_PTR _stdcall options::KeyMapDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)

View File

@ -11,24 +11,24 @@ short partman::_field_size[] =
datFileStruct* partman::load_records(LPCSTR lpFileName, int resolution, bool fullTiltMode) datFileStruct* partman::load_records(LPCSTR lpFileName, int resolution, bool fullTiltMode)
{ {
_OFSTRUCT ReOpenBuff{};
datFileHeader header{}; datFileHeader header{};
dat8BitBmpHeader bmpHeader{}; dat8BitBmpHeader bmpHeader{};
dat16BitBmpHeader zMapHeader{}; dat16BitBmpHeader zMapHeader{};
const HFILE fileHandle = OpenFile(lpFileName, &ReOpenBuff, 0); FILE* fileHandle;
if (fileHandle == -1) fopen_s(&fileHandle, lpFileName, "rb");
if (fileHandle == nullptr)
return nullptr; return nullptr;
_lread(fileHandle, &header, 183u); fread(&header, 1, sizeof datFileHeader, fileHandle);
if (lstrcmpA("PARTOUT(4.0)RESOURCE", header.FileSignature)) if (lstrcmpA("PARTOUT(4.0)RESOURCE", header.FileSignature))
{ {
_lclose(fileHandle); fclose(fileHandle);
return nullptr; return nullptr;
} }
auto datFile = memory::allocate<datFileStruct>(); auto datFile = memory::allocate<datFileStruct>();
if (!datFile) if (!datFile)
{ {
_lclose(fileHandle); fclose(fileHandle);
return nullptr; return nullptr;
} }
if (lstrlenA(header.Description) <= 0) if (lstrlenA(header.Description) <= 0)
@ -42,7 +42,7 @@ datFileStruct* partman::load_records(LPCSTR lpFileName, int resolution, bool ful
datFile->Description = descriptionBuf; datFile->Description = descriptionBuf;
if (!descriptionBuf) if (!descriptionBuf)
{ {
_lclose(fileHandle); fclose(fileHandle);
memory::free(datFile); memory::free(datFile);
return nullptr; return nullptr;
} }
@ -54,13 +54,13 @@ datFileStruct* partman::load_records(LPCSTR lpFileName, int resolution, bool ful
auto unknownBuf = memory::allocate(header.Unknown); auto unknownBuf = memory::allocate(header.Unknown);
if (!unknownBuf) if (!unknownBuf)
{ {
_lclose(fileHandle); fclose(fileHandle);
if (datFile->Description) if (datFile->Description)
memory::free(datFile->Description); memory::free(datFile->Description);
memory::free(datFile); memory::free(datFile);
return nullptr; return nullptr;
} }
_lread(fileHandle, static_cast<void*>(unknownBuf), header.Unknown); fread(unknownBuf, 1, header.Unknown, fileHandle);
memory::free(unknownBuf); memory::free(unknownBuf);
} }
@ -97,10 +97,10 @@ datFileStruct* partman::load_records(LPCSTR lpFileName, int resolution, bool ful
if (entryType == datFieldTypes::Bitmap8bit) if (entryType == datFieldTypes::Bitmap8bit)
{ {
_hread(fileHandle, &bmpHeader, sizeof(dat8BitBmpHeader)); fread(&bmpHeader, 1, sizeof(dat8BitBmpHeader), fileHandle);
if (bmpHeader.Resolution != resolution && bmpHeader.Resolution != -1) if (bmpHeader.Resolution != resolution && bmpHeader.Resolution != -1)
{ {
_llseek(fileHandle, bmpHeader.Size, 1); fseek(fileHandle, bmpHeader.Size, SEEK_CUR);
continue; continue;
} }
@ -124,7 +124,7 @@ datFileStruct* partman::load_records(LPCSTR lpFileName, int resolution, bool ful
abort = true; abort = true;
break; break;
} }
_hread(fileHandle, bmp->BmpBufPtr1, bmpHeader.Size); fread(bmp->BmpBufPtr1, 1, bmpHeader.Size, fileHandle);
bmp->XPosition = bmpHeader.XPosition; bmp->XPosition = bmpHeader.XPosition;
bmp->YPosition = bmpHeader.YPosition; bmp->YPosition = bmpHeader.YPosition;
} }
@ -137,19 +137,19 @@ datFileStruct* partman::load_records(LPCSTR lpFileName, int resolution, bool ful
fieldSize--; fieldSize--;
if (zMapResolution != resolution && zMapResolution != -1) if (zMapResolution != resolution && zMapResolution != -1)
{ {
_llseek(fileHandle, fieldSize, 1); fseek(fileHandle, fieldSize, SEEK_CUR);
continue; continue;
} }
} }
_hread(fileHandle, &zMapHeader, sizeof(dat16BitBmpHeader)); fread(&zMapHeader, 1, sizeof(dat16BitBmpHeader), fileHandle);
int length = fieldSize - sizeof(dat16BitBmpHeader); int length = fieldSize - sizeof(dat16BitBmpHeader);
auto zmap = memory::allocate<zmap_header_type>(1, length); auto zmap = memory::allocate<zmap_header_type>(1, length);
zmap->Width = zMapHeader.Width; zmap->Width = zMapHeader.Width;
zmap->Height = zMapHeader.Height; zmap->Height = zMapHeader.Height;
zmap->Stride = zMapHeader.Stride; zmap->Stride = zMapHeader.Stride;
_hread(fileHandle, zmap->ZBuffer, length); fread(zmap->ZBuffer, 1, length, fileHandle);
entryData->Buffer = reinterpret_cast<char*>(zmap); entryData->Buffer = reinterpret_cast<char*>(zmap);
} }
else else
@ -161,7 +161,7 @@ datFileStruct* partman::load_records(LPCSTR lpFileName, int resolution, bool ful
abort = true; abort = true;
break; break;
} }
_hread(fileHandle, entryBuffer, fieldSize); fread(entryBuffer, 1, fieldSize, fileHandle);
} }
entryData->FieldSize = fieldSize; entryData->FieldSize = fieldSize;
@ -170,7 +170,7 @@ datFileStruct* partman::load_records(LPCSTR lpFileName, int resolution, bool ful
datFile->NumberOfGroups = groupIndex + 1; datFile->NumberOfGroups = groupIndex + 1;
} }
_lclose(fileHandle); fclose(fileHandle);
if (datFile->NumberOfGroups == header.NumberOfGroups) if (datFile->NumberOfGroups == header.NumberOfGroups)
return datFile; return datFile;
unload_records(datFile); unload_records(datFile);
@ -280,16 +280,16 @@ char* partman::field_labeled(datFileStruct* datFile, LPCSTR lpString, datFieldTy
return groupIndex < 0 ? nullptr : field(datFile, groupIndex, fieldType); return groupIndex < 0 ? nullptr : field(datFile, groupIndex, fieldType);
} }
char partman::_lread_char(HFILE hFile) char partman::_lread_char(FILE* file)
{ {
char Buffer = 0; char Buffer = 0;
_lread(hFile, &Buffer, 1u); fread(&Buffer, 1, 1, file);
return Buffer; return Buffer;
} }
int partman::_lread_long(HFILE hFile) int partman::_lread_long(FILE* file)
{ {
int Buffer = 0; int Buffer = 0;
_lread(hFile, &Buffer, 4u); fread(&Buffer, 1, 4, file);
return Buffer; return Buffer;
} }

View File

@ -119,6 +119,6 @@ public:
static char* field_labeled(datFileStruct* datFile, LPCSTR lpString, datFieldTypes fieldType); static char* field_labeled(datFileStruct* datFile, LPCSTR lpString, datFieldTypes fieldType);
private: private:
static short _field_size[]; static short _field_size[];
static char _lread_char(HFILE hFile); static char _lread_char(FILE* file);
static int _lread_long(HFILE hFile); static int _lread_long(FILE* file);
}; };

View File

@ -33,7 +33,7 @@ high_score_struct pb::highscore_table[5];
bool pb::FullTiltMode = false; bool pb::FullTiltMode = false;
int pb::init(SDL_Renderer* render) int pb::init()
{ {
float projMat[12], zMin = 0, zScaler = 0; float projMat[12], zMin = 0, zScaler = 0;
CHAR datFileName[300]; CHAR datFileName[300];
@ -52,7 +52,7 @@ int pb::init(SDL_Renderer* render)
if (!record_table) if (!record_table)
return 1; return 1;
auto plt = (PALETTEENTRY*)partman::field_labeled(record_table, "background", datFieldTypes::Palette); auto plt = (ColorRgba*)partman::field_labeled(record_table, "background", datFieldTypes::Palette);
gdrv::display_palette(plt); gdrv::display_palette(plt);
auto backgroundBmp = (gdrv_bitmap8*)partman::field_labeled(record_table, "background", datFieldTypes::Bitmap8bit); auto backgroundBmp = (gdrv_bitmap8*)partman::field_labeled(record_table, "background", datFieldTypes::Bitmap8bit);
@ -75,7 +75,7 @@ int pb::init(SDL_Renderer* render)
zScaler = cameraInfo[2]; zScaler = cameraInfo[2];
} }
gdrv::init(render, resInfo->TableWidth, resInfo->TableHeight); gdrv::init(resInfo->TableWidth, resInfo->TableHeight);
render::init(nullptr, zMin, zScaler, resInfo->TableWidth, resInfo->TableHeight); render::init(nullptr, zMin, zScaler, resInfo->TableWidth, resInfo->TableHeight);
gdrv::copy_bitmap( gdrv::copy_bitmap(
&render::vscreen, &render::vscreen,
@ -448,7 +448,7 @@ void pb::keydown(int key)
{ {
switch (key) switch (key)
{ {
case 'B': case 'b':
TBall* ball; TBall* ball;
if (MainTable->BallList->GetCount() <= 0) if (MainTable->BallList->GetCount() <= 0)
{ {
@ -477,17 +477,17 @@ void pb::keydown(int key)
ball->Acceleration.Y = 0.0; ball->Acceleration.Y = 0.0;
ball->Acceleration.X = 0.0; ball->Acceleration.X = 0.0;
break; break;
case 'H': case 'h':
char String1[200]; char String1[200];
lstrcpyA(String1, pinball::get_rc_string(26, 0)); lstrcpyA(String1, pinball::get_rc_string(26, 0));
high_score::show_and_set_high_score_dialog(highscore_table, 1000000000, 1, String1); high_score::show_and_set_high_score_dialog(highscore_table, 1000000000, 1, String1);
break; break;
case 'M': case 'm':
char buffer[20]; char buffer[20];
sprintf_s(buffer, "%zu", memory::use_total); sprintf_s(buffer, "%zu", memory::use_total);
MessageBoxA(winmain::hwnd_frame, buffer, "Mem:", 0x2000u); SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Mem:", buffer, winmain::MainWindow);
break; break;
case 'R': case 'r':
control::cheat_bump_rank(); control::cheat_bump_rank();
break; break;
case VK_F11: case VK_F11:

View File

@ -16,7 +16,7 @@ public:
static high_score_struct highscore_table[5]; static high_score_struct highscore_table[5];
static bool FullTiltMode; static bool FullTiltMode;
static int init(SDL_Renderer* render); static int init();
static int uninit(); static int uninit();
static void reset_table(); static void reset_table();
static void firsttime_setup(); static void firsttime_setup();

View File

@ -19,7 +19,7 @@
#include <cstdint> #include <cstdint>
#include <type_traits> /*For control template*/ #include <type_traits> /*For control template*/
#include <chrono> #include <chrono>
#include <iostream> //#include <iostream>
#include <iomanip> #include <iomanip>
//#include <cstdlib> //#include <cstdlib>
@ -27,6 +27,10 @@
#include "SDL.h" #include "SDL.h"
#include <SDL_mixer.h> #include <SDL_mixer.h>
//typedef const char* LPCSTR;
//typedef int HINSTANCE;
//typedef int HWND;
/*Use (void) to silent unused warnings.*/ /*Use (void) to silent unused warnings.*/
#define assertm(exp, msg) assert(((void)msg, exp)) #define assertm(exp, msg) assert(((void)msg, exp))

View File

@ -206,7 +206,7 @@ std::map<uint32_t, LPCSTR> rc_strings
{2032, "Use &Maximum Resolution (1024 x 768)"} {2032, "Use &Maximum Resolution (1024 x 768)"}
}; };
int LoadStringL(HINSTANCE hInstance, UINT uID, LPSTR lpBuffer, int cchBufferMax) int LoadStringAlt(UINT uID, LPSTR lpBuffer, int cchBufferMax)
{ {
auto str = rc_strings.find(uID); auto str = rc_strings.find(uID);
if (str == rc_strings.end()) if (str == rc_strings.end())
@ -214,7 +214,7 @@ int LoadStringL(HINSTANCE hInstance, UINT uID, LPSTR lpBuffer, int cchBufferMax)
return 0; return 0;
} }
lstrcpyA(lpBuffer, str->second); strncpy_s(lpBuffer, cchBufferMax, str->second, cchBufferMax);
return 1; return 1;
} }
@ -229,7 +229,7 @@ int pinball::RightShift = -1;
char* pinball::get_rc_string(int uID, int a2) char* pinball::get_rc_string(int uID, int a2)
{ {
char* result = &getRcBuffer[256 * rc_string_slot]; char* result = &getRcBuffer[256 * rc_string_slot];
if (!LoadStringL(winmain::hinst, uID, &getRcBuffer[256 * rc_string_slot], 255)) if (!LoadStringAlt(uID, &getRcBuffer[256 * rc_string_slot], 255))
*result = 0; *result = 0;
if (++rc_string_slot >= 6) if (++rc_string_slot >= 6)
rc_string_slot = 0; rc_string_slot = 0;
@ -239,7 +239,7 @@ char* pinball::get_rc_string(int uID, int a2)
int pinball::get_rc_int(int uID, int* dst) int pinball::get_rc_int(int uID, int* dst)
{ {
char buffer[255]; char buffer[255];
int result = LoadStringL(winmain::hinst, uID, buffer, 255); int result = LoadStringAlt(uID, buffer, 255);
if (!result) if (!result)
return result; return result;
*dst = atoi(buffer); *dst = atoi(buffer);

View File

@ -138,7 +138,7 @@ void render::update()
auto dirtyRect = &(*dirtyPtr)->DirtyRect; auto dirtyRect = &(*dirtyPtr)->DirtyRect;
auto width2 = (*dirtyPtr)->DirtyRect.Width; auto width2 = (*dirtyPtr)->DirtyRect.Width;
if (width2 > 0) if (width2 > 0)
gdrv::blit_sequence( gdrv::blit(
&vscreen, &vscreen,
dirtyRect->XPosition, dirtyRect->XPosition,
dirtyRect->YPosition, dirtyRect->YPosition,
@ -165,7 +165,7 @@ void render::update()
if (maths::overlapping_box(dirtyRect, rectCopy, &overlapRect) && dirtyRect->Width > 0) if (maths::overlapping_box(dirtyRect, rectCopy, &overlapRect) && dirtyRect->Width > 0)
{ {
if (overlapRect.Width > 0) if (overlapRect.Width > 0)
gdrv::blit_sequence( gdrv::blit(
&vscreen, &vscreen,
overlapRect.XPosition, overlapRect.XPosition,
overlapRect.YPosition, overlapRect.YPosition,
@ -177,7 +177,7 @@ void render::update()
else else
{ {
if (dirtyRect->Width > 0) if (dirtyRect->Width > 0)
gdrv::blit_sequence( gdrv::blit(
&vscreen, &vscreen,
dirtyRect->XPosition, dirtyRect->XPosition,
dirtyRect->YPosition, dirtyRect->YPosition,
@ -186,7 +186,7 @@ void render::update()
dirtyRect->Width, dirtyRect->Width,
dirtyRect->Height); dirtyRect->Height);
if (rectCopy->Width > 0) if (rectCopy->Width > 0)
gdrv::blit_sequence( gdrv::blit(
&vscreen, &vscreen,
rectCopy->XPosition, rectCopy->XPosition,
rectCopy->YPosition, rectCopy->YPosition,

View File

@ -250,7 +250,7 @@ void score::update(scoreStruct* score)
{ {
unsigned char curChar = scoreBuf[index]; unsigned char curChar = scoreBuf[index];
curChar -= '0'; curChar -= '0';
gdrv_bitmap8* bmp = score->CharBmp[curChar % 10]; gdrv_bitmap8* bmp = score->CharBmp[curChar % 10u];
x -= bmp->Width; x -= bmp->Width;
int height = bmp->Height; int height = bmp->Height;
int width = bmp->Width; int width = bmp->Width;

View File

@ -13,10 +13,9 @@
const double TargetFps = 60, TargetFrameTime = 1000 / TargetFps; const double TargetFps = 60, TargetFrameTime = 1000 / TargetFps;
HINSTANCE winmain::hinst = nullptr;
HWND winmain::hwnd_frame = nullptr;
HCURSOR winmain::mouse_hsave; HCURSOR winmain::mouse_hsave;
SDL_Window* winmain::MainWindow = nullptr; SDL_Window* winmain::MainWindow = nullptr;
SDL_Renderer* winmain::Renderer = nullptr;
int winmain::return_value = 0; int winmain::return_value = 0;
int winmain::bQuit = 0; int winmain::bQuit = 0;
@ -47,13 +46,7 @@ uint32_t timeGetTimeAlt()
return static_cast<uint32_t>(millis); return static_cast<uint32_t>(millis);
} }
int winmain::WinMain(LPCSTR lpCmdLine)
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
return winmain::WinMain(hInstance, hPrevInstance, lpCmdLine, nShowCmd);
}
int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{ {
memory::init(memalloc_failure); memory::init(memalloc_failure);
++memory::critical_allocation; ++memory::critical_allocation;
@ -70,7 +63,6 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
} }
pinball::quickFlag = strstr(lpCmdLine, "-quick") != nullptr; pinball::quickFlag = strstr(lpCmdLine, "-quick") != nullptr;
hinst = hInstance;
auto regSpaceCadet = pinball::get_rc_string(166, 0); auto regSpaceCadet = pinball::get_rc_string(166, 0);
options::get_string(regSpaceCadet, "Pinball Data", DatFileName, pinball::get_rc_string(168, 0), 300); options::get_string(regSpaceCadet, "Pinball Data", DatFileName, pinball::get_rc_string(168, 0), 300);
@ -85,20 +77,8 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
strcpy_s(DatFileName, "CADET.DAT"); strcpy_s(DatFileName, "CADET.DAT");
pb::FullTiltMode = true; pb::FullTiltMode = true;
} }
iFrostUniqueMsg = RegisterWindowMessageA("PinballThemeSwitcherUniqueMsgString"); auto splash = splash::splash_screen(nullptr, "splash_bitmap", "splash_bitmap");
auto windowClass = pinball::get_rc_string(167, 0);
auto windowHandle = FindWindowA(windowClass, nullptr);
if (windowHandle)
{
SendMessageA(windowHandle, iFrostUniqueMsg, 0, 0);
return 0;
}
if (check_expiration_date())
return 0;
auto splash = splash::splash_screen(hInstance, "splash_bitmap", "splash_bitmap");
pinball::FindShiftKeys(); pinball::FindShiftKeys();
options::init_resolution(); options::init_resolution();
@ -123,6 +103,7 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
-1, -1,
SDL_RENDERER_ACCELERATED SDL_RENDERER_ACCELERATED
); );
Renderer = renderer;
if (!renderer) if (!renderer)
{ {
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Could not create renderer", SDL_GetError(), window); SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Could not create renderer", SDL_GetError(), window);
@ -141,10 +122,10 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
options::menu_set(Menu1_Sounds, 0); options::menu_set(Menu1_Sounds, 0);
Sound::Activate(); Sound::Activate();
if (!pinball::quickFlag && !midi::music_init((HWND)window)) if (!pinball::quickFlag && !midi::music_init())
options::menu_set(Menu1_Music, 0); options::menu_set(Menu1_Music, 0);
if (pb::init(renderer)) if (pb::init())
_exit(0); _exit(0);
SetCursor(prevCursor); SetCursor(prevCursor);
auto changeDisplayFg = options::get_int(nullptr, "Change Display", 1); auto changeDisplayFg = options::get_int(nullptr, "Change Display", 1);
@ -160,7 +141,7 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
--memory::critical_allocation; --memory::critical_allocation;
} }
auto menuHandle = GetMenu(windowHandle); auto menuHandle = GetMenu(nullptr);
options::init(menuHandle); options::init(menuHandle);
pb::reset_table(); pb::reset_table();
pb::firsttime_setup(); pb::firsttime_setup();
@ -180,11 +161,7 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
splash::splash_destroy(splash); splash::splash_destroy(splash);
} }
pinball::adjust_priority(options::Options.PriorityAdj); pinball::adjust_priority(options::Options.PriorityAdj);
const auto startTime = timeGetTimeAlt();
MSG wndMessage{};
while (timeGetTimeAlt() >= startTime && timeGetTimeAlt() - startTime < 0) // Don't wait for now, was 2000
PeekMessageA(&wndMessage, hwnd_frame, 0, 0, 1u);
if (strstr(lpCmdLine, "-demo")) if (strstr(lpCmdLine, "-demo"))
pb::toggle_demo(); pb::toggle_demo();
@ -217,7 +194,7 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
{ {
if (!gfr_display.BmpBufPtr1) if (!gfr_display.BmpBufPtr1)
{ {
auto plt = static_cast<PALETTEENTRY*>(malloc(1024u)); auto plt = static_cast<ColorRgba*>(malloc(1024u));
auto pltPtr = &plt[10]; auto pltPtr = &plt[10];
for (int i1 = 0, i2 = 0; i1 < 256 - 10; ++i1, i2 += 8) for (int i1 = 0, i2 = 0; i1 < 256 - 10; ++i1, i2 += 8)
{ {
@ -228,7 +205,8 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
redGreen = i1; redGreen = i1;
} }
*pltPtr++ = {redGreen, redGreen, blue}; auto clr = Rgba{ redGreen, redGreen, blue, 0 };
*pltPtr++ = { *reinterpret_cast<uint32_t*>(&clr) };
} }
gdrv::display_palette(plt); gdrv::display_palette(plt);
free(plt); free(plt);
@ -291,18 +269,20 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
} }
--updateCounter; --updateCounter;
then = now; then = now;
auto frameEnd = static_cast<double>(SDL_GetPerformanceCounter());
auto elapsedMs = (frameEnd - frameStart) * sdlTimerResMs;
if (elapsedMs >= TargetFrameTime)
{
// Keep track of remainder, limited to one frame time.
frameStart = frameEnd - min(elapsedMs - TargetFrameTime, TargetFrameTime) / sdlTimerResMs;
SDL_RenderPresent(renderer);
frameCounter++;
}
} }
} }
auto frameEnd = static_cast<double>(SDL_GetPerformanceCounter());
auto elapsedMs = (frameEnd - frameStart) * sdlTimerResMs;
if (elapsedMs >= TargetFrameTime)
{
// Keep track of remainder, limited to one frame time.
frameStart = frameEnd - min(elapsedMs - TargetFrameTime, TargetFrameTime) / sdlTimerResMs;
SDL_RenderClear(renderer);
gdrv::BlitScreen();
SDL_RenderPresent(renderer);
frameCounter++;
}
} }
} }
@ -312,9 +292,10 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
pb::uninit(); pb::uninit();
Sound::Close(); Sound::Close();
gdrv::uninit(); gdrv::uninit();
DestroyWindow(hwnd_frame); SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
options::path_uninit(); options::path_uninit();
UnregisterClassA(windowClass, hinst);
if (restart) if (restart)
{ {
@ -385,17 +366,17 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP
++memory::critical_allocation; ++memory::critical_allocation;
auto prevCursor = SetCursor(LoadCursorA(nullptr, IDC_WAIT)); auto prevCursor = SetCursor(LoadCursorA(nullptr, IDC_WAIT));
gdrv::init(nullptr,0,0); gdrv::init(0,0);
auto voiceCount = options::get_int(nullptr, "Voices", 8); auto voiceCount = options::get_int(nullptr, "Voices", 8);
if (!Sound::Init(voiceCount)) if (!Sound::Init(voiceCount))
options::menu_set(Menu1_Sounds, 0); options::menu_set(Menu1_Sounds, 0);
Sound::Activate(); Sound::Activate();
if (!pinball::quickFlag && !midi::music_init(hWnd)) if (!pinball::quickFlag && !midi::music_init())
options::menu_set(Menu1_Music, 0); options::menu_set(Menu1_Music, 0);
if (pb::init(nullptr)) if (pb::init())
_exit(0); _exit(0);
SetCursor(prevCursor); SetCursor(prevCursor);
auto changeDisplayFg = options::get_int(nullptr, "Change Display", 1); auto changeDisplayFg = options::get_int(nullptr, "Change Display", 1);
@ -485,10 +466,10 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP
case VK_ESCAPE: case VK_ESCAPE:
if (options::Options.FullScreen) if (options::Options.FullScreen)
options::toggle(0x193u); options::toggle(0x193u);
SendMessageA(hwnd_frame, 0x112u, 0xF020u, 0); SendMessageA(nullptr, 0x112u, 0xF020u, 0);
break; break;
case VK_F1: case VK_F1:
help_introduction(hinst, hWnd); help_introduction(nullptr, hWnd);
break; break;
case VK_F2: case VK_F2:
new_game(); new_game();
@ -574,7 +555,7 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP
{ {
char cmdLine[0x1F4u]; char cmdLine[0x1F4u];
options::get_string(nullptr, "Shell Exe", tmpBuf, "", 500); options::get_string(nullptr, "Shell Exe", tmpBuf, "", 500);
auto iHwnd = reinterpret_cast<size_t>(hwnd_frame); auto iHwnd = reinterpret_cast<size_t>(nullptr);
sprintf_s( sprintf_s(
cmdLine, cmdLine,
"%s %s%zX %s%zX", "%s %s%zX %s%zX",
@ -587,7 +568,7 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP
{ {
auto caption = pinball::get_rc_string(170, 0); auto caption = pinball::get_rc_string(170, 0);
auto text = pinball::get_rc_string(171, 0); auto text = pinball::get_rc_string(171, 0);
MessageBoxA(hwnd_frame, text, caption, 0x2010u); MessageBoxA(nullptr, text, caption, 0x2010u);
} }
memory::free(tmpBuf); memory::free(tmpBuf);
} }
@ -610,7 +591,7 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP
case Menu1_Help_Topics: case Menu1_Help_Topics:
if (!single_step) if (!single_step)
pause(); pause();
help_introduction(hinst, hWnd); help_introduction(nullptr, hWnd);
break; break;
case 106: // End game button? case 106: // End game button?
pb::end_game(); pb::end_game();
@ -637,7 +618,7 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP
case Menu1_About_Pinball: case Menu1_About_Pinball:
if (!single_step) if (!single_step)
pause(); pause();
a_dialog(hinst, hWnd); a_dialog(nullptr, hWnd);
break; break;
case Menu1_High_Scores: case Menu1_High_Scores:
if (!single_step) if (!single_step)
@ -745,7 +726,7 @@ int winmain::event_handler(const SDL_Event* event)
SDL_MinimizeWindow(MainWindow); SDL_MinimizeWindow(MainWindow);
break; break;
case SDLK_F1: case SDLK_F1:
help_introduction(hinst, (HWND)MainWindow); help_introduction(nullptr, (HWND)MainWindow);
break; break;
case SDLK_F2: case SDLK_F2:
new_game(); new_game();
@ -876,6 +857,10 @@ int winmain::event_handler(const SDL_Event* event)
gdrv::get_focus(); gdrv::get_focus();
pb::loose_focus(); pb::loose_focus();
break; break;
case SDL_WINDOWEVENT_RESIZED:
fullscrn::window_size_changed();
fullscrn::force_redraw();
break;
default: ; default: ;
} }
break; break;
@ -914,12 +899,6 @@ void winmain::memalloc_failure()
_exit(1); _exit(1);
} }
int winmain::check_expiration_date()
{
return 0;
}
HDC winmain::_BeginPaint(HWND hWnd, LPPAINTSTRUCT lpPaint) HDC winmain::_BeginPaint(HWND hWnd, LPPAINTSTRUCT lpPaint)
{ {
HDC context = BeginPaint(hWnd, lpPaint); HDC context = BeginPaint(hWnd, lpPaint);
@ -1004,5 +983,6 @@ void winmain::help_introduction(HINSTANCE a1, HWND a2)
void winmain::Restart() void winmain::Restart()
{ {
restart = true; restart = true;
PostMessageA(hwnd_frame, WM_QUIT, 0, 0); SDL_Event event{SDL_QUIT};
SDL_PushEvent(&event);
} }

View File

@ -4,19 +4,16 @@
class winmain class winmain
{ {
public: public:
static const DWORD WndStyle = WS_GROUP | WS_SYSMENU | WS_DLGFRAME | WS_BORDER | WS_MAXIMIZE | WS_CLIPCHILDREN |
WS_THICKFRAME | WS_MAXIMIZEBOX;
static char DatFileName[300]; static char DatFileName[300];
static int single_step; static int single_step;
static HINSTANCE hinst; static SDL_Window* MainWindow;
static HWND hwnd_frame; static SDL_Renderer* Renderer;
static int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd); static int WinMain(LPCSTR lpCmdLine);
static LRESULT CALLBACK message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); static LRESULT CALLBACK message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
static int event_handler(const SDL_Event* event); static int event_handler(const SDL_Event* event);
static void memalloc_failure(); static void memalloc_failure();
static int ProcessWindowMessages(); static int ProcessWindowMessages();
static int check_expiration_date();
static HDC _GetDC(HWND hWnd); static HDC _GetDC(HWND hWnd);
static int a_dialog(HINSTANCE hInstance, HWND hWnd); static int a_dialog(HINSTANCE hInstance, HWND hWnd);
static void end_pause(); static void end_pause();
@ -32,7 +29,6 @@ private:
static gdrv_bitmap8 gfr_display; static gdrv_bitmap8 gfr_display;
static HCURSOR mouse_hsave; static HCURSOR mouse_hsave;
static bool restart; static bool restart;
static SDL_Window* MainWindow;
static HDC _BeginPaint(HWND hWnd, LPPAINTSTRUCT lpPaint); static HDC _BeginPaint(HWND hWnd, LPPAINTSTRUCT lpPaint);
}; };

View File

@ -127,9 +127,9 @@ void zdrv::paint_spliced_bmp(int xPos, int yPos, gdrv_bitmap8* dstBmp, zmap_head
if (yOffset < 0) if (yOffset < 0)
return; return;
auto bmpDstPtr = &dstBmp->BmpBufPtr2[xOffset + yOffset * dstBmp->Stride]; auto bmpDstPtr = &dstBmp->BmpBufPtr1[xOffset + yOffset * dstBmp->Stride];
auto zMapDstPtr = &dstZmap->ZPtr2[xOffset + yOffset * dstZmap->Stride]; auto zMapDstPtr = &dstZmap->ZPtr2[xOffset + yOffset * dstZmap->Stride];
auto bmpSrcPtr = reinterpret_cast<unsigned short*>(srcBmp->BmpBufPtr2); auto bmpSrcPtr = reinterpret_cast<unsigned short*>(srcBmp->BmpBufPtr1);
while (true) while (true)
{ {