X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_holmes.pas;h=1222cd6c73da25c92ce45a6b16c643137e5bdea8;hb=b4a2614636a9cc12ce9766ec1e2bf04cd5bec0ea;hp=82256a81a0ea3692debe27236dc52789f3361b27;hpb=25ba6656c65ad0e4d9292c6093b4eb2644e0beba;p=d2df-sdl.git diff --git a/src/game/g_holmes.pas b/src/game/g_holmes.pas index 82256a8..1222cd6 100644 --- a/src/game/g_holmes.pas +++ b/src/game/g_holmes.pas @@ -19,7 +19,7 @@ unit g_holmes; interface uses - e_log, + e_log, e_input, g_textures, g_basic, e_graphics, g_phys, g_grid, g_player, g_monsters, g_window, g_map, g_triggers, g_items, g_game, g_panel, g_console, xprofiler; @@ -68,8 +68,9 @@ type sym: Word; // SDLK_XXX bstate: Word; // button state kstate: Word; // keyboard state - end; + public + end; procedure g_Holmes_VidModeChanged (); procedure g_Holmes_WindowFocused (); @@ -86,6 +87,13 @@ procedure g_Holmes_plrView (viewPortX, viewPortY, viewPortW, viewPortH: Integer) procedure g_Holmes_plrLaser (ax0, ay0, ax1, ay1: Integer); +operator = (constref ev: THKeyEvent; const s: AnsiString): Boolean; +operator = (const s: AnsiString; constref ev: THKeyEvent): Boolean; + +operator = (constref ev: THMouseEvent; const s: AnsiString): Boolean; +operator = (const s: AnsiString; constref ev: THMouseEvent): Boolean; + + var g_holmes_enabled: Boolean = {$IF DEFINED(D2F_DEBUG)}true{$ELSE}false{$ENDIF}; @@ -116,6 +124,108 @@ var {$INCLUDE g_holmes_ui.inc} +// ////////////////////////////////////////////////////////////////////////// // +// any mods = 255: nothing was defined +function parseModKeys (const s: AnsiString; out kmods: Byte; out mbuts: Byte): AnsiString; +var + pos, epos: Integer; +begin + kmods := 255; + mbuts := 255; + pos := 1; + while (pos <= Length(s)) and (s[pos] <= ' ') do Inc(pos); + while (pos < Length(s)) do + begin + if (Length(s)-pos >= 2) and (s[pos+1] = '-') then + begin + case s[pos] of + 'C', 'c': begin if (kmods = 255) then kmods := 0; kmods := kmods or THKeyEvent.ModCtrl; Inc(pos, 2); continue; end; + 'M', 'm': begin if (kmods = 255) then kmods := 0; kmods := kmods or THKeyEvent.ModAlt; Inc(pos, 2); continue; end; + 'S', 's': begin if (kmods = 255) then kmods := 0; kmods := kmods or THKeyEvent.ModShift; Inc(pos, 2); continue; end; + end; + break; + end; + if (Length(s)-pos >= 4) and ((s[pos+1] = 'M') or (s[pos+1] = 'm')) and ((s[pos+2] = 'B') or (s[pos+1] = 'b')) and (s[pos+3] = '-') then + begin + case s[pos] of + 'L', 'l': begin if (mbuts = 255) then mbuts := 0; mbuts := mbuts or THMouseEvent.Left; Inc(pos, 4); continue; end; + 'R', 'r': begin if (mbuts = 255) then mbuts := 0; mbuts := mbuts or THMouseEvent.Right; Inc(pos, 4); continue; end; + 'M', 'm': begin if (mbuts = 255) then mbuts := 0; mbuts := mbuts or THMouseEvent.Middle; Inc(pos, 4); continue; end; + end; + break; + end; + break; + end; + epos := Length(s)+1; + while (epos > pos) and (s[epos-1] <= ' ') do Dec(epos); + if (epos > pos) then result := Copy(s, pos, epos-pos) else result := ''; +end; + + +operator = (constref ev: THKeyEvent; const s: AnsiString): Boolean; +var + f: Integer; + kmods: Byte = 255; + mbuts: Byte = 255; + kname: AnsiString; +begin + result := false; + kname := parseModKeys(s, kmods, mbuts); + if (kmods = 255) then kmods := 0; + if (ev.kstate <> kmods) then exit; + if (mbuts <> 255) and (ev.bstate <> mbuts) then exit; + for f := 1 to High(e_KeyNames) do + begin + if (CompareText(kname, e_KeyNames[f]) = 0) then + begin + result := (ev.scan = f); + exit; + end; + end; +end; + + +operator = (const s: AnsiString; constref ev: THKeyEvent): Boolean; +begin + result := (ev = s); +end; + + +operator = (constref ev: THMouseEvent; const s: AnsiString): Boolean; +var + kmods: Byte = 255; + mbuts: Byte = 255; + kname: AnsiString; + but: Integer = -1; +begin + result := false; + kname := parseModKeys(s, kmods, mbuts); + if (CompareText(kname, 'LMB') = 0) then but := THMouseEvent.Left + else if (CompareText(kname, 'RMB') = 0) then but := THMouseEvent.Right + else if (CompareText(kname, 'MMB') = 0) then but := THMouseEvent.Middle + else if (CompareText(kname, 'None') = 0) then but := 0 + else exit; + + //conwritefln('s=[%s]; kname=[%s]; kmods=%s; mbuts=%s; but=%s', [s, kname, kmods, mbuts, but]); + + if (mbuts = 255) then mbuts := 0; + if (kmods <> 255) and (ev.kstate <> kmods) then exit; + + if (ev.kind = ev.Press) then mbuts := mbuts or but + else if (ev.kind = ev.Release) then mbuts := mbuts and (not but); + + //conwritefln(' ev.bstate=%s; ev.but=%s; mbuts=%s', [ev.bstate, ev.but, mbuts]); + + result := (ev.bstate = mbuts) and (ev.but = but); +end; + + +operator = (const s: AnsiString; constref ev: THMouseEvent): Boolean; +begin + result := (ev = s); +end; + + // ////////////////////////////////////////////////////////////////////////// // var g_ol_nice: Boolean = false; @@ -132,11 +242,45 @@ var // ////////////////////////////////////////////////////////////////////////// // var + winHelp: THTopWindow = nil; winOptions: THTopWindow = nil; winLayers: THTopWindow = nil; winOutlines: THTopWindow = nil; +procedure createHelpWindow (); +var + llb: THCtlSimpleText; +begin + llb := THCtlSimpleText.Create(0, 0); + llb.appendItem('common keys', true, true); + llb.appendItem(' F1 -- toggle this window'); + llb.appendItem(' M-F1 -- toggle options window'); + llb.appendItem(''); + llb.appendItem('control keys', true, true); + llb.appendItem(' M-M -- one monster think step'); + llb.appendItem(' M-I -- toggle monster info'); + llb.appendItem(' M-K -- toggle monster LOS to player'); + llb.appendItem(' M-G -- toggle "show all cells occupied by monsters" (SLOW!)'); + llb.appendItem(' M-A -- wake up monster'); + llb.appendItem(' C-T -- teleport player'); + llb.appendItem(' C-P -- show cursor position on the map'); + llb.appendItem(' C-G -- toggle grid'); + llb.appendItem(' C-L -- toggle layers window'); + llb.appendItem(' C-O -- toggle outlines window'); + llb.appendItem(''); + llb.appendItem('mouse', true, true); + llb.appendItem(' LMB -- select monster'); + llb.appendItem(' M-LMB -- dump monsters in cell (to log)'); + llb.appendItem(' RMB -- dump wall info to log'); + llb.appendItem(' M-LMB -- disable wall'); + winHelp := THTopWindow.Create('Holmes Help', 10, 10); + winHelp.escClose := true; + winHelp.appendChild(llb); + winHelp.centerInScreen(); +end; + + procedure winLayersClosed (me: THControl; dummy: Integer); begin showLayersWindow := false; end; procedure winOutlinesClosed (me: THControl; dummy: Integer); begin showOutlineWindow := false; end; @@ -227,6 +371,7 @@ begin winOptions := THTopWindow.Create('Holmes Options', 100, 100); winOptions.escClose := true; winOptions.appendChild(llb); + winOptions.centerInScreen(); end; @@ -294,7 +439,7 @@ procedure plrDebugMouse (var ev: THMouseEvent); begin result := false; // don't stop e_WriteLog(Format('wall #%d(%d); enabled=%d (%d); (%d,%d)-(%d,%d)', [pan.arrIdx, pan.proxyId, Integer(pan.Enabled), Integer(mapGrid.proxyEnabled[pan.proxyId]), pan.X, pan.Y, pan.Width, pan.Height]), MSG_NOTIFY); - if ((kbS and THKeyEvent.ModAlt) <> 0) then + if (kbS = THKeyEvent.ModAlt) then begin if pan.Enabled then g_Map_DisableWall(pan.arrIdx) else g_Map_EnableWall(pan.arrIdx); end; @@ -321,33 +466,33 @@ begin e_WriteLog(Format('mev: %d', [Integer(ev.kind)]), MSG_NOTIFY); + if (ev.but = THMouseEvent.Right) then + begin + // dump/toggle wall + e_WriteLog('=== TOGGLE WALL ===', MSG_NOTIFY); + mapGrid.forEachAtPoint(pmsCurMapX, pmsCurMapY, wallToggle, (GridTagWall or GridTagDoor)); + e_WriteLog('--- toggle wall ---', MSG_NOTIFY); + exit; + end; + if (ev.but = THMouseEvent.Left) then begin - if ((kbS and THKeyEvent.ModShift) <> 0) then + if (kbS = THKeyEvent.ModAlt) then begin // dump monsters in cell e_WriteLog('===========================', MSG_NOTIFY); monsGrid.forEachInCell(pmsCurMapX, pmsCurMapY, monsInCell); e_WriteLog('---------------------------', MSG_NOTIFY); end - else + else if (kbS = 0) then begin - // toggle wall - e_WriteLog('=== TOGGLE WALL ===', MSG_NOTIFY); - mapGrid.forEachAtPoint(pmsCurMapX, pmsCurMapY, wallToggle, (GridTagWall or GridTagDoor)); - e_WriteLog('--- toggle wall ---', MSG_NOTIFY); + monMarkedUID := -1; + e_WriteLog('===========================', MSG_NOTIFY); + monsGrid.forEachAtPoint(pmsCurMapX, pmsCurMapY, monsAtDump); + e_WriteLog('---------------------------', MSG_NOTIFY); end; exit; end; - - if (ev.but = THMouseEvent.Right) then - begin - monMarkedUID := -1; - e_WriteLog('===========================', MSG_NOTIFY); - monsGrid.forEachAtPoint(pmsCurMapX, pmsCurMapY, monsAtDump); - e_WriteLog('---------------------------', MSG_NOTIFY); - exit; - end; end; @@ -783,7 +928,7 @@ begin if (ev.kind = THKeyEvent.Press) then begin // M-M: one monster think step - if (ev.scan = SDL_SCANCODE_M) and ((ev.kstate and THKeyEvent.ModAlt) <> 0) then + if (ev = 'M-M') then begin result := true; gmon_debug_think := false; @@ -791,28 +936,28 @@ begin exit; end; // M-I: toggle monster info - if (ev.scan = SDL_SCANCODE_I) and ((ev.kstate and THKeyEvent.ModAlt) <> 0) then + if (ev = 'M-I') then begin result := true; showMonsInfo := not showMonsInfo; exit; end; // M-L: toggle monster LOS to player - if (ev.scan = SDL_SCANCODE_L) and ((ev.kstate and THKeyEvent.ModAlt) <> 0) then + if (ev = 'M-L') then begin result := true; showMonsLOS2Plr := not showMonsLOS2Plr; exit; end; // M-G: toggle "show all cells occupied by monsters" - if (ev.scan = SDL_SCANCODE_G) and ((ev.kstate and THKeyEvent.ModAlt) <> 0) then + if (ev = 'M-G') then begin result := true; showAllMonsCells := not showAllMonsCells; exit; end; // M-A: wake up monster - if (ev.scan = SDL_SCANCODE_A) and ((ev.kstate and THKeyEvent.ModAlt) <> 0) then + if (ev = 'M-A') then begin result := true; if (monMarkedUID <> -1) then @@ -823,7 +968,7 @@ begin exit; end; // C-T: teleport player - if (ev.scan = SDL_SCANCODE_T) and ((ev.kstate and THKeyEvent.ModCtrl) <> 0) then + if (ev = 'C-T') then begin result := true; //e_WriteLog(Format('TELEPORT: (%d,%d)', [pmsCurMapX, pmsCurMapY]), MSG_NOTIFY); @@ -835,21 +980,21 @@ begin exit; end; // C-P: show cursor position on the map - if (ev.scan = SDL_SCANCODE_P) and ((ev.kstate and THKeyEvent.ModCtrl) <> 0) then + if (ev = 'C-P') then begin result := true; showMapCurPos := not showMapCurPos; exit; end; // C-G: toggle grid - if (ev.scan = SDL_SCANCODE_G) and ((ev.kstate and THKeyEvent.ModCtrl) <> 0) then + if (ev = 'C-G') then begin result := true; showGrid := not showGrid; exit; end; // C-L: toggle layers window - if (ev.scan = SDL_SCANCODE_L) and ((ev.kstate and THKeyEvent.ModCtrl) <> 0) then + if (ev = 'C-L') then begin result := true; showLayersWindow := not showLayersWindow; @@ -857,7 +1002,7 @@ begin exit; end; // C-O: toggle outlines window - if (ev.scan = SDL_SCANCODE_O) and ((ev.kstate and THKeyEvent.ModCtrl) <> 0) then + if (ev = 'C-O') then begin result := true; showOutlineWindow := not showOutlineWindow; @@ -865,13 +1010,22 @@ begin exit; end; // F1: toggle options window - if (ev.scan = SDL_SCANCODE_F1) and (ev.kstate = 0) then + if (ev = 'F1') then + begin + result := true; + if (winHelp = nil) then createHelpWindow(); + if not uiVisibleWindow(winHelp) then uiAddWindow(winHelp) else uiRemoveWindow(winHelp); + exit; + end; + // M-F1: toggle options window + if (ev = 'M-F1') then begin result := true; if (winOptions = nil) then createOptionsWindow(); if not uiVisibleWindow(winOptions) then uiAddWindow(winOptions) else uiRemoveWindow(winOptions); exit; end; + {$IF DEFINED(D2F_DEBUG)} // C-UP, C-DOWN, C-LEFT, C-RIGHT: trace 10 pixels from cursor in the respective direction if ((ev.scan = SDL_SCANCODE_UP) or (ev.scan = SDL_SCANCODE_DOWN) or (ev.scan = SDL_SCANCODE_LEFT) or (ev.scan = SDL_SCANCODE_RIGHT)) and ((ev.kstate and THKeyEvent.ModCtrl) <> 0) then @@ -897,6 +1051,7 @@ begin e_LogWritefln('v-trace: (%d,%d)-(%d,%d); end=(%d,%d); hit=%d', [pmsCurMapX, pmsCurMapY, dx, dy, ex, ey, (pan <> nil)]); exit; end; + {$ENDIF} end; end;