我正在开发一个项目,为旧游戏添加功能;这个想法是添加运行窗口选项(最初它只支持800x600全屏)。DirectDraw输出自适应
到目前为止,我修改了directDraw的初始化以删除全屏独占模式并使其能够与GDI一起工作,创建了一个剪辑器并正确设置了所有事情,游戏将全屏模式设置为8位颜色深度,运行窗口它会导致这样的图像输出垃圾:
到目前为止,我试图做使用的GetDIBits和SetDIBits来解决这个问题一些技巧,但我没有成功。
该游戏适用于一个非常古老的directDraw版本(没有关于此版本的文档,大部分工作都基于猜测和测试)。
游戏使用BltFast获取信息到屏幕。
这里是一块已写入尝试使用双位
PrimarySurface =游戏主表面本身
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
来解决该问题的代码是有什么办法可以转换的8bit色彩格式通过改变调用BltFast直接从缓冲区直接输出到屏幕?
它是一个更好的解决方案,重新路由输出到另一个DC然后使用GetDIBits/SetDIBits来修复图像?
它看起来的版本或者你的源格式是不是您所期望它是或者你的目标不是。你确定游戏没有使用800x600x4(16种颜色)吗?无论如何,我认为你会错误地采用这种方式,我根本不会使用GDI。我只写了一个DirectDraw封装器,它使用DirectDraw窗口模式来模拟独占模式。无需修补可执行文件或使用程序集。只需将您自己的DDRAW.DLL转储到同一个目录即可。已经有至少一个程序,谁的名字逃脱我,这已经这样做。 –
我有点新DirectDraw,所以我真的不知道我将如何模仿基于全屏的窗口模式,你有任何参考?此外,游戏使用ddraw的极其旧的版本,我猜想windows会切换到某些兼容版本(如果您使用随游戏分发的ddraw,根本没有任何工作) –
DirectDraw 7仍在线记录:https:// msdn.microsoft.com/en-us/library/windows/desktop/gg426124.aspx –