DEADSOFTWARE

moved debug inspector to g_holmes.pas
authorKetmar Dark <ketmar@ketmar.no-ip.org>
Wed, 23 Aug 2017 11:08:20 +0000 (14:08 +0300)
committerKetmar Dark <ketmar@ketmar.no-ip.org>
Wed, 23 Aug 2017 18:23:55 +0000 (21:23 +0300)
src/game/Doom2DF.dpr
src/game/g_game.pas
src/game/g_holmes.pas [new file with mode: 0644]
src/game/g_player.pas
src/game/g_window.pas

index 18ab86f560c6121986c0726caa8265303ab0fd80..7473b43b9ebe8abaca200b344504b6007ecd2e9e 100644 (file)
@@ -89,6 +89,7 @@ uses
   g_triggers in 'g_triggers.pas',
   g_weapons in 'g_weapons.pas',
   g_window in 'g_window.pas',
+  g_holmes in 'g_holmes.pas',
   SysUtils,
 {$IFDEF USE_FMOD}
   fmod in '../lib/FMOD/fmod.pas',
index 99e1a3d8ce26a22509465542a792278615d3ce9a..833baf5d45d6cd544cf5f3d86af065869779b715 100644 (file)
@@ -316,12 +316,12 @@ var
   g_profile_los: Boolean = false;
   g_profile_history_size: Integer = 1000;
 
-  postdrawMouse: procedure = nil;
 
 procedure g_ResetDynlights ();
 procedure g_AddDynLight (x, y, radius: Integer; r, g, b, a: Single);
 procedure g_DynLightExplosion (x, y, radius: Integer; r, g, b: Single);
 
+
 implementation
 
 uses
@@ -331,7 +331,7 @@ uses
   g_triggers, MAPDEF, g_monsters, e_sound, CONFIG,
   BinEditor, g_language, g_net, SDL,
   ENet, e_msg, g_netmsg, g_netmaster, GL, GLExt,
-  utils, sfs;
+  utils, sfs, g_holmes;
 
 
 // ////////////////////////////////////////////////////////////////////////// //
@@ -3254,6 +3254,9 @@ begin
     g_ActiveWindow.Draw();
   end;
 
+  // draw inspector
+  g_Holmes_Draw();
+
   g_Console_Draw();
 
   if g_debug_Sounds and gGameOn then
@@ -3274,8 +3277,6 @@ begin
                      Format('%d:%.2d:%.2d', [gTime div 1000 div 3600, (gTime div 1000 div 60) mod 60, gTime div 1000 mod 60]),
                      gStdFont);
 
-  if gGameOn and assigned(postdrawMouse) then postdrawMouse();
-
   if gGameOn then drawProfilers();
 end;
 
