]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/menu/xonotic/charmap.c
Fix weapon count when there's a complain_weapon (add it only if you don't have it!)
[xonotic/xonotic-data.pk3dir.git] / qcsrc / menu / xonotic / charmap.c
index 6966aaf481b7460b337387762e542ac171dc7a7f..686d9003467bd42b3f5a3ec9c7a029e48e68debd 100644 (file)
@@ -1,5 +1,5 @@
 #ifdef INTERFACE
-CLASS(XonoticCharmap) EXTENDS(Image)
+CLASS(XonoticCharmap) EXTENDS(Item)
        METHOD(XonoticCharmap, configureXonoticCharmap, void(entity, entity))
        METHOD(XonoticCharmap, mousePress, float(entity, vector))
        METHOD(XonoticCharmap, mouseRelease, float(entity, vector))
@@ -7,146 +7,234 @@ CLASS(XonoticCharmap) EXTENDS(Image)
        METHOD(XonoticCharmap, mouseDrag, float(entity, vector))
        METHOD(XonoticCharmap, keyDown, float(entity, float, float, float))
        METHOD(XonoticCharmap, focusLeave, void(entity))
+       METHOD(XonoticCharmap, resizeNotify, void(entity, vector, vector, vector, vector))
        METHOD(XonoticCharmap, draw, void(entity))
-       ATTRIB(XonoticCharmap, controlledTextbox, entity, NULL)
-       ATTRIB(XonoticCharmap, image, string, SKINGFX_CHARMAP)
-       ATTRIB(XonoticCharmap, image2, string, SKINGFX_CHARMAP_SELECTED)
        ATTRIB(XonoticCharmap, focusable, float, 1)
-       ATTRIB(XonoticCharmap, previouslySelectedCharacterCell, float, -1)
-       ATTRIB(XonoticCharmap, selectedCharacterCell, float, 0)
-       ATTRIB(XonoticCharmap, mouseSelectedCharacterCell, float, -1)
+
+       METHOD(XonoticCharmap, moveFocus, void(entity, vector, vector))
+       METHOD(XonoticCharmap, enterChar, void(entity))
+       ATTRIB(XonoticCharmap, inputBox, entity, NULL)
+       ATTRIB(XonoticCharmap, realFontSize, vector, '0 0 0')
+       ATTRIB(XonoticCharmap, realCellSize, vector, '0 0 0')
+       ATTRIB(XonoticCharmap, focusedCell, vector, '-1 -1 0')
+       ATTRIB(XonoticCharmap, previouslyFocusedCell, vector, '-1 -1 0')
 ENDCLASS(XonoticCharmap)
-entity makeXonoticCharmap(entity theTextbox);
+entity makeXonoticCharmap(entity controlledInputBox);
 #endif
 
 #ifdef IMPLEMENTATION
-entity makeXonoticCharmap(entity theTextbox)
+
+#define CHARMAP_COLS 14
+#define CHARMAP_ROWS 10
+
+string CHARMAP =
+       "★◆■▮▰▬◣◤◥◢◀▲▶▼"
+       "🌍🌎🌏🚀🌌👽🔫⌖❇❈←↑→↓"
+       "☠☣☢⚛⚡⚙🔥❌⚠⛔❰❱❲❳"
+       "😃😊😁😄😆😎😈😇😉😛😝😘❤ "
+       "😐😒😕😮😲😞😟😠😣😭😵😴  "
+       "\xEE\x83\xA1\xEE\x83\xA2\xEE\x83\xA3\xEE\x83\xA4\xEE\x83\xA5\xEE\x83\xA6\xEE\x83\xA7"
+       "\xEE\x83\xA8\xEE\x83\xA9\xEE\x83\xAA\xEE\x83\xAB\xEE\x83\xAC\xEE\x83\xAD\xEE\x83\xAE"
+       "\xEE\x83\xAF\xEE\x83\xB0\xEE\x83\xB1\xEE\x83\xB2\xEE\x83\xB3\xEE\x83\xB4\xEE\x83\xB5"
+       "\xEE\x83\xB6\xEE\x83\xB7\xEE\x83\xB8\xEE\x83\xB9\xEE\x83\xBA\xEE\x80\x90\xEE\x80\x91"
+       "\xEE\x82\xB0\xEE\x82\xB1\xEE\x82\xB2\xEE\x82\xB3\xEE\x82\xB4\xEE\x82\xB5\xEE\x82\xB6"
+       "\xEE\x82\xB7\xEE\x82\xB8\xEE\x82\xB9\xEE\x82\xA1\xEE\x82\xBF\xEE\x82\xA6\xEE\x82\xA5"
+       "\xEE\x83\x81\xEE\x83\x82\xEE\x83\x83\xEE\x83\x84\xEE\x83\x85\xEE\x83\x86\xEE\x83\x87"
+       "\xEE\x83\x88\xEE\x83\x89\xEE\x83\x8A\xEE\x83\x8B\xEE\x83\x8C\xEE\x83\x8D\xEE\x83\x8E"
+       "\xEE\x83\x8F\xEE\x83\x90\xEE\x83\x91\xEE\x83\x92\xEE\x83\x93\xEE\x83\x94\xEE\x83\x95"
+       "\xEE\x83\x96\xEE\x83\x97\xEE\x83\x98\xEE\x83\x99\xEE\x83\x9A\xEE\x81\x9B\xEE\x81\x9D";
+
+string charmap_cellToChar(vector cell)
+{
+       string character = substring(CHARMAP, cell_y * CHARMAP_COLS + cell_x, 1);
+
+       if (character != " ")
+               return character;
+       else
+               return "";
+}
+
+entity makeXonoticCharmap(entity controlledInputBox)
 {
        entity me;
        me = spawnXonoticCharmap();
-       me.configureXonoticCharmap(me, theTextbox);
+       me.configureXonoticCharmap(me, controlledInputBox);
        return me;
 }
 
