foxygit / doom Log in
commit 73f27119add06b37dadc4a62343e1301585a828f
Author:     Simon Howard <fraggle@gmail.com>
AuthorDate: Sat Sep 24 16:30:24 2011 +0000
Commit:     Simon Howard <fraggle@gmail.com>
CommitDate: Sat Sep 24 16:30:24 2011 +0000

    Rework mouse speed box drawing code and move to common code, so that it
    can be added to other games.

    Subversion-branch: /branches/v2-branch
    Subversion-revision: 2395
---
 src/doom/d_main.c   |   2 +-
 src/doom/doomstat.h |   1 +
 src/doom/g_game.c   | 114 ++---------------------------------------
 src/i_video.c       |  30 +++++++++++
 src/i_video.h       |   1 +
 src/v_video.c       | 145 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/v_video.h       |   7 +++
 7 files changed, 188 insertions(+), 112 deletions(-)

diff --git a/src/doom/d_main.c b/src/doom/d_main.c
index 0348c39d..2784c26d 100644
--- a/src/doom/d_main.c
+++ b/src/doom/d_main.c
@@ -283,7 +283,7 @@ void D_Display (void)
     {
         // Box showing current mouse speed

-        G_DrawMouseSpeedBox();
+        V_DrawMouseSpeedBox(testcontrols_mousespeed);
     }

     menuactivestate = menuactive;
diff --git a/src/doom/doomstat.h b/src/doom/doomstat.h
index cd626fdf..b0cff548 100644
--- a/src/doom/doomstat.h
+++ b/src/doom/doomstat.h
@@ -162,6 +162,7 @@ extern	int		viewwidth;
 extern	int		scaledviewwidth;

 extern  boolean         testcontrols;
+extern  int             testcontrols_mousespeed;



diff --git a/src/doom/g_game.c b/src/doom/g_game.c
index d7f86b20..433e35e3 100644
--- a/src/doom/g_game.c
+++ b/src/doom/g_game.c
@@ -152,6 +152,9 @@ boolean         singledemo;            	// quit after playing a demo from cmdlin
 boolean         precache = true;        // if true, load all graphics at start

 boolean         testcontrols = false;    // Invoked by setup to test controls
+int             testcontrols_mousespeed;
+
+

 wbstartstruct_t wminfo;               	// parms for world map / intermission

@@ -229,8 +232,6 @@ static boolean *joybuttons = &joyarray[1];		// allow [-1]
 static int      savegameslot;
 static char     savedescription[32];

-static int      testcontrols_mousespeed;
-
 #define	BODYQUESIZE	32

 mobj_t*		bodyque[BODYQUESIZE];
@@ -239,115 +240,6 @@ int		bodyqueslot;
 int             vanilla_savegame_limit = 1;
 int             vanilla_demo_limit = 1;

-
-#define MOUSE_SPEED_BOX_WIDTH 16
-#define COLOR_RED    0xb0
-#define COLOR_BLACK  0x00
-#define COLOR_WHITE  0x04
-#define COLOR_YELLOW 0xe7
-
-void G_DrawMouseSpeedBox(void)
-{
-    extern int usemouse;
-    int i;
-    int box_x, box_y;
-    int original_speed;
-    int x, y;
-    int redline_x;
-    int linelen;
-    char *lumpname;
-    int color;
-
-    // If the mouse is turned off or acceleration is turned off, don't
-    // draw the box at all.
-
-    if (!usemouse || fabs(mouse_acceleration - 1) < 0.01)
-    {
-        return;
-    }
-
-    // Calculate box position
-
-    box_x = SCREENWIDTH - MOUSE_SPEED_BOX_WIDTH * 8;
-    box_y = SCREENHEIGHT - 9;
-
-    // Draw the box.
-
-    x = box_x;
-
-    for (i=0; i<MOUSE_SPEED_BOX_WIDTH; ++i)
-    {
-        if (i == 0)
-        {
-            lumpname = "M_LSLEFT";
-        }
-        else if (i == MOUSE_SPEED_BOX_WIDTH - 1)
-        {
-            lumpname = "M_LSRGHT";
-        }
-        else
-        {
-            lumpname = "M_LSCNTR";
-        }
-
-        V_DrawPatchDirect(x, box_y,
-                          W_CacheLumpName(DEH_String(lumpname), PU_CACHE));
-        x += 8;
-    }
-
-    // Calculate the position of the red line.  This is 1/3 of the way
-    // along the box.
-
-    redline_x = (MOUSE_SPEED_BOX_WIDTH / 3) * 8;
-
-    // Undo acceleration and get back the original mouse speed
-
-    if (testcontrols_mousespeed < mouse_threshold)
-    {
-        original_speed = testcontrols_mousespeed;
-    }
-    else
-    {
-        original_speed = testcontrols_mousespeed - mouse_threshold;
-        original_speed = (int) (original_speed / mouse_acceleration);
-        original_speed += mouse_threshold;
-    }
-
-    // Calculate line length
-
-    linelen = (original_speed * redline_x) / mouse_threshold;
-
-    // Draw horizontal "thermometer"
-
-    for (x=0; x<(MOUSE_SPEED_BOX_WIDTH - 1) * 8; ++x)
-    {
-        if (x < linelen)
-        {
-            if (x < redline_x)
-            {
-                color = COLOR_WHITE;
-            }
-            else
-            {
-                color = COLOR_YELLOW;
-            }
-        }
-        else
-        {
-            color = COLOR_BLACK;
-        }
-
-        I_VideoBuffer[(box_y - 4) * SCREENWIDTH + box_x + x + 1] = color;
-    }
-
-    // Draw red line
-
-    for (y=box_y - 8; y<box_y; ++y)
-    {
-        I_VideoBuffer[y * SCREENWIDTH + box_x + redline_x] = COLOR_RED;
-    }
-}
-
 int G_CmdChecksum (ticcmd_t* cmd)
 {
     size_t		i;
diff --git a/src/i_video.c b/src/i_video.c
index 925bf3dc..dfb8086e 100644
--- a/src/i_video.c
+++ b/src/i_video.c
@@ -1131,6 +1131,36 @@ void I_SetPalette (byte *doompalette)
     palette_to_set = true;
 }