diff --git a/src/game/g_holmes.pas b/src/game/g_holmes.pas
new file mode 100644 (file)
index 0000000..007ffbb
--- /dev/null
@@ -0,0 +1,394 @@
+(* Copyright (C)  DooM 2D:Forever Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *)
+{$INCLUDE ../shared/a_modes.inc}
+unit g_holmes;
+
+interface
+
+uses
+  e_log,
+  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;
+
+
+type
+  THMouseEvent = record
+  public
+    const
+      // both for but and for bstate
+      Left = $0001;
+      Right = $0002;
+      Middle = $0004;
+      WheelUp = $0008;
+      WheelDown = $0010;
+
+      // event types
+      Motion = 0;
+      Press = 1;
+      Release = 2;
+
+  public
+    kind: Byte; // motion, press, release
+    x, y: Integer;
+    dx, dy: Integer; // for wheel this is wheel motion, otherwise this is relative mouse motion
+    but: Word; // current pressed button or 0
+    bstate: Word; // button state
+    kstate: Word; // keyboard state (see THKeyEvent);
+  end;
+
+  THKeyEvent = record
+  public
+    const
+      ModCtrl = $0001;
+      ModAlt = $0002;
+      ModShift = $0004;
+  end;
+
+
+procedure g_Holmes_VidModeChanged ();
+procedure g_Holmes_WindowFocused ();
+procedure g_Holmes_WindowBlured ();
+
+procedure g_Holmes_Draw ();
+
+function g_Holmes_mouseEvent (var ev: THMouseEvent): Boolean; // returns `true` if event was eaten
+function g_Holmes_KeyEvent (var ev: THKeyEvent): Boolean; // returns `true` if event was eaten
+
+// hooks for player
+procedure g_Holmes_plrView (viewPortX, viewPortY, viewPortW, viewPortH: Integer);
+procedure g_Holmes_plrLaser (ax0, ay0, ax1, ay1: Integer);
+
+
+implementation
+
+uses
+  SysUtils, GL,
+  g_options;
+
+
+var
+  //globalInited: Boolean = false;
+  msX: Integer = -666;
+  msY: Integer = -666;
+  msB: Word = 0; // button state
+  kbS: Word = 0; // keyboard modifiers state
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+// cursor (hi, Death Track!)
+const curWidth = 17;
+const curHeight = 23;
+
+const cursorImg: array[0..curWidth*curHeight-1] of Byte = (
+  0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,3,2,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  1,0,3,2,2,0,0,0,0,0,0,0,0,0,0,0,0,
+  1,1,3,3,2,2,0,0,0,0,0,0,0,0,0,0,0,
+  1,1,3,3,4,2,2,0,0,0,0,0,0,0,0,0,0,
+  1,1,3,3,4,4,2,2,0,0,0,0,0,0,0,0,0,
+  1,1,3,3,4,4,4,2,2,0,0,0,0,0,0,0,0,
+  1,1,3,3,4,4,4,4,2,2,0,0,0,0,0,0,0,
+  1,1,3,3,4,4,4,5,6,2,2,0,0,0,0,0,0,
+  1,1,3,3,4,4,5,6,7,5,2,2,0,0,0,0,0,
+  1,1,3,3,4,5,6,7,5,4,5,2,2,0,0,0,0,
+  1,1,3,3,5,6,7,5,4,5,6,7,2,2,0,0,0,
+  1,1,3,3,6,7,5,4,5,6,7,7,7,2,2,0,0,
+  1,1,3,3,7,5,4,5,6,7,7,7,7,7,2,2,0,
+  1,1,3,3,5,4,5,6,8,8,8,8,8,8,8,8,2,
+  1,1,3,3,4,5,6,3,8,8,8,8,8,8,8,8,8,
+  1,1,3,3,5,6,3,3,1,1,1,1,1,1,1,0,0,
+  1,1,3,3,6,3,3,1,1,1,1,1,1,1,1,0,0,
+  1,1,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,
+  1,1,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,
+  1,1,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+);
+const cursorPal: array[0..9*4-1] of Byte = (
+    0,  0,  0,  0,
+    0,  0,  0,163,
+   85,255,255,255,
+   85, 85,255,255,
+  255, 85, 85,255,
+  170,  0,170,255,
+   85, 85, 85,255,
+    0,  0,  0,255,
+    0,  0,170,255
+);
+
+
+var
+  curtexid: GLuint = 0;
+
+procedure createCursorTexture ();
+var
+  tex, tpp: PByte;
+  c: Integer;
+  x, y: Integer;
+begin
+  if (curtexid <> 0) then exit; //begin glDeleteTextures(1, @curtexid); curtexid := 0; end;
+
+  GetMem(tex, curWidth*curHeight*4);
+
+  tpp := tex;
+  for y := 0 to curHeight-1 do
+  begin
+    for x := 0 to curWidth-1 do
+    begin
+      c := cursorImg[y*curWidth+x]*4;
+      tpp^ := cursorPal[c+0]; Inc(tpp);
+      tpp^ := cursorPal[c+1]; Inc(tpp);
+      tpp^ := cursorPal[c+2]; Inc(tpp);
+      tpp^ := cursorPal[c+3]; Inc(tpp);
+    end;
+  end;
+
+  glGenTextures(1, @curtexid);
+  if (curtexid = 0) then raise Exception.Create('can''t create Holmes texture');
+
+  glBindTexture(GL_TEXTURE_2D, curtexid);
+  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+  //GLfloat[4] bclr = 0.0;
+  //glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, bclr.ptr);
+
+  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, curWidth, curHeight, 0, GL_RGBA{gltt}, GL_UNSIGNED_BYTE, tex);
+
+  //FreeMem(tex);
+end;
+
+
+procedure drawCursor ();
+begin
+  if (curtexid = 0) then createCursorTexture() else glBindTexture(GL_TEXTURE_2D, curtexid);
+  // blend it
+  glEnable(GL_BLEND);
+  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+  glEnable(GL_TEXTURE_2D);
+  // color and opacity
+  glColor4f(1, 1, 1, 0.9);
+  Dec(msX, 2);
+  glBegin(GL_QUADS);
+    glTexCoord2f(0.0, 0.0); glVertex2i(msX, msY); // top-left
+    glTexCoord2f(1.0, 0.0); glVertex2i(msX+curWidth, msY); // top-right
+    glTexCoord2f(1.0, 1.0); glVertex2i(msX+curWidth, msY+curHeight); // bottom-right
+    glTexCoord2f(0.0, 1.0); glVertex2i(msX, msY+curHeight); // bottom-left
+  glEnd();
+  Inc(msX, 2);
+  glDisable(GL_BLEND);
+  glDisable(GL_TEXTURE_2D);
+  glColor4f(1, 1, 1, 1);
+  glBindTexture(GL_TEXTURE_2D, 0);
+end;
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+procedure g_Holmes_VidModeChanged ();
+begin
+  e_WriteLog(Format('Inspector: videomode changed: %dx%d', [gScreenWidth, gScreenHeight]), MSG_NOTIFY);
+  curtexid := 0; // texture is possibly lost here, idc
+  //createCursorTexture();
+end;
+
+procedure g_Holmes_WindowFocused ();
+begin
+  msB := 0;
+  kbS := 0;
+end;
+
+procedure g_Holmes_WindowBlured ();
+begin
+end;
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+var
+  vpSet: Boolean = false;
+  vpx, vpy: Integer;
+  vpw, vph: Integer;
+  laserSet: Boolean = false;
+  laserX0, laserY0, laserX1, laserY1: Integer;
+  monMarkedUID: Integer = -1;
+
+procedure g_Holmes_plrView (viewPortX, viewPortY, viewPortW, viewPortH: Integer);
+begin
+  vpSet := true;
+  vpx := viewPortX;
+  vpy := viewPortY;
+  vpw := viewPortW;
+  vph := viewPortH;
+end;
+
+procedure g_Holmes_plrLaser (ax0, ay0, ax1, ay1: Integer);
+begin
+  laserSet := true;
+  laserX0 := ax0;
+  laserY0 := ay0;
+  laserX1 := ax1;
+  laserY1 := ay1;
+end;
+
+
+function pmsCurMapX (): Integer; inline; begin result := msX+vpx; end;
+function pmsCurMapY (): Integer; inline; begin result := msY+vpy; end;
+
+
+procedure plrDebugMouse (var ev: THMouseEvent);
+
+  function wallToggle (pan: TPanel; tag: Integer): Boolean;
+  begin
+    result := false; // don't stop
+    if pan.Enabled then g_Map_DisableWall(pan.arrIdx) else g_Map_EnableWall(pan.arrIdx);
+  end;
+
+  function monsAtDump (mon: TMonster; tag: Integer): Boolean;
+  begin
+    result := false; // don't stop
+    e_WriteLog(Format('monster #%d; UID=%d', [mon.arrIdx, mon.UID]), MSG_NOTIFY);
+    monMarkedUID := mon.UID;
+    //if pan.Enabled then g_Map_DisableWall(pan.arrIdx) else g_Map_EnableWall(pan.arrIdx);
+  end;
+
+begin
+  //e_WriteLog(Format('mouse: x=%d; y=%d; but=%d; bstate=%d', [msx, msy, but, bstate]), MSG_NOTIFY);
+  if (gPlayer1 = nil) then exit;
+  if (ev.kind <> THMouseEvent.Press) then exit;
+
+  if (ev.but = THMouseEvent.Left) then
+  begin
+    mapGrid.forEachAtPoint(pmsCurMapX, pmsCurMapY, wallToggle, (GridTagWall or GridTagDoor));
+    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;
+
+
+procedure plrDebugDraw ();
+
+  function monsCollector (mon: TMonster; tag: Integer): Boolean;
+  var
+    ex, ey: Integer;
+    mx, my, mw, mh: Integer;
+  begin
+    result := false;
+    mon.getMapBox(mx, my, mw, mh);
+    e_DrawQuad(mx, my, mx+mw-1, my+mh-1, 255, 255, 0, 96);
+    if lineAABBIntersects(laserX0, laserY0, laserX1, laserY1, mx, my, mw, mh, ex, ey) then
+    begin
+      e_DrawPoint(8, ex, ey, 0, 255, 0);
+    end;
+  end;
+
+var
+  mon: TMonster;
+  mx, my, mw, mh: Integer;
+begin
+  //e_DrawPoint(4, plrMouseX, plrMouseY, 255, 0, 255);
+  if (gPlayer1 = nil) then exit;
+
+  //e_WriteLog(Format('(%d,%d)-(%d,%d)', [laserX0, laserY0, laserX1, laserY1]), MSG_NOTIFY);
+
+  glPushMatrix();
+  glTranslatef(-vpx, -vpy, 0);
+
+  g_Mons_AlongLine(laserX0, laserY0, laserX1, laserY1, monsCollector, true);
+
+  if (monMarkedUID <> -1) then
+  begin
+    mon := g_Monsters_ByUID(monMarkedUID);
+    if (mon <> nil) then
+    begin
+      mon.getMapBox(mx, my, mw, mh);
+      e_DrawQuad(mx, my, mx+mw-1, my+mh-1, 255, 0, 0, 30);
+    end;
+  end;
+
+  //e_DrawPoint(16, laserX0, laserY0, 255, 255, 255);
+
+  glPopMatrix();
+end;
+
+
+{
+    procedure drawTileGrid ();
+    var
+      x, y: Integer;
+    begin
+      y := mapGrid.gridY0;
+      while (y < mapGrid.gridY0+mapGrid.gridHeight) do
+      begin
+        x := mapGrid.gridX0;
+        while (x < mapGrid.gridX0+mapGrid.gridWidth) do
+        begin
+          if (x+mapGrid.tileSize > vpx) and (y+mapGrid.tileSize > vpy) and
+             (x < vpx+vpw) and (y < vpy+vph) then
+          begin
+            e_DrawQuad(x, y, x+mapGrid.tileSize-1, y+mapGrid.tileSize-1, 96, 96, 96, 96);
+          end;
+          Inc(x, mapGrid.tileSize);
+        end;
+        Inc(y, mapGrid.tileSize);
+      end;
+    end;
+}
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+function g_Holmes_mouseEvent (var ev: THMouseEvent): Boolean;
+begin
+  result := true;
+  msX := ev.x;
+  msY := ev.y;
+  msB := ev.bstate;
+  kbS := ev.kstate;
+  plrDebugMouse(ev);
+end;
+
+
+function g_Holmes_KeyEvent (var ev: THKeyEvent): Boolean;
+begin
+  result := false;
+end;
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+procedure g_Holmes_Draw ();
+begin
+  glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // modify color buffer
+  glDisable(GL_STENCIL_TEST);
+  glDisable(GL_BLEND);
+  glDisable(GL_SCISSOR_TEST);
+  glDisable(GL_TEXTURE_2D);
+
+  plrDebugDraw();
+
+  drawCursor();
+end;
+
+
+end.
index 69cc9021fc74547423ced6a82f1c626c4155cb93..e72a75689012b6f2e44462e0cfd5e327f0fa2c55 100644 (file)
@@ -526,7 +526,7 @@ uses
   e_log, g_map, g_items, g_console, SysUtils, g_gfx, Math,
   g_options, g_triggers, g_menu, MAPDEF, g_game, g_grid,
   wadreader, g_main, g_monsters, CONFIG, g_language,
