2017-11-27 4 views
0

저는 현대 Windows 환경에서 구식 프로그램과 레거시 프로그램을 실행하기위한 지원을 제공하는 DxWnd 도구의 저자입니다.SetDIBitsToDevice 에뮬레이션

매우 이상한 게임은 Win-10 시스템에서 네이티브로 실행할 수 있음에도 불구하고 그래픽 조작에 심각한 문제를 초래하는 G-Nome입니다.

게임은 ddraw와 연결되지만 모든 프레임을 DIB_PAL_COLORS DIB로 작성하고 SetDIBitsToDevice user32 호출을 사용하여 DIB를 화면에 표시합니다. 이 작업은 32 비트 컬러 심도 비디오 모드에서도 비디오의 OBJ_DC DC 형식으로 지원되지만 MEM_DC 유형 DC에 적용 할 때 잘못된 색상을 생성합니다. 나는이 같은 일반적인 스키마를 사용하여 DIB를 확장하려고 동안이 발견 (변수 선언과 오류가 간결 제거 확인) :

hTempDc=CreateCompatibleDC(hdc); 
hbmPic=CreateCompatibleBitmap(hdc, OrigWidth, OrigHeight); 
SelectObject(hTempDc, hbmPic); 
SetDIBitsToDevice(hTempDc, 0, 0, OrigWidth, OrigHeight, XSrc, YSrc, uStartScan, cScanLines, lpvBits, lpbmi, fuColorUse); 
StretchBlt(hdc, XDest, YDest, dwWidth, dwHeight, hTempDc, 0, 0, OrigWidth, OrigHeight, SRCCOPY); 

픽셀이 매핑됩니다 당신을 DIB_PAL_COLORS DIB 출력 MSDN에 따르면, "현재"팔레트를 실현했지만, 당연히 32 비트 표면에 있으며 DC 복제본에는 팔레트가 전혀 없기 때문에 픽셀 색상이 완전히 잘못 보입니다.

대체 솔루션 DC는 다음 StretchBlt과 의지에 따라 확장 할 수있는 32 비트 메모리에 건물 SetDIBitsToDevice 행동을 모방 할 수 있지만 다시 내가 DIB 8bpp를 DIB_PAL_COLORS을 변환 할 수있는 방법을 문서화되어 있지 않습니다에 대한 중 하나 32bpp의 DIB_RGB_DIB 또는 32bpp DC.

이미 여러 가지 방법으로 시도했지만, 모든 경우에 픽셀 인덱스를 변환하는 데 사용되는 올바른 팔레트를 식별 할 수없는 것으로 보입니다. 누군가가 8bpp DIB_PAL_COLORS DIB 형식을 해석하는 데 도움이 될 수 있습니까?

+0

또한 현재 팔레트와 함께 SelectObject를 추가하려했으나 사용 가능하지 않은 GetCurrentObject (hdc, OBJ_PAL)는 NULL을 반환합니다. – gho

답변

1

질문을 올바르게 이해하면 색상 표가있는 DIB 형식의 원본 이미지가 있고이 이미지를 SetDIBitsToDevice를 사용하여 팔레트가 아닌 DC로 가져 오려고합니다.

아주 오랫동안 팔레트를 사용하지는 않았지만 대상 DC가 팔레트 장치가 아니면 DIB_PAL_COLORS를 올바르게 사용할 수 없습니다. 그것은 당신의 메모리 DC는 팔레트 장치 같지는 않다,하지만 당신은 확인할 수 있습니다

GetDeviceCaps(hTempDc, RASTERCAPS) & RC_PALETTE 

은 팔레트 장치 아니라 가정, 난 당신이 fuColorUse에 대한 DIB_RGB_COLORS를 사용하는 것 같아요. SetDIBitsToDevice는 각 픽셀의 인덱스를 사용하여 색상 표에서 해당 RGBQUAD 값을 조회합니다. (색상 표는 lpbmi가 가리키는 BITMAPINFO의 BITMAPINFOHEADER 뒤에옵니다.) RGBQUAD 값은 대상 장치에 픽셀 단위로 적용됩니다.

여전히 문제가있는 경우 픽셀 데이터 형식과 해당 색상 표 형식이 올바르게 표시되도록 BITMAPINFO 및 제공하는 색상 표를 자세히 살펴볼 것입니다.

+0

불행히도, 나는 선택의 자유가 없습니다. DxWnd는 GDI32, USER32 또는 DDRAW와 같은 라이브러리 호출을 인터셉트하고 프로그램 흐름을 매킨토시 루틴으로 재 라우팅하는 API 후커입니다.그것은 G-Nome PC 게임이 입력에서 DIB_PAL_COLORS 이미지를 갖는 SetDIBitToDevice 호출을 호출하여 프레임을 비디오로 렌더링한다는 것을 발견 한 로그를보고 있습니다. 그래서, 나는 동일한 입력을 받고 사용자 정의 크기와 바탕 화면 네이티브 컬러 깊이로 윈도우 표면에 DIB를 blit해야하는 창세기 루틴을 작성할 수 있지만 프로그램 실행 파일 (사용 가능한 C 코드는 없음) 작동 방식을 변경할 수는 없습니다. . – gho

+0

질문을 오해하지 않는 한, 소스 게임을 변경할 필요가 없습니다. 바른 일을해야하는 것이 바로 후크 기능입니다. –

+0

혼란 스럽습니다 : MSDN에 따르면 DIB_RGB_COLORS DIB는 BITMAPINFOHEADER 다음에 RGBQUAD 배열이있는 반면 DIB_PAL_COLORS DIB에는 팔레트에 대한 WORD 인덱스 배열이 뒤 따르고 있습니다 (내 메모리 덤프는 인덱스 배열 바로 뒤에 표시됨). 따라서 선언 할 수 있도록 다른 ColorUse 값은 임의의 색상을 유도해야합니다. 사실 나는 당신이 제안한 것을했는데 그 결과는 내가 가진 최고 중 하나였습니다. 대부분의 색상은 괜찮 았지만 스크린 샷을 보면 단순히 마젠타 픽셀의 비율이 높았 기 때문에 닫기가되었지만 투명도 문제가 있습니다 ... – gho

0

오, 나는 범인이 생긴 것 같아요. 다른 DxWnd 창녀가 RC_PALETTE 기능을 위조하여 GetDeviceCaps()에 있습니다. 가짜 기능을 제거하면 게임에서 더 이상 DIB_PAL_COLORS 형식을 사용하지 않고 더 관리하기 쉬운 DIB_RGB_COLORS DIB를 만듭니다. 문제가 수정되었습니다. 잘못된 트랙을 유감스럽게 생각하며 도움을 주셔서 감사합니다.