+// Given an RGB value, find the closest matching palette index.
+
+int I_GetPaletteIndex(int r, int g, int b)
+{
+    int best, best_diff, diff;
+    int i;
+
+    best = 0; best_diff = INT_MAX;
+
+    for (i = 0; i < 256; ++i)
+    {
+        diff = (r - palette[i].r) * (r - palette[i].r)
+             + (g - palette[i].g) * (g - palette[i].g)
+             + (b - palette[i].b) * (b - palette[i].b);
+
+        if (diff < best_diff)
+        {
+            best = i;
+            best_diff = diff;
+        }
+
+        if (diff == 0)
+        {
+            break;
+        }
+    }
+
+    return best;
+}
+
 //
 // Set the window title
 //
diff --git a/src/i_video.h b/src/i_video.h
index c3c50c4b..272ffb08 100644
--- a/src/i_video.h
+++ b/src/i_video.h
@@ -83,6 +83,7 @@ void I_ShutdownGraphics(void);

 // Takes full 8 bit values.
 void I_SetPalette (byte* palette);
+int I_GetPaletteIndex(int r, int g, int b);

 void I_UpdateNoBlit (void);
 void I_FinishUpdate (void);
diff --git a/src/v_video.c b/src/v_video.c
index d18dbb7a..97d40ec0 100644
--- a/src/v_video.c
+++ b/src/v_video.c
@@ -524,6 +524,61 @@ void V_DrawBlock(int x, int y, int width, int height, byte *src)
     }
 }

+void V_DrawFilledBox(int x, int y, int w, int h, int c)
+{
+    uint8_t *buf, *buf1;
+    int x1, y1;
+
+    buf = I_VideoBuffer + SCREENWIDTH * y + x;
+
+    for (y1 = 0; y1 < h; ++y1)
+    {
+        buf1 = buf;
+
+        for (x1 = 0; x1 < w; ++x1)
+        {
+            *buf1++ = c;
+        }
+
+        buf += SCREENWIDTH;
+    }
+}
+
+void V_DrawHorizLine(int x, int y, int w, int c)
+{
+    uint8_t *buf;
+    int x1;
+
+    buf = I_VideoBuffer + SCREENWIDTH * y + x;
+
+    for (x1 = 0; x1 < w; ++x1)
+    {
+        *buf++ = c;
+    }
+}
+
+void V_DrawVertLine(int x, int y, int h, int c)
+{
+    uint8_t *buf;
+    int y1;
+
+    buf = I_VideoBuffer + SCREENWIDTH * y + x;
+
+    for (y1 = 0; y1 < h; ++y1)
+    {
+        *buf = c;
+        buf += SCREENWIDTH;
+    }
+}
+
+void V_DrawBox(int x, int y, int w, int h, int c)
+{
+    V_DrawHorizLine(x, y, w, c);
+    V_DrawHorizLine(x, y+h-1, w, c);
+    V_DrawVertLine(x, y, h, c);
+    V_DrawVertLine(x+w-1, y, h, c);
+}
+
 //
 // Draw a "raw" screen (lump containing raw data to blit directly
 // to the screen)
