首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DirectDraw输出自适应

DirectDraw输出自适应
EN

Stack Overflow用户
提问于 2016-08-06 02:01:40
回答 2查看 375关注 0票数 0

我正在做一个项目,为一个老游戏添加功能;我的想法是添加选项,以窗口方式运行它(最初它只支持800x600全屏)。

到目前为止,我修改了directDraw的初始化,删除了全屏独占模式,并使其能够与GDI一起工作,创建了一个裁剪程序,并正确地设置了所有内容。重点是,游戏将全屏模式设置为8位颜色深度,窗口运行会导致输出垃圾,如下图所示:

到目前为止,我尝试了一些技巧,使用GetDIBits和SetDIBits来解决这个问题,但没有成功。

这个游戏使用一个非常旧的directDraw版本(没有任何关于这个版本的文档,我的大部分工作都是基于猜测和测试的)。

游戏使用BltFast将信息显示在屏幕上。

以下是尝试使用DIBits修复该问题的一段代码

PrimarySurface =游戏主表面本身

代码语言:javascript
复制
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 

有没有什么方法可以通过更改对BltFast的调用来直接从缓冲区转换8位颜色格式以正确地输出到屏幕上?

将输出重新路由到另一个DC,然后使用GetDIBits/SetDIBits修复图像是更好的解决方案吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-08-09 22:20:53

经过大量的研究,我找到了一个包装器(根据Ross Ridge的建议),它完成了这个技巧,并强制游戏与openGL一起工作,而且还支持许多整洁的功能,甚至与ddraw的第一个版本也是兼容的

https://sourceforge.net/p/dxwnd

票数 2
EN

Stack Overflow用户

发布于 2016-08-06 02:59:59

最初的游戏是8位的,所以它依赖于调色板。GetDIBits将使用与其DC相关联的当前调色板,以便将8位像素值转换为您在bitmapHeader中请求的32位值。

我认为这是问题的第一部分,因为游戏的DC可能没有选择和实现调色板。因为它是在独占模式下使用DirectDraw,所以它可能是直接在显卡中设置调色板,而GDI不知道调色板是什么。

要解决这个问题,我认为您需要找到设置和修改调色板的代码,然后在执行GetDIBits之前显式选择该调色板并将其实现到游戏的DC中。

在那之后,我不清楚你是如何将像素获取到窗口DC的。您似乎创建了一个与window兼容的内存DC,然后使用SetDIBits将数据放入其中,但我不明白从内存DC到实际的window DC的blit在哪里。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38795346

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档