-  g_net, g_netmsg, g_window, GL;
+  g_net, g_netmsg, g_window, GL, g_holmes;
 
 type
   TBotProfile = record
@@ -2316,102 +2316,6 @@ begin
 end;
 
 
-var
-  plrMouseX: Integer = -666;
-  plrMouseY: Integer = -666;
-  vpx, vpy: Integer;
-  //vpw, vph: Integer;
-  laserX0, laserY0, laserX1, laserY1: Integer;
-  monMarkedUID: Integer = -1;
-
-function pmsCurMapX (): Integer; inline; begin result := plrMouseX+vpx; end;
-function pmsCurMapY (): Integer; inline; begin result := plrMouseY+vpy; end;
-
-procedure plrDebugMouse (msx, msy, but: Integer; bstate: Integer);
-
-  function wallToggle (pan: TPanel; tag: Integer): Boolean;
-  begin
-    result := false; // don't stop
-    if pan.Enabled then g_Map_DisableWall(pan.arrIdx) else g_Map_EnableWall(pan.arrIdx);
-  end;
-
-  function monsAtDump (mon: TMonster; tag: Integer): Boolean;
-  begin
-    result := false; // don't stop
-    e_WriteLog(Format('monster #%d; UID=%d', [mon.arrIdx, mon.UID]), MSG_NOTIFY);
-    monMarkedUID := mon.UID;
-    //if pan.Enabled then g_Map_DisableWall(pan.arrIdx) else g_Map_EnableWall(pan.arrIdx);
-  end;
-
-begin
-  plrMouseX := msx;
-  plrMouseY := msy;
-  //e_WriteLog(Format('mouse: x=%d; y=%d; but=%d; bstate=%d', [msx, msy, but, bstate]), MSG_NOTIFY);
-  if (gPlayer1 = nil) then exit;
-
-  if (but = MouseLeft) then
-  begin
-    mapGrid.forEachAtPoint(pmsCurMapX, pmsCurMapY, wallToggle, (GridTagWall or GridTagDoor));
-    exit;
-  end;
-
-  if (but = MouseRight) then
-  begin
-    monMarkedUID := -1;
-    e_WriteLog('===========================', MSG_NOTIFY);
-    monsGrid.forEachAtPoint(pmsCurMapX, pmsCurMapY, monsAtDump);
-    e_WriteLog('---------------------------', MSG_NOTIFY);
-    exit;
-  end;
-end;
-
-
-procedure plrDebugDrawMouse ();
-
-  function monsCollector (mon: TMonster; tag: Integer): Boolean;
-  var
-    ex, ey: Integer;
-    mx, my, mw, mh: Integer;
-  begin
-    result := false;
-    mon.getMapBox(mx, my, mw, mh);
-    e_DrawQuad(mx, my, mx+mw-1, my+mh-1, 255, 255, 0, 96);
-    if lineAABBIntersects(laserX0, laserY0, laserX1, laserY1, mx, my, mw, mh, ex, ey) then
-    begin
-      e_DrawPoint(8, ex, ey, 0, 255, 0);
-    end;
-  end;
-
-var
-  mon: TMonster;
-  mx, my, mw, mh: Integer;
-begin
-  e_DrawPoint(4, plrMouseX, plrMouseY, 255, 0, 255);
-  if (gPlayer1 = nil) then exit;
-
-  //e_WriteLog(Format('(%d,%d)-(%d,%d)', [laserX0, laserY0, laserX1, laserY1]), MSG_NOTIFY);
-
-  glPushMatrix();
-  glTranslatef(-vpx, -vpy, 0);
-
-  g_Mons_AlongLine(laserX0, laserY0, laserX1, laserY1, monsCollector, true);
-
-  if (monMarkedUID <> -1) then
-  begin
-    mon := g_Monsters_ByUID(monMarkedUID);
-    if (mon <> nil) then
-    begin
-      mon.getMapBox(mx, my, mw, mh);
-      e_DrawQuad(mx, my, mx+mw-1, my+mh-1, 255, 0, 0, 30);
-    end;
-  end;
-
-  //e_DrawPoint(16, laserX0, laserY0, 255, 255, 255);
-
-  glPopMatrix();
-end;
-
-
 procedure TPlayer.DrawAim();
   procedure drawCast (sz: Integer; ax0, ay0, ax1, ay1: Integer);
 
