Ich arbeite an einem Projekt, um Funktionalität zu einem alten Spiel hinzuzufügen; Die Idee ist, die Option hinzuzufügen, um es windowed zu starten (ursprünglich unterstützt es nur Vollbild 800x600).DirectDraw Ausgabe Anpassung
Bisher habe ich die DirectDraw-Initialisierung geändert, um den exklusiven Vollbildmodus zu entfernen und mit GDI zu arbeiten, einen Clipper erstellt und alles richtig gesetzt, ist der Punkt, das Spiel setzt den Vollbildmodus auf 8bit Farbtiefe, läuft es gefenstert zur Ausgabe von Müll verursacht es wie dieses Bild:
i, um das Problem zu arbeiten, einige Tricks GetDIBits und SetDIBits zu tun mit, aber ich hatte keinen Erfolg Bisher versuchen.
Das Spiel funktioniert mit einer sehr alten DirectDraw-Version (es gibt keine Dokumentation über diese Version, der Großteil meiner Arbeit basiert auf Vermutungen und Tests).
Das Spiel verwendet BltFast, um Informationen auf den Bildschirm zu bekommen.
Hier ist ein Stück des Codes, der das Problem mit Di-Bits
PrimarySurface = Spiel primäre Oberfläche selbst
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
Gibt es eine Weise, die ich umwandeln kann das 8-Bit-Farbformat zu beheben wurde geschrieben, um zu versuchen, direkt aus dem Puffer, indem Sie den Aufruf von BltFast ändern, um korrekt auf den Bildschirm auszugeben?
Ist es eine bessere Lösung, die Ausgabe zu einem anderen DC umzuleiten, um dann GetDIBits/SetDIBits zu verwenden, um das Bild zu reparieren?
entweder Format ist Ihre Quelle sieht nicht, was Sie es sein oder Ihr Ziel erwarten nicht. Bist du sicher, dass das Spiel nicht 800x600x4 (16 Farben) verwendet? Auf jeden Fall glaube ich, dass du diesen falschen Weg eingeschlagen hast, ich würde GDI überhaupt nicht benutzen. Ich würde nur einen DirectDraw-Wrapper schreiben, der den exklusiven Modus im DirectDraw-Fenstermodus emuliert. Keine Notwendigkeit, die ausführbare Datei zu patchen oder Assembly zu verwenden. Werfen Sie einfach Ihre eigene DDRAW.DLL im selben Verzeichnis auf.Es gibt schon mindestens ein Programm, dessen Name mir entgeht, das tut das schon. –
Ich bin irgendwie neu zu DirectDraw, also habe ich wirklich keine Idee, wie ich Fenstermodus auf dem Vollbild emulieren würde, haben Sie irgendwelche Hinweise darauf? Außerdem verwendet das Spiel eine extrem alte Version von ddraw, die Windows auf eine Kompatibilitätsversion von Windows umschaltet (wenn du dd draw benutzt, wird nichts funktionieren) –
DirectDraw 7 ist noch online dokumentiert: https: // msdn.microsoft.com/en-us/library/windows/desktop/gg426124.aspx –