@@ -678,3 +733,93 @@ void V_ScreenShot(char *format)
                  W_CacheLumpName (DEH_String("PLAYPAL"), PU_CACHE));
 }

+#define MOUSE_SPEED_BOX_WIDTH  120
+#define MOUSE_SPEED_BOX_HEIGHT 9
+
+void V_DrawMouseSpeedBox(int speed)
+{
+    extern int usemouse;
+    int bgcolor, bordercolor, red, black, white, yellow;
+    int box_x, box_y;
+    int original_speed;
+    int redline_x;
+    int linelen;
+
+    // Get palette indices for colors for widget. These depend on the
+    // palette of the game being played.
+
+    bgcolor = I_GetPaletteIndex(0x77, 0x77, 0x77);
+    bordercolor = I_GetPaletteIndex(0x55, 0x55, 0x55);
+    red = I_GetPaletteIndex(0xff, 0x00, 0x00);
+    black = I_GetPaletteIndex(0x00, 0x00, 0x00);
+    yellow = I_GetPaletteIndex(0xff, 0xff, 0x00);
+    white = I_GetPaletteIndex(0xff, 0xff, 0xff);
+
+    // If the mouse is turned off or acceleration is turned off, don't
+    // draw the box at all.
+
+    if (!usemouse || fabs(mouse_acceleration - 1) < 0.01)
+    {
+        return;
+    }
+
+    // Calculate box position
+
+    box_x = SCREENWIDTH - MOUSE_SPEED_BOX_WIDTH - 10;
+    box_y = 10;
+
+    V_DrawFilledBox(box_x, box_y,
+                    MOUSE_SPEED_BOX_WIDTH, MOUSE_SPEED_BOX_HEIGHT, bgcolor);
+    V_DrawBox(box_x, box_y,
+              MOUSE_SPEED_BOX_WIDTH, MOUSE_SPEED_BOX_HEIGHT, bordercolor);
+
+    // Calculate the position of the red line.  This is 1/3 of the way
+    // along the box.
+
+    redline_x = MOUSE_SPEED_BOX_WIDTH / 3;
+
+    // Undo acceleration and get back the original mouse speed
+
+    if (speed < mouse_threshold)
+    {
+        original_speed = speed;
+    }
+    else
+    {
+        original_speed = speed - mouse_threshold;
+        original_speed = (int) (original_speed / mouse_acceleration);
+        original_speed += mouse_threshold;
+    }
+
+    // Calculate line length
+
+    linelen = (original_speed * redline_x) / mouse_threshold;
+
+    // Draw horizontal "thermometer"
+
+    if (linelen > MOUSE_SPEED_BOX_WIDTH - 1)
+    {
+        linelen = MOUSE_SPEED_BOX_WIDTH - 1;
+    }
+
+    V_DrawHorizLine(box_x + 1, box_y + 4, MOUSE_SPEED_BOX_WIDTH - 2, black);
+
+    if (linelen < redline_x)
+    {
+        V_DrawHorizLine(box_x + 1, box_y + MOUSE_SPEED_BOX_HEIGHT / 2,
+                      linelen, white);
+    }
+    else
+    {
+        V_DrawHorizLine(box_x + 1, box_y + MOUSE_SPEED_BOX_HEIGHT / 2,
+                        redline_x, white);
+        V_DrawHorizLine(box_x + redline_x, box_y + MOUSE_SPEED_BOX_HEIGHT / 2,
+                        linelen - redline_x, yellow);
+    }
+
+    // Draw red line
+
+    V_DrawVertLine(box_x + redline_x, box_y + 1,
+                 MOUSE_SPEED_BOX_HEIGHT - 2, red);
+}
+
diff --git a/src/v_video.h b/src/v_video.h
index 01791d6c..93a46552 100644
--- a/src/v_video.h
+++ b/src/v_video.h
@@ -76,6 +76,11 @@ void V_DrawBlock(int x, int y, int width, int height, byte *src);

 void V_MarkRect(int x, int y, int width, int height);

+void V_DrawFilledBox(int x, int y, int w, int h, int c);
+void V_DrawHorizLine(int x, int y, int w, int c);
+void V_DrawVertLine(int x, int y, int h, int c);
+void V_DrawBox(int x, int y, int w, int h, int c);
+
 // Draw a raw screen lump

 void V_DrawRawScreen(byte *raw);
@@ -105,5 +110,7 @@ void V_LoadTintTable(void);

 void V_LoadXlaTable(void);

+void V_DrawMouseSpeedBox(int speed);
+
 #endif