@@ -2438,24 +2342,13 @@ procedure TPlayer.DrawAim();
 
   var
     ex, ey: Integer;
-    //mon: TMonster;
-    //mx, my, mw, mh: Integer;
   begin
     if isValidViewPort and (self = gPlayer1) then
     begin
-      vpx := viewPortX;
-      vpy := viewPortY;
-      //vpw := viewPortW;
-      //vpy := viewPortH;
-      evMouseCB := plrDebugMouse;
-      postdrawMouse := plrDebugDrawMouse;
+      g_Holmes_plrView(viewPortX, viewPortY, viewPortW, viewPortH);
+      g_Holmes_plrLaser(ax0, ay0, ax1, ay1);
     end;
 
-    laserX0 := ax0;
-    laserY0 := ay0;
-    laserX1 := ax1;
-    laserY1 := ay1;
-
     e_DrawLine(sz, ax0, ay0, ax1, ay1, 255, 0, 0, 96);
     if (g_Map_traceToNearestWall(ax0, ay0, ax1, ay1, @ex, @ey) <> nil) then
     begin
@@ -2466,23 +2359,6 @@ procedure TPlayer.DrawAim();
       e_DrawLine(sz, ax0, ay0, ex, ey, 0, 0, 255, 96);
     end;
 
-    {
-    mon := g_Mons_ByIdx(0);
-    mon.getMapBox(mx, my, mw, mh);
-    ax1 := mx+mw div 2;
-    ay1 := my+mh div 2;
-    e_DrawLine(2, ax0, ay0, ax1, ay1, 0, 96, 96, 96);
-
-    if lineAABBIntersects(ax0, ay0, ax1, ay1, mx, my, mw, mh, ex, ey) then
-    begin
-      e_DrawLine(2, ax0, ay0, ex, ey, 255, 255, 0, 96);
-    end
-    else
-    begin
-      e_DrawLine(2, ax0, ay0, ex, ey, 255, 127, 0, 96);
-    end;
-    }
-
     drawTileGrid();
   end;
 
