diff --git a/src/drivers/win/config.cpp b/src/drivers/win/config.cpp index b6b2ffc7..cae5dd58 100644 --- a/src/drivers/win/config.cpp +++ b/src/drivers/win/config.cpp @@ -75,6 +75,7 @@ extern bool TASEdit_bind_markers; extern bool TASEdit_branch_full_movie; extern bool TASEdit_branch_only_when_rec; extern bool TASEdit_view_branches_tree; +extern bool TASEdit_branch_scr_hud; extern bool TASEdit_restore_position; extern bool TASEdit_show_dot; extern int TASEdit_greenzone_capacity; @@ -304,6 +305,7 @@ static CFGSTRUCT fceuconfig[] = { AC(TASEdit_branch_full_movie), AC(TASEdit_branch_only_when_rec), AC(TASEdit_view_branches_tree), + AC(TASEdit_branch_scr_hud), AC(TASEdit_restore_position), AC(TASEdit_show_dot), AC(TASEdit_greenzone_capacity), diff --git a/src/drivers/win/res.rc b/src/drivers/win/res.rc index 5ecfc108..a129b2e8 100644 --- a/src/drivers/win/res.rc +++ b/src/drivers/win/res.rc @@ -260,10 +260,11 @@ BEGIN POPUP "&Config" BEGIN MENUITEM "Set &greenzone capacity", ID_CONFIG_SETGREENZONECAPACITY - MENUITEM "Set max undo levels", ID_CONFIG_SETMAXUNDOLEVELS + MENUITEM "Set max &undo levels", ID_CONFIG_SETMAXUNDOLEVELS MENUITEM SEPARATOR - MENUITEM "Branches restore entire Movie", ID_CONFIG_BRANCHESRESTOREFULLMOVIE - MENUITEM "Branches work only when Recording", ID_CONFIG_BRANCHESWORKONLYWHENRECORDING + MENUITEM "Branches restore entire &Movie", ID_CONFIG_BRANCHESRESTOREFULLMOVIE + MENUITEM "Branches work only when &Recording", ID_CONFIG_BRANCHESWORKONLYWHENRECORDING + MENUITEM "&HUD in Branch screenshots", ID_CONFIG_HUDINBRANCHSCREENSHOTS MENUITEM SEPARATOR MENUITEM "&Bind Markers to Input", ID_CONFIG_BINDMARKERSTOINPUT MENUITEM SEPARATOR diff --git a/src/drivers/win/resource.h b/src/drivers/win/resource.h index 5a4b58b2..a8f55b93 100644 --- a/src/drivers/win/resource.h +++ b/src/drivers/win/resource.h @@ -179,7 +179,7 @@ #define IDB_BITMAP17 180 #define IDB_BITMAP18 181 #define IDB_BITMAP19 182 -#define IDB_BRANCH_SPRITESHEET 184 +#define IDB_BRANCH_SPRITESHEET 184 #define MENU_RESET 200 #define BUTTON_ROMS 200 #define TXT_PAD1 200 @@ -529,6 +529,7 @@ #define CHECK_FOLLOW_CURSOR 1263 #define IDC_BOOKMARKS_BOX 1264 #define IDC_BRANCHES_BITMAP 1265 +#define IDC_SCREENSHOT_BITMAP 1266 #define MENU_NETWORK 40040 #define MENU_PALETTE 40041 #define MENU_SOUND 40042 @@ -890,6 +891,7 @@ #define ID_VIEW_JUMPWHENMAKINGUNDO 40472 #define ID_CONFIG_BRANCHESRESTOREFULLMOVIE 40473 #define ID_CONFIG_BRANCHESWORKONLYWHENRECORDING 40474 +#define ID_CONFIG_HUDINBRANCHSCREENSHOTS 40475 #define IDC_DEBUGGER_ICONTRAY 55535 #define MW_ValueLabel2 65423 #define MW_ValueLabel1 65426 @@ -899,8 +901,8 @@ #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 185 -#define _APS_NEXT_COMMAND_VALUE 40475 -#define _APS_NEXT_CONTROL_VALUE 1266 +#define _APS_NEXT_COMMAND_VALUE 40476 +#define _APS_NEXT_CONTROL_VALUE 1267 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/src/drivers/win/tasedit.cpp b/src/drivers/win/tasedit.cpp index eae9cd0f..3b1e9d4d 100644 --- a/src/drivers/win/tasedit.cpp +++ b/src/drivers/win/tasedit.cpp @@ -25,7 +25,8 @@ int old_multitrack_recording_joypad, multitrack_recording_joypad; bool old_movie_readonly; bool TASEdit_focus = false; bool Tasedit_rewind_now = false; -int listItems; // number of items per list page +int listItems; // number of items per list page +int list_row_height; // in pixels // saved FCEU config int saved_eoptions; int saved_EnableAutosave; @@ -40,6 +41,7 @@ bool TASEdit_bind_markers = true; bool TASEdit_branch_full_movie = true; bool TASEdit_branch_only_when_rec = false; bool TASEdit_view_branches_tree = false; +bool TASEdit_branch_scr_hud = true; bool TASEdit_restore_position = false; int TASEdit_greenzone_capacity = GREENZONE_CAPACITY_DEFAULT; extern bool muteTurbo; @@ -302,6 +304,8 @@ void UpdateTasEdit() void UpdateList() { + // first update number of items in markers array + markers.update(); //update the number of items in the list int currLVItemCount = ListView_GetItemCount(hwndList); int movie_size = currMovieData.getNumRecords(); @@ -322,8 +326,6 @@ void UpdateList() } } } - // also update number of items in markers array - markers.update(); } void RedrawWindowCaption() @@ -982,6 +984,23 @@ LRESULT APIENTRY BookmarksListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM case WM_SETFOCUS: case WM_KILLFOCUS: return 0; + case WM_MOUSEMOVE: + { + if (!bookmarks.mouse_over_bitmap) + { + bookmarks.mouse_over_bookmarkslist = true; + bookmarks.list_tme.hwndTrack = hWnd; + TrackMouseEvent(&bookmarks.list_tme); + } + bookmarks.MouseMove(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); + break; + } + case WM_MOUSELEAVE: + { + bookmarks.mouse_over_bookmarkslist = false; + bookmarks.MouseMove(-1, -1); + break; + } case WM_SYSKEYDOWN: { if (wParam == VK_F10) @@ -1050,7 +1069,6 @@ LRESULT APIENTRY BranchesBitmapWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARA return CallWindowProc(hwndBranchesBitmap_oldWndProc, hWnd, msg, wParam, lParam); } - void AddFourscore() { // add list columns @@ -1346,7 +1364,7 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar case WM_INITDIALOG: if (TasEdit_wndx==-32000) TasEdit_wndx=0; //Just in case if (TasEdit_wndy==-32000) TasEdit_wndy=0; - SetWindowPos(hwndDlg,0,TasEdit_wndx,TasEdit_wndy,0,0,SWP_NOSIZE|SWP_NOZORDER|SWP_NOOWNERZORDER); + SetWindowPos(hwndDlg, 0, TasEdit_wndx, TasEdit_wndy, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER); // save references to dialog items hwndList = GetDlgItem(hwndDlg, IDC_LIST1); listItems = ListView_GetCountPerPage(hwndList); @@ -1366,6 +1384,7 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar hwndRB_Rec3P = GetDlgItem(hwndDlg, IDC_RADIO5); hwndRB_Rec4P = GetDlgItem(hwndDlg, IDC_RADIO6); hwndBranchesBitmap = GetDlgItem(hwndDlg, IDC_BRANCHES_BITMAP); + break; case WM_MOVE: @@ -1376,8 +1395,11 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar GetWindowRect(hwndDlg,&wrect); TasEdit_wndx = wrect.left; TasEdit_wndy = wrect.top; - WindowBoundsCheckNoResize(TasEdit_wndx,TasEdit_wndy,wrect.right); + // also move screenshot bitmap if it's open + extern HWND hwndScrBmp; + if (hwndScrBmp) + SetWindowPos(hwndScrBmp, 0, TasEdit_wndx + bookmarks.scr_bmp_x, TasEdit_wndy + bookmarks.scr_bmp_y, 0, 0,SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE); } break; } @@ -1672,6 +1694,11 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar CheckMenuItem(hmenu, ID_CONFIG_BRANCHESWORKONLYWHENRECORDING, TASEdit_branch_only_when_rec?MF_CHECKED : MF_UNCHECKED); bookmarks.RedrawBookmarksCaption(); break; + case ID_CONFIG_HUDINBRANCHSCREENSHOTS: + //switch "HUD in Branch screenshots" flag + TASEdit_branch_scr_hud ^= 1; + CheckMenuItem(hmenu, ID_CONFIG_HUDINBRANCHSCREENSHOTS, TASEdit_branch_scr_hud?MF_CHECKED : MF_UNCHECKED); + break; case IDC_PROGRESS_BUTTON: // click on progressbar - stop seeking if (playback.pauseframe) playback.SeekingStop(); @@ -1888,6 +1915,7 @@ void EnterTasEdit() CheckMenuItem(hmenu, ID_CONFIG_BINDMARKERSTOINPUT, TASEdit_bind_markers?MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hmenu, ID_CONFIG_BRANCHESRESTOREFULLMOVIE, TASEdit_branch_full_movie?MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hmenu, ID_CONFIG_BRANCHESWORKONLYWHENRECORDING, TASEdit_branch_only_when_rec?MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hmenu, ID_CONFIG_HUDINBRANCHSCREENSHOTS, TASEdit_branch_scr_hud?MF_CHECKED : MF_UNCHECKED); CheckDlgButton(hwndTasEdit,CHECK_AUTORESTORE_PLAYBACK,TASEdit_restore_position?BST_CHECKED:BST_UNCHECKED); CheckMenuItem(hmenu, ID_CONFIG_MUTETURBO, muteTurbo?MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hmenu, ID_VIEW_SHOWDOTINEMPTYCELLS, TASEdit_show_dot?MF_CHECKED : MF_UNCHECKED); @@ -2024,6 +2052,12 @@ void EnterTasEdit() // add pads 3 and 4 and frame_number2 if (currMovieData.fourscore) AddFourscore(); UpdateList(); + // calculate scr_bmp coordinates (relative to the listview top-left corner + RECT temp_rect, parent_rect; + GetWindowRect(hwndTasEdit, &parent_rect); + GetWindowRect(hwndHeader, &temp_rect); + bookmarks.scr_bmp_x = temp_rect.left - parent_rect.left; + bookmarks.scr_bmp_y = temp_rect.bottom - parent_rect.top; // prepare bookmarks listview ListView_SetExtendedListViewStyleEx(hwndBookmarksList, LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES, LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES); diff --git a/src/drivers/win/taseditlib/bookmark.cpp b/src/drivers/win/taseditlib/bookmark.cpp index b9830d28..d32b8037 100644 --- a/src/drivers/win/taseditlib/bookmark.cpp +++ b/src/drivers/win/taseditlib/bookmark.cpp @@ -8,6 +8,10 @@ extern GREENZONE greenzone; +extern bool TASEdit_branch_scr_hud; +extern uint8 *XBuf; +extern uint8 *XBackBuf; + BOOKMARK::BOOKMARK() { @@ -27,6 +31,16 @@ void BOOKMARK::set() snapshot.jump_frame = currFrameCounter; savestate = greenzone.savestates[currFrameCounter]; // save screenshot + std::vector temp_screenshot(SCREENSHOT_SIZE); + if (TASEdit_branch_scr_hud) + memcpy(&temp_screenshot[0], &XBuf[0], SCREENSHOT_SIZE); + else + memcpy(&temp_screenshot[0], &XBackBuf[0], SCREENSHOT_SIZE); + // compress the screenshot + uLongf comprlen = (SCREENSHOT_SIZE>>9)+12 + SCREENSHOT_SIZE; + saved_screenshot.resize(comprlen); + compress(&saved_screenshot[0], &comprlen, &temp_screenshot[0], SCREENSHOT_SIZE); + saved_screenshot.resize(comprlen); not_empty = true; flash_phase = FLASH_PHASE_MAX; @@ -59,7 +73,9 @@ void BOOKMARK::save(EMUFILE *os) write32le(size, os); os->fwrite(&savestate[0], size); // write saved_screenshot - + size = saved_screenshot.size(); + write32le(size, os); + os->fwrite(&saved_screenshot[0], size); } else write8le((uint8)0, os); } // returns true if couldn't load @@ -72,7 +88,7 @@ bool BOOKMARK::load(EMUFILE *is) { // read parent_branch if (!read8le(&tmp, is)) return true; - parent_branch = *(int8*)(&tmp); // don't kill me for that + parent_branch = *(int8*)(&tmp); // read snapshot if (snapshot.load(is)) return true; // read savestate @@ -81,7 +97,9 @@ bool BOOKMARK::load(EMUFILE *is) savestate.resize(size); if ((int)is->fread(&savestate[0], size) < size) return true; // read saved_screenshot - + if (!read32le((uint32 *)&size, is)) return true; + saved_screenshot.resize(size); + if ((int)is->fread(&saved_screenshot[0], size) < size) return true; } // all ok flash_type = flash_phase = 0; diff --git a/src/drivers/win/taseditlib/bookmark.h b/src/drivers/win/taseditlib/bookmark.h index 6ff1ce8f..fc4fa7e6 100644 --- a/src/drivers/win/taseditlib/bookmark.h +++ b/src/drivers/win/taseditlib/bookmark.h @@ -5,6 +5,10 @@ #define FLASH_TYPE_JUMP 1 #define FLASH_TYPE_UNLEASH 2 +#define SCREENSHOT_WIDTH 256 +#define SCREENSHOT_HEIGHT 240 +#define SCREENSHOT_SIZE SCREENSHOT_WIDTH * SCREENSHOT_HEIGHT + class BOOKMARK { public: diff --git a/src/drivers/win/taseditlib/bookmarks.cpp b/src/drivers/win/taseditlib/bookmarks.cpp index 907b4683..03dc7c1b 100644 --- a/src/drivers/win/taseditlib/bookmarks.cpp +++ b/src/drivers/win/taseditlib/bookmarks.cpp @@ -9,6 +9,14 @@ #pragma comment(lib, "msimg32.lib") +LRESULT CALLBACK ScrBmpWndProc(HWND, UINT, WPARAM, LPARAM); +char szClassName[] = "BmpTestApp"; +HWND hwndScrBmp, scr_bmp_pic; +WNDCLASSEX wincl; +BLENDFUNCTION blend; +extern HWND hwndTasEdit; +extern int TasEdit_wndx, TasEdit_wndy; + char bookmarks_save_id[BOOKMARKS_ID_LEN] = "BOOKMARKS"; char bookmarksCaption[3][23] = { " Bookmarks ", " Bookmarks / Branches ", " Branches " }; @@ -39,6 +47,8 @@ extern bool TASEdit_branch_full_movie; extern bool TASEdit_branch_only_when_rec; extern bool TASEdit_view_branches_tree; +extern int list_row_height; + BOOKMARKS::BOOKMARKS() { // create font @@ -53,6 +63,42 @@ BOOKMARKS::BOOKMARKS() tme.cbSize = sizeof(tme); tme.dwFlags = TME_LEAVE; tme.hwndTrack = hwndBranchesBitmap; + list_tme.cbSize = sizeof(tme); + list_tme.dwFlags = TME_LEAVE; + list_tme.hwndTrack = hwndBookmarksList; + + // create BITMAPINFO for scr_bmp + scr_bmi = (LPBITMAPINFO)malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)); + scr_bmi->bmiHeader.biSize = sizeof(scr_bmi->bmiHeader); + scr_bmi->bmiHeader.biWidth = SCREENSHOT_WIDTH; + scr_bmi->bmiHeader.biHeight = -SCREENSHOT_HEIGHT; // negative value = top-down bmp + scr_bmi->bmiHeader.biPlanes = 1; + scr_bmi->bmiHeader.biBitCount = 8; + scr_bmi->bmiHeader.biCompression = BI_RGB; + scr_bmi->bmiHeader.biSizeImage = 0; + + // register ScrBmp window class + wincl.hInstance = fceu_hInstance; + wincl.lpszClassName = szClassName; + wincl.lpfnWndProc = ScrBmpWndProc; + wincl.style = CS_DBLCLKS; + wincl.cbSize = sizeof(WNDCLASSEX); + wincl.hIcon = 0; + wincl.hIconSm = 0; + wincl.hCursor = 0; + wincl.lpszMenuName = 0; + wincl.cbClsExtra = 0; + wincl.cbWndExtra = 0; + wincl.hbrBackground = 0; + if(!RegisterClassEx(&wincl)) + FCEU_printf("Error registering ScrBmp window class\n"); + // create blendfunction + blend.BlendOp = AC_SRC_OVER; + blend.BlendFlags = 0; + blend.AlphaFormat = 0; + blend.SourceConstantAlpha = 255; + + } void BOOKMARKS::init() @@ -87,6 +133,19 @@ void BOOKMARKS::init() bookmarks_array[i].init(); ListView_SetItemCountEx(hwndBookmarksList, TOTAL_BOOKMARKS, LVSICF_NOSCROLL | LVSICF_NOINVALIDATEALL); + // find rows top/height (for mouseover hittest calculations) + RECT temp_rect; + if (ListView_GetSubItemRect(hwndBookmarksList, 0, 2, LVIR_BOUNDS, &temp_rect)) + { + branch_row_top = temp_rect.top; + branch_row_left = temp_rect.left; + branch_row_height = temp_rect.bottom - temp_rect.top; + } else + { + // couldn't get rect, set default values + branch_row_top = 0; + branch_row_height = 14; + } // init GDI stuff HDC win_hdc = GetWindowDC(hwndBookmarksList); hBitmapDC = CreateCompatibleDC(win_hdc); @@ -103,6 +162,16 @@ void BOOKMARKS::init() // create pens normal_pen = CreatePen(PS_SOLID, 1, 0x0); select_pen = CreatePen(PS_SOLID, 2, 0xFF9080); + // prepare screenshot bitmap + // fill scr_bmp palette with current palette colors + extern PALETTEENTRY *color_palette; + for (int i = 0; i < 256; ++i) + { + scr_bmi->bmiColors[i].rgbRed = color_palette[i].peRed; + scr_bmi->bmiColors[i].rgbGreen = color_palette[i].peGreen; + scr_bmi->bmiColors[i].rgbBlue = color_palette[i].peBlue; + } + scr_bmp = CreateDIBSection(win_hdc, scr_bmi, DIB_RGB_COLORS, (void**)&scr_ptr, 0, 0); RedrawBookmarksCaption(); update(); @@ -111,9 +180,10 @@ void BOOKMARKS::reset() { transition_phase = animation_frame = 0; mouse_x = mouse_y = -1; - item_under_mouse = ITEM_UNDER_MOUSE_NONE; + screenshot_currently_shown = item_under_mouse = ITEM_UNDER_MOUSE_NONE; + scr_bmp_phase = 0; mouse_over_bitmap = false; - must_recalculate_branches_tree = must_redraw_branches_tree = true; + must_recalculate_branches_tree = must_redraw_branches_tree = must_check_item_under_mouse = true; check_flash_shedule = clock() + BOOKMARKS_FLASH_TICK; next_animation_time = clock() + BRANCHES_ANIMATION_TICK; } @@ -162,11 +232,18 @@ void BOOKMARKS::free() DeleteObject(branchesSpritesheet); branchesSpritesheet = NULL; } + if (scr_bmp) + { + DeleteObject(scr_bmp); + scr_bmp = NULL; + } + + } void BOOKMARKS::update() { - // once per 50 milliseconds fade bookmark flashes + // once per 100 milliseconds fade bookmark flashes if (clock() > check_flash_shedule) { check_flash_shedule = clock() + BOOKMARKS_FLASH_TICK; @@ -176,7 +253,7 @@ void BOOKMARKS::update() { bookmarks_array[i].flash_phase--; RedrawBookmarksRow((i + TOTAL_BOOKMARKS - 1) % TOTAL_BOOKMARKS); - must_redraw_branches_tree = true; + must_redraw_branches_tree = true; // because borders of some branch digit has changed } } } @@ -184,14 +261,15 @@ void BOOKMARKS::update() if (must_recalculate_branches_tree) RecalculateBranchesTree(); - if (edit_mode == EDIT_MODE_BRANCHES) + // once per 50 milliseconds update branches_bitmap and scr_bmp + if (clock() > next_animation_time) { - if (clock() > next_animation_time) + // animate branches_bitmap + next_animation_time = clock() + BRANCHES_ANIMATION_TICK; + animation_frame = (animation_frame + 1) % BRANCHES_ANIMATION_FRAMES; + if (edit_mode == EDIT_MODE_BRANCHES) { - // animate - next_animation_time = clock() + BRANCHES_ANIMATION_TICK; - animation_frame = (animation_frame + 1) % BRANCHES_ANIMATION_FRAMES; - // grow or shring fireball + // grow or shrink fireball size if (changes_since_current_branch) { fireball_size++; @@ -205,15 +283,65 @@ void BOOKMARKS::update() if (transition_phase) { transition_phase--; - must_redraw_branches_tree = true; + must_check_item_under_mouse = must_redraw_branches_tree = true; } else if (!must_redraw_branches_tree) { + // just update sprites InvalidateRect(hwndBranchesBitmap, 0, FALSE); } } - // render + // controls + if (must_check_item_under_mouse) + CheckMousePos(); + // render branches_bitmap if (must_redraw_branches_tree) RedrawBranchesTree(); + + // change screenshot_bitmap alpha if needed + if (item_under_mouse >= 0 && item_under_mouse < TOTAL_BOOKMARKS) + { + if (!hwndScrBmp) + { + // create window + hwndScrBmp = CreateWindowEx(WS_EX_LAYERED | WS_EX_TRANSPARENT, szClassName, szClassName, WS_POPUP, TasEdit_wndx + scr_bmp_x, TasEdit_wndy + scr_bmp_y, SCREENSHOT_WIDTH, SCREENSHOT_HEIGHT, hwndTasEdit, NULL, fceu_hInstance, NULL); + RedrawScreenshotBitmap(); + ShowWindow(hwndScrBmp, SW_SHOWNA); + } + // change screenshot_bitmap pic if needed + if (item_under_mouse != screenshot_currently_shown) + { + if (bookmarks_array[item_under_mouse].not_empty) + ChangeScreenshotBitmap(); + } + if (scr_bmp_phase < SCR_BMP_PHASE_MAX) + { + scr_bmp_phase++; + // update alpha + SetLayeredWindowAttributes(hwndScrBmp, 0, (255 * scr_bmp_phase) / SCR_BMP_PHASE_MAX, LWA_ALPHA); + UpdateLayeredWindow(hwndScrBmp, 0, 0, 0, 0, 0, 0, &blend, ULW_ALPHA); + } + } else + { + if (scr_bmp_phase > 0) + { + scr_bmp_phase--; + if (hwndScrBmp) + { + // update alpha + SetLayeredWindowAttributes(hwndScrBmp, 0, (255 * scr_bmp_phase) / SCR_BMP_PHASE_MAX, LWA_ALPHA); + UpdateLayeredWindow(hwndScrBmp, 0, 0, 0, 0, 0, 0, &blend, ULW_ALPHA); + } + } else + { + // destroy screenshot bitmap window + scr_bmp_phase = 0; + if (hwndScrBmp) + { + DestroyWindow(hwndScrBmp); + hwndScrBmp = 0; + } + } + } } } @@ -230,6 +358,10 @@ void BOOKMARKS::set(int slot) bookmarks_array[slot].set(); + // if this screenshot is shown on screen - reinit and redraw it + if (screenshot_currently_shown == slot) + screenshot_currently_shown = ITEM_UNDER_MOUSE_NONE; + // inherit current branch if (slot != current_branch) { @@ -430,7 +562,7 @@ bool BOOKMARKS::load(EMUFILE *is) // read current branch and flag of changes since it uint8 tmp; if (!read8le(&tmp, is)) return true; - current_branch = tmp; + current_branch = *(int8*)(&tmp); if (!read8le(&tmp, is)) return true; changes_since_current_branch = (tmp != 0); // read current_position time @@ -448,6 +580,7 @@ bool BOOKMARKS::load(EMUFILE *is) // ---------------------------------------------------------- void BOOKMARKS::RedrawBookmarksCaption() { + int prev_edit_mode = edit_mode; if (TASEdit_branch_only_when_rec && movie_readonly) { edit_mode = EDIT_MODE_BOOKMARKS; @@ -466,6 +599,8 @@ void BOOKMARKS::RedrawBookmarksCaption() ShowWindow(hwndBookmarksList, SW_SHOW); RedrawBookmarksList(); } + if (prev_edit_mode != edit_mode) + must_check_item_under_mouse = true; SetWindowText(hwndBookmarks, bookmarksCaption[edit_mode]); } void BOOKMARKS::RedrawBookmarksList() @@ -488,23 +623,6 @@ void BOOKMARKS::RedrawBookmarksRow(int index) void BOOKMARKS::RedrawBranchesTree() { - // first calculate current positions of branch items - for (int i = 0; i <= TOTAL_BOOKMARKS; ++i) - { - BranchCurrX[i] = (BranchX[i] * (BRANCHES_TRANSITION_MAX - transition_phase) + BranchPrevX[i] * transition_phase) / BRANCHES_TRANSITION_MAX; - BranchCurrY[i] = (BranchY[i] * (BRANCHES_TRANSITION_MAX - transition_phase) + BranchPrevY[i] * transition_phase) / BRANCHES_TRANSITION_MAX; - } - int cloud_x = (CloudX * (BRANCHES_TRANSITION_MAX - transition_phase) + CloudPrevX * transition_phase) / BRANCHES_TRANSITION_MAX; - // find item under mouse - item_under_mouse = ITEM_UNDER_MOUSE_NONE; - for (int i = 0; i < TOTAL_BOOKMARKS; ++i) - if (item_under_mouse == ITEM_UNDER_MOUSE_NONE && mouse_x >= BranchCurrX[i] - DIGIT_RECT_HALFWIDTH && mouse_x < BranchCurrX[i] - DIGIT_RECT_HALFWIDTH + DIGIT_RECT_WIDTH && mouse_y >= BranchCurrY[i] - DIGIT_RECT_HALFHEIGHT && mouse_y < BranchCurrY[i] - DIGIT_RECT_HALFHEIGHT + DIGIT_RECT_HEIGHT) - item_under_mouse = i; - if (item_under_mouse == ITEM_UNDER_MOUSE_NONE && mouse_x >= cloud_x - BRANCHES_CLOUD_HALFWIDTH && mouse_x < cloud_x - BRANCHES_CLOUD_HALFWIDTH + BRANCHES_CLOUD_WIDTH && mouse_y >= BRANCHES_CLOUD_Y - BRANCHES_CLOUD_HALFHEIGHT && mouse_y < BRANCHES_CLOUD_Y - BRANCHES_CLOUD_HALFHEIGHT + BRANCHES_CLOUD_HEIGHT) - item_under_mouse = ITEM_UNDER_MOUSE_CLOUD; - if (item_under_mouse == ITEM_UNDER_MOUSE_NONE && changes_since_current_branch && mouse_x >= BranchCurrX[TOTAL_BOOKMARKS] - DIGIT_RECT_HALFWIDTH && mouse_x < BranchCurrX[TOTAL_BOOKMARKS] - DIGIT_RECT_HALFWIDTH + DIGIT_RECT_WIDTH && mouse_y >= BranchCurrY[TOTAL_BOOKMARKS] - DIGIT_RECT_HALFHEIGHT && mouse_y < BranchCurrY[TOTAL_BOOKMARKS] - DIGIT_RECT_HALFHEIGHT + DIGIT_RECT_HEIGHT) - item_under_mouse = TOTAL_BOOKMARKS; - // draw background gradient TRIVERTEX vertex[2] ; vertex[0].x = 0; @@ -523,6 +641,7 @@ void BOOKMARKS::RedrawBranchesTree() gRect.UpperLeft = 0; gRect.LowerRight = 1; GradientFill(hBitmapDC, vertex, 2, &gRect, 1, GRADIENT_FILL_RECT_H); + // lines int branch_x, branch_y, parent_x, parent_y, child_id; SelectObject(hBitmapDC, normal_pen); @@ -643,6 +762,29 @@ void BOOKMARKS::RedrawBranchesTree() must_redraw_branches_tree = false; InvalidateRect(hwndBranchesBitmap, 0, FALSE); } + +void BOOKMARKS::ChangeScreenshotBitmap() +{ + // uncompress + uLongf destlen = SCREENSHOT_SIZE; + int e = uncompress(&scr_ptr[0], &destlen, &bookmarks_array[item_under_mouse].saved_screenshot[0], bookmarks_array[item_under_mouse].saved_screenshot.size()); + if (e != Z_OK && e != Z_BUF_ERROR) + { + // error decompressing + FCEU_printf("Error decompressing screenshot %d\n", item_under_mouse); + // at least fill bitmap with zeros + memset(&scr_ptr[0], 0, SCREENSHOT_SIZE); + } + screenshot_currently_shown = item_under_mouse; + RedrawScreenshotBitmap(); +} +void BOOKMARKS::RedrawScreenshotBitmap() +{ + HBITMAP temp_bmp = (HBITMAP)SendMessage(scr_bmp_pic, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)scr_bmp); + if (temp_bmp && temp_bmp != scr_bmp) + DeleteObject(temp_bmp); +} + // this is called by wndproc on WM_PAINT void BOOKMARKS::PaintBranchesBitmap(HDC hdc) { @@ -692,7 +834,47 @@ void BOOKMARKS::MouseMove(int new_x, int new_y) { mouse_x = new_x; mouse_y = new_y; - must_redraw_branches_tree = true; + must_check_item_under_mouse = true; +} +void BOOKMARKS::CheckMousePos() +{ + int prev_item_under_mouse = item_under_mouse; + if (edit_mode == EDIT_MODE_BRANCHES) + { + // Mouse over Branches bitmap + // first calculate current positions of branch items + for (int i = 0; i <= TOTAL_BOOKMARKS; ++i) + { + BranchCurrX[i] = (BranchX[i] * (BRANCHES_TRANSITION_MAX - transition_phase) + BranchPrevX[i] * transition_phase) / BRANCHES_TRANSITION_MAX; + BranchCurrY[i] = (BranchY[i] * (BRANCHES_TRANSITION_MAX - transition_phase) + BranchPrevY[i] * transition_phase) / BRANCHES_TRANSITION_MAX; + } + cloud_x = (CloudX * (BRANCHES_TRANSITION_MAX - transition_phase) + CloudPrevX * transition_phase) / BRANCHES_TRANSITION_MAX; + // find item under mouse + item_under_mouse = ITEM_UNDER_MOUSE_NONE; + for (int i = 0; i < TOTAL_BOOKMARKS; ++i) + if (item_under_mouse == ITEM_UNDER_MOUSE_NONE && mouse_x >= BranchCurrX[i] - DIGIT_RECT_HALFWIDTH && mouse_x < BranchCurrX[i] - DIGIT_RECT_HALFWIDTH + DIGIT_RECT_WIDTH && mouse_y >= BranchCurrY[i] - DIGIT_RECT_HALFHEIGHT && mouse_y < BranchCurrY[i] - DIGIT_RECT_HALFHEIGHT + DIGIT_RECT_HEIGHT) + item_under_mouse = i; + if (item_under_mouse == ITEM_UNDER_MOUSE_NONE && mouse_x >= cloud_x - BRANCHES_CLOUD_HALFWIDTH && mouse_x < cloud_x - BRANCHES_CLOUD_HALFWIDTH + BRANCHES_CLOUD_WIDTH && mouse_y >= BRANCHES_CLOUD_Y - BRANCHES_CLOUD_HALFHEIGHT && mouse_y < BRANCHES_CLOUD_Y - BRANCHES_CLOUD_HALFHEIGHT + BRANCHES_CLOUD_HEIGHT) + item_under_mouse = ITEM_UNDER_MOUSE_CLOUD; + if (item_under_mouse == ITEM_UNDER_MOUSE_NONE && changes_since_current_branch && mouse_x >= BranchCurrX[TOTAL_BOOKMARKS] - DIGIT_RECT_HALFWIDTH && mouse_x < BranchCurrX[TOTAL_BOOKMARKS] - DIGIT_RECT_HALFWIDTH + DIGIT_RECT_WIDTH && mouse_y >= BranchCurrY[TOTAL_BOOKMARKS] - DIGIT_RECT_HALFHEIGHT && mouse_y < BranchCurrY[TOTAL_BOOKMARKS] - DIGIT_RECT_HALFHEIGHT + DIGIT_RECT_HEIGHT) + item_under_mouse = TOTAL_BOOKMARKS; + if (prev_item_under_mouse != item_under_mouse) + must_redraw_branches_tree = true; + } else if (edit_mode == EDIT_MODE_BOTH) + { + // Mouse over Bookmarks list + if (mouse_x > branch_row_left) + { + item_under_mouse = (mouse_y - branch_row_top) / branch_row_height; + if (item_under_mouse >= 0 && item_under_mouse < TOTAL_BOOKMARKS) + { + item_under_mouse = (item_under_mouse + 1) % TOTAL_BOOKMARKS; + if (!bookmarks_array[item_under_mouse].not_empty) + item_under_mouse = ITEM_UNDER_MOUSE_NONE; + } + } else item_under_mouse = ITEM_UNDER_MOUSE_NONE; + } else item_under_mouse = ITEM_UNDER_MOUSE_NONE; + must_check_item_under_mouse = false; } // ---------------------------------------------------------------------------------------- void BOOKMARKS::GetDispInfo(NMLVDISPINFO* nmlvDispInfo) @@ -1112,4 +1294,24 @@ void BOOKMARKS::RecursiveSetYPos(int parent, int parentY) } } } +// ---------------------------------------------------------------------------------------- +LRESULT CALLBACK ScrBmpWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch(message) + { + HWND logo; + case WM_CREATE: + { + scr_bmp_pic = CreateWindow(WC_STATIC, NULL, SS_BITMAP | WS_CHILD | WS_VISIBLE, 0, 0, 255, 255, hwnd, NULL, NULL, NULL); + break; + } + case WM_DESTROY: + PostQuitMessage(0); + break; + default: + return DefWindowProc(hwnd, message, wParam, lParam); + } + return 0; +} + diff --git a/src/drivers/win/taseditlib/bookmarks.h b/src/drivers/win/taseditlib/bookmarks.h index 7a1d1ec9..215ffda0 100644 --- a/src/drivers/win/taseditlib/bookmarks.h +++ b/src/drivers/win/taseditlib/bookmarks.h @@ -81,6 +81,10 @@ #define BOOKMARKS_ID_LEN 10 #define TIME_DESC_LENGTH 9 // "HH:MM:SS" +// screenshot bitmap +#define SCR_BMP_PHASE_MAX 10 + + class BOOKMARKS { public: @@ -113,6 +117,7 @@ public: void PaintBranchesBitmap(HDC hdc); void MouseMove(int new_x, int new_y); + void CheckMousePos(); void ChangesMadeSinceBranch(); @@ -120,11 +125,25 @@ public: void RecursiveAddHeight(int branch_num, int amount); void RecursiveSetYPos(int parent, int parentY); + void ChangeScreenshotBitmap(); + void RedrawScreenshotBitmap(); + std::vector bookmarks_array; // not saved vars - bool mouse_over_bitmap; - TRACKMOUSEEVENT tme; + bool mouse_over_bitmap, mouse_over_bookmarkslist; + TRACKMOUSEEVENT tme, list_tme; + int branch_row_top; + int branch_row_left; + int branch_row_height; + // screenshot bmp stuff + LPBITMAPINFO scr_bmi; + HBITMAP scr_bmp; + uint8* scr_ptr; + int scr_bmp_x; + int scr_bmp_y; + int scr_bmp_phase; + int screenshot_currently_shown; private: void SetCurrentPosTime(); @@ -140,6 +159,7 @@ private: int edit_mode; int animation_frame; // 0-13 int next_animation_time; + bool must_check_item_under_mouse; bool must_redraw_branches_tree; bool must_recalculate_branches_tree; std::vector BranchX; // in pixels @@ -148,7 +168,7 @@ private: std::vector BranchPrevY; std::vector BranchCurrX; std::vector BranchCurrY; - int CloudX, CloudPrevX; + int CloudX, CloudPrevX, cloud_x; int CursorX, CursorPrevX, CursorY, CursorPrevY; int transition_phase; int fireball_size; diff --git a/src/drivers/win/taseditlib/inputsnapshot.cpp b/src/drivers/win/taseditlib/inputsnapshot.cpp index fcdf86d2..16206125 100644 --- a/src/drivers/win/taseditlib/inputsnapshot.cpp +++ b/src/drivers/win/taseditlib/inputsnapshot.cpp @@ -191,7 +191,7 @@ bool INPUT_SNAPSHOT::load(EMUFILE *is) has_hot_changes = (tmp != 0); // read description if (!read8le(&tmp, is)) return true; - if (tmp < 0 || tmp >= SNAPSHOT_DESC_MAX_LENGTH) return true; + if (tmp >= SNAPSHOT_DESC_MAX_LENGTH) return true; if (is->fread(&description[0], tmp) != tmp) return true; description[tmp] = 0; // add '0' because it wasn't saved // read data @@ -255,7 +255,7 @@ bool INPUT_SNAPSHOT::skipLoad(EMUFILE *is) if (!read8le(&tmp1, is)) return true; // read description if (!read8le(&tmp1, is)) return true; - if (tmp1 < 0 || tmp1 >= SNAPSHOT_DESC_MAX_LENGTH) return true; + if (tmp1 >= SNAPSHOT_DESC_MAX_LENGTH) return true; if (is->fseek(tmp1, SEEK_CUR) != 0) return true; // read joysticks data if (!read32le(&tmp, is)) return true;