-string CharMap_CellToChar(float c)
+void XonoticCharmap_configureXonoticCharmap(entity me, entity controlledInputBox)
 {
-       if (cvar("utf8_enable")) {
-               if(c == 13)
-                       return chr(0xE000 + 127);
-               else if(c < 32)
-                       return chr(0xE000 + c);
-               else
-                       return chr(0xE000 + c + 96);
-       } else {
-               if(c == 13)
-                       return chr(127);
-               else if(c < 32)
-                       return chr(c);
-               else
-                       return chr(c + 96);
-       }
+       me.inputBox = controlledInputBox;
+       me.realCellSize = eX / CHARMAP_COLS + eY / CHARMAP_ROWS;
 }
 
-void XonoticCharmap_configureXonoticCharmap(entity me, entity theTextbox)
+void XonoticCharmap_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
 {
-       me.controlledTextbox = theTextbox;
-       me.configureImage(me, me.image);
+       SUPER(XonoticCharmap).resizeNotify(me, relOrigin, relSize, absOrigin, absSize);
+
+       float maxFontWidth = SKINFONTSIZE_NORMAL / absSize_x;
+       float maxFontHeight = SKINFONTSIZE_NORMAL / absSize_y;
+
+       if((me.realCellSize_x * absSize_x) > (me.realCellSize_y * absSize_y))
+       {
+               me.realFontSize_x = me.realCellSize_y * absSize_y / absSize_x;
+               me.realFontSize_y = me.realCellSize_y;
+       }
+       else
+       {
+               me.realFontSize_x = me.realCellSize_x;
+               me.realFontSize_y = me.realCellSize_x * absSize_x / absSize_y;
+       }
+
+       if(me.realFontSize_x > maxFontWidth || me.realFontSize_y > maxFontHeight)
+               me.realFontSize = eX * maxFontWidth + eY * maxFontHeight;
 }
 
 float XonoticCharmap_mouseMove(entity me, vector coords)
 {
-       float x, y, c;
-       x = floor(coords_x * 16);
-       y = floor(coords_y * 10);
-       if(x < 0 || y < 0 || x >= 16 || y >= 10)
+       me.focusedCell_x = floor(coords_x * CHARMAP_COLS);
+       me.focusedCell_y = floor(coords_y * CHARMAP_ROWS);
+
+       if(me.focusedCell_x < 0 || me.focusedCell_y < 0 ||
+          me.focusedCell_x >= CHARMAP_COLS || me.focusedCell_y >= CHARMAP_ROWS)
        {
-               me.mouseSelectedCharacterCell = -1;
+               me.focusedCell = '-1 -1 0';
                return 0;
        }
-       c = y * 16 + x;
-       if(c != me.mouseSelectedCharacterCell || me.mouseSelectedCharacterCell != me.selectedCharacterCell)
-               me.mouseSelectedCharacterCell = me.selectedCharacterCell = c;
+
        return 1;
 }
+
 float XonoticCharmap_mouseDrag(entity me, vector coords)
 {
        return me.mouseMove(me, coords);
 }
+
 float XonoticCharmap_mousePress(entity me, vector coords)
 {
        me.mouseMove(me, coords);
-       if(me.mouseSelectedCharacterCell >= 0)
+
+       if(me.focusedCell_x >= 0)
        {
                me.pressed = 1;
-               me.previouslySelectedCharacterCell = me.selectedCharacterCell;
+               me.previouslyFocusedCell = me.focusedCell;
        }
+
        return 1;
 }
+
 float XonoticCharmap_mouseRelease(entity me, vector coords)
 {
        if(!me.pressed)
                return 0;
+
        me.mouseMove(me, coords);
-       if(me.selectedCharacterCell == me.previouslySelectedCharacterCell)
-               me.controlledTextbox.enterText(me.controlledTextbox, CharMap_CellToChar(me.selectedCharacterCell));
+
+       if(me.focusedCell == me.previouslyFocusedCell)
+               me.enterChar(me);
+
        me.pressed = 0;
        return 1;
 }