index f5c4618dfc59c9e32de902c998c4f82e87109861..998c681e91992f8722c847c3546e4a162afc8b78 100644 (file)
@@ -42,23 +42,6 @@ var
   gwin_k8_enable_light_experiments: Boolean = false;
 
 
-// both for but and for bstate
-const
-  MouseLeft = $0001;
-  MouseRight = $0002;
-  MouseMiddle = $0004;
-  MouseWheelUp = $0008;
-  MouseWheelDown = $0010;
-
-type
-  // but=0: motion; but <0: release, do (-but) to get MouseXXX
-  // on press, bstate will contain pressed button; on release it won't
-  TMouseHandler = procedure (x, y, but: Integer; bstate: Integer);
-
-var
-  evMouseCB: TMouseHandler = nil;
-
-
 implementation
 
 uses
@@ -66,7 +49,7 @@ uses
   SDL2, GL, GLExt, e_graphics, e_log, g_main,
   g_console, SysUtils, e_input, g_options, g_game,
   g_basic, g_textures, e_sound, g_sound, g_menu, ENet, g_net,
-  g_map, g_gfx, g_monsters;
+  g_map, g_gfx, g_monsters, g_holmes;
 
 var
   h_Wnd: PSDL_Window;
@@ -87,7 +70,8 @@ var
   ticksOverflow: Int64 = -1;
   lastTicks: Uint32 = 0; // to detect overflow
 {$ENDIF}
