From 5c983ede8177c098faa5cea1b1357e3b338445f0 Mon Sep 17 00:00:00 2001 From: zeromus Date: Mon, 24 Jul 2017 13:47:30 -0500 Subject: [PATCH] winport - support 15bpp as well --- desmume/src/frontend/windows/aviout.cpp | 26 +++++- desmume/src/frontend/windows/hotkey.cpp | 40 ++++++--- desmume/src/frontend/windows/main.cpp | 82 +++++++++++++------ desmume/src/frontend/windows/main.h | 1 + desmume/src/frontend/windows/resource.h | 3 +- desmume/src/frontend/windows/resources.rc | 15 ++-- .../colorspacehandler/colorspacehandler.h | 1 + 7 files changed, 121 insertions(+), 47 deletions(-) diff --git a/desmume/src/frontend/windows/aviout.cpp b/desmume/src/frontend/windows/aviout.cpp index 9d70f9977..79bf92bf3 100644 --- a/desmume/src/frontend/windows/aviout.cpp +++ b/desmume/src/frontend/windows/aviout.cpp @@ -310,6 +310,27 @@ static int avi_open(const char* filename, const BITMAPINFOHEADER* pbmih, const W return result; } +//converts 16bpp to 24bpp and flips +static void do_video_conversion555(AVIFile* avi, const u16* buffer) +{ + int width = avi->prescaleLevel * 256; + int height = avi->prescaleLevel * 384; + u8* outbuf = avi_file->convert_buffer + width*(height - 1) * 3; + + for(int y = 0; y < height; y++) + { + for(int x = 0; x < width; x++) + { + u32 dst = ColorspaceConvert555To8888Opaque(*buffer++); + *outbuf++ = dst & 0xFF; + *outbuf++ = (dst >> 8) & 0xFF; + *outbuf++ = (dst >> 16) & 0xFF; + } + + outbuf -= width * 3 * 2; + } +} + //converts 32bpp to 24bpp and flips static void do_video_conversion(AVIFile* avi, const u32* buffer) { @@ -424,7 +445,10 @@ void DRV_AviVideoUpdate() if(video.prescaleHD != avi_file->prescaleLevel) return; - do_video_conversion(avi_file, buffer); + if(gpu_bpp == 15) + do_video_conversion555(avi_file, (u16*)buffer); + else + do_video_conversion(avi_file, buffer); if(FAILED(AVIStreamWrite(avi_file->compressed_streams[VIDEO_STREAM], avi_file->video_frames, 1, avi_file->convert_buffer, diff --git a/desmume/src/frontend/windows/hotkey.cpp b/desmume/src/frontend/windows/hotkey.cpp index c295a5de1..177bd48b7 100644 --- a/desmume/src/frontend/windows/hotkey.cpp +++ b/desmume/src/frontend/windows/hotkey.cpp @@ -163,23 +163,37 @@ void HK_QuickScreenShot(int param, bool justPressed) switch(path.imageformat()) { - case path.PNG: + case PathInfo::PNG: { strcat(fname, ".png"); - u32* swapbuf = (u32*)malloc_alignedCacheLine(dispInfo.customWidth * dispInfo.customHeight * 2 * 4); - ColorspaceConvertBuffer888XTo8888Opaque((const u32*)dispInfo.masterCustomBuffer, swapbuf, dispInfo.customWidth * dispInfo.customHeight * 2); - free_aligned(swapbuf); - NDS_WritePNG_32bppBuffer(dispInfo.customWidth, dispInfo.customHeight*2, swapbuf, fname); - free_aligned(swapbuf); + if(gpu_bpp == 15) + { + NDS_WritePNG_15bpp(dispInfo.customWidth, dispInfo.customHeight * 2, (const u16*)dispInfo.masterCustomBuffer, fname); + } + else + { + u32* swapbuf = (u32*)malloc_alignedCacheLine(dispInfo.customWidth * dispInfo.customHeight * 2 * 4); + ColorspaceConvertBuffer888XTo8888Opaque((const u32*)dispInfo.masterCustomBuffer, swapbuf, dispInfo.customWidth * dispInfo.customHeight * 2); + free_aligned(swapbuf); + NDS_WritePNG_32bppBuffer(dispInfo.customWidth, dispInfo.customHeight*2, swapbuf, fname); + free_aligned(swapbuf); + } } break; - case path.BMP: + case PathInfo::BMP: { strcat(fname, ".bmp"); - u32* swapbuf = (u32*)malloc_alignedCacheLine(dispInfo.customWidth * dispInfo.customHeight * 2 * 4); - ColorspaceConvertBuffer888XTo8888Opaque((const u32*)dispInfo.masterCustomBuffer, swapbuf, dispInfo.customWidth * dispInfo.customHeight * 2); - NDS_WriteBMP_32bppBuffer(dispInfo.customWidth, dispInfo.customHeight *2, swapbuf, fname); - free_aligned(swapbuf); + if(gpu_bpp == 15) + { + NDS_WriteBMP_15bpp(dispInfo.customWidth, dispInfo.customHeight * 2, (const u16*)dispInfo.masterCustomBuffer, fname); + } + else + { + u32* swapbuf = (u32*)malloc_alignedCacheLine(dispInfo.customWidth * dispInfo.customHeight * 2 * 4); + ColorspaceConvertBuffer888XTo8888Opaque((const u32*)dispInfo.masterCustomBuffer, swapbuf, dispInfo.customWidth * dispInfo.customHeight * 2); + NDS_WriteBMP_32bppBuffer(dispInfo.customWidth, dispInfo.customHeight *2, swapbuf, fname); + free_aligned(swapbuf); + } } break; } @@ -212,13 +226,13 @@ void HK_PrintScreen(int param, bool justPressed) path.formatname(file); filename += file; - if(path.imageformat() == path.PNG) + if(path.imageformat() == PathInfo::PNG) { filename += ".png"; ofn.lpstrDefExt = "png"; ofn.nFilterIndex = 1; } - else if(path.imageformat() == path.BMP) + else if(path.imageformat() == PathInfo::BMP) { filename += ".bmp"; ofn.lpstrDefExt = "bmp"; diff --git a/desmume/src/frontend/windows/main.cpp b/desmume/src/frontend/windows/main.cpp index afa9bc8d2..e94ae480b 100644 --- a/desmume/src/frontend/windows/main.cpp +++ b/desmume/src/frontend/windows/main.cpp @@ -328,7 +328,7 @@ bool start_paused; extern bool killStylusTopScreen; extern bool killStylusOffScreen; -static int gpu_bpp = 24; +int gpu_bpp = 24; extern LRESULT CALLBACK RamSearchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); void InitRamSearch(); @@ -1630,7 +1630,14 @@ static void OGL_DoDisplay() glGenTextures(1,&tex); glBindTexture(GL_TEXTURE_2D,tex); - glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA, video.width,video.height,0,GL_RGBA,GL_UNSIGNED_BYTE,video.finalBuffer()); + + if(gpu_bpp == 15) + { + //yeah, it's 32bits here still. we've converted it previously, for compositing the HUD + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, video.width, video.height, 0, GL_BGRA, GL_UNSIGNED_BYTE, video.finalBuffer()); + } + else + glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA, video.width,video.height,0,GL_RGBA,GL_UNSIGNED_BYTE,video.finalBuffer()); //the ds screen fills the texture entirely, so we dont have garbage at edge to worry about, //but we need to make sure this is clamped for when filtering is selected @@ -1796,7 +1803,10 @@ static void DD_DoDisplay() //it seems to work OK... //we have to do this because we couldn't ask the GPU for a swapped color format (it only uses the one 888 format internally) //in openGL we can fix it at the last minute, but in DD we can't. - ColorspaceConvertBuffer888XTo8888Opaque((u32*)video.finalBuffer(),(u32*)video.finalBuffer(),video.size()); + //if(gpu_bpp == 15) + // ColorspaceConvertBuffer555To8888Opaque((u16*)video.finalBuffer(), (u32*)video.finalBuffer(), video.size()); + //else + // ColorspaceConvertBuffer888XTo8888Opaque((u32*)video.finalBuffer(),(u32*)video.finalBuffer(),video.size()); if(ddraw.surfDescBack.dwWidth != video.rotatedwidth() || ddraw.surfDescBack.dwHeight != video.rotatedheight()) { @@ -1962,7 +1972,10 @@ static void DoDisplay(bool firstTime) displayNoPostponeNext = false; //we have to do a copy here because we're about to draw the OSD onto it. bummer. - memcpy(video.buffer, video.srcBuffer, video.srcBufferSize); + if(gpu_bpp == 15) + ColorspaceConvertBuffer555To8888Opaque((u16 *)video.srcBuffer, video.buffer, video.srcBufferSize / sizeof(u16)); + else + memcpy(video.buffer, video.srcBuffer, video.srcBufferSize); if(firstTime) { @@ -2063,10 +2076,12 @@ void Display() { const NDSDisplayInfo &dispInfo = GPU->GetDisplayInfo(); + const int PS = gpu_bpp==15?2:4; + if(CommonSettings.single_core()) { video.srcBuffer = (u8*)dispInfo.masterCustomBuffer; - video.srcBufferSize = dispInfo.customWidth*dispInfo.customHeight*2*4; + video.srcBufferSize = dispInfo.customWidth*dispInfo.customHeight*2* PS; DoDisplay(true); } else @@ -2084,7 +2099,7 @@ void Display() else newestDisplayBuffer = (currDisplayBuffer+2)%3; DisplayBuffer& db = displayBuffers[newestDisplayBuffer]; - int targetSize = 256*192*2*4*video.prescaleHD*video.prescaleHD; + int targetSize = 256*192*2* PS*video.prescaleHD*video.prescaleHD; if(db.size != targetSize) { free_aligned(db.buffer); @@ -2878,12 +2893,11 @@ static void SyncGpuBpp() { //either of these works. 666 must be packed as 888 if(gpu_bpp == 18) - GPU->SetColorFormat(NDSColorFormat_BGR666_Rev); + GPU->SetColorFormat(NDSColorFormat_BGR666_Rev); + else if(gpu_bpp == 15) + GPU->SetColorFormat(NDSColorFormat_BGR555_Rev); else - GPU->SetColorFormat(NDSColorFormat_BGR888_Rev); - - //555 doesnt work (packed to u16, needs widespread support) - //GPU->SetColorFormat(NDSColorFormat_BGR555_Rev); + GPU->SetColorFormat(NDSColorFormat_BGR888_Rev); } #define GPU3D_NULL_SAVED -1 @@ -4236,23 +4250,39 @@ void ScreenshotToClipboard(bool extraInfo) RECT rc; SetRect(&rc, 0, 0, width, height + exHeight); + FillRect(hMemDC, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH)); + BITMAPV4HEADER bmi; memset(&bmi, 0, sizeof(bmi)); - bmi.bV4Size = sizeof(bmi); - bmi.bV4Planes = 1; - bmi.bV4BitCount = 32; - bmi.bV4V4Compression = BI_RGB; - bmi.bV4Width = width; - bmi.bV4Height = -height; + bmi.bV4Size = sizeof(bmi); + bmi.bV4Planes = 1; + bmi.bV4BitCount = 32; + bmi.bV4V4Compression = BI_RGB; + bmi.bV4Width = width; + bmi.bV4Height = -height; + if(gpu_bpp == 15) + { + bmi.bV4Size = sizeof(bmi); + bmi.bV4Planes = 1; + bmi.bV4BitCount = 16; + bmi.bV4V4Compression = BI_RGB | BI_BITFIELDS; + bmi.bV4RedMask = 0x001F; + bmi.bV4GreenMask = 0x03E0; + bmi.bV4BlueMask = 0x7C00; + bmi.bV4Width = width; + bmi.bV4Height = -height; + SetDIBitsToDevice(hMemDC, 0, 0, width, height, 0, 0, 0, height, dispInfo.masterCustomBuffer, (BITMAPINFO*)&bmi, DIB_RGB_COLORS); + } + else + { + u32* swapbuf = (u32*)malloc_alignedCacheLine(width*height * 4); + ColorspaceConvertBuffer888XTo8888Opaque((const u32*)dispInfo.masterCustomBuffer, swapbuf, width * height); - u32* swapbuf = (u32*)malloc_alignedCacheLine(width*height*4); - ColorspaceConvertBuffer888XTo8888Opaque((const u32*)dispInfo.masterCustomBuffer, swapbuf, width * height); + SetDIBitsToDevice(hMemDC, 0, 0, width, height, 0, 0, 0, height, swapbuf, (BITMAPINFO*)&bmi, DIB_RGB_COLORS); - FillRect(hMemDC, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH)); - SetDIBitsToDevice(hMemDC, 0, 0, width, height, 0, 0, 0, height, swapbuf, (BITMAPINFO*)&bmi, DIB_RGB_COLORS); - - free_aligned(swapbuf); + free_aligned(swapbuf); + } //center-justify the extra text int xo = (width - 256)/2; @@ -4275,7 +4305,7 @@ void ScreenshotToClipboard(bool extraInfo) else TextOut(hMemDC, xo + 0, height + 14, nameandver, strlen(nameandver)); - char str[32] = {0}; + char str[64] = {0}; TextOut(hMemDC, xo + 8, height + 14 * (twolinever ? 3:2), gameInfo.ROMname, strlen(gameInfo.ROMname)); TextOut(hMemDC, xo + 8, height + 14 * (twolinever ? 4:3), gameInfo.ROMserial, strlen(gameInfo.ROMserial)); @@ -4286,7 +4316,7 @@ void ScreenshotToClipboard(bool extraInfo) sprintf(str, "FPS: %i/%i (%02d%%/%02d%%) | %s", mainLoopData.fps, mainLoopData.fps3d, Hud.cpuload[0], Hud.cpuload[1], paused ? "Paused":"Running"); TextOut(hMemDC, xo + 8, height + 14 * (twolinever ? 6:5), str, strlen(str)); - sprintf(str, "3D Render: %s", core3DList[cur3DCore]->name); + sprintf(str, "3D %s (%d BPP)", core3DList[cur3DCore]->name, gpu_bpp); TextOut(hMemDC, xo + 8, height + 14 * (twolinever ? 7:6), str, strlen(str)); } @@ -6371,6 +6401,7 @@ LRESULT CALLBACK GFX3DSettingsDlgProc(HWND hw, UINT msg, WPARAM wp, LPARAM lp) CheckDlgButton(hw, IDC_GPU_24BPP, gpu_bpp == 24); CheckDlgButton(hw, IDC_GPU_18BPP, gpu_bpp == 18); + CheckDlgButton(hw, IDC_GPU_15BPP, gpu_bpp == 15); CheckDlgButton(hw,IDC_TEX_DEPOSTERIZE, CommonSettings.GFX3D_Renderer_TextureDeposterize); CheckDlgButton(hw,IDC_TEX_SMOOTH, CommonSettings.GFX3D_Renderer_TextureSmoothing); @@ -6403,6 +6434,7 @@ LRESULT CALLBACK GFX3DSettingsDlgProc(HWND hw, UINT msg, WPARAM wp, LPARAM lp) if(IsDlgCheckboxChecked(hw,IDC_TEXSCALE_1)) CommonSettings.GFX3D_Renderer_TextureScalingFactor = 1; if(IsDlgCheckboxChecked(hw,IDC_TEXSCALE_2)) CommonSettings.GFX3D_Renderer_TextureScalingFactor = 2; if(IsDlgCheckboxChecked(hw,IDC_TEXSCALE_4)) CommonSettings.GFX3D_Renderer_TextureScalingFactor = 4; + if(IsDlgCheckboxChecked(hw, IDC_GPU_15BPP)) gpu_bpp = 15; if(IsDlgCheckboxChecked(hw,IDC_GPU_18BPP)) gpu_bpp = 18; if(IsDlgCheckboxChecked(hw, IDC_GPU_24BPP)) gpu_bpp = 24; CommonSettings.GFX3D_Renderer_TextureDeposterize = IsDlgCheckboxChecked(hw,IDC_TEX_DEPOSTERIZE); diff --git a/desmume/src/frontend/windows/main.h b/desmume/src/frontend/windows/main.h index 35fcd2b2d..c7cdec69d 100644 --- a/desmume/src/frontend/windows/main.h +++ b/desmume/src/frontend/windows/main.h @@ -61,6 +61,7 @@ extern void Change3DCoreWithFallbackAndSave(int newCore); extern int backupmemorytype; extern u32 backupmemorysize; +extern int gpu_bpp; void WIN_InstallCFlash(); void WIN_InstallGBACartridge(); diff --git a/desmume/src/frontend/windows/resource.h b/desmume/src/frontend/windows/resource.h index 5a97b0b69..46de3140a 100644 --- a/desmume/src/frontend/windows/resource.h +++ b/desmume/src/frontend/windows/resource.h @@ -473,9 +473,10 @@ #define IDC_LIST 1069 #define IDC_TEXSCALE_4 1070 #define IDC_SNUMBER 1071 -#define IDC_TEXSCALE_5 1071 #define IDC_GPU_24BPP 1071 #define IDC_GPU_18BPP 1072 +#define IDC_GPU_18BPP2 1073 +#define IDC_GPU_15BPP 1073 #define IDC_CHECK1 1074 #define IDC_CHECK2 1075 #define IDC_CAP0_SRC 1075 diff --git a/desmume/src/frontend/windows/resources.rc b/desmume/src/frontend/windows/resources.rc index fa094264b..31e146a5b 100644 --- a/desmume/src/frontend/windows/resources.rc +++ b/desmume/src/frontend/windows/resources.rc @@ -118,9 +118,9 @@ BEGIN COMBOBOX IDC_3DCORE,15,23,153,138,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "Unrealistically High-Precision Color Interpolation",IDC_INTERPOLATECOLOR, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,62,165,10 - CONTROL "Enable Edge Marking",IDC_3DSETTINGS_EDGEMARK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,196,109,84,10 - CONTROL "Enable Fog",IDC_3DSETTINGS_FOG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,196,122,52,10 - CONTROL "Enable Textures",IDC_3DSETTINGS_TEXTURE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,196,133,67,10 + CONTROL "Enable Edge Marking",IDC_3DSETTINGS_EDGEMARK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,196,119,84,10 + CONTROL "Enable Fog",IDC_3DSETTINGS_FOG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,196,130,52,10 + CONTROL "Enable Textures",IDC_3DSETTINGS_TEXTURE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,196,140,67,10 CONTROL "Enable Multisample Antialiasing",IDC_3DSETTINGS_ANTIALIASING, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,157,114,10 EDITTEXT IDC_TEXT_PRESCALEHD,262,16,20,14,ES_AUTOHSCROLL @@ -137,14 +137,15 @@ BEGIN GROUPBOX "OpenGL Renderer Options",IDC_STATIC,7,145,176,34 GROUPBOX "General Options",IDC_STATIC,189,6,118,175 LTEXT "GPU Scaling Factor",IDC_STATIC,195,19,64,8 - CONTROL "Texture Scaling 1x",IDC_TEXSCALE_1,"Button",BS_AUTORADIOBUTTON,195,71,77,10 - CONTROL "Texture Scaling 2x",IDC_TEXSCALE_2,"Button",BS_AUTORADIOBUTTON,195,81,79,10 - CONTROL "Texture Scaling 4x",IDC_TEXSCALE_4,"Button",BS_AUTORADIOBUTTON,195,92,72,10 - CONTROL "Deposterize Textures",IDC_TEX_DEPOSTERIZE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,196,60,79,10 + CONTROL "Texture Scaling 1x",IDC_TEXSCALE_1,"Button",BS_AUTORADIOBUTTON,195,81,77,10 + CONTROL "Texture Scaling 2x",IDC_TEXSCALE_2,"Button",BS_AUTORADIOBUTTON,195,91,79,10 + CONTROL "Texture Scaling 4x",IDC_TEXSCALE_4,"Button",BS_AUTORADIOBUTTON,195,102,72,10 + CONTROL "Deposterize Textures",IDC_TEX_DEPOSTERIZE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,196,70,79,10 CONTROL "Smooth Textures",IDC_TEX_SMOOTH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,167,75,10 LTEXT "You may need to toggle off && on by scene.",ID_LABEL_TXTHACK2,16,91,165,11 CONTROL "GPU Color Depth 24 bit",IDC_GPU_24BPP,"Button",BS_AUTORADIOBUTTON,195,33,98,10 CONTROL "GPU Color Depth 18 bit",IDC_GPU_18BPP,"Button",BS_AUTORADIOBUTTON,195,43,98,10 + CONTROL "GPU Color Depth 15 bit",IDC_GPU_15BPP,"Button",BS_AUTORADIOBUTTON,195,53,98,10 END IDD_ABOUT_BOX DIALOGEX 0, 0, 268, 198 diff --git a/desmume/src/utils/colorspacehandler/colorspacehandler.h b/desmume/src/utils/colorspacehandler/colorspacehandler.h index b73b3d021..d878fb6f6 100644 --- a/desmume/src/utils/colorspacehandler/colorspacehandler.h +++ b/desmume/src/utils/colorspacehandler/colorspacehandler.h @@ -73,6 +73,7 @@ enum NDSColorFormat //NDSColorFormat_ABGR8888_Rev = 0x20208208, // Color formats used by the output framebuffers. + // The 555 format is packed into u16; the 666 and 888 format is packed into u32 NDSColorFormat_BGR555_Rev = 0x20005145, NDSColorFormat_BGR666_Rev = 0x20006186, NDSColorFormat_BGR888_Rev = 0x20008208