+
 float XonoticCharmap_keyDown(entity me, float key, float ascii, float shift)
 {
        switch(key)
        {
                case K_LEFTARROW:
                case K_KP_LEFTARROW:
-                       me.selectedCharacterCell = mod(me.selectedCharacterCell + 159, 160);
+                       me.moveFocus(me, me.focusedCell, '-1 0 0');
                        return 1;
                case K_RIGHTARROW:
                case K_KP_RIGHTARROW:
-                       me.selectedCharacterCell = mod(me.selectedCharacterCell + 1, 160);
+                       me.moveFocus(me, me.focusedCell, '1 0 0');
                        return 1;
                case K_UPARROW:
                case K_KP_UPARROW:
-                       me.selectedCharacterCell = mod(me.selectedCharacterCell + 144, 160);
+                       me.moveFocus(me, me.focusedCell, '0 -1 0');
                        return 1;
                case K_DOWNARROW:
                case K_KP_DOWNARROW:
-                       me.selectedCharacterCell = mod(me.selectedCharacterCell + 16, 160);
+                       me.moveFocus(me, me.focusedCell, '0 1 0');
                        return 1;
                case K_HOME:
                case K_KP_HOME:
-                       me.selectedCharacterCell = 0;
+                       me.focusedCell = '0 0 0';
                        return 1;
                case K_END:
                case K_KP_END:
-                       me.selectedCharacterCell = 159;
+                       me.focusedCell_x = CHARMAP_COLS - 1;
+                       me.focusedCell_y = CHARMAP_ROWS - 1;
                        return 1;
-               case K_SPACE:
                case K_ENTER:
                case K_KP_ENTER:
                case K_INS:
                case K_KP_INS:
-                       me.controlledTextbox.enterText(me.controlledTextbox, CharMap_CellToChar(me.selectedCharacterCell));
+                       me.enterChar(me);
                        return 1;
                default:
-                       return me.controlledTextbox.keyDown(me.controlledTextbox, key, ascii, shift);
+                       return me.inputBox.keyDown(me.inputBox, key, ascii, shift);
        }
 }
+
+void XonoticCharmap_moveFocus(entity me, vector initialCell, vector step)
+{
+       me.focusedCell_x = mod(me.focusedCell_x + step_x + CHARMAP_COLS, CHARMAP_COLS);
+       me.focusedCell_y = mod(me.focusedCell_y + step_y + CHARMAP_ROWS, CHARMAP_ROWS);
+
+       if(me.focusedCell != initialCell) // Recursion break
+               if(charmap_cellToChar(me.focusedCell) == "")
+                       me.moveFocus(me, initialCell, step);
+}
+
+void XonoticCharmap_enterChar(entity me)
+{
+       string character = charmap_cellToChar(me.focusedCell);
+       if(character != "")
+               me.inputBox.enterText(me.inputBox, character);
+}
+
 void XonoticCharmap_focusLeave(entity me)
 {
-       me.controlledTextbox.saveCvars(me.controlledTextbox);
+       me.inputBox.saveCvars(me.inputBox);
 }
+
 void XonoticCharmap_draw(entity me)
 {
-       if(me.focused)
+       string character;
+       vector cell, cellPos, charPos;
+       cell = '0 0 0';
+       cellPos = '0 0 0';
+       charPos = '0 0 0';
+
+       float CHAR_OFFSET_X = me.realCellSize_x / 2;
+       float CHAR_OFFSET_Y = (me.realCellSize_y - me.realFontSize_y) / 2;
+
+       for(cell_y = 0; cell_y < CHARMAP_ROWS; ++cell_y)
        {
-               if(!me.pressed || (me.selectedCharacterCell == me.previouslySelectedCharacterCell))
+               charPos_y = cell_y / CHARMAP_ROWS + CHAR_OFFSET_Y;
+               for(cell_x = 0; cell_x < CHARMAP_COLS; ++cell_x)
                {
-                       vector c;
-                       c = eX * (mod(me.selectedCharacterCell, 16) / 16.0);
-                       c += eY * (floor(me.selectedCharacterCell / 16.0) / 10.0);
-                       draw_Picture(c, me.image2, '0.0625 0.1 0', '1 1 1', 1);
+                       character = charmap_cellToChar(cell);
+
+                       if(character == "")
+                               continue;
+
+                       // Draw focused cell
+                       if(cell == me.focusedCell && me.focused)
+                       {
+                               if(!me.pressed || me.focusedCell == me.previouslyFocusedCell)
+                               {
+                                       cellPos_x = mod(me.focusedCell_x, CHARMAP_COLS) / CHARMAP_COLS;
+                                       cellPos_y = mod(me.focusedCell_y, CHARMAP_ROWS) / CHARMAP_ROWS;
+                                       draw_Fill(cellPos, me.realCellSize, SKINCOLOR_CHARMAP_FOCUS, SKINALPHA_CHARMAP_FOCUS);
+                               }
+                       }
+
+                       // Draw character
+                       charPos_x = cell_x / CHARMAP_COLS + CHAR_OFFSET_X;
+                       draw_CenterText(charPos, character, me.realFontSize, SKINCOLOR_CHARMAP_CHAR, SKINALPHA_CHARMAP_CHAR, 0);
                }
        }
-       SUPER(XonoticCharmap).draw(me);
 }
 #endif