-  curMsButState: Integer = 0;
+  curMsButState: Word = 0;
+  curKbState: Word = 0;
   curMsX: Integer = 0;
   curMsY: Integer = 0;
 
@@ -212,6 +196,7 @@ begin
   g_Game_SetupScreenSize();
   g_Menu_Reset();
   g_Game_ClearLoading();
+  g_Holmes_VidModeChanged();
 end;
 
 function g_Window_SetSize(W, H: Word; FScreen: Boolean): Boolean;
@@ -264,6 +249,7 @@ begin
     SDL_WINDOWEVENT_MINIMIZED:
     begin
       curMsButState := 0;
+      curKbState := 0;
       if not wMinimized then
       begin
         e_ResizeWindow(0, 0);
@@ -280,6 +266,8 @@ begin
 
     SDL_WINDOWEVENT_RESIZED:
     begin
+      curMsButState := 0;
+      curKbState := 0;
       gScreenWidth := ev.data1;
       gScreenHeight := ev.data2;
       ChangeWindowSize();
@@ -296,6 +284,8 @@ begin
 
     SDL_WINDOWEVENT_MAXIMIZED:
     begin
+      curMsButState := 0;
+      curKbState := 0;
       if wMinimized then
       begin
         e_ResizeWindow(gScreenWidth, gScreenHeight);
