diff --git a/hacking/ChangeLog b/hacking/ChangeLog index 298187f6..73220f18 100644 --- a/hacking/ChangeLog +++ b/hacking/ChangeLog @@ -2465,3 +2465,5 @@ Machine dialog (Marek) 20080215 ui/win32/win32ui.c: Win32: Implementation of the Filters dialog using a reusable selector_dialog (Marek) +20080217 ui/win32/{win32ui.c,pokefinder.{c,rc},win32internals.h,Makefile.am: + Win32: Fixes for pokefinder (Marek) diff --git a/ui/win32/Makefile.am b/ui/win32/Makefile.am index d0131809..23bcb403 100644 --- a/ui/win32/Makefile.am +++ b/ui/win32/Makefile.am @@ -37,6 +37,7 @@ libuiwin32_a_SOURCES = debugger.c \ options.c \ options.rc \ picture.c \ + pokefinder.c \ pokefinder.rc \ statusbar.c \ win32display.c \ diff --git a/ui/win32/pokefinder.c b/ui/win32/pokefinder.c index db5359a7..cfedb7d9 100644 --- a/ui/win32/pokefinder.c +++ b/ui/win32/pokefinder.c @@ -23,53 +23,64 @@ */ -#include "win32internals.h" -#include "pokefinder/pokefinder.h" +#define _WIN32_IE 0x400 /* needed by LPNMITEMACTIVATE (dbl click on listview) */ +#include +#include + +#include "debugger/debugger.h" #include "pokefinder.h" +#include "pokefinder/pokefinder.h" +#include "ui/ui.h" +#include "win32internals.h" -void win32_pokefinder_incremented(); -void win32_pokefinder_decremented(); -void win32_pokefinder_search(); -void win32_pokefinder_reset(); -void win32_pokefinder_close(); +void win32ui_pokefinder_incremented(); +void win32ui_pokefinder_decremented(); +void win32ui_pokefinder_search(); +void win32ui_pokefinder_reset(); +void win32ui_pokefinder_close(); void update_pokefinder( void ); -/* -void possible_click( GtkCList *clist, gint row, gint column, - GdkEventButton *event, gpointer user_data ); -*/ +void possible_click( LPNMITEMACTIVATE lpnmitem ); #define MAX_POSSIBLE 20 int possible_page[ MAX_POSSIBLE ]; libspectrum_word possible_offset[ MAX_POSSIBLE ]; -BOOL CALLBACK PokefinderProc( HWND hWnd, UINT msg, - WPARAM wParam, LPARAM lParam ) +INT_PTR CALLBACK +win32ui_pokefinder_proc( HWND hWnd, UINT msg, + WPARAM wParam, LPARAM lParam ) { switch( msg ) { case WM_COMMAND: switch( LOWORD( wParam ) ) { case IDC_PF_CLOSE: - win32_pokefinder_close(); + win32ui_pokefinder_close(); return TRUE; case IDC_PF_INC: - win32_pokefinder_incremented(); + win32ui_pokefinder_incremented(); return TRUE; case IDC_PF_DEC: - win32_pokefinder_decremented(); + win32ui_pokefinder_decremented(); return TRUE; case IDC_PF_SEARCH: - win32_pokefinder_search(); + win32ui_pokefinder_search(); return TRUE; case IDC_PF_RESET: - win32_pokefinder_reset(); + win32ui_pokefinder_reset(); return TRUE; } return FALSE; case WM_CLOSE: - win32_pokefinder_close(); + win32ui_pokefinder_close(); return TRUE; + case WM_NOTIFY: + switch ( ( ( LPNMHDR ) lParam )->code ) { + case NM_DBLCLK: + possible_click( ( LPNMITEMACTIVATE ) lParam ); + return TRUE; + } + return FALSE; } return FALSE; } @@ -78,127 +89,189 @@ void update_pokefinder( void ) { size_t page, offset; - char buffer[256], *possible_text[2] = { &buffer[0], &buffer[128] }; + TCHAR buffer[256], *possible_text[2] = { &buffer[0], &buffer[128] }; - HWND hLocListView; - hLocListView = GetDlgItem( fuse_hPFWnd, IDC_PF_LIST ); - - /* delete the whole list */ - ListView_DeleteAllItems( hLocListView ); + /* clear the listview */ + SendDlgItemMessage( fuse_hPFWnd, IDC_PF_LIST, LVM_DELETEALLITEMS, 0, 0 ); /* display suspected locations if < 20 */ - int i; - i = 0; + int i = 0; LV_ITEM lvi; lvi.mask = LVIF_TEXT; if( pokefinder_count && pokefinder_count <= MAX_POSSIBLE ) { - size_t which; + size_t which = 0; - which = 0; + for( page = 0; page < 2 * SPECTRUM_RAM_PAGES; page++ ) + for( offset = 0; offset < 0x2000; offset++ ) + if( ! (pokefinder_impossible[page][offset/8] & 1 << (offset & 7)) ) { - for( page = 0; page < 8; page++ ) - for( offset = 0; offset < 0x4000; offset++ ) - if( pokefinder_possible[page][offset] != -1 ) { - possible_page[ which ] = page; - possible_offset[ which ] = offset; - which++; + possible_page[ which ] = page / 2; + possible_offset[ which ] = offset + 8192 * (page & 1); + which++; + + _sntprintf( possible_text[0], 128, "%d", (unsigned)page ); + _sntprintf( possible_text[1], 128, "0x%04X", (unsigned)offset ); - snprintf( possible_text[0], 128, "%lu", (unsigned long)page ); - snprintf( possible_text[1], 128, "0x%04X", (unsigned)offset ); + /* set new count of items */ + SendDlgItemMessage( fuse_hPFWnd, IDC_PF_LIST, LVM_SETITEMCOUNT, + i, 0 ); + /* add the item */ lvi.iItem = i; lvi.iSubItem = 0; lvi.pszText = possible_text[0]; - ListView_InsertItem( hLocListView, &lvi ); - ListView_SetItemText( hLocListView, i, 1, possible_text[1]); + SendDlgItemMessage( fuse_hPFWnd, IDC_PF_LIST, LVM_INSERTITEM, 0, + ( LPARAM ) &lvi ); + lvi.iSubItem = 1; + lvi.pszText = possible_text[1]; + SendDlgItemMessage( fuse_hPFWnd, IDC_PF_LIST, LVM_SETITEM, 0, + ( LPARAM ) &lvi ); + i++; } + + /* show the listview */ + ShowWindow( GetDlgItem( fuse_hPFWnd, IDC_PF_LIST ), SW_SHOW ); + + } else { + /* hide the listview */ + ShowWindow( GetDlgItem( fuse_hPFWnd, IDC_PF_LIST ), SW_HIDE ); } - /* set number of possible locations */ - HWND hPossibleLocs; - hPossibleLocs = GetDlgItem( fuse_hPFWnd, IDC_PF_LOCATIONS ); - - snprintf( buffer, 256, "Possible locations: %lu", - (unsigned long)pokefinder_count ); - SendMessage( hPossibleLocs, WM_SETTEXT, 0, (LPARAM) buffer ); -/* - TODO: why doesn't it display 131072??? -*/ + /* print possible locations */ + _sntprintf( buffer, 256, "Possible locations: %d\n", pokefinder_count ); + SendDlgItemMessage( fuse_hPFWnd, IDC_PF_LOCATIONS, WM_SETTEXT, 0, (LPARAM) buffer ); } void menu_machine_pokefinder( int action ) { if (fuse_hPFWnd == NULL) { - fuse_hPFWnd = CreateDialog( fuse_hInstance, "DLG_POKEFINDER", fuse_hWnd, - (DLGPROC) PokefinderProc ); - win32_verror( fuse_hPFWnd == NULL ); + /* FIXME: Implement accelerators for this dialog */ + fuse_hPFWnd = CreateDialog( fuse_hInstance, "IDD_POKEFINDER", fuse_hWnd, + (DLGPROC) win32ui_pokefinder_proc ); + if ( fuse_hPFWnd == NULL ) { + win32_verror( 1 ); /* FIXME: improve this function */ + return; + } - /* get handle to the listview and set kind and the column names */ - HWND hLocListView; - hLocListView = GetDlgItem( fuse_hPFWnd, IDC_PF_LIST ); + /* set extended listview style to select full row, when an item is selected */ + DWORD lv_ext_style; + lv_ext_style = SendDlgItemMessage( fuse_hPFWnd, IDC_PF_LIST, + LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0 ); + lv_ext_style |= LVS_EX_FULLROWSELECT; + SendDlgItemMessage( fuse_hPFWnd, IDC_PF_LIST, + LVM_SETEXTENDEDLISTVIEWSTYLE, 0, lv_ext_style ); + /* create columns */ LVCOLUMN lvc; lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT ; lvc.fmt = LVCFMT_LEFT; - lvc.cx = 60; - lvc.pszText = "Page"; - ListView_InsertColumn( hLocListView, 0, &lvc ); - lvc.cx = 92; - lvc.pszText = "Offset"; - ListView_InsertColumn( hLocListView, 1, &lvc ); - - update_pokefinder(); + lvc.cx = 114; + lvc.pszText = TEXT( "Page" ); + SendDlgItemMessage( fuse_hPFWnd, IDC_PF_LIST, LVM_INSERTCOLUMN, 0, + ( LPARAM ) &lvc ); + lvc.mask |= LVCF_SUBITEM; + lvc.cx = 114; + lvc.pszText = TEXT( "Offset" ); + SendDlgItemMessage( fuse_hPFWnd, IDC_PF_LIST, LVM_INSERTCOLUMN, 1, + ( LPARAM ) &lvc ); } else { SetActiveWindow( fuse_hPFWnd ); } + update_pokefinder(); } void -win32_pokefinder_incremented() +win32ui_pokefinder_incremented() { pokefinder_incremented(); update_pokefinder(); } void -win32_pokefinder_decremented() +win32ui_pokefinder_decremented() { pokefinder_decremented(); update_pokefinder(); } void -win32_pokefinder_search() +win32ui_pokefinder_search() { - char buffer[256]; + long value; + TCHAR *buffer; + int buffer_size; - HWND hEditBox; - hEditBox = GetDlgItem( fuse_hPFWnd, IDC_PF_EDIT ); + /* poll the size of the value in Search box first */ + buffer_size = SendDlgItemMessage( fuse_hPFWnd, IDC_PF_EDIT, WM_GETTEXTLENGTH, + (WPARAM) 0, (LPARAM) 0 ); + buffer = malloc( ( buffer_size + 1 ) * sizeof( TCHAR ) ); + if( buffer == NULL ) { + ui_error( UI_ERROR_ERROR, "Out of memory in %s.", __func__ ); + return; + } - SendMessage( hEditBox, WM_GETTEXT, (WPARAM) 256, (LPARAM) buffer ); + /* get the value in Search box first */ + if( SendDlgItemMessage( fuse_hPFWnd, IDC_PF_EDIT, WM_GETTEXT, + (WPARAM) ( buffer_size + 1 ), + (LPARAM) buffer ) != buffer_size ) { + ui_error( UI_ERROR_ERROR, "Couldn't get the content of the Search text box" ); + return; + } - pokefinder_search( atoi( buffer ) ); + value = _ttol( buffer ); + free( buffer ); + + if( value < 0 || value > 255 ) { + ui_error( UI_ERROR_ERROR, "Invalid value: use an integer from 0 to 255" ); + return; + } + + pokefinder_search( value ); update_pokefinder(); } void -win32_pokefinder_reset() +win32ui_pokefinder_reset() { pokefinder_clear(); update_pokefinder(); } void -win32_pokefinder_close() +win32ui_pokefinder_close() { DestroyWindow( fuse_hPFWnd ); fuse_hPFWnd = NULL; } -/* TODO: implement clicking on value in the location - list to set the breakpoint -*/ +void +possible_click( LPNMITEMACTIVATE lpnmitem ) +{ + /* FIXME: implement equivalent of GTK's select-via-keyboard to enter here */ + + int error; + libspectrum_word row; + + if( lpnmitem->iItem < 0 ) return; + + row = lpnmitem->iItem; + + error = debugger_breakpoint_add_address( + DEBUGGER_BREAKPOINT_TYPE_WRITE, possible_page[ row ], + possible_offset[ row ], 0, DEBUGGER_BREAKPOINT_LIFE_PERMANENT, NULL + ); + if( error ) return; + + ui_debugger_update(); +} + +void +win32ui_pokefinder_clear( void ) +{ + pokefinder_clear(); + if( fuse_hPFWnd != NULL ) update_pokefinder(); +} diff --git a/ui/win32/pokefinder.rc b/ui/win32/pokefinder.rc index 1dcb6119..2dc15080 100644 --- a/ui/win32/pokefinder.rc +++ b/ui/win32/pokefinder.rc @@ -26,23 +26,25 @@ #include #include "pokefinder.h" -DLG_POKEFINDER DIALOG DISCARDABLE 6,6,341,83 +IDD_POKEFINDER DIALOGEX DISCARDABLE 6,6,341,83 CAPTION "Fuse - Poke Finder" -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_VISIBLE | WS_SYSMENU +STYLE WS_POPUP | WS_CAPTION | WS_VISIBLE | WS_SYSMENU +FONT 8,"Ms Shell Dlg 2",400,0,1 BEGIN CTEXT "Search for:", IDC_PF_SEARCH_FOR, 20, 25, 38, 9 CTEXT "Possible locations: 6", IDC_PF_LOCATIONS, 232/*250*/, 5, 84, 9 - PUSHBUTTON "Incremented", IDC_PF_INC, 4, 64, 60, 15 - PUSHBUTTON "Decremented", IDC_PF_DEC, 72, 64, 60, 15 - PUSHBUTTON "Search", IDC_PF_SEARCH, 140, 64, 60, 15 - PUSHBUTTON "Reset", IDC_PF_RESET, 208, 64, 60, 15 - PUSHBUTTON "Close", IDC_PF_CLOSE, 276, 64, 60, 15 + PUSHBUTTON "&Incremented", IDC_PF_INC, 4, 64, 60, 15 + PUSHBUTTON "&Decremented", IDC_PF_DEC, 72, 64, 60, 15 + DEFPUSHBUTTON "&Search", IDC_PF_SEARCH, 140, 64, 60, 15 + PUSHBUTTON "&Reset", IDC_PF_RESET, 208, 64, 60, 15 + PUSHBUTTON "&Close", IDC_PF_CLOSE, 276, 64, 60, 15 - EDITTEXT IDC_PF_EDIT, 84, 24, 140, 13, + EDITTEXT IDC_PF_EDIT, 70, 24, 80, 12, WS_CHILD | WS_VISIBLE, WS_EX_CLIENTEDGE CONTROL "",IDC_PF_LIST,"SysListView32", - WS_CHILD | WS_VISIBLE | LVS_REPORT, 232, 20, 102, 39, WS_EX_CLIENTEDGE + WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS , + 170, 20, 165, 39, WS_EX_CLIENTEDGE END diff --git a/ui/win32/win32internals.h b/ui/win32/win32internals.h index 25ee1804..63f8817b 100644 --- a/ui/win32/win32internals.h +++ b/ui/win32/win32internals.h @@ -58,4 +58,10 @@ void handle_menu( DWORD cmd, HWND okno ); int win32ui_picture( const char *filename, int border ); +/* + * Dialog box reset + */ + +void win32ui_pokefinder_clear( void ); + #endif /* #ifndef FUSE_WIN32INTERNALS_H */ diff --git a/ui/win32/win32ui.c b/ui/win32/win32ui.c index b826b3fc..37d4b026 100644 --- a/ui/win32/win32ui.c +++ b/ui/win32/win32ui.c @@ -415,7 +415,7 @@ ui_joystick_poll( void ) int ui_widgets_reset( void ) { - STUB; + win32ui_pokefinder_clear(); return 0; } @@ -979,6 +979,5 @@ menu_machine_select( int action ) fuse_emulation_unpause(); } -void menu_machine_pokefinder( int action ) { STUB; } void menu_machine_memorybrowser( int action ) { STUB; } void menu_media_tape_browse( int action ) { STUB; }