I'm working on a project to add functionality to an old game; the idea is to add the option to run it windowed (originally it only supports 800x600 fullscreen).
So far, i modified directDraw's initialization to remove fullscreen exclusive mode and to enable it to work with GDI, created a clipper and set everything properly the point is, the game sets the fullscreen mode to 8bit color depth, running it windowed causes it to output garbage like this image:
So far i tried to do some tricks using GetDIBits and SetDIBits to work around the problem but i had no success.
The game works with a very old directDraw version (there is no documentation at all about this version, most of my work is based on guesses and tests).
The game uses BltFast to get information to the screen.
Here is a piece of the code that was written to try to fix the issue using DIBits
PrimarySurface = Game primary surface itself
patch_1:
; Blt interface
CALL DWORD [EDX+1Ch] ;<--- Surface->BltFast() Outputs game screen, params pushed to stack elsewhere
pushad
; Get diBits and transform it properly to display
push surfaceDC
mov eax, [PrimarySurface]
mov edx, [eax]
push eax
call dword [edx+44h] ; Surface->GetDC(&surfaceDC)
test eax, eax
je patch_1_abort
invoke FindWindowA, 0, 'Rising Lands'
mov [windowHandle], eax
invoke GetDC, eax
mov [windowDC], eax
invoke CreateCompatibleDC, [surfaceDC]
mov [compatibleDC], eax
invoke CreateCompatibleDC, [windowDC]
mov [compatibleWindowDC], eax
invoke CreateCompatibleBitmap, [windowDC], 800, 600
mov [zbitmap], eax
; Get screen header
invoke GetDIBits, [compatibleWindowDC], [zbitmap], 0, 0, 0, bitmapHeader, 0
; Get game screen data
invoke GetDIBits, [compatibleDC], [zbitmap], 0, 600, bbuffer, bitmapHeader, 0
; Copy content back to screen
invoke SetDIBits, [compatibleWindowDC], [zbitmap], 0, 600, bbuffer, bitmapHeader, 0
; Release
push [surfaceDC]
mov eax, [PrimarySurface]
mov edx, [eax]
push eax
call dword [edx+68h]
patch_1_abort:
popad
; Original code finalization
MOV EDX,EAX
TEST EAX, EAX
jmp [p1r]
surfaceDC dd 0
windowHandle dd 0
windowDC dd 0
compatibleDC dd 0
compatibleWindowDC dd 0
zbitmap dd 0
bitmapInfo dd bitmapHeader
dd 0
bitmapHeader:
hSize dd endHeader - bitmapHeader
hWidth dd 0;800
hHeight dd 0;600
hPlanes dw 0;1
hBitCount dw 0;32
hCompression dd 0
hSizeImage dd 0
hxPPm dd 0
hyPPm dd 0
hClrUsed dd 0
hClrImp dd 0
endHeader:
bbuffer rb 800*600*10
Is there any way i can convert the 8bit color format directly from the buffer by changing the call to BltFast to output correctly to the screen?
Is it a better solution to reroute the output to another DC to then use GetDIBits/SetDIBits to fix the image?
After a lot of research, i found a wrapper (as suggested by Ross Ridge) that does the trick and forces the game to work with openGL and also enables a lot of neat features as well and is compatible even with the first versions of ddraw