@@ -316,6 +306,7 @@ begin
     SDL_WINDOWEVENT_RESTORED:
     begin
       curMsButState := 0;
+      curKbState := 0;
       if wMinimized then
       begin
         e_ResizeWindow(gScreenWidth, gScreenHeight);
@@ -333,16 +324,20 @@ begin
 
     SDL_WINDOWEVENT_FOCUS_GAINED:
     begin
+      curMsButState := 0;
+      curKbState := 0;
       wActivate := True;
       //e_WriteLog('window gained focus!', MSG_NOTIFY);
-      curMsButState := 0;
+      g_Holmes_WindowFocused();
     end;
 
     SDL_WINDOWEVENT_FOCUS_LOST:
     begin
+      curMsButState := 0;
+      curKbState := 0;
       wDeactivate := True;
       //e_WriteLog('window lost focus!', MSG_NOTIFY);
-      curMsButState := 0;
+      g_Holmes_WindowBlured();
     end;
   end;
 
@@ -398,29 +393,33 @@ var
   key, keychr: Word;
   uc: UnicodeChar;
   //joy: Integer;
-  but: Integer;
+  msev: THMouseEvent;
 
-  function buildBut (b: Byte): Integer;
+  function buildBut (b: Byte): Word;
   begin
     result := 0;
     case b of
-      SDL_BUTTON_LEFT: result := result or MouseLeft;
-      SDL_BUTTON_MIDDLE: result := result or MouseMiddle;
-      SDL_BUTTON_RIGHT: result := result or MouseRight;
+      SDL_BUTTON_LEFT: result := result or THMouseEvent.Left;
+      SDL_BUTTON_MIDDLE: result := result or THMouseEvent.Middle;
+      SDL_BUTTON_RIGHT: result := result or THMouseEvent.Right;
     end;
   end;
 
-  function buildButState (b: Byte): Integer;
+  procedure updateKBState ();
+  var
+    kbstate: PUint8;
   begin
-    result := 0;
-    case b of
-      SDL_BUTTON_LEFT: result := result or MouseLeft;
-      SDL_BUTTON_MIDDLE: result := result or MouseMiddle;
-      SDL_BUTTON_RIGHT: result := result or MouseRight;
-    end;
+    curKbState := 0;
+    kbstate := SDL_GetKeyboardState(nil);
+    if (kbstate[SDL_SCANCODE_LCTRL] <> 0) or (kbstate[SDL_SCANCODE_RCTRL] <> 0) then curKbState := curKbState or THKeyEvent.ModCtrl;
+    if (kbstate[SDL_SCANCODE_LALT] <> 0) or (kbstate[SDL_SCANCODE_RALT] <> 0) then curKbState := curKbState or THKeyEvent.ModAlt;
+    if (kbstate[SDL_SCANCODE_LSHIFT] <> 0) or (kbstate[SDL_SCANCODE_RSHIFT] <> 0) then curKbState := curKbState or THKeyEvent.ModShift;
   end;
