mirror of https://github.com/snes9xgit/snes9x.git
win32: only load screenshots in preview dialogs
This commit is contained in:
parent
3c2ef2aa21
commit
04a15d9a2e
|
@ -71,88 +71,96 @@ bool CSaveLoadWithPreviewDlg::init_preview_bmps()
|
|||
|
||||
void CSaveLoadWithPreviewDlg::load_slot_image_text(int slot, HWND hDlg)
|
||||
{
|
||||
// load the snapshot to receive the saved screenshot
|
||||
FreezeUnfreezeSlot(slot, FALSE);
|
||||
uint16 *image_buffer;
|
||||
int width, height;
|
||||
|
||||
// create temporary bitmap storage for screenshot, 16bit RGB
|
||||
uint8_t* buffer = NULL;
|
||||
BITMAPINFO *bm = (BITMAPINFO *)calloc(sizeof(BITMAPINFOHEADER) + 3 * sizeof(RGBQUAD), 1);
|
||||
bm->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bm->bmiHeader.biWidth = IPPU.RenderedScreenWidth;
|
||||
bm->bmiHeader.biHeight = -IPPU.RenderedScreenHeight; // negative is top-down
|
||||
bm->bmiHeader.biPlanes = 1;
|
||||
bm->bmiHeader.biBitCount = 16;
|
||||
bm->bmiHeader.biCompression = BI_BITFIELDS;
|
||||
bm->bmiHeader.biSizeImage = IPPU.RenderedScreenWidth * IPPU.RenderedScreenHeight * 2;
|
||||
*(unsigned long *)&bm->bmiColors[0] = FIRST_COLOR_MASK_RGB565;
|
||||
*(unsigned long *)&bm->bmiColors[1] = SECOND_COLOR_MASK_RGB565;
|
||||
*(unsigned long *)&bm->bmiColors[2] = THIRD_COLOR_MASK_RGB565;
|
||||
HBITMAP imageBmp = CreateDIBSection(NULL, bm, DIB_RGB_COLORS, (void**)&buffer, 0, 0);
|
||||
if(imageBmp == NULL)
|
||||
// load the saved screenshot from a snapshot
|
||||
if(UnfreezeScreenshotSlot(slot, &image_buffer, width, height))
|
||||
{
|
||||
// create temporary bitmap storage for screenshot, 16bit RGB
|
||||
uint8_t* buffer = NULL;
|
||||
BITMAPINFO *bm = (BITMAPINFO *)calloc(sizeof(BITMAPINFOHEADER) + 3 * sizeof(RGBQUAD), 1);
|
||||
bm->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bm->bmiHeader.biWidth = width;
|
||||
bm->bmiHeader.biHeight = -height; // negative is top-down
|
||||
bm->bmiHeader.biPlanes = 1;
|
||||
bm->bmiHeader.biBitCount = 16;
|
||||
bm->bmiHeader.biCompression = BI_BITFIELDS;
|
||||
bm->bmiHeader.biSizeImage = width * height * 2;
|
||||
*(unsigned long *)&bm->bmiColors[0] = FIRST_COLOR_MASK_RGB565;
|
||||
*(unsigned long *)&bm->bmiColors[1] = SECOND_COLOR_MASK_RGB565;
|
||||
*(unsigned long *)&bm->bmiColors[2] = THIRD_COLOR_MASK_RGB565;
|
||||
HBITMAP imageBmp = CreateDIBSection(NULL, bm, DIB_RGB_COLORS, (void**)&buffer, 0, 0);
|
||||
if(imageBmp == NULL)
|
||||
{
|
||||
free(bm);
|
||||
return;
|
||||
}
|
||||
|
||||
int row_bytes = width * 2 / 4 * 4; // DIBs always have 4-byte aligned rows
|
||||
if(width * 2 % 4)
|
||||
row_bytes += 4;
|
||||
|
||||
// copy saved screenshot into temporary bitmap
|
||||
uint16 *screen = image_buffer;
|
||||
for(int h = 0; h < height; h++, screen += width)
|
||||
{
|
||||
uint16_t *row_start = (uint16_t*)(buffer + (h * row_bytes));
|
||||
for(int w = 0; w < width; w++)
|
||||
{
|
||||
row_start[w] = screen[w];
|
||||
}
|
||||
}
|
||||
|
||||
// strech temporary bitmap into HBIMAP for button
|
||||
HDC cdc = CreateCompatibleDC(GetDC(NULL));
|
||||
HGDIOBJ old = SelectObject(cdc, previewHbmps[slot]);
|
||||
int ret = StretchDIBits(cdc, 0, 0, PREVIEW_IMAGE_WIDTH, PREVIEW_IMAGE_HEIGHT, 0, 0, width, height, buffer, bm, DIB_RGB_COLORS, SRCCOPY);
|
||||
SelectObject(cdc, old);
|
||||
DeleteDC(cdc);
|
||||
|
||||
free(bm);
|
||||
return;
|
||||
}
|
||||
|
||||
int row_bytes = IPPU.RenderedScreenWidth * 2 / 4 * 4; // DIBs always have 4-byte aligned rows
|
||||
if(IPPU.RenderedScreenWidth * 2 % 4)
|
||||
row_bytes += 4;
|
||||
// set image to button
|
||||
SendMessage(GetDlgItem(hDlg, IDC_BUTTON_SLOT_1 + slot), BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)previewHbmps[slot]);
|
||||
|
||||
// copy saved screenshot into temporary bitmap
|
||||
uint16 *screen = GFX.Screen;
|
||||
for(int h = 0; h < IPPU.RenderedScreenHeight; h++, screen += GFX.RealPPL)
|
||||
{
|
||||
uint16_t *row_start = (uint16_t*)(buffer + (h * row_bytes));
|
||||
for(int w = 0; w < IPPU.RenderedScreenWidth; w++)
|
||||
char filename[_MAX_PATH + 1];
|
||||
GetSlotFilename(slot, filename);
|
||||
Utf8ToWide filenameW(filename);
|
||||
|
||||
// text with filename and last write time
|
||||
std::wstring static_text(PathFindFileName(filenameW));
|
||||
|
||||
// get file time details
|
||||
HANDLE file_handle = CreateFile(filenameW, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if(file_handle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
row_start[w] = screen[w];
|
||||
FILETIME ft;
|
||||
SYSTEMTIME stUTC, stLocal;
|
||||
// transform from file time to local time
|
||||
if(GetFileTime(file_handle, NULL, NULL, &ft) &&
|
||||
FileTimeToSystemTime(&ft, &stUTC) &&
|
||||
SystemTimeToTzSpecificLocalTime(NULL, &stUTC, &stLocal))
|
||||
{
|
||||
// reserve space for date and time (both received individually)
|
||||
std::vector<wchar_t> date_string;
|
||||
date_string.resize(max(
|
||||
GetDateFormatEx(LOCALE_NAME_USER_DEFAULT, DATE_AUTOLAYOUT | DATE_LONGDATE, &stLocal, NULL, NULL, 0, NULL),
|
||||
GetTimeFormatEx(LOCALE_NAME_USER_DEFAULT, 0, &stLocal, NULL, NULL, 0)
|
||||
));
|
||||
|
||||
GetDateFormatEx(LOCALE_NAME_USER_DEFAULT, DATE_AUTOLAYOUT | DATE_LONGDATE, &stLocal, NULL, &date_string[0], 100, NULL);
|
||||
static_text.append(L"\n").append(&date_string[0]);
|
||||
GetTimeFormatEx(LOCALE_NAME_USER_DEFAULT, 0, &stLocal, NULL, &date_string[0], 100);
|
||||
static_text.append(L" ").append(&date_string[0]);
|
||||
}
|
||||
}
|
||||
|
||||
// set the description text
|
||||
SetWindowText(GetDlgItem(hDlg, IDC_STATIC_SLOT_1 + slot), static_text.c_str());
|
||||
|
||||
free(image_buffer);
|
||||
}
|
||||
|
||||
// strech temporary bitmap into HBIMAP for button
|
||||
HDC cdc = CreateCompatibleDC(GetDC(NULL));
|
||||
HGDIOBJ old = SelectObject(cdc, previewHbmps[slot]);
|
||||
int ret = StretchDIBits(cdc, 0, 0, PREVIEW_IMAGE_WIDTH, PREVIEW_IMAGE_HEIGHT, 0, 0, IPPU.RenderedScreenWidth, IPPU.RenderedScreenHeight, buffer, bm, DIB_RGB_COLORS, SRCCOPY);
|
||||
SelectObject(cdc, old);
|
||||
DeleteDC(cdc);
|
||||
|
||||
free(bm);
|
||||
|
||||
// set image to button
|
||||
SendMessage(GetDlgItem(hDlg, IDC_BUTTON_SLOT_1 + slot), BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)previewHbmps[slot]);
|
||||
|
||||
// text with filename and last write time
|
||||
std::wstring static_text(PathFindFileName((wchar_t*)_tFromChar(Memory.ROMFilename)));
|
||||
|
||||
// get file time details
|
||||
char filename[_MAX_PATH + 1];
|
||||
GetSlotFilename(slot, filename);
|
||||
HANDLE file_handle = CreateFile(_tFromChar(filename), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if(file_handle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
FILETIME ft;
|
||||
SYSTEMTIME stUTC, stLocal;
|
||||
// transform from file time to local time
|
||||
if(GetFileTime(file_handle, NULL, NULL, &ft) &&
|
||||
FileTimeToSystemTime(&ft, &stUTC) &&
|
||||
SystemTimeToTzSpecificLocalTime(NULL, &stUTC, &stLocal))
|
||||
{
|
||||
// reserve space for date and time (both received individually)
|
||||
std::vector<wchar_t> date_string;
|
||||
date_string.resize(max(
|
||||
GetDateFormatEx(LOCALE_NAME_USER_DEFAULT, DATE_AUTOLAYOUT | DATE_LONGDATE, &stLocal, NULL, NULL, 0, NULL),
|
||||
GetTimeFormatEx(LOCALE_NAME_USER_DEFAULT, 0, &stLocal, NULL, NULL, 0)
|
||||
));
|
||||
|
||||
GetDateFormatEx(LOCALE_NAME_USER_DEFAULT, DATE_AUTOLAYOUT | DATE_LONGDATE, &stLocal, NULL, &date_string[0], 100, NULL);
|
||||
static_text.append(L"\n").append(&date_string[0]);
|
||||
GetTimeFormatEx(LOCALE_NAME_USER_DEFAULT, 0, &stLocal, NULL, &date_string[0], 100);
|
||||
static_text.append(L" ").append(&date_string[0]);
|
||||
}
|
||||
}
|
||||
|
||||
// set the description text
|
||||
SetWindowText(GetDlgItem(hDlg, IDC_STATIC_SLOT_1 + slot), static_text.c_str());
|
||||
}
|
||||
|
||||
void CSaveLoadWithPreviewDlg::init_window(HWND hDlg)
|
||||
|
@ -160,13 +168,6 @@ void CSaveLoadWithPreviewDlg::init_window(HWND hDlg)
|
|||
if(is_save_dialog)
|
||||
SetWindowText(hDlg, L"Save with preview");
|
||||
|
||||
// we need to load snapshots to receive the preview images, so we save the current state,
|
||||
// load the slots, then reload the backup
|
||||
std::string backup_filename = S9xGetFilename(".preview_backup", SNAPSHOT_DIR);
|
||||
|
||||
// create backup
|
||||
FreezeUnfreeze(backup_filename.c_str(), true);
|
||||
|
||||
int x_pos = 0;
|
||||
int y_pos = 0;
|
||||
for(int i = 0; i < NUM_DIALOG_SLOTS; i++)
|
||||
|
@ -222,10 +223,6 @@ void CSaveLoadWithPreviewDlg::init_window(HWND hDlg)
|
|||
int left = (mi.rcWork.right - mi.rcWork.left - dialog_width) / 2;
|
||||
int top = (mi.rcWork.bottom - mi.rcWork.top - dialog_height) / 2;
|
||||
SetWindowPos(hDlg, NULL, left, top, dialog_width, dialog_height, SWP_NOZORDER);
|
||||
|
||||
// load backup, remove temporary state
|
||||
FreezeUnfreeze(backup_filename.c_str(), false);
|
||||
remove(backup_filename.c_str());
|
||||
}
|
||||
|
||||
INT_PTR CALLBACK CSaveLoadWithPreviewDlg::DlgLoadWithPreview(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
|
|
|
@ -3703,6 +3703,14 @@ void FreezeUnfreeze (const char *filename, bool8 freeze)
|
|||
S9xClearPause (PAUSE_FREEZE_FILE);
|
||||
}
|
||||
|
||||
bool UnfreezeScreenshotSlot(int slot, uint16 **image_buffer, int &width, int &height)
|
||||
{
|
||||
char filename[_MAX_PATH + 1];
|
||||
GetSlotFilename(slot, filename);
|
||||
|
||||
return S9xUnfreezeScreenshot(filename, image_buffer, width, height);
|
||||
}
|
||||
|
||||
void CheckDirectoryIsWritable (const char *filename)
|
||||
{
|
||||
FILE *fs = fopen (filename, "w+");
|
||||
|
|
|
@ -463,5 +463,6 @@ void GetSlotFilename(int slot, char filename[_MAX_PATH + 1]);
|
|||
void FreezeUnfreezeSlot(int slot, bool8 freeze);
|
||||
void FreezeUnfreezeDialog(bool8 freeze);
|
||||
void FreezeUnfreeze(const char *filename, bool8 freeze);
|
||||
bool UnfreezeScreenshotSlot(int slot, uint16 **image_buffer, int &width, int &height);
|
||||
|
||||
#endif // !defined(SNES9X_H_INCLUDED)
|
||||
|
|
Loading…
Reference in New Issue