+
 begin
   Result := False;
+  updateKBState();
+
   case ev.type_ of
     SDL_WINDOWEVENT:
       Result := WindowEventHandler(ev.window);
@@ -446,49 +445,53 @@ begin
       KeyPress(key);
     end;
 
-    SDL_MOUSEBUTTONDOWN:
+    SDL_MOUSEBUTTONDOWN, SDL_MOUSEBUTTONUP:
       begin
+        msev.dx := ev.button.x-curMsX;
+        msev.dy := ev.button.y-curMsY;
         curMsX := ev.button.x;
         curMsY := ev.button.y;
-        but := buildBut(ev.button.button);
-        if (but <> 0) then
+        if (ev.type_ = SDL_MOUSEBUTTONDOWN) then msev.kind := THMouseEvent.Press else msev.kind := THMouseEvent.Release;
+        msev.but := buildBut(ev.button.button);
+        msev.x := curMsX;
+        msev.y := curMsY;
+        if (msev.but <> 0) then
         begin
           // ev.button.clicks: Byte
-          curMsButState := curMsButState or but;
-          if assigned(evMouseCB) then evMouseCB(ev.button.x, ev.button.y, but, curMsButState);
-        end;
-      end;
-    SDL_MOUSEBUTTONUP:
-      begin
-        curMsX := ev.button.x;
-        curMsY := ev.button.y;
-        but := buildBut(ev.button.button);
-        if (but <> 0) then
-        begin
-          curMsButState := curMsButState and (not but);
-          if assigned(evMouseCB) then evMouseCB(ev.button.x, ev.button.y, -but, curMsButState);
+          curMsButState := curMsButState or msev.but;
+          msev.bstate := curMsButState;
+          msev.kstate := curKbState;
+          g_Holmes_mouseEvent(msev);
         end;
       end;
     SDL_MOUSEWHEEL:
       begin
-        if assigned(evMouseCB) then
+        if (ev.wheel.y <> 0) then
         begin
-          (*
-          if (ev.wheel.direction = SDL_MOUSEWHEEL_FLIPPED) then
-          begin
-            ev.wheel.x := -ev.wheel.x;
-            ev.wheel.y := -ev.wheel.y;
-          end;
-          *)
-          if (ev.wheel.y > 0) then evMouseCB(curMsX, curMsY, MouseWheelUp, curMsButState);
-          if (ev.wheel.y < 0) then evMouseCB(curMsX, curMsY, MouseWheelDown, curMsButState);
+          msev.dx := 0;
+          msev.dy := ev.wheel.y;
+          msev.kind := THMouseEvent.Press;
+          if (ev.wheel.y < 0) then msev.but := THMouseEvent.WheelUp else msev.but := THMouseEvent.WheelDown;
+          msev.x := curMsX;
+          msev.y := curMsY;
+          msev.bstate := curMsButState;
+          msev.kstate := curKbState;
+          g_Holmes_mouseEvent(msev);
         end;
       end;
     SDL_MOUSEMOTION:
       begin
-        curMsX := ev.motion.x;
-        curMsY := ev.motion.y;
-        if assigned(evMouseCB) then evMouseCB(curMsX, curMsY, 0, curMsButState);
+        msev.dx := ev.button.x-curMsX;
+        msev.dy := ev.button.y-curMsY;
+        curMsX := ev.button.x;
+        curMsY := ev.button.y;
+        msev.kind := THMouseEvent.Motion;
+        msev.but := 0;
+        msev.x := curMsX;
+        msev.y := curMsY;
+        msev.bstate := curMsButState;
+        msev.kstate := curKbState;
+        g_Holmes_mouseEvent(msev);
       end;
 
     SDL_TEXTINPUT: