mirror of
				https://github.com/coop-deluxe/sm64coopdx.git
				synced 2025-10-30 08:01:01 +00:00 
			
		
		
		
	Compare commits
	
		
			16 commits
		
	
	
		
			2d4651e74f
			...
			632977dea6
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 632977dea6 | ||
|   | 5fd55ffac1 | ||
|   | 9f7ad0f93e | ||
|   | b0ebaeed63 | ||
|   | b2f029bea7 | ||
|   | 6c48a5c115 | ||
|   | e16e2b4d5c | ||
|   | 5812dad90a | ||
|   | 5c939c6ded | ||
|   | 88a7b246ab | ||
|   | 9138125c8a | ||
|   | 2decea5693 | ||
|   | 1805004135 | ||
|   | 09d29d8e98 | ||
|   | 7990d05ccb | ||
|   | f137f77826 | 
					 33 changed files with 697 additions and 91 deletions
				
			
		|  | @ -3914,8 +3914,14 @@ function djui_hud_get_raw_mouse_y() | ||||||
|     -- ... |     -- ... | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
|  | --- @return boolean | ||||||
|  | --- Checks if the cursor is locked to the window | ||||||
|  | function djui_hud_is_mouse_locked() | ||||||
|  |     -- ... | ||||||
|  | end | ||||||
|  | 
 | ||||||
| --- @param locked boolean | --- @param locked boolean | ||||||
| --- Sets if the cursor is hidden and constrainted to the window | --- Locks (or unlocks) the cursor to the window | ||||||
| function djui_hud_set_mouse_locked(locked) | function djui_hud_set_mouse_locked(locked) | ||||||
|     -- ... |     -- ... | ||||||
| end | end | ||||||
|  | @ -3954,12 +3960,12 @@ end | ||||||
| --- @param y number | --- @param y number | ||||||
| --- @param width number | --- @param width number | ||||||
| --- @param height number | --- @param height number | ||||||
| --- Sets the viewport to the specified position and size, this will resize | --- Sets the viewport to the specified position and size, this will resize any subsequent DJUI graphics | ||||||
| function djui_hud_set_viewport(x, y, width, height) | function djui_hud_set_viewport(x, y, width, height) | ||||||
|     -- ... |     -- ... | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
| --- put the description here | --- Resets the viewport to a fullscreen state | ||||||
| function djui_hud_reset_viewport() | function djui_hud_reset_viewport() | ||||||
|     -- ... |     -- ... | ||||||
| end | end | ||||||
|  | @ -3968,12 +3974,12 @@ end | ||||||
| --- @param y number | --- @param y number | ||||||
| --- @param width number | --- @param width number | ||||||
| --- @param height number | --- @param height number | ||||||
| --- put the description here | --- Sets the scissor rectangle to the specified position and size, this will cut off any subsequent DJUI graphics not within the rectangle | ||||||
| function djui_hud_set_scissor(x, y, width, height) | function djui_hud_set_scissor(x, y, width, height) | ||||||
|     -- ... |     -- ... | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
| --- put the description here | --- Resets the scissor rectangle to a fullscreen state | ||||||
| function djui_hud_reset_scissor() | function djui_hud_reset_scissor() | ||||||
|     -- ... |     -- ... | ||||||
| end | end | ||||||
|  | @ -6443,14 +6449,14 @@ end | ||||||
| 
 | 
 | ||||||
| --- @param m MarioState | --- @param m MarioState | ||||||
| --- @return integer | --- @return integer | ||||||
| --- Performs a full Mario stationary physics step (4 substeps) and returns an `GROUND_STEP_*` result | --- Performs a full Mario stationary physics step (4 substeps) and returns a `GROUND_STEP_*` result | ||||||
| function stationary_ground_step(m) | function stationary_ground_step(m) | ||||||
|     -- ... |     -- ... | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
| --- @param m MarioState | --- @param m MarioState | ||||||
| --- @return integer | --- @return integer | ||||||
| --- Performs a full Mario ground physics step (4 substeps) and returns an `GROUND_STEP_*` result | --- Performs a full Mario ground physics step (4 substeps) and returns a `GROUND_STEP_*` result | ||||||
| function perform_ground_step(m) | function perform_ground_step(m) | ||||||
|     -- ... |     -- ... | ||||||
| end | end | ||||||
|  | @ -10029,7 +10035,7 @@ end | ||||||
| 
 | 
 | ||||||
| --- @param player integer | --- @param player integer | ||||||
| --- @return integer | --- @return integer | ||||||
| --- Gets the tempo of `player` | --- Gets the `tempo` of `player` | ||||||
| function sequence_player_get_tempo(player) | function sequence_player_get_tempo(player) | ||||||
|     -- ... |     -- ... | ||||||
| end | end | ||||||
|  | @ -10043,7 +10049,7 @@ end | ||||||
| 
 | 
 | ||||||
| --- @param player integer | --- @param player integer | ||||||
| --- @return integer | --- @return integer | ||||||
| --- Gets the tempoAcc (tempo accumulation) of `player` | --- Gets the `tempoAcc` (tempo accumulation) of `player` | ||||||
| function sequence_player_get_tempo_acc(player) | function sequence_player_get_tempo_acc(player) | ||||||
|     -- ... |     -- ... | ||||||
| end | end | ||||||
|  | @ -10057,7 +10063,7 @@ end | ||||||
| 
 | 
 | ||||||
| --- @param player integer | --- @param player integer | ||||||
| --- @return integer | --- @return integer | ||||||
| --- Gets the transposition (pitch) of `player` | --- Gets the `transposition` (pitch) of `player` | ||||||
| function sequence_player_get_transposition(player) | function sequence_player_get_transposition(player) | ||||||
|     -- ... |     -- ... | ||||||
| end | end | ||||||
|  |  | ||||||
|  | @ -3140,10 +3140,31 @@ Returns the y coordinate of the mouse relative to the screen | ||||||
| 
 | 
 | ||||||
| <br /> | <br /> | ||||||
| 
 | 
 | ||||||
|  | ## [djui_hud_is_mouse_locked](#djui_hud_is_mouse_locked) | ||||||
|  | 
 | ||||||
|  | ### Description | ||||||
|  | Checks if the cursor is locked to the window | ||||||
|  | 
 | ||||||
|  | ### Lua Example | ||||||
|  | `local booleanValue = djui_hud_is_mouse_locked()` | ||||||
|  | 
 | ||||||
|  | ### Parameters | ||||||
|  | - None | ||||||
|  | 
 | ||||||
|  | ### Returns | ||||||
|  | - `boolean` | ||||||
|  | 
 | ||||||
|  | ### C Prototype | ||||||
|  | `bool djui_hud_is_mouse_locked(void);` | ||||||
|  | 
 | ||||||
|  | [:arrow_up_small:](#) | ||||||
|  | 
 | ||||||
|  | <br /> | ||||||
|  | 
 | ||||||
| ## [djui_hud_set_mouse_locked](#djui_hud_set_mouse_locked) | ## [djui_hud_set_mouse_locked](#djui_hud_set_mouse_locked) | ||||||
| 
 | 
 | ||||||
| ### Description | ### Description | ||||||
| Sets if the cursor is hidden and constrainted to the window | Locks (or unlocks) the cursor to the window | ||||||
| 
 | 
 | ||||||
| ### Lua Example | ### Lua Example | ||||||
| `djui_hud_set_mouse_locked(locked)` | `djui_hud_set_mouse_locked(locked)` | ||||||
|  | @ -3271,7 +3292,7 @@ Returns the amount scrolled vertically (-down/up+) | ||||||
| ## [djui_hud_set_viewport](#djui_hud_set_viewport) | ## [djui_hud_set_viewport](#djui_hud_set_viewport) | ||||||
| 
 | 
 | ||||||
| ### Description | ### Description | ||||||
| Sets the viewport to the specified position and size, this will resize | Sets the viewport to the specified position and size, this will resize any subsequent DJUI graphics | ||||||
| 
 | 
 | ||||||
| ### Lua Example | ### Lua Example | ||||||
| `djui_hud_set_viewport(x, y, width, height)` | `djui_hud_set_viewport(x, y, width, height)` | ||||||
|  | @ -3297,7 +3318,7 @@ Sets the viewport to the specified position and size, this will resize | ||||||
| ## [djui_hud_reset_viewport](#djui_hud_reset_viewport) | ## [djui_hud_reset_viewport](#djui_hud_reset_viewport) | ||||||
| 
 | 
 | ||||||
| ### Description | ### Description | ||||||
| put the description here | Resets the viewport to a fullscreen state | ||||||
| 
 | 
 | ||||||
| ### Lua Example | ### Lua Example | ||||||
| `djui_hud_reset_viewport()` | `djui_hud_reset_viewport()` | ||||||
|  | @ -3318,7 +3339,7 @@ put the description here | ||||||
| ## [djui_hud_set_scissor](#djui_hud_set_scissor) | ## [djui_hud_set_scissor](#djui_hud_set_scissor) | ||||||
| 
 | 
 | ||||||
| ### Description | ### Description | ||||||
| put the description here | Sets the scissor rectangle to the specified position and size, this will cut off any subsequent DJUI graphics not within the rectangle | ||||||
| 
 | 
 | ||||||
| ### Lua Example | ### Lua Example | ||||||
| `djui_hud_set_scissor(x, y, width, height)` | `djui_hud_set_scissor(x, y, width, height)` | ||||||
|  | @ -3344,7 +3365,7 @@ put the description here | ||||||
| ## [djui_hud_reset_scissor](#djui_hud_reset_scissor) | ## [djui_hud_reset_scissor](#djui_hud_reset_scissor) | ||||||
| 
 | 
 | ||||||
| ### Description | ### Description | ||||||
| put the description here | Resets the scissor rectangle to a fullscreen state | ||||||
| 
 | 
 | ||||||
| ### Lua Example | ### Lua Example | ||||||
| `djui_hud_reset_scissor()` | `djui_hud_reset_scissor()` | ||||||
|  |  | ||||||
|  | @ -4070,7 +4070,7 @@ Sets all of Mario's velocity variables to 0 and sets his Y position to the floor | ||||||
| ## [stationary_ground_step](#stationary_ground_step) | ## [stationary_ground_step](#stationary_ground_step) | ||||||
| 
 | 
 | ||||||
| ### Description | ### Description | ||||||
| Performs a full Mario stationary physics step (4 substeps) and returns an `GROUND_STEP_*` result | Performs a full Mario stationary physics step (4 substeps) and returns a `GROUND_STEP_*` result | ||||||
| 
 | 
 | ||||||
| ### Lua Example | ### Lua Example | ||||||
| `local integerValue = stationary_ground_step(m)` | `local integerValue = stationary_ground_step(m)` | ||||||
|  | @ -4093,7 +4093,7 @@ Performs a full Mario stationary physics step (4 substeps) and returns an `GROUN | ||||||
| ## [perform_ground_step](#perform_ground_step) | ## [perform_ground_step](#perform_ground_step) | ||||||
| 
 | 
 | ||||||
| ### Description | ### Description | ||||||
| Performs a full Mario ground physics step (4 substeps) and returns an `GROUND_STEP_*` result | Performs a full Mario ground physics step (4 substeps) and returns a `GROUND_STEP_*` result | ||||||
| 
 | 
 | ||||||
| ### Lua Example | ### Lua Example | ||||||
| `local integerValue = perform_ground_step(m)` | `local integerValue = perform_ground_step(m)` | ||||||
|  |  | ||||||
|  | @ -5276,7 +5276,7 @@ Returns the current sound mode (e.g., stereo, mono) stored in the save file. Use | ||||||
| ## [sequence_player_get_tempo](#sequence_player_get_tempo) | ## [sequence_player_get_tempo](#sequence_player_get_tempo) | ||||||
| 
 | 
 | ||||||
| ### Description | ### Description | ||||||
| Gets the tempo of `player` | Gets the `tempo` of `player` | ||||||
| 
 | 
 | ||||||
| ### Lua Example | ### Lua Example | ||||||
| `local integerValue = sequence_player_get_tempo(player)` | `local integerValue = sequence_player_get_tempo(player)` | ||||||
|  | @ -5323,7 +5323,7 @@ Sets the `tempo` of `player`. Resets when another sequence is played | ||||||
| ## [sequence_player_get_tempo_acc](#sequence_player_get_tempo_acc) | ## [sequence_player_get_tempo_acc](#sequence_player_get_tempo_acc) | ||||||
| 
 | 
 | ||||||
| ### Description | ### Description | ||||||
| Gets the tempoAcc (tempo accumulation) of `player` | Gets the `tempoAcc` (tempo accumulation) of `player` | ||||||
| 
 | 
 | ||||||
| ### Lua Example | ### Lua Example | ||||||
| `local integerValue = sequence_player_get_tempo_acc(player)` | `local integerValue = sequence_player_get_tempo_acc(player)` | ||||||
|  | @ -5370,7 +5370,7 @@ Sets the `tempoAcc` (tempo accumulation) of `player`. Resets when another sequen | ||||||
| ## [sequence_player_get_transposition](#sequence_player_get_transposition) | ## [sequence_player_get_transposition](#sequence_player_get_transposition) | ||||||
| 
 | 
 | ||||||
| ### Description | ### Description | ||||||
| Gets the transposition (pitch) of `player` | Gets the `transposition` (pitch) of `player` | ||||||
| 
 | 
 | ||||||
| ### Lua Example | ### Lua Example | ||||||
| `local integerValue = sequence_player_get_transposition(player)` | `local integerValue = sequence_player_get_transposition(player)` | ||||||
|  |  | ||||||
|  | @ -770,6 +770,7 @@ | ||||||
|    - [djui_hud_get_mouse_y](functions-3.md#djui_hud_get_mouse_y) |    - [djui_hud_get_mouse_y](functions-3.md#djui_hud_get_mouse_y) | ||||||
|    - [djui_hud_get_raw_mouse_x](functions-3.md#djui_hud_get_raw_mouse_x) |    - [djui_hud_get_raw_mouse_x](functions-3.md#djui_hud_get_raw_mouse_x) | ||||||
|    - [djui_hud_get_raw_mouse_y](functions-3.md#djui_hud_get_raw_mouse_y) |    - [djui_hud_get_raw_mouse_y](functions-3.md#djui_hud_get_raw_mouse_y) | ||||||
|  |    - [djui_hud_is_mouse_locked](functions-3.md#djui_hud_is_mouse_locked) | ||||||
|    - [djui_hud_set_mouse_locked](functions-3.md#djui_hud_set_mouse_locked) |    - [djui_hud_set_mouse_locked](functions-3.md#djui_hud_set_mouse_locked) | ||||||
|    - [djui_hud_get_mouse_buttons_down](functions-3.md#djui_hud_get_mouse_buttons_down) |    - [djui_hud_get_mouse_buttons_down](functions-3.md#djui_hud_get_mouse_buttons_down) | ||||||
|    - [djui_hud_get_mouse_buttons_pressed](functions-3.md#djui_hud_get_mouse_buttons_pressed) |    - [djui_hud_get_mouse_buttons_pressed](functions-3.md#djui_hud_get_mouse_buttons_pressed) | ||||||
|  |  | ||||||
|  | @ -58,6 +58,8 @@ MOD_DESC = "/moderator [JMÉNO|ID] - Hráč bude moci používat příkazy jako | ||||||
| NAMETAGS_DESC = "/nametags [show-tag|show-health] - Změňte, zda vidíte svůj vlastní štítek a zda vidíte zdraví" | NAMETAGS_DESC = "/nametags [show-tag|show-health] - Změňte, zda vidíte svůj vlastní štítek a zda vidíte zdraví" | ||||||
| UNRECOGNIZED = "Neznámý příkaz." | UNRECOGNIZED = "Neznámý příkaz." | ||||||
| MOD_GRANTED = "\\#fff982\\Jste nyní moderátor." | MOD_GRANTED = "\\#fff982\\Jste nyní moderátor." | ||||||
|  | ALL_COMMANDS = "Všechny příkazy" | ||||||
|  | TAB_COMPLETE_INFO = "Stiskni TAB pro automatické dokončení příkazů, Shift+TAB naviguje zpět" | ||||||
| 
 | 
 | ||||||
| [MENU] | [MENU] | ||||||
| BACK = "Zpět" | BACK = "Zpět" | ||||||
|  | @ -105,6 +107,7 @@ DEADZONE = "Deadzone" | ||||||
| RUMBLE_STRENGTH = "Síla vibrace" | RUMBLE_STRENGTH = "Síla vibrace" | ||||||
| 
 | 
 | ||||||
| CHAT = "Chat" | CHAT = "Chat" | ||||||
|  | CHAT_COMMAND = "Chat (Příkaz)" | ||||||
| PLAYERS = "Hráči" | PLAYERS = "Hráči" | ||||||
| D_UP = "D-Pad nahoru" | D_UP = "D-Pad nahoru" | ||||||
| D_DOWN = "D-Pad dolů" | D_DOWN = "D-Pad dolů" | ||||||
|  | @ -319,7 +322,17 @@ DEBUG_ERRORS = "Debug Errors" | ||||||
| MISC_TITLE = "JINE" | MISC_TITLE = "JINE" | ||||||
| PAUSE_IN_SINGLEPLAYER = "Pauza v hře s jedním hráčem" | PAUSE_IN_SINGLEPLAYER = "Pauza v hře s jedním hráčem" | ||||||
| DISABLE_POPUPS = "Vypnout vyskakovací okna" | DISABLE_POPUPS = "Vypnout vyskakovací okna" | ||||||
| USE_STANDARD_KEY_BINDINGS_CHAT = "Klasické ovládání chatu" | USE_STANDARD_KEY_BINDINGS_CHAT = "Použít ovládání chatu Terminal/CMD" | ||||||
|  | CHAT_WIDTH = "Šířka chatu" | ||||||
|  | CHAT_WIDTH_TINY = "Drobná" | ||||||
|  | CHAT_WIDTH_VERY_SMALL = "Velmi malá" | ||||||
|  | CHAT_WIDTH_SMALL = "Malá" | ||||||
|  | CHAT_WIDTH_NORMAL = "Normální" | ||||||
|  | CHAT_WIDTH_BIG = "Velká" | ||||||
|  | CHAT_WIDTH_VERY_BIG = "Velmi velká" | ||||||
|  | CHAT_WIDTH_HUGE = "Obrovská" | ||||||
|  | CHAT_CHAR_COUNTER = "Zobrazit počitadlo znaků chatu" | ||||||
|  | DISABLE_CHAT_WHEN_CLOSED = "Skrýt chat, když je zavřený" | ||||||
| MENU_OPTIONS = "Nastavení hlavního menu" | MENU_OPTIONS = "Nastavení hlavního menu" | ||||||
| INFORMATION = "Informace" | INFORMATION = "Informace" | ||||||
| DEBUG = "Debug" | DEBUG = "Debug" | ||||||
|  |  | ||||||
|  | @ -58,6 +58,8 @@ MOD_DESC = "/moderator [NAAM|ID] - Geeft deze spelere de toestemming om commando | ||||||
| NAMETAGS_DESC = "/nametags [show-tag|show-health] - Verander of je je eigen naamtag ziet en of je gezondheid ziet" | NAMETAGS_DESC = "/nametags [show-tag|show-health] - Verander of je je eigen naamtag ziet en of je gezondheid ziet" | ||||||
| UNRECOGNIZED = "onbekent Chat commando." | UNRECOGNIZED = "onbekent Chat commando." | ||||||
| MOD_GRANTED = "\\#fff982\\Je bent nu een Moderator." | MOD_GRANTED = "\\#fff982\\Je bent nu een Moderator." | ||||||
|  | ALL_COMMANDS = "Alle commando's" | ||||||
|  | TAB_COMPLETE_INFO = "Druk op TAB om opdrachten automatisch aan te vullen, gebruik Shift+TAB om terug te gaan" | ||||||
| 
 | 
 | ||||||
| [MENU] | [MENU] | ||||||
| BACK = "Terug" | BACK = "Terug" | ||||||
|  | @ -105,6 +107,7 @@ DEADZONE = "Doode-zone" | ||||||
| RUMBLE_STRENGTH = "Rommel Kracht" | RUMBLE_STRENGTH = "Rommel Kracht" | ||||||
| 
 | 
 | ||||||
| CHAT = "Chat" | CHAT = "Chat" | ||||||
|  | CHAT_COMMAND = "Chat (Commando)" | ||||||
| PLAYERS = "Spelers" | PLAYERS = "Spelers" | ||||||
| D_UP = "D Omhoog" | D_UP = "D Omhoog" | ||||||
| D_DOWN = "D Naar Beneden" | D_DOWN = "D Naar Beneden" | ||||||
|  | @ -319,7 +322,17 @@ DEBUG_ERRORS = "Debug Errors" | ||||||
| MISC_TITLE = "MISC" | MISC_TITLE = "MISC" | ||||||
| PAUSE_IN_SINGLEPLAYER = "Pauzeer in een speler" | PAUSE_IN_SINGLEPLAYER = "Pauzeer in een speler" | ||||||
| DISABLE_POPUPS = "Popups uitzetten" | DISABLE_POPUPS = "Popups uitzetten" | ||||||
| USE_STANDARD_KEY_BINDINGS_CHAT = "Klassieke chatbediening" | USE_STANDARD_KEY_BINDINGS_CHAT = "Terminal/CMD Chatbox besturingen gebruiken" | ||||||
|  | CHAT_WIDTH = "Chatbreedte" | ||||||
|  | CHAT_WIDTH_TINY = "Zeer klein" | ||||||
|  | CHAT_WIDTH_VERY_SMALL = "Erg klein" | ||||||
|  | CHAT_WIDTH_SMALL = "Klein" | ||||||
|  | CHAT_WIDTH_NORMAL = "Normaal" | ||||||
|  | CHAT_WIDTH_BIG = "Groot" | ||||||
|  | CHAT_WIDTH_VERY_BIG = "Zeer groot" | ||||||
|  | CHAT_WIDTH_HUGE = "Enorm" | ||||||
|  | CHAT_CHAR_COUNTER = "Chat-tekensteller weergeven" | ||||||
|  | DISABLE_CHAT_WHEN_CLOSED = "Chat verbergen wanneer gesloten" | ||||||
| MENU_OPTIONS = "Menu Instellingen" | MENU_OPTIONS = "Menu Instellingen" | ||||||
| INFORMATION = "Informatie" | INFORMATION = "Informatie" | ||||||
| DEBUG = "Debug" | DEBUG = "Debug" | ||||||
|  |  | ||||||
|  | @ -58,6 +58,8 @@ MOD_DESC = "/moderator [NAME|ID] - Make this player able to use commands like /k | ||||||
| NAMETAGS_DESC = "/nametags [show-tag|show-health] - Change whether or not you see your own nametag and whether or not you see health" | NAMETAGS_DESC = "/nametags [show-tag|show-health] - Change whether or not you see your own nametag and whether or not you see health" | ||||||
| UNRECOGNIZED = "Unrecognized chat command." | UNRECOGNIZED = "Unrecognized chat command." | ||||||
| MOD_GRANTED = "\\#fff982\\You are now a Moderator." | MOD_GRANTED = "\\#fff982\\You are now a Moderator." | ||||||
|  | ALL_COMMANDS = "All commands" | ||||||
|  | TAB_COMPLETE_INFO = "Press TAB to autocomplete commands, use Shift+TAB to navigate backwards" | ||||||
| 
 | 
 | ||||||
| [MENU] | [MENU] | ||||||
| BACK = "Back" | BACK = "Back" | ||||||
|  | @ -105,6 +107,7 @@ DEADZONE = "Deadzone" | ||||||
| RUMBLE_STRENGTH = "Rumble Strength" | RUMBLE_STRENGTH = "Rumble Strength" | ||||||
| 
 | 
 | ||||||
| CHAT = "Chat" | CHAT = "Chat" | ||||||
|  | CHAT_COMMAND = "Chat (Command)" | ||||||
| PLAYERS = "Players" | PLAYERS = "Players" | ||||||
| D_UP = "D-Up" | D_UP = "D-Up" | ||||||
| D_DOWN = "D-Down" | D_DOWN = "D-Down" | ||||||
|  | @ -319,7 +322,17 @@ DEBUG_ERRORS = "Debug Errors" | ||||||
| MISC_TITLE = "MISC" | MISC_TITLE = "MISC" | ||||||
| PAUSE_IN_SINGLEPLAYER = "Pause In Singleplayer" | PAUSE_IN_SINGLEPLAYER = "Pause In Singleplayer" | ||||||
| DISABLE_POPUPS = "Disable Popups" | DISABLE_POPUPS = "Disable Popups" | ||||||
| USE_STANDARD_KEY_BINDINGS_CHAT = "Classic Chatbox Controls" | USE_STANDARD_KEY_BINDINGS_CHAT = "Use Terminal/CMD Chatbox Controls" | ||||||
|  | CHAT_WIDTH = "Chat Width" | ||||||
|  | CHAT_WIDTH_TINY = "Tiny" | ||||||
|  | CHAT_WIDTH_VERY_SMALL = "Very Small" | ||||||
|  | CHAT_WIDTH_SMALL = "Small" | ||||||
|  | CHAT_WIDTH_NORMAL = "Normal" | ||||||
|  | CHAT_WIDTH_BIG = "Big" | ||||||
|  | CHAT_WIDTH_VERY_BIG = "Very Big" | ||||||
|  | CHAT_WIDTH_HUGE = "Huge" | ||||||
|  | CHAT_CHAR_COUNTER = "Show Chat Character Counter" | ||||||
|  | DISABLE_CHAT_WHEN_CLOSED = "Hide Chat When Closed" | ||||||
| MENU_OPTIONS = "Menu Options" | MENU_OPTIONS = "Menu Options" | ||||||
| INFORMATION = "Info" | INFORMATION = "Info" | ||||||
| DEBUG = "Debug" | DEBUG = "Debug" | ||||||
|  |  | ||||||
|  | @ -58,6 +58,8 @@ MOD_DESC = "/moderator [NAME|ID] - Rend ce joueur capable d'utiliser des command | ||||||
| NAMETAGS_DESC = "/nametags [show-tag|show-health] - Modifiez si vous voyez votre propre étiquette de nom et si vous voyez la santé" | NAMETAGS_DESC = "/nametags [show-tag|show-health] - Modifiez si vous voyez votre propre étiquette de nom et si vous voyez la santé" | ||||||
| UNRECOGNIZED = "Cette commande n'est pas reconnue." | UNRECOGNIZED = "Cette commande n'est pas reconnue." | ||||||
| MOD_GRANTED = "\\#fff982\\Vous êtes désormais un modérateur." | MOD_GRANTED = "\\#fff982\\Vous êtes désormais un modérateur." | ||||||
|  | ALL_COMMANDS = "Toutes les commandes" | ||||||
|  | TAB_COMPLETE_INFO = "Appuie sur TAB pour compléter automatiquement les commandes, utilise Shift+TAB pour revenir en arrière" | ||||||
| 
 | 
 | ||||||
| [MENU] | [MENU] | ||||||
| BACK = "Retour" | BACK = "Retour" | ||||||
|  | @ -105,6 +107,7 @@ DEADZONE = "Zone Morte" | ||||||
| RUMBLE_STRENGTH = "Vibrations" | RUMBLE_STRENGTH = "Vibrations" | ||||||
| 
 | 
 | ||||||
| CHAT = "Chat" | CHAT = "Chat" | ||||||
|  | CHAT_COMMAND = "Chat (Commande)" | ||||||
| PLAYERS = "Joueurs" | PLAYERS = "Joueurs" | ||||||
| D_UP = "D Haut" | D_UP = "D Haut" | ||||||
| D_DOWN = "D Bas" | D_DOWN = "D Bas" | ||||||
|  | @ -319,7 +322,17 @@ DEBUG_ERRORS = "Erreurs de Débogage" | ||||||
| MISC_TITLE = "AUTRES" | MISC_TITLE = "AUTRES" | ||||||
| PAUSE_IN_SINGLEPLAYER = "Pause en Solo" | PAUSE_IN_SINGLEPLAYER = "Pause en Solo" | ||||||
| DISABLE_POPUPS = "Désactiver les Pop-ups" | DISABLE_POPUPS = "Désactiver les Pop-ups" | ||||||
| USE_STANDARD_KEY_BINDINGS_CHAT = "Commandes de chat classiques" | USE_STANDARD_KEY_BINDINGS_CHAT = "Utiliser les contrôles de chat Terminal/CMD" | ||||||
|  | CHAT_WIDTH = "Largeur du chat" | ||||||
|  | CHAT_WIDTH_TINY = "Minuscule" | ||||||
|  | CHAT_WIDTH_VERY_SMALL = "Très petite" | ||||||
|  | CHAT_WIDTH_SMALL = "Petite" | ||||||
|  | CHAT_WIDTH_NORMAL = "Normale" | ||||||
|  | CHAT_WIDTH_BIG = "Grande" | ||||||
|  | CHAT_WIDTH_VERY_BIG = "Très grande" | ||||||
|  | CHAT_WIDTH_HUGE = "Énorme" | ||||||
|  | CHAT_CHAR_COUNTER = "Afficher le compteur de caractères du chat" | ||||||
|  | DISABLE_CHAT_WHEN_CLOSED = "Masquer le chat lorsqu'il est fermé" | ||||||
| MENU_OPTIONS = "Options du menu" | MENU_OPTIONS = "Options du menu" | ||||||
| INFORMATION = "Information" | INFORMATION = "Information" | ||||||
| DEBUG = "Débogage" | DEBUG = "Débogage" | ||||||
|  |  | ||||||
|  | @ -58,6 +58,8 @@ MOD_DESC = "/moderator [NAME|ID] - Gebe einem Spieler Moderator rechte wie /kick | ||||||
| NAMETAGS_DESC = "/nametags [show-tag|show-health] - Sichtbarkeit von Spielernamen sowie der KP/Kraft aktivieren oder deaktivieren " | NAMETAGS_DESC = "/nametags [show-tag|show-health] - Sichtbarkeit von Spielernamen sowie der KP/Kraft aktivieren oder deaktivieren " | ||||||
| UNRECOGNIZED = "Unbekannter Befehl!" | UNRECOGNIZED = "Unbekannter Befehl!" | ||||||
| MOD_GRANTED = "\\#fff982\\Du bist jetzt ein Moderator." | MOD_GRANTED = "\\#fff982\\Du bist jetzt ein Moderator." | ||||||
|  | ALL_COMMANDS = "Alle Befehle" | ||||||
|  | TAB_COMPLETE_INFO = "Drücke TAB zum Autovervollständigen der Befehle, mit Shift+TAB navigierst du rückwärts" | ||||||
| 
 | 
 | ||||||
| [MENU] | [MENU] | ||||||
| BACK = "Zurück" | BACK = "Zurück" | ||||||
|  | @ -105,6 +107,7 @@ DEADZONE = "Tote Zone" | ||||||
| RUMBLE_STRENGTH = "Vibration-Stärke" | RUMBLE_STRENGTH = "Vibration-Stärke" | ||||||
| 
 | 
 | ||||||
| CHAT = "Chat" | CHAT = "Chat" | ||||||
|  | CHAT_COMMAND = "Chat (Befehl)" | ||||||
| PLAYERS = "Spieler" | PLAYERS = "Spieler" | ||||||
| D_UP = "D-Hoch" | D_UP = "D-Hoch" | ||||||
| D_DOWN = "D-Unten" | D_DOWN = "D-Unten" | ||||||
|  | @ -319,7 +322,17 @@ DEBUG_ERRORS = "Debug Fehler" | ||||||
| MISC_TITLE = "SONSTIGES" | MISC_TITLE = "SONSTIGES" | ||||||
| PAUSE_IN_SINGLEPLAYER = "Pause im Einzelspieler" | PAUSE_IN_SINGLEPLAYER = "Pause im Einzelspieler" | ||||||
| DISABLE_POPUPS = "Pop-ups deaktivieren" | DISABLE_POPUPS = "Pop-ups deaktivieren" | ||||||
| USE_STANDARD_KEY_BINDINGS_CHAT = "Standard-Tastennavigation im Chat" | USE_STANDARD_KEY_BINDINGS_CHAT = "Terminal/CMD Chatbox-Steuerung verwenden" | ||||||
|  | CHAT_WIDTH = "Chatbreite" | ||||||
|  | CHAT_WIDTH_TINY = "Winzig" | ||||||
|  | CHAT_WIDTH_VERY_SMALL = "Sehr klein" | ||||||
|  | CHAT_WIDTH_SMALL = "Klein" | ||||||
|  | CHAT_WIDTH_NORMAL = "Normal" | ||||||
|  | CHAT_WIDTH_BIG = "Groß" | ||||||
|  | CHAT_WIDTH_VERY_BIG = "Sehr groß" | ||||||
|  | CHAT_WIDTH_HUGE = "Riesig" | ||||||
|  | CHAT_CHAR_COUNTER = "Chat-Zeichenzähler anzeigen" | ||||||
|  | DISABLE_CHAT_WHEN_CLOSED = "Verstecke Chat wenn geschlossen" | ||||||
| MENU_OPTIONS = "Menüoptionen" | MENU_OPTIONS = "Menüoptionen" | ||||||
| INFORMATION = "Info" | INFORMATION = "Info" | ||||||
| DEBUG = "Debug" | DEBUG = "Debug" | ||||||
|  |  | ||||||
|  | @ -58,6 +58,8 @@ MOD_DESC = "/moderator [NAME|ID] - Dai al giocatore il permesso di eseguire coma | ||||||
| NAMETAGS_DESC = "/nametags [show-tag|show-health] - Cambia la visibilità del tuo nome e della salute" | NAMETAGS_DESC = "/nametags [show-tag|show-health] - Cambia la visibilità del tuo nome e della salute" | ||||||
| UNRECOGNIZED = "Comando non riconosciuto." | UNRECOGNIZED = "Comando non riconosciuto." | ||||||
| MOD_GRANTED = "\\#fff982\\Ora sei un moderatore." | MOD_GRANTED = "\\#fff982\\Ora sei un moderatore." | ||||||
|  | ALL_COMMANDS = "Tutti i comandi" | ||||||
|  | TAB_COMPLETE_INFO = "Premi TAB per completare automaticamente i comandi, usa Shift+TAB per navigare all'indietro" | ||||||
| 
 | 
 | ||||||
| [MENU] | [MENU] | ||||||
| BACK = "Indietro" | BACK = "Indietro" | ||||||
|  | @ -103,6 +105,7 @@ GAMEPAD = "Controller" | ||||||
| DEADZONE = "Zona Morta" | DEADZONE = "Zona Morta" | ||||||
| RUMBLE_STRENGTH = "Intesità Vibrazione" | RUMBLE_STRENGTH = "Intesità Vibrazione" | ||||||
| CHAT = "Chat" | CHAT = "Chat" | ||||||
|  | CHAT_COMMAND = "Chat (Comando)" | ||||||
| PLAYERS = "Giocatori" | PLAYERS = "Giocatori" | ||||||
| D_UP = "D Su" | D_UP = "D Su" | ||||||
| D_DOWN = "D Giù" | D_DOWN = "D Giù" | ||||||
|  | @ -317,7 +320,17 @@ DEBUG_ERRORS = "Errori di debug" | ||||||
| MISC_TITLE = "VARIE" | MISC_TITLE = "VARIE" | ||||||
| PAUSE_IN_SINGLEPLAYER = "Pausa in Giocatore Singolo" | PAUSE_IN_SINGLEPLAYER = "Pausa in Giocatore Singolo" | ||||||
| DISABLE_POPUPS = "Disabilita Popup" | DISABLE_POPUPS = "Disabilita Popup" | ||||||
| USE_STANDARD_KEY_BINDINGS_CHAT = "Controlli della chat classici" | USE_STANDARD_KEY_BINDINGS_CHAT = "Usa controlli chat Terminale/CMD" | ||||||
|  | CHAT_WIDTH = "Larghezza chat" | ||||||
|  | CHAT_WIDTH_TINY = "Minuscola" | ||||||
|  | CHAT_WIDTH_VERY_SMALL = "Molto piccola" | ||||||
|  | CHAT_WIDTH_SMALL = "Piccola" | ||||||
|  | CHAT_WIDTH_NORMAL = "Normale" | ||||||
|  | CHAT_WIDTH_BIG = "Grande" | ||||||
|  | CHAT_WIDTH_VERY_BIG = "Molto grande" | ||||||
|  | CHAT_WIDTH_HUGE = "Enorme" | ||||||
|  | CHAT_CHAR_COUNTER = "Mostra contatore caratteri della chat" | ||||||
|  | DISABLE_CHAT_WHEN_CLOSED = "Nascondi chat quando è chiusa" | ||||||
| MENU_OPTIONS = "Opzioni Menù" | MENU_OPTIONS = "Opzioni Menù" | ||||||
| INFORMATION = "Informazione" | INFORMATION = "Informazione" | ||||||
| DEBUG = "Debug" | DEBUG = "Debug" | ||||||
|  |  | ||||||
|  | @ -58,6 +58,8 @@ MOD_DESC = "/moderator [NAME|ID] - プレイヤーに/kick、/ban、/permbanの | ||||||
| NAMETAGS_DESC = "/nametags [show-tag|show-health] - あなたの体力やネームタグの表示を変更します。" | NAMETAGS_DESC = "/nametags [show-tag|show-health] - あなたの体力やネームタグの表示を変更します。" | ||||||
| UNRECOGNIZED = "未知のコマンドです。" | UNRECOGNIZED = "未知のコマンドです。" | ||||||
| MOD_GRANTED = "\\#fff982\\あなたはモデレーターになりました。" | MOD_GRANTED = "\\#fff982\\あなたはモデレーターになりました。" | ||||||
|  | ALL_COMMANDS = "すべてのコマンド" | ||||||
|  | TAB_COMPLETE_INFO = "TABキーでコマンドを自動補完、Shift+TABで逆方向に移動" | ||||||
| 
 | 
 | ||||||
| [MENU] | [MENU] | ||||||
| BACK = "戻る" | BACK = "戻る" | ||||||
|  | @ -106,6 +108,7 @@ DEADZONE = "デッドゾーン" | ||||||
| RUMBLE_STRENGTH = "振動の強さ" | RUMBLE_STRENGTH = "振動の強さ" | ||||||
| 
 | 
 | ||||||
| CHAT = "チャット" | CHAT = "チャット" | ||||||
|  | CHAT_COMMAND = "チャット(コマンド)" | ||||||
| PLAYERS = "プレイヤーリストの表示" | PLAYERS = "プレイヤーリストの表示" | ||||||
| D_UP = "十字キー 上" | D_UP = "十字キー 上" | ||||||
| D_DOWN = "十字キー 下" | D_DOWN = "十字キー 下" | ||||||
|  | @ -320,7 +323,17 @@ DEBUG_ERRORS = "デバッグのエラー" | ||||||
| MISC_TITLE = "MISC" | MISC_TITLE = "MISC" | ||||||
| PAUSE_IN_SINGLEPLAYER = "ソロプレイでの一時停止" | PAUSE_IN_SINGLEPLAYER = "ソロプレイでの一時停止" | ||||||
| DISABLE_POPUPS = "ポップアップを無効にする" | DISABLE_POPUPS = "ポップアップを無効にする" | ||||||
| USE_STANDARD_KEY_BINDINGS_CHAT = "初期のチャット操作" | USE_STANDARD_KEY_BINDINGS_CHAT = "ターミナル/CMDチャットボックスコントロールを使用" | ||||||
|  | CHAT_WIDTH = "チャット幅" | ||||||
|  | CHAT_WIDTH_TINY = "とても小さい" | ||||||
|  | CHAT_WIDTH_VERY_SMALL = "かなり小さい" | ||||||
|  | CHAT_WIDTH_SMALL = "小さい" | ||||||
|  | CHAT_WIDTH_NORMAL = "標準" | ||||||
|  | CHAT_WIDTH_BIG = "大きい" | ||||||
|  | CHAT_WIDTH_VERY_BIG = "とても大きい" | ||||||
|  | CHAT_WIDTH_HUGE = "巨大" | ||||||
|  | CHAT_CHAR_COUNTER = "チャットの文字数カウンターを表示" | ||||||
|  | DISABLE_CHAT_WHEN_CLOSED = "閉じているときはチャットを隠す" | ||||||
| MENU_OPTIONS = "メニューの設定" | MENU_OPTIONS = "メニューの設定" | ||||||
| INFORMATION = "情報" | INFORMATION = "情報" | ||||||
| DEBUG = "デバッグ" | DEBUG = "デバッグ" | ||||||
|  |  | ||||||
|  | @ -58,6 +58,8 @@ MOD_DESC = "/moderator [NAME|ID] - Umożliwia temu graczowi korzystanie z polece | ||||||
| NAMETAGS_DESC = "/nametags [show-tag|show-health] - Zmień, czy widzisz swój identyfikator i czy widzisz zdrowie" | NAMETAGS_DESC = "/nametags [show-tag|show-health] - Zmień, czy widzisz swój identyfikator i czy widzisz zdrowie" | ||||||
| UNRECOGNIZED = "Nieznane polecenie czatu." | UNRECOGNIZED = "Nieznane polecenie czatu." | ||||||
| MOD_GRANTED = "\\#fff982\\Jesteś teraz Moderatorem." | MOD_GRANTED = "\\#fff982\\Jesteś teraz Moderatorem." | ||||||
|  | ALL_COMMANDS = "Wszystkie komendy" | ||||||
|  | TAB_COMPLETE_INFO = "Naciśnij TAB, aby autouzupełnić polecenia, użyj Shift+TAB, aby cofnąć się" | ||||||
| 
 | 
 | ||||||
| [MENU] | [MENU] | ||||||
| BACK = "Wróć" | BACK = "Wróć" | ||||||
|  | @ -105,6 +107,7 @@ DEADZONE = "Martwa Strefa" | ||||||
| RUMBLE_STRENGTH = "Siła Wibracji" | RUMBLE_STRENGTH = "Siła Wibracji" | ||||||
| 
 | 
 | ||||||
| CHAT = "Czat" | CHAT = "Czat" | ||||||
|  | CHAT_COMMAND = "Czat (Komenda)" | ||||||
| PLAYERS = "Gracze" | PLAYERS = "Gracze" | ||||||
| D_UP = "Kierunek w Górę" | D_UP = "Kierunek w Górę" | ||||||
| D_DOWN = "Kierunek w Dół" | D_DOWN = "Kierunek w Dół" | ||||||
|  | @ -319,7 +322,17 @@ DEBUG_ERRORS = "Błędy z Debugowania" | ||||||
| MISC_TITLE = "POZOSTAŁE OPCJE" | MISC_TITLE = "POZOSTAŁE OPCJE" | ||||||
| PAUSE_IN_SINGLEPLAYER = "Pauza w Trybie Pojedynczego Gracza" | PAUSE_IN_SINGLEPLAYER = "Pauza w Trybie Pojedynczego Gracza" | ||||||
| DISABLE_POPUPS = "Wyłącz Dymki Powiadomień" | DISABLE_POPUPS = "Wyłącz Dymki Powiadomień" | ||||||
| USE_STANDARD_KEY_BINDINGS_CHAT = "Klasyczna Historia Czatu" | USE_STANDARD_KEY_BINDINGS_CHAT = "Użyj sterowania czatu Terminal/CMD" | ||||||
|  | CHAT_WIDTH = "Szerokość czatu" | ||||||
|  | CHAT_WIDTH_TINY = "Maleńka" | ||||||
|  | CHAT_WIDTH_VERY_SMALL = "Bardzo mała" | ||||||
|  | CHAT_WIDTH_SMALL = "Mała" | ||||||
|  | CHAT_WIDTH_NORMAL = "Normalna" | ||||||
|  | CHAT_WIDTH_BIG = "Duża" | ||||||
|  | CHAT_WIDTH_VERY_BIG = "Bardzo duża" | ||||||
|  | CHAT_WIDTH_HUGE = "Ogromna" | ||||||
|  | CHAT_CHAR_COUNTER = "Pokaż licznik znaków czatu" | ||||||
|  | DISABLE_CHAT_WHEN_CLOSED = "Ukryj czat, gdy jest zamknięty" | ||||||
| MENU_OPTIONS = "Opcje Menu" | MENU_OPTIONS = "Opcje Menu" | ||||||
| INFORMATION = "Informacja" | INFORMATION = "Informacja" | ||||||
| DEBUG = "Debugowanie" | DEBUG = "Debugowanie" | ||||||
|  |  | ||||||
|  | @ -58,6 +58,8 @@ MOD_DESC = "/moderator [NOME|ID] - Permite que um jogador use comandos como /kic | ||||||
| NAMETAGS_DESC = "/nametags [show-tag|show-health] - Altera se você vê sua própria etiqueta ou a barra de vida de outros jogadores" | NAMETAGS_DESC = "/nametags [show-tag|show-health] - Altera se você vê sua própria etiqueta ou a barra de vida de outros jogadores" | ||||||
| UNRECOGNIZED = "Comando de chat desconhecido." | UNRECOGNIZED = "Comando de chat desconhecido." | ||||||
| MOD_GRANTED = "\\#fff982\\Você é um(a) moderador(a) agora." | MOD_GRANTED = "\\#fff982\\Você é um(a) moderador(a) agora." | ||||||
|  | ALL_COMMANDS = "Todos os comandos" | ||||||
|  | TAB_COMPLETE_INFO = "Pressiona TAB para autocompletar comandos, usa Shift+TAB para navegar para trás" | ||||||
| 
 | 
 | ||||||
| [MENU] | [MENU] | ||||||
| BACK = "Voltar" | BACK = "Voltar" | ||||||
|  | @ -105,6 +107,7 @@ DEADZONE = "Zona morta" | ||||||
| RUMBLE_STRENGTH = "Força de vibração" | RUMBLE_STRENGTH = "Força de vibração" | ||||||
| 
 | 
 | ||||||
| CHAT = "Chat" | CHAT = "Chat" | ||||||
|  | CHAT_COMMAND = "Chat (Comando)" | ||||||
| PLAYERS = "Jogadores" | PLAYERS = "Jogadores" | ||||||
| D_UP = "D-Cima" | D_UP = "D-Cima" | ||||||
| D_DOWN = "D-Baixo" | D_DOWN = "D-Baixo" | ||||||
|  | @ -319,7 +322,17 @@ DEBUG_ERRORS = "Erros de debug" | ||||||
| MISC_TITLE = "OUTROS" | MISC_TITLE = "OUTROS" | ||||||
| PAUSE_IN_SINGLEPLAYER = "Pausar com apenas um jogador" | PAUSE_IN_SINGLEPLAYER = "Pausar com apenas um jogador" | ||||||
| DISABLE_POPUPS = "Desativar pop-ups" | DISABLE_POPUPS = "Desativar pop-ups" | ||||||
| USE_STANDARD_KEY_BINDINGS_CHAT = "Controles clássicos do chat" | USE_STANDARD_KEY_BINDINGS_CHAT = "Usar controles de chat Terminal/CMD" | ||||||
|  | CHAT_WIDTH = "Largura do chat" | ||||||
|  | CHAT_WIDTH_TINY = "Minúsculo" | ||||||
|  | CHAT_WIDTH_VERY_SMALL = "Muito pequena" | ||||||
|  | CHAT_WIDTH_SMALL = "Pequena" | ||||||
|  | CHAT_WIDTH_NORMAL = "Normal" | ||||||
|  | CHAT_WIDTH_BIG = "Grande" | ||||||
|  | CHAT_WIDTH_VERY_BIG = "Muito grande" | ||||||
|  | CHAT_WIDTH_HUGE = "Enorme" | ||||||
|  | CHAT_CHAR_COUNTER = "Mostrar contador de caracteres do chat" | ||||||
|  | DISABLE_CHAT_WHEN_CLOSED = "Ocultar chat quando fechado" | ||||||
| MENU_OPTIONS = "Opções de menu" | MENU_OPTIONS = "Opções de menu" | ||||||
| INFORMATION = "Informações" | INFORMATION = "Informações" | ||||||
| DEBUG = "Debug" | DEBUG = "Debug" | ||||||
|  |  | ||||||
|  | @ -58,6 +58,8 @@ MOD_DESC = "/moderator [NAME|ID] - Разрешить игроку исполь | ||||||
| NAMETAGS_DESC = "/nametags [show-tag|show-health] - Измените, видите ли вы свой собственный тег и видите ли здоровье" | NAMETAGS_DESC = "/nametags [show-tag|show-health] - Измените, видите ли вы свой собственный тег и видите ли здоровье" | ||||||
| UNRECOGNIZED = "Неизвестная команда чата." | UNRECOGNIZED = "Неизвестная команда чата." | ||||||
| MOD_GRANTED = "\\#fff982\\Теперь вы модератор." | MOD_GRANTED = "\\#fff982\\Теперь вы модератор." | ||||||
|  | ALL_COMMANDS = "Все команды" | ||||||
|  | TAB_COMPLETE_INFO = "Нажми TAB для автодополнения команд, Shift+TAB — переход назад" | ||||||
| 
 | 
 | ||||||
| [MENU] | [MENU] | ||||||
| BACK = "Назад" | BACK = "Назад" | ||||||
|  | @ -104,6 +106,7 @@ DEADZONE = "Mёртвая зона" | ||||||
| RUMBLE_STRENGTH = "Вибрация" | RUMBLE_STRENGTH = "Вибрация" | ||||||
| 
 | 
 | ||||||
| CHAT = "Чат" | CHAT = "Чат" | ||||||
|  | CHAT_COMMAND = "Чат (Команда)" | ||||||
| PLAYERS = "Игроки" | PLAYERS = "Игроки" | ||||||
| D_UP = "Крестовина вверх" | D_UP = "Крестовина вверх" | ||||||
| D_DOWN = "Крестовина вниз" | D_DOWN = "Крестовина вниз" | ||||||
|  | @ -318,7 +321,17 @@ DEBUG_ERRORS = "Ошибки отладки" | ||||||
| MISC_TITLE = "MISC" | MISC_TITLE = "MISC" | ||||||
| PAUSE_IN_SINGLEPLAYER = "Пауза в одиночной игре" | PAUSE_IN_SINGLEPLAYER = "Пауза в одиночной игре" | ||||||
| DISABLE_POPUPS = "Отключить всплывающие окна" | DISABLE_POPUPS = "Отключить всплывающие окна" | ||||||
| USE_STANDARD_KEY_BINDINGS_CHAT = "Классическое управление чатом" | USE_STANDARD_KEY_BINDINGS_CHAT = "Использовать управление чатом Terminal/CMD" | ||||||
|  | CHAT_WIDTH = "Ширина чата" | ||||||
|  | CHAT_WIDTH_TINY = "Крошечная" | ||||||
|  | CHAT_WIDTH_VERY_SMALL = "Очень маленькая" | ||||||
|  | CHAT_WIDTH_SMALL = "Маленькая" | ||||||
|  | CHAT_WIDTH_NORMAL = "Обычная" | ||||||
|  | CHAT_WIDTH_BIG = "Большая" | ||||||
|  | CHAT_WIDTH_VERY_BIG = "Очень большая" | ||||||
|  | CHAT_WIDTH_HUGE = "Огромная" | ||||||
|  | CHAT_CHAR_COUNTER = "Показывать счётчик символов чата" | ||||||
|  | DISABLE_CHAT_WHEN_CLOSED = "Скрывать чат, когда он закрыт" | ||||||
| MENU_OPTIONS = "Параметры меню" | MENU_OPTIONS = "Параметры меню" | ||||||
| INFORMATION = "Информация" | INFORMATION = "Информация" | ||||||
| DEBUG = "Отладка" | DEBUG = "Отладка" | ||||||
|  |  | ||||||
|  | @ -58,6 +58,8 @@ MOD_DESC = "/moderator [NAME|ID] - Permite a un jugador usar comandos como /kick | ||||||
| NAMETAGS_DESC = "/nametags [show-tag|show-health] - Cambia si ves tu propia etiqueta y si ves la salud" | NAMETAGS_DESC = "/nametags [show-tag|show-health] - Cambia si ves tu propia etiqueta y si ves la salud" | ||||||
| UNRECOGNIZED = "Comando desconocido." | UNRECOGNIZED = "Comando desconocido." | ||||||
| MOD_GRANTED = "\\#fff982\\Ahora eres un moderador." | MOD_GRANTED = "\\#fff982\\Ahora eres un moderador." | ||||||
|  | ALL_COMMANDS = "Todos los comandos" | ||||||
|  | TAB_COMPLETE_INFO = "Pulsa TAB para autocompletar comandos, usa Shift+TAB para retroceder" | ||||||
| 
 | 
 | ||||||
| [MENU] | [MENU] | ||||||
| BACK = "Volver" | BACK = "Volver" | ||||||
|  | @ -105,6 +107,7 @@ DEADZONE = "Zona muerta" | ||||||
| RUMBLE_STRENGTH = "Intensidad de vibración" | RUMBLE_STRENGTH = "Intensidad de vibración" | ||||||
| 
 | 
 | ||||||
| CHAT = "Chat" | CHAT = "Chat" | ||||||
|  | CHAT_COMMAND = "Chat (Comando)" | ||||||
| PLAYERS = "Jugadores" | PLAYERS = "Jugadores" | ||||||
| D_UP = "Cruz Arriba" | D_UP = "Cruz Arriba" | ||||||
| D_DOWN = "Cruz Abajo" | D_DOWN = "Cruz Abajo" | ||||||
|  | @ -319,7 +322,17 @@ DEBUG_ERRORS = "Errores de Depuración" | ||||||
| MISC_TITLE = "OTROS" | MISC_TITLE = "OTROS" | ||||||
| PAUSE_IN_SINGLEPLAYER = "Pausa en modo de un jugador" | PAUSE_IN_SINGLEPLAYER = "Pausa en modo de un jugador" | ||||||
| DISABLE_POPUPS = "Deshabilitar mensajes emergentes" | DISABLE_POPUPS = "Deshabilitar mensajes emergentes" | ||||||
| USE_STANDARD_KEY_BINDINGS_CHAT = "Controles de chat clásicos" | USE_STANDARD_KEY_BINDINGS_CHAT = "Usar controles de chat Terminal/CMD" | ||||||
|  | CHAT_WIDTH = "Ancho del chat" | ||||||
|  | CHAT_WIDTH_TINY = "Minúsculo" | ||||||
|  | CHAT_WIDTH_VERY_SMALL = "Muy pequeño" | ||||||
|  | CHAT_WIDTH_SMALL = "Pequeño" | ||||||
|  | CHAT_WIDTH_NORMAL = "Normal" | ||||||
|  | CHAT_WIDTH_BIG = "Grande" | ||||||
|  | CHAT_WIDTH_VERY_BIG = "Muy grande" | ||||||
|  | CHAT_WIDTH_HUGE = "Enorme" | ||||||
|  | CHAT_CHAR_COUNTER = "Mostrar contador de caracteres del chat" | ||||||
|  | DISABLE_CHAT_WHEN_CLOSED = "Ocultar chat cuando esté cerrado" | ||||||
| MENU_OPTIONS = "Opciones del menú" | MENU_OPTIONS = "Opciones del menú" | ||||||
| INFORMATION = "Información" | INFORMATION = "Información" | ||||||
| DEBUG = "Depuración" | DEBUG = "Depuración" | ||||||
|  |  | ||||||
|  | @ -300,7 +300,7 @@ hook_event(HOOK_ON_INTERACT, star_counter_on_interact) | ||||||
| hook_event(HOOK_ON_HUD_RENDER, hud_render_psc) | hook_event(HOOK_ON_HUD_RENDER, hud_render_psc) | ||||||
| hook_event(HOOK_ON_HUD_RENDER_BEHIND, behind_hud_render_psc) | hook_event(HOOK_ON_HUD_RENDER_BEHIND, behind_hud_render_psc) | ||||||
| hook_event(HOOK_UPDATE, psc_update) | hook_event(HOOK_UPDATE, psc_update) | ||||||
| hook_chat_command('psc', "On|Off - Displays stars you've collected. Default is On.", toggle_psc) | hook_chat_command('psc', "[On|Off] - Displays stars you've collected. Default is On.", toggle_psc) | ||||||
| 
 | 
 | ||||||
| -- Globalize functions for other mods to use | -- Globalize functions for other mods to use | ||||||
| -- Created by PeachyPeach | -- Created by PeachyPeach | ||||||
|  |  | ||||||
|  | @ -15,15 +15,15 @@ void sequence_channel_set_volume(struct SequenceChannel *seqChannel, u8 volume); | ||||||
| void process_sequences(s32 iterationsRemaining); | void process_sequences(s32 iterationsRemaining); | ||||||
| void init_sequence_player(u32 player); | void init_sequence_player(u32 player); | ||||||
| void init_sequence_players(void); | void init_sequence_players(void); | ||||||
| /* |description|Gets the tempo of `player`|descriptionEnd| */ | /* |description|Gets the `tempo` of `player`|descriptionEnd| */ | ||||||
| u16 sequence_player_get_tempo(u8 player); | u16 sequence_player_get_tempo(u8 player); | ||||||
| /* |description|Sets the `tempo` of `player`. Resets when another sequence is played|descriptionEnd| */ | /* |description|Sets the `tempo` of `player`. Resets when another sequence is played|descriptionEnd| */ | ||||||
| void sequence_player_set_tempo(u8 player, u16 tempo); | void sequence_player_set_tempo(u8 player, u16 tempo); | ||||||
| /* |description|Gets the tempoAcc (tempo accumulation) of `player`|descriptionEnd| */ | /* |description|Gets the `tempoAcc` (tempo accumulation) of `player`|descriptionEnd| */ | ||||||
| u16 sequence_player_get_tempo_acc(u8 player); | u16 sequence_player_get_tempo_acc(u8 player); | ||||||
| /* |description|Sets the `tempoAcc` (tempo accumulation) of `player`. Resets when another sequence is played|descriptionEnd| */ | /* |description|Sets the `tempoAcc` (tempo accumulation) of `player`. Resets when another sequence is played|descriptionEnd| */ | ||||||
| void sequence_player_set_tempo_acc(u8 player, u16 tempoAcc); | void sequence_player_set_tempo_acc(u8 player, u16 tempoAcc); | ||||||
| /* |description|Gets the transposition (pitch) of `player`|descriptionEnd| */ | /* |description|Gets the `transposition` (pitch) of `player`|descriptionEnd| */ | ||||||
| u16 sequence_player_get_transposition(u8 player); | u16 sequence_player_get_transposition(u8 player); | ||||||
| /* |description|Sets the `transposition` (pitch) of `player`. Resets when another sequence is played|descriptionEnd| */ | /* |description|Sets the `transposition` (pitch) of `player`. Resets when another sequence is played|descriptionEnd| */ | ||||||
| void sequence_player_set_transposition(u8 player, u16 transposition); | void sequence_player_set_transposition(u8 player, u16 transposition); | ||||||
|  |  | ||||||
|  | @ -3,6 +3,7 @@ static u32 networkBowserAnimationIndex = 0; | ||||||
| static u8 bowserIsDying = FALSE; | static u8 bowserIsDying = FALSE; | ||||||
| static u8 bowserCutscenePlayed = FALSE; | static u8 bowserCutscenePlayed = FALSE; | ||||||
| static u8 bowserIsCutscenePlayer = FALSE; | static u8 bowserIsCutscenePlayer = FALSE; | ||||||
|  | static u8 bowserCutsceneGlobalIndex = UNKNOWN_GLOBAL_INDEX; | ||||||
| 
 | 
 | ||||||
| void bowser_tail_anchor_act_0(void) { | void bowser_tail_anchor_act_0(void) { | ||||||
|     struct Object* bowser = o->parentObj; |     struct Object* bowser = o->parentObj; | ||||||
|  | @ -777,6 +778,10 @@ void bowser_act_thrown_dropped(void) | ||||||
|             o->oAction = 4; |             o->oAction = 4; | ||||||
|         else |         else | ||||||
|             o->oAction = 12; |             o->oAction = 12; | ||||||
|  |          | ||||||
|  |         if (is_nearest_mario_state_to_object(gMarioState, o)) { | ||||||
|  |             network_send_object(o); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -1125,8 +1130,17 @@ void bowser_act_ride_tilting_platform(void) { | ||||||
|     cur_obj_extend_animation_if_at_end(); |     cur_obj_extend_animation_if_at_end(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void bowser_act_nothing(void) { | void bowser_act_nothing(void) { // start moving if cutscene player is inactive
 | ||||||
|      |     if (bowserCutsceneGlobalIndex == UNKNOWN_GLOBAL_INDEX) { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     struct NetworkPlayer* np = network_player_from_global_index(bowserCutsceneGlobalIndex); | ||||||
|  |     if (np == NULL || !is_player_active(&gMarioStates[np->localIndex])) { | ||||||
|  |         bowserCutscenePlayed = TRUE; | ||||||
|  |         bowser_initialize_action(); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| s32 bowser_check_fallen_off_stage(void) // bowser off stage?
 | s32 bowser_check_fallen_off_stage(void) // bowser off stage?
 | ||||||
|  | @ -1232,6 +1246,7 @@ void bowser_held_update(void) { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     o->parentObj = player; | ||||||
|     o->oBowserUnkF4 &= ~0x20000; |     o->oBowserUnkF4 &= ~0x20000; | ||||||
|     cur_obj_become_intangible(); |     cur_obj_become_intangible(); | ||||||
| 
 | 
 | ||||||
|  | @ -1385,6 +1400,13 @@ static u8 bhv_bowser_ignore_if_true(void) { | ||||||
|     return FALSE; |     return FALSE; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void bhv_bowser_on_received_post(UNUSED u8 localIndex) { | ||||||
|  |     // prevent sync from putting bowser in text action instead of nothing action
 | ||||||
|  |     if (!(bowserIsCutscenePlayer || bowserCutscenePlayed) && (o->oAction == 5 || o->oAction == 6)) { | ||||||
|  |         o->oAction = 20; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void bhv_bowser_init(void) { | void bhv_bowser_init(void) { | ||||||
|     bowserIsDying = FALSE; |     bowserIsDying = FALSE; | ||||||
|     s32 level; // 0 is dw, 1 is fs, 2 is sky
 |     s32 level; // 0 is dw, 1 is fs, 2 is sky
 | ||||||
|  | @ -1408,9 +1430,11 @@ void bhv_bowser_init(void) { | ||||||
|     // Make sure we're the first to trigger Bowser.
 |     // Make sure we're the first to trigger Bowser.
 | ||||||
|     if (!is_other_player_active()) { |     if (!is_other_player_active()) { | ||||||
|         bowserIsCutscenePlayer = TRUE; |         bowserIsCutscenePlayer = TRUE; | ||||||
|  |         bowserCutsceneGlobalIndex = gNetworkPlayerLocal->globalIndex; | ||||||
|         o->oAction = 5; // bowser_act_text_wait
 |         o->oAction = 5; // bowser_act_text_wait
 | ||||||
|     } else { // If we aren't do nothing till we get our sync.
 |     } else { // If we aren't do nothing till we get our sync.
 | ||||||
|         bowserIsCutscenePlayer = FALSE; |         bowserIsCutscenePlayer = FALSE; | ||||||
|  |         bowserCutsceneGlobalIndex = UNKNOWN_GLOBAL_INDEX; | ||||||
|         o->oAction = 20; // bowser_act_nothing
 |         o->oAction = 20; // bowser_act_nothing
 | ||||||
|     } |     } | ||||||
|      |      | ||||||
|  | @ -1419,9 +1443,11 @@ void bhv_bowser_init(void) { | ||||||
|         if (so) { |         if (so) { | ||||||
|             so->override_ownership = bhv_bowser_override_ownership; |             so->override_ownership = bhv_bowser_override_ownership; | ||||||
|             so->ignore_if_true = bhv_bowser_ignore_if_true; |             so->ignore_if_true = bhv_bowser_ignore_if_true; | ||||||
|  |             so->on_received_post = bhv_bowser_on_received_post; | ||||||
|             so->fullObjectSync = TRUE; |             so->fullObjectSync = TRUE; | ||||||
|             sync_object_init_field_with_size(o, &o->header.gfx.node.flags, 16); |             sync_object_init_field_with_size(o, &o->header.gfx.node.flags, 16); | ||||||
|             sync_object_init_field_with_size(o, &o->header.gfx.animInfo.animFrame, 16); |             sync_object_init_field_with_size(o, &o->header.gfx.animInfo.animFrame, 16); | ||||||
|  |             sync_object_init_field_with_size(o, &bowserCutsceneGlobalIndex, 8); | ||||||
|             sync_object_init_field(o, &networkBowserAnimationIndex); |             sync_object_init_field(o, &networkBowserAnimationIndex); | ||||||
|             sync_object_init_field(o, &o->header.gfx.scale[0]); |             sync_object_init_field(o, &o->header.gfx.scale[0]); | ||||||
|             sync_object_init_field(o, &o->header.gfx.scale[1]); |             sync_object_init_field(o, &o->header.gfx.scale[1]); | ||||||
|  |  | ||||||
|  | @ -23,7 +23,7 @@ void bhv_heave_ho_throw_mario_loop(void) { | ||||||
|                 if (player) { |                 if (player) { | ||||||
|                     player->oInteractStatus |= INT_STATUS_MARIO_UNK2; |                     player->oInteractStatus |= INT_STATUS_MARIO_UNK2; | ||||||
|                 } |                 } | ||||||
|                 if (marioState) { |                 if (marioState && marioState->action == ACT_GRABBED) { | ||||||
|                     marioState->forwardVel = -45.0f; |                     marioState->forwardVel = -45.0f; | ||||||
|                     marioState->vel[1] = 95.0f; |                     marioState->vel[1] = 95.0f; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|  | @ -36,9 +36,9 @@ u32 mario_update_moving_sand(struct MarioState *m); | ||||||
| u32 mario_update_windy_ground(struct MarioState *m); | u32 mario_update_windy_ground(struct MarioState *m); | ||||||
| /* |description|Sets all of Mario's velocity variables to 0 and sets his Y position to the floor height|descriptionEnd| */ | /* |description|Sets all of Mario's velocity variables to 0 and sets his Y position to the floor height|descriptionEnd| */ | ||||||
| void stop_and_set_height_to_floor(struct MarioState *m); | void stop_and_set_height_to_floor(struct MarioState *m); | ||||||
| /* |description|Performs a full Mario stationary physics step (4 substeps) and returns an `GROUND_STEP_*` result|descriptionEnd| */ | /* |description|Performs a full Mario stationary physics step (4 substeps) and returns a `GROUND_STEP_*` result|descriptionEnd| */ | ||||||
| s32 stationary_ground_step(struct MarioState *m); | s32 stationary_ground_step(struct MarioState *m); | ||||||
| /* |description|Performs a full Mario ground physics step (4 substeps) and returns an `GROUND_STEP_*` result|descriptionEnd| */ | /* |description|Performs a full Mario ground physics step (4 substeps) and returns a `GROUND_STEP_*` result|descriptionEnd| */ | ||||||
| s32 perform_ground_step(struct MarioState *m); | s32 perform_ground_step(struct MarioState *m); | ||||||
| /* |description|Performs a full Mario air physics step (4 substeps) and returns an `AIR_STEP_*` result|descriptionEnd| */ | /* |description|Performs a full Mario air physics step (4 substeps) and returns an `AIR_STEP_*` result|descriptionEnd| */ | ||||||
| s32 perform_air_step(struct MarioState *m, u32 stepArg); | s32 perform_air_step(struct MarioState *m, u32 stepArg); | ||||||
|  |  | ||||||
|  | @ -4,6 +4,9 @@ | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <assert.h> | #include <assert.h> | ||||||
|  | #ifdef _WIN32 | ||||||
|  | #include <windows.h> | ||||||
|  | #endif | ||||||
| #include <ctype.h> | #include <ctype.h> | ||||||
| 
 | 
 | ||||||
| #include "platform.h" | #include "platform.h" | ||||||
|  | @ -114,6 +117,7 @@ unsigned int configKeyStickDown[MAX_BINDS]        = { 0x001F,     VK_INVALID, VK | ||||||
| unsigned int configKeyStickLeft[MAX_BINDS]        = { 0x001E,     VK_INVALID, VK_INVALID }; | unsigned int configKeyStickLeft[MAX_BINDS]        = { 0x001E,     VK_INVALID, VK_INVALID }; | ||||||
| unsigned int configKeyStickRight[MAX_BINDS]       = { 0x0020,     VK_INVALID, VK_INVALID }; | unsigned int configKeyStickRight[MAX_BINDS]       = { 0x0020,     VK_INVALID, VK_INVALID }; | ||||||
| unsigned int configKeyChat[MAX_BINDS]             = { 0x001C,     VK_INVALID, VK_INVALID }; | unsigned int configKeyChat[MAX_BINDS]             = { 0x001C,     VK_INVALID, VK_INVALID }; | ||||||
|  | unsigned int configKeyChatCommand[MAX_BINDS]      = { VK_INVALID, VK_INVALID, VK_INVALID }; | ||||||
| unsigned int configKeyPlayerList[MAX_BINDS]       = { 0x000F,     0x1004,     VK_INVALID }; | unsigned int configKeyPlayerList[MAX_BINDS]       = { 0x000F,     0x1004,     VK_INVALID }; | ||||||
| unsigned int configKeyDUp[MAX_BINDS]              = { 0x0147,     0x100b,     VK_INVALID }; | unsigned int configKeyDUp[MAX_BINDS]              = { 0x0147,     0x100b,     VK_INVALID }; | ||||||
| unsigned int configKeyDDown[MAX_BINDS]            = { 0x014f,     0x100c,     VK_INVALID }; | unsigned int configKeyDDown[MAX_BINDS]            = { 0x014f,     0x100c,     VK_INVALID }; | ||||||
|  | @ -128,7 +132,10 @@ unsigned int configRumbleStrength                 = 50; | ||||||
| unsigned int configGamepadNumber                  = 0; | unsigned int configGamepadNumber                  = 0; | ||||||
| bool         configBackgroundGamepad              = true; | bool         configBackgroundGamepad              = true; | ||||||
| bool         configDisableGamepads                = false; | bool         configDisableGamepads                = false; | ||||||
| bool         configUseStandardKeyBindingsChat     = false; | bool         configUseStandardKeyBindingsChat     = true; | ||||||
|  | bool         configChatCharCounter                = true; | ||||||
|  | bool         configDisableChatWhenClosed          = false; | ||||||
|  | unsigned int configChatWidth                      = 800; | ||||||
| bool         configSmoothScrolling                = false; | bool         configSmoothScrolling                = false; | ||||||
| // free camera settings
 | // free camera settings
 | ||||||
| bool         configEnableFreeCamera               = false; | bool         configEnableFreeCamera               = false; | ||||||
|  | @ -257,6 +264,7 @@ static const struct ConfigOption options[] = { | ||||||
|     {.name = "key_stickleft",                  .type = CONFIG_TYPE_BIND, .uintValue = configKeyStickLeft}, |     {.name = "key_stickleft",                  .type = CONFIG_TYPE_BIND, .uintValue = configKeyStickLeft}, | ||||||
|     {.name = "key_stickright",                 .type = CONFIG_TYPE_BIND, .uintValue = configKeyStickRight}, |     {.name = "key_stickright",                 .type = CONFIG_TYPE_BIND, .uintValue = configKeyStickRight}, | ||||||
|     {.name = "key_chat",                       .type = CONFIG_TYPE_BIND, .uintValue = configKeyChat}, |     {.name = "key_chat",                       .type = CONFIG_TYPE_BIND, .uintValue = configKeyChat}, | ||||||
|  |     {.name = "key_chat_command",               .type = CONFIG_TYPE_BIND, .uintValue = configKeyChatCommand}, | ||||||
|     {.name = "key_playerlist",                 .type = CONFIG_TYPE_BIND, .uintValue = configKeyPlayerList}, |     {.name = "key_playerlist",                 .type = CONFIG_TYPE_BIND, .uintValue = configKeyPlayerList}, | ||||||
|     {.name = "key_dup",                        .type = CONFIG_TYPE_BIND, .uintValue = configKeyDUp}, |     {.name = "key_dup",                        .type = CONFIG_TYPE_BIND, .uintValue = configKeyDUp}, | ||||||
|     {.name = "key_ddown",                      .type = CONFIG_TYPE_BIND, .uintValue = configKeyDDown}, |     {.name = "key_ddown",                      .type = CONFIG_TYPE_BIND, .uintValue = configKeyDDown}, | ||||||
|  | @ -274,6 +282,9 @@ static const struct ConfigOption options[] = { | ||||||
|     {.name = "disable_gamepads",               .type = CONFIG_TYPE_BOOL, .boolValue = &configDisableGamepads}, |     {.name = "disable_gamepads",               .type = CONFIG_TYPE_BOOL, .boolValue = &configDisableGamepads}, | ||||||
| #endif | #endif | ||||||
|     {.name = "use_standard_key_bindings_chat", .type = CONFIG_TYPE_BOOL, .boolValue = &configUseStandardKeyBindingsChat}, |     {.name = "use_standard_key_bindings_chat", .type = CONFIG_TYPE_BOOL, .boolValue = &configUseStandardKeyBindingsChat}, | ||||||
|  |     {.name = "chat_width",                     .type = CONFIG_TYPE_UINT, .uintValue = &configChatWidth}, | ||||||
|  |     {.name = "chat_char_counter",              .type = CONFIG_TYPE_BOOL, .boolValue = &configChatCharCounter}, | ||||||
|  |     {.name = "disable_chat_when_closed",       .type = CONFIG_TYPE_BOOL, .boolValue = &configDisableChatWhenClosed}, | ||||||
|     {.name = "smooth_scrolling",               .type = CONFIG_TYPE_BOOL, .boolValue = &configSmoothScrolling}, |     {.name = "smooth_scrolling",               .type = CONFIG_TYPE_BOOL, .boolValue = &configSmoothScrolling}, | ||||||
|     {.name = "stick_rotate_left",              .type = CONFIG_TYPE_BOOL, .boolValue = &configStick.rotateLeft}, |     {.name = "stick_rotate_left",              .type = CONFIG_TYPE_BOOL, .boolValue = &configStick.rotateLeft}, | ||||||
|     {.name = "stick_invert_left_x",            .type = CONFIG_TYPE_BOOL, .boolValue = &configStick.invertLeftX}, |     {.name = "stick_invert_left_x",            .type = CONFIG_TYPE_BOOL, .boolValue = &configStick.invertLeftX}, | ||||||
|  | @ -666,6 +677,23 @@ static void configfile_load_internal(const char *filename, bool* error) { | ||||||
|     if (file == NULL) { |     if (file == NULL) { | ||||||
|         // Create a new config file and save defaults
 |         // Create a new config file and save defaults
 | ||||||
|         printf("Config file '%s' not found. Creating it.\n", filename); |         printf("Config file '%s' not found. Creating it.\n", filename); | ||||||
|  |         // set sensible default for chat command key depending on keyboard layout
 | ||||||
|  |         if (configKeyChatCommand[0] == VK_INVALID && configKeyChatCommand[1] == VK_INVALID && configKeyChatCommand[2] == VK_INVALID) { | ||||||
|  | #ifdef _WIN32 | ||||||
|  |             HKL hkl = GetKeyboardLayout(0); | ||||||
|  |             LANGID lang = LOWORD(hkl); | ||||||
|  |             switch (PRIMARYLANGID(lang)) { | ||||||
|  |                 case LANG_GERMAN: | ||||||
|  |                     configKeyChatCommand[0] = 0x002B; // '#' on QWERTZ (OEM_5 position)
 | ||||||
|  |                     break; | ||||||
|  |                 default: | ||||||
|  |                     configKeyChatCommand[0] = 0x0035; // '/' on US QWERTY
 | ||||||
|  |                     break; | ||||||
|  |             } | ||||||
|  | #else | ||||||
|  |             configKeyChatCommand[0] = 0x0035; // '/' default on non-Windows
 | ||||||
|  | #endif | ||||||
|  |         } | ||||||
|         configfile_save(filename); |         configfile_save(filename); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  | @ -777,6 +805,23 @@ NEXT_OPTION: | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fs_close(file); |     fs_close(file); | ||||||
|  |     // If user has no chat command bind yet, set a default based on layout
 | ||||||
|  |     if (configKeyChatCommand[0] == VK_INVALID && configKeyChatCommand[1] == VK_INVALID && configKeyChatCommand[2] == VK_INVALID) { | ||||||
|  | #ifdef _WIN32 | ||||||
|  |         HKL hkl = GetKeyboardLayout(0); | ||||||
|  |         LANGID lang = LOWORD(hkl); | ||||||
|  |         switch (PRIMARYLANGID(lang)) { | ||||||
|  |             case LANG_GERMAN: | ||||||
|  |                 configKeyChatCommand[0] = 0x002B; // '#'
 | ||||||
|  |                 break; | ||||||
|  |             default: | ||||||
|  |                 configKeyChatCommand[0] = 0x0035; // '/'
 | ||||||
|  |                 break; | ||||||
|  |         } | ||||||
|  | #else | ||||||
|  |         configKeyChatCommand[0] = 0x0035; | ||||||
|  | #endif | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     if (configFramerateMode < 0 || configFramerateMode > RRM_MAX) { configFramerateMode = 0; } |     if (configFramerateMode < 0 || configFramerateMode > RRM_MAX) { configFramerateMode = 0; } | ||||||
|     if (configFrameLimit < 30)   { configFrameLimit = 30; } |     if (configFrameLimit < 30)   { configFrameLimit = 30; } | ||||||
|  |  | ||||||
|  | @ -80,6 +80,7 @@ extern unsigned int configKeyStickDown[MAX_BINDS]; | ||||||
| extern unsigned int configKeyStickLeft[MAX_BINDS]; | extern unsigned int configKeyStickLeft[MAX_BINDS]; | ||||||
| extern unsigned int configKeyStickRight[MAX_BINDS]; | extern unsigned int configKeyStickRight[MAX_BINDS]; | ||||||
| extern unsigned int configKeyChat[MAX_BINDS]; | extern unsigned int configKeyChat[MAX_BINDS]; | ||||||
|  | extern unsigned int configKeyChatCommand[MAX_BINDS]; | ||||||
| extern unsigned int configKeyPlayerList[MAX_BINDS]; | extern unsigned int configKeyPlayerList[MAX_BINDS]; | ||||||
| extern unsigned int configKeyDUp[MAX_BINDS]; | extern unsigned int configKeyDUp[MAX_BINDS]; | ||||||
| extern unsigned int configKeyDDown[MAX_BINDS]; | extern unsigned int configKeyDDown[MAX_BINDS]; | ||||||
|  | @ -95,6 +96,9 @@ extern unsigned int configGamepadNumber; | ||||||
| extern bool         configBackgroundGamepad; | extern bool         configBackgroundGamepad; | ||||||
| extern bool         configDisableGamepads; | extern bool         configDisableGamepads; | ||||||
| extern bool         configUseStandardKeyBindingsChat; | extern bool         configUseStandardKeyBindingsChat; | ||||||
|  | extern bool         configChatCharCounter; | ||||||
|  | extern bool         configDisableChatWhenClosed; | ||||||
|  | extern unsigned int configChatWidth; | ||||||
| extern bool         configSmoothScrolling; | extern bool         configSmoothScrolling; | ||||||
| // free camera settings
 | // free camera settings
 | ||||||
| extern bool         configEnableFreeCamera; | extern bool         configEnableFreeCamera; | ||||||
|  |  | ||||||
|  | @ -54,6 +54,11 @@ void sent_history_init(ArrayList *arrayList) { | ||||||
| void sent_history_add_message(ArrayList *arrayList, const char *newMessage) { | void sent_history_add_message(ArrayList *arrayList, const char *newMessage) { | ||||||
|     if (!configUseStandardKeyBindingsChat && (!newMessage || newMessage[0] != '/')) { return; } |     if (!configUseStandardKeyBindingsChat && (!newMessage || newMessage[0] != '/')) { return; } | ||||||
| 
 | 
 | ||||||
|  |     // Don't add duplicate messages - check if the new message is the same as the last one
 | ||||||
|  |     if (arrayList->size > 0 && strcmp(arrayList->messages[arrayList->size - 1], newMessage) == 0) { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     if (arrayList->size == MAX_HISTORY_SIZE) { |     if (arrayList->size == MAX_HISTORY_SIZE) { | ||||||
|         for (s32 i = 1; i < MAX_HISTORY_SIZE; i++) { |         for (s32 i = 1; i < MAX_HISTORY_SIZE; i++) { | ||||||
|             snprintf(arrayList->messages[i-1], MAX_CHAT_MSG_LENGTH, "%s", arrayList->messages[i]); |             snprintf(arrayList->messages[i-1], MAX_CHAT_MSG_LENGTH, "%s", arrayList->messages[i]); | ||||||
|  | @ -100,7 +105,7 @@ void sent_history_reset_navigation(ArrayList *arrayList) { | ||||||
| bool djui_chat_box_render(struct DjuiBase* base) { | bool djui_chat_box_render(struct DjuiBase* base) { | ||||||
|     struct DjuiChatBox* chatBox = (struct DjuiChatBox*)base; |     struct DjuiChatBox* chatBox = (struct DjuiChatBox*)base; | ||||||
|     struct DjuiBase* ccBase = &chatBox->chatContainer->base; |     struct DjuiBase* ccBase = &chatBox->chatContainer->base; | ||||||
|     djui_base_set_size(ccBase, 1.0f, chatBox->base.comp.height - 32 - 8); |     djui_base_set_size(ccBase, 1.0f, chatBox->base.comp.height - 32 - 18); | ||||||
|     if (chatBox->scrolling) { |     if (chatBox->scrolling) { | ||||||
|         f32 yMax = chatBox->chatContainer->base.elem.height - chatBox->chatFlow->base.height.value; |         f32 yMax = chatBox->chatContainer->base.elem.height - chatBox->chatFlow->base.height.value; | ||||||
|         f32 target = chatBox->chatFlow->base.y.value + (chatBox->scrollY - chatBox->chatFlow->base.y.value) * (configSmoothScrolling ? 0.5f : 1.f); |         f32 target = chatBox->chatFlow->base.y.value + (chatBox->scrollY - chatBox->chatFlow->base.y.value) * (configSmoothScrolling ? 0.5f : 1.f); | ||||||
|  | @ -130,7 +135,12 @@ static void djui_chat_box_set_focus_style(void) { | ||||||
|         djui_interactable_set_input_focus(&gDjuiChatBox->chatInput->base); |         djui_interactable_set_input_focus(&gDjuiChatBox->chatInput->base); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     djui_base_set_color(&gDjuiChatBox->chatFlow->base, 0, 0, 0, gDjuiChatBoxFocus ? 128 : 0); |     bool hasMessages = (gDjuiChatBox->chatFlow->base.height.value > 2.0f); | ||||||
|  |     u8 alpha = 0; | ||||||
|  |     if (hasMessages) { | ||||||
|  |         alpha = gDjuiChatBoxFocus ? 160 : 0; | ||||||
|  |     } | ||||||
|  |     djui_base_set_color(&gDjuiChatBox->chatFlow->base, 0, 0, 0, alpha); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void djui_chat_box_input_enter(struct DjuiInputbox* chatInput) { | static void djui_chat_box_input_enter(struct DjuiInputbox* chatInput) { | ||||||
|  | @ -140,6 +150,10 @@ static void djui_chat_box_input_enter(struct DjuiInputbox* chatInput) { | ||||||
|         sent_history_add_message(&sentHistory, chatInput->buffer); |         sent_history_add_message(&sentHistory, chatInput->buffer); | ||||||
|         if (chatInput->buffer[0] == '/') { |         if (chatInput->buffer[0] == '/') { | ||||||
|             if (strcmp(chatInput->buffer, "/help") == 0 || strcmp(chatInput->buffer, "/?") == 0 || strcmp(chatInput->buffer, "/") == 0) { |             if (strcmp(chatInput->buffer, "/help") == 0 || strcmp(chatInput->buffer, "/?") == 0 || strcmp(chatInput->buffer, "/") == 0) { | ||||||
|  |                 char tabcompletionHint[MAX_CHAT_MSG_LENGTH]; | ||||||
|  |                 snprintf(tabcompletionHint, sizeof(tabcompletionHint), "\\#ff2020\\%s \\#ffa020\\(%s)\\#ff2020\\:\\#000000\\",  | ||||||
|  |                     DLANG(CHAT, ALL_COMMANDS), DLANG(CHAT, TAB_COMPLETE_INFO)); | ||||||
|  |                 djui_chat_message_create(tabcompletionHint); | ||||||
|                 display_chat_commands(); |                 display_chat_commands(); | ||||||
|             } else if (!exec_chat_command(chatInput->buffer)) { |             } else if (!exec_chat_command(chatInput->buffer)) { | ||||||
|                 char extendedUnknownCommandMessage[MAX_CHAT_MSG_LENGTH]; |                 char extendedUnknownCommandMessage[MAX_CHAT_MSG_LENGTH]; | ||||||
|  | @ -176,7 +190,7 @@ static char* get_main_command_from_input(const char* input) { | ||||||
|     return command; |     return command; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static bool complete_subcommand(const char* mainCommand, const char* subCommandPrefix) { | static bool complete_subcommand(const char* mainCommand, const char* subCommandPrefix, bool reverse) { | ||||||
|     char** subcommands = smlua_get_chat_subcommands_list(mainCommand); |     char** subcommands = smlua_get_chat_subcommands_list(mainCommand); | ||||||
| 
 | 
 | ||||||
|     if (!subcommands || !subcommands[0]) { |     if (!subcommands || !subcommands[0]) { | ||||||
|  | @ -192,7 +206,13 @@ static bool complete_subcommand(const char* mainCommand, const char* subCommandP | ||||||
| 
 | 
 | ||||||
|     bool completionSuccess = false; |     bool completionSuccess = false; | ||||||
|     if (foundSubCommandsCount > 0) { |     if (foundSubCommandsCount > 0) { | ||||||
|         sCommandsTabCompletionIndex = (sCommandsTabCompletionIndex + 1) % foundSubCommandsCount; |         if (reverse) { | ||||||
|  |             sCommandsTabCompletionIndex = (sCommandsTabCompletionIndex <= 0)  | ||||||
|  |                 ? foundSubCommandsCount - 1  | ||||||
|  |                 : (sCommandsTabCompletionIndex - 1) % foundSubCommandsCount; | ||||||
|  |         } else { | ||||||
|  |             sCommandsTabCompletionIndex = (sCommandsTabCompletionIndex + 1) % foundSubCommandsCount; | ||||||
|  |         } | ||||||
|         s32 currentIndex = 0; |         s32 currentIndex = 0; | ||||||
| 
 | 
 | ||||||
|         for (s32 i = 0; subcommands[i] != NULL; i++) { |         for (s32 i = 0; subcommands[i] != NULL; i++) { | ||||||
|  | @ -273,7 +293,7 @@ void djui_inputbox_replace_current_word(struct DjuiInputbox* inputbox, char* tex | ||||||
|     djui_inputbox_move_cursor_to_position(inputbox, currentWordStart + strlen(text)); |     djui_inputbox_move_cursor_to_position(inputbox, currentWordStart + strlen(text)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static bool complete_player_name(const char* namePrefix) { | static bool complete_player_name(const char* namePrefix, bool reverse) { | ||||||
|     char** playerNames = smlua_get_chat_player_list(); |     char** playerNames = smlua_get_chat_player_list(); | ||||||
|     if (!playerNames || !playerNames[0]) { |     if (!playerNames || !playerNames[0]) { | ||||||
|         if (playerNames) { |         if (playerNames) { | ||||||
|  | @ -291,7 +311,13 @@ static bool complete_player_name(const char* namePrefix) { | ||||||
| 
 | 
 | ||||||
|     bool completionSuccess = false; |     bool completionSuccess = false; | ||||||
|     if (foundNamesCount > 0) { |     if (foundNamesCount > 0) { | ||||||
|         sPlayersTabCompletionIndex = (sPlayersTabCompletionIndex + 1) % foundNamesCount; |         if (reverse) { | ||||||
|  |             sPlayersTabCompletionIndex = (sPlayersTabCompletionIndex <= 0)  | ||||||
|  |                 ? foundNamesCount - 1  | ||||||
|  |                 : (sPlayersTabCompletionIndex - 1) % foundNamesCount; | ||||||
|  |         } else { | ||||||
|  |             sPlayersTabCompletionIndex = (sPlayersTabCompletionIndex + 1) % foundNamesCount; | ||||||
|  |         } | ||||||
|         s32 currentIndex = 0; |         s32 currentIndex = 0; | ||||||
| 
 | 
 | ||||||
|         for (s32 i = 0; playerNames[i] != NULL; i++) { |         for (s32 i = 0; playerNames[i] != NULL; i++) { | ||||||
|  | @ -314,14 +340,83 @@ static bool complete_player_name(const char* namePrefix) { | ||||||
|     return completionSuccess; |     return completionSuccess; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void handle_tab_completion(void) { | char* get_next_tab_completion_preview(const char* input) { | ||||||
|  |     if (input[0] != '/') { | ||||||
|  |         return NULL; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     char* spacePosition = strrchr(input, ' '); | ||||||
|  |     if (spacePosition != NULL) { | ||||||
|  |         // Subcommand completion
 | ||||||
|  |         char* mainCommand = get_main_command_from_input(input); | ||||||
|  |         if (mainCommand) { | ||||||
|  |             char** subcommands = smlua_get_chat_subcommands_list(mainCommand + 1); | ||||||
|  |             if (subcommands && subcommands[0]) { | ||||||
|  |                 s32 foundSubCommandsCount = 0; | ||||||
|  |                  | ||||||
|  |                 // Count matching subcommands
 | ||||||
|  |                 for (s32 i = 0; subcommands[i] != NULL; i++) { | ||||||
|  |                     if (strncmp(subcommands[i], spacePosition + 1, strlen(spacePosition + 1)) == 0) { | ||||||
|  |                         foundSubCommandsCount++; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                  | ||||||
|  |                 if (foundSubCommandsCount > 0) { | ||||||
|  |                     // Find the first matching subcommand
 | ||||||
|  |                     for (s32 i = 0; subcommands[i] != NULL; i++) { | ||||||
|  |                         if (strncmp(subcommands[i], spacePosition + 1, strlen(spacePosition + 1)) == 0) { | ||||||
|  |                             char* preview = malloc(MAX_CHAT_MSG_LENGTH); | ||||||
|  |                             // Only show the missing part of the subcommand
 | ||||||
|  |                             char* inputSubcommand = spacePosition + 1; | ||||||
|  |                             char* missingPart = subcommands[i] + strlen(inputSubcommand); | ||||||
|  |                             snprintf(preview, MAX_CHAT_MSG_LENGTH, "%s", missingPart); | ||||||
|  |                             free(mainCommand); | ||||||
|  |                             return preview; | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             free(mainCommand); | ||||||
|  |         } | ||||||
|  |     } else { | ||||||
|  |         // Main command completion
 | ||||||
|  |         char* bufferWithoutSlash = (char*)input + 1; | ||||||
|  |         char** commands = smlua_get_chat_maincommands_list(); | ||||||
|  |         if (commands && commands[0]) { | ||||||
|  |             s32 foundCommandsCount = 0; | ||||||
|  |              | ||||||
|  |             // Count matching commands
 | ||||||
|  |             for (s32 i = 0; commands[i] != NULL; i++) { | ||||||
|  |                 if (strncmp(commands[i], bufferWithoutSlash, strlen(bufferWithoutSlash)) == 0) { | ||||||
|  |                     foundCommandsCount++; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |              | ||||||
|  |             if (foundCommandsCount > 0) { | ||||||
|  |                 // Find the first matching command
 | ||||||
|  |                 for (s32 i = 0; commands[i] != NULL; i++) { | ||||||
|  |                     if (strncmp(commands[i], bufferWithoutSlash, strlen(bufferWithoutSlash)) == 0) { | ||||||
|  |                         char* preview = malloc(MAX_CHAT_MSG_LENGTH); | ||||||
|  |                         // Only show the missing part of the command
 | ||||||
|  |                         snprintf(preview, MAX_CHAT_MSG_LENGTH, "%s", commands[i] + strlen(bufferWithoutSlash)); | ||||||
|  |                         return preview; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     return NULL; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void handle_tab_completion(bool reverse) { | ||||||
|     bool alreadyTabCompleted = false; |     bool alreadyTabCompleted = false; | ||||||
|     if (gDjuiChatBox->chatInput->buffer[0] == '/') { |     if (gDjuiChatBox->chatInput->buffer[0] == '/') { | ||||||
|         char* spacePosition = strrchr(sCommandsTabCompletionOriginalText, ' '); |         char* spacePosition = strrchr(sCommandsTabCompletionOriginalText, ' '); | ||||||
|         if (spacePosition != NULL) { |         if (spacePosition != NULL) { | ||||||
|             char* mainCommand = get_main_command_from_input(sCommandsTabCompletionOriginalText); |             char* mainCommand = get_main_command_from_input(sCommandsTabCompletionOriginalText); | ||||||
|             if (mainCommand) { |             if (mainCommand) { | ||||||
|                 if (!complete_subcommand(mainCommand + 1, spacePosition + 1)) { |                 if (!complete_subcommand(mainCommand + 1, spacePosition + 1, reverse)) { | ||||||
|                     reset_tab_completion_all(); |                     reset_tab_completion_all(); | ||||||
|                 } else { |                 } else { | ||||||
|                     alreadyTabCompleted = true; |                     alreadyTabCompleted = true; | ||||||
|  | @ -344,7 +439,13 @@ static void handle_tab_completion(void) { | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if (foundCommandsCount > 0) { |             if (foundCommandsCount > 0) { | ||||||
|                 sCommandsTabCompletionIndex = (sCommandsTabCompletionIndex + 1) % foundCommandsCount; |                 if (reverse) { | ||||||
|  |                     sCommandsTabCompletionIndex = (sCommandsTabCompletionIndex <= 0)  | ||||||
|  |                         ? foundCommandsCount - 1  | ||||||
|  |                         : (sCommandsTabCompletionIndex - 1) % foundCommandsCount; | ||||||
|  |                 } else { | ||||||
|  |                     sCommandsTabCompletionIndex = (sCommandsTabCompletionIndex + 1) % foundCommandsCount; | ||||||
|  |                 } | ||||||
|                 s32 currentIndex = 0; |                 s32 currentIndex = 0; | ||||||
| 
 | 
 | ||||||
|                 for (s32 i = 0; commands[i] != NULL; i++) { |                 for (s32 i = 0; commands[i] != NULL; i++) { | ||||||
|  | @ -364,7 +465,7 @@ static void handle_tab_completion(void) { | ||||||
|                 if (spacePositionB != NULL) { |                 if (spacePositionB != NULL) { | ||||||
|                     char* mainCommandB = get_main_command_from_input(sCommandsTabCompletionOriginalText); |                     char* mainCommandB = get_main_command_from_input(sCommandsTabCompletionOriginalText); | ||||||
|                     if (mainCommandB) { |                     if (mainCommandB) { | ||||||
|                         if (!complete_subcommand(mainCommandB + 1, spacePositionB + 1)) { |                         if (!complete_subcommand(mainCommandB + 1, spacePositionB + 1, reverse)) { | ||||||
|                             reset_tab_completion_all(); |                             reset_tab_completion_all(); | ||||||
|                         } else { |                         } else { | ||||||
|                             alreadyTabCompleted = true; |                             alreadyTabCompleted = true; | ||||||
|  | @ -404,7 +505,7 @@ static void handle_tab_completion(void) { | ||||||
|             if (sPlayersTabCompletionIndex == -1) { |             if (sPlayersTabCompletionIndex == -1) { | ||||||
|                 snprintf(sPlayersTabCompletionOriginalText, MAX_CHAT_MSG_LENGTH, "%s", wordInfo.word); |                 snprintf(sPlayersTabCompletionOriginalText, MAX_CHAT_MSG_LENGTH, "%s", wordInfo.word); | ||||||
|             } |             } | ||||||
|             if (!complete_player_name(sPlayersTabCompletionOriginalText)) { |             if (!complete_player_name(sPlayersTabCompletionOriginalText, reverse)) { | ||||||
|                 reset_tab_completion_players(); |                 reset_tab_completion_players(); | ||||||
|             } else { |             } else { | ||||||
|                 alreadyTabCompleted = true; |                 alreadyTabCompleted = true; | ||||||
|  | @ -457,7 +558,7 @@ static bool djui_chat_box_input_on_key_down(UNUSED struct DjuiBase* base, int sc | ||||||
|             gDjuiChatBox->scrollY -= pageAmount; |             gDjuiChatBox->scrollY -= pageAmount; | ||||||
|             break; |             break; | ||||||
|         case SCANCODE_TAB: |         case SCANCODE_TAB: | ||||||
|             handle_tab_completion(); |             handle_tab_completion(gDjuiInputHeldShift); | ||||||
|             return true; |             return true; | ||||||
|         case SCANCODE_ENTER: |         case SCANCODE_ENTER: | ||||||
|             reset_tab_completion_all(); |             reset_tab_completion_all(); | ||||||
|  | @ -520,6 +621,19 @@ void djui_chat_box_toggle(void) { | ||||||
|     gDjuiChatBox->chatFlow->base.y.value = gDjuiChatBox->chatContainer->base.elem.height - gDjuiChatBox->chatFlow->base.height.value; |     gDjuiChatBox->chatFlow->base.y.value = gDjuiChatBox->chatContainer->base.elem.height - gDjuiChatBox->chatFlow->base.height.value; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void djui_chat_box_open_with_text(const char* text) { | ||||||
|  |     if (gDjuiChatBox == NULL) { return; } | ||||||
|  |     if (!gDjuiChatBoxFocus) { | ||||||
|  |         sDjuiChatBoxClearText = false; | ||||||
|  |         gDjuiChatBoxFocus = true; | ||||||
|  |         djui_chat_box_set_focus_style(); | ||||||
|  |     } | ||||||
|  |     if (gDjuiChatBox->chatInput != NULL && text != NULL) { | ||||||
|  |         djui_inputbox_set_text(gDjuiChatBox->chatInput, (char*)text); | ||||||
|  |         djui_inputbox_move_cursor_to_end(gDjuiChatBox->chatInput); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| struct DjuiChatBox* djui_chat_box_create(void) { | struct DjuiChatBox* djui_chat_box_create(void) { | ||||||
|     if (gDjuiChatBox != NULL) { |     if (gDjuiChatBox != NULL) { | ||||||
|         djui_base_destroy(&gDjuiChatBox->base); |         djui_base_destroy(&gDjuiChatBox->base); | ||||||
|  | @ -531,7 +645,7 @@ struct DjuiChatBox* djui_chat_box_create(void) { | ||||||
| 
 | 
 | ||||||
|     djui_base_init(&gDjuiRoot->base, base, djui_chat_box_render, djui_chat_box_destroy); |     djui_base_init(&gDjuiRoot->base, base, djui_chat_box_render, djui_chat_box_destroy); | ||||||
|     djui_base_set_size_type(base, DJUI_SVT_ABSOLUTE, DJUI_SVT_ABSOLUTE); |     djui_base_set_size_type(base, DJUI_SVT_ABSOLUTE, DJUI_SVT_ABSOLUTE); | ||||||
|     djui_base_set_size(base, 600, 400); |     djui_base_set_size(base, configChatWidth, 400); | ||||||
|     djui_base_set_alignment(base, DJUI_HALIGN_LEFT, DJUI_VALIGN_BOTTOM); |     djui_base_set_alignment(base, DJUI_HALIGN_LEFT, DJUI_VALIGN_BOTTOM); | ||||||
|     djui_base_set_color(base, 0, 0, 0, 0); |     djui_base_set_color(base, 0, 0, 0, 0); | ||||||
|     djui_base_set_padding(base, 0, 8, 8, 8); |     djui_base_set_padding(base, 0, 8, 8, 8); | ||||||
|  | @ -545,12 +659,12 @@ struct DjuiChatBox* djui_chat_box_create(void) { | ||||||
| 
 | 
 | ||||||
|     struct DjuiFlowLayout* chatFlow = djui_flow_layout_create(ccBase); |     struct DjuiFlowLayout* chatFlow = djui_flow_layout_create(ccBase); | ||||||
|     struct DjuiBase* cfBase = &chatFlow->base; |     struct DjuiBase* cfBase = &chatFlow->base; | ||||||
|     djui_base_set_location(cfBase, 0, 0); |     djui_base_set_location(cfBase, 0, 8); | ||||||
|     djui_base_set_size_type(cfBase, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); |     djui_base_set_size_type(cfBase, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); | ||||||
|     djui_base_set_size(cfBase, 1.0f, 2); |     djui_base_set_size(cfBase, 1.0f, 2); | ||||||
|     djui_base_set_color(cfBase, 0, 0, 0, 128); |     djui_base_set_color(cfBase, 0, 0, 0, 64); | ||||||
|     djui_base_set_padding(cfBase, 2, 2, 2, 2); |     djui_base_set_padding(cfBase, 0, 2, 0, 2); | ||||||
|     djui_flow_layout_set_margin(chatFlow, 2); |     djui_flow_layout_set_margin(chatFlow, 0); | ||||||
|     djui_flow_layout_set_flow_direction(chatFlow, DJUI_FLOW_DIR_UP); |     djui_flow_layout_set_flow_direction(chatFlow, DJUI_FLOW_DIR_UP); | ||||||
|     cfBase->addChildrenToHead = true; |     cfBase->addChildrenToHead = true; | ||||||
|     cfBase->abandonAfterChildRenderFail = true; |     cfBase->abandonAfterChildRenderFail = true; | ||||||
|  | @ -561,6 +675,9 @@ struct DjuiChatBox* djui_chat_box_create(void) { | ||||||
|     djui_base_set_size_type(ciBase, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); |     djui_base_set_size_type(ciBase, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); | ||||||
|     djui_base_set_size(ciBase, 1.0f, 32); |     djui_base_set_size(ciBase, 1.0f, 32); | ||||||
|     djui_base_set_alignment(ciBase, DJUI_HALIGN_LEFT, DJUI_VALIGN_BOTTOM); |     djui_base_set_alignment(ciBase, DJUI_HALIGN_LEFT, DJUI_VALIGN_BOTTOM); | ||||||
|  |     djui_base_set_location(ciBase, 0, 0); | ||||||
|  |     djui_base_set_border_width(ciBase, 0); | ||||||
|  | 
 | ||||||
|     djui_interactable_hook_key(&chatInput->base, djui_chat_box_input_on_key_down, djui_inputbox_on_key_up); |     djui_interactable_hook_key(&chatInput->base, djui_chat_box_input_on_key_down, djui_inputbox_on_key_up); | ||||||
|     djui_interactable_hook_text_input(&chatInput->base, djui_chat_box_input_on_text_input); |     djui_interactable_hook_text_input(&chatInput->base, djui_chat_box_input_on_text_input); | ||||||
|     djui_interactable_hook_text_editing(&chatInput->base, djui_chat_box_input_on_text_editing); |     djui_interactable_hook_text_editing(&chatInput->base, djui_chat_box_input_on_text_editing); | ||||||
|  |  | ||||||
|  | @ -14,4 +14,6 @@ extern struct DjuiChatBox* gDjuiChatBox; | ||||||
| extern bool gDjuiChatBoxFocus; | extern bool gDjuiChatBoxFocus; | ||||||
| 
 | 
 | ||||||
| void djui_chat_box_toggle(void); | void djui_chat_box_toggle(void); | ||||||
|  | void djui_chat_box_open_with_text(const char* text); | ||||||
|  | char* get_next_tab_completion_preview(const char* input); | ||||||
| struct DjuiChatBox* djui_chat_box_create(void); | struct DjuiChatBox* djui_chat_box_create(void); | ||||||
|  |  | ||||||
|  | @ -24,14 +24,16 @@ static bool djui_chat_message_render(struct DjuiBase* base) { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (gDjuiChatBoxFocus) { |     if (gDjuiChatBoxFocus) { | ||||||
|         djui_base_set_color(base, 0, 0, 0, 120); |         djui_base_set_color(base, 0, 0, 0, 0); | ||||||
|         djui_base_set_color(ctBase, 255, 255, 255, 255); |         djui_base_set_color(ctBase, 255, 255, 255, 255); | ||||||
|         djui_base_set_size_type(base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); |         djui_base_set_size_type(base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); | ||||||
|         djui_base_set_size(base, 1.0f, chatMessage->base.height.value); |         djui_base_set_size(base, 1.0f, chatMessage->base.height.value); | ||||||
|  |     } else if (configDisableChatWhenClosed) { | ||||||
|  |         return false; | ||||||
|     } else if (f <= 0.1f) { |     } else if (f <= 0.1f) { | ||||||
|         return false; |         return false; | ||||||
|     } else { |     } else { | ||||||
|         djui_base_set_color(base, 0, 0, 0, 180 * f); |         djui_base_set_color(base, 0, 0, 0, 140 * f); | ||||||
|         djui_base_set_color(ctBase, 255, 255, 255, 255 * f); |         djui_base_set_color(ctBase, 255, 255, 255, 255 * f); | ||||||
|         djui_base_set_size_type(base, DJUI_SVT_ABSOLUTE, DJUI_SVT_ABSOLUTE); |         djui_base_set_size_type(base, DJUI_SVT_ABSOLUTE, DJUI_SVT_ABSOLUTE); | ||||||
|         djui_base_set_size(base, chatMessage->messageWidth, chatMessage->base.height.value); |         djui_base_set_size(base, chatMessage->messageWidth, chatMessage->base.height.value); | ||||||
|  | @ -76,8 +78,8 @@ void djui_chat_message_create(const char* message) { | ||||||
|     djui_base_init(&gDjuiChatBox->chatFlow->base, base, djui_chat_message_render, djui_chat_message_destroy); |     djui_base_init(&gDjuiChatBox->chatFlow->base, base, djui_chat_message_render, djui_chat_message_destroy); | ||||||
|     djui_base_set_size_type(base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); |     djui_base_set_size_type(base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); | ||||||
|     djui_base_set_size(base, 1.0f, 0); |     djui_base_set_size(base, 1.0f, 0); | ||||||
|     djui_base_set_color(base, 0, 0, 0, 64); |     djui_base_set_color(base, 0, 0, 0, 0); | ||||||
|     djui_base_set_padding(base, 2, 4, 2, 4); |     djui_base_set_padding(base, 0, 4, 0, 4); | ||||||
|     djui_base_set_alignment(base, DJUI_HALIGN_LEFT, DJUI_VALIGN_BOTTOM); |     djui_base_set_alignment(base, DJUI_HALIGN_LEFT, DJUI_VALIGN_BOTTOM); | ||||||
| 
 | 
 | ||||||
|     f32 maxTextWidth = gDjuiChatBox->base.width.value - gDjuiChatBox->base.padding.left.value - gDjuiChatBox->base.padding.right.value - base->padding.left.value - base->padding.right.value; |     f32 maxTextWidth = gDjuiChatBox->base.width.value - gDjuiChatBox->base.padding.left.value - gDjuiChatBox->base.padding.right.value - base->padding.left.value - base->padding.right.value; | ||||||
|  |  | ||||||
|  | @ -33,7 +33,7 @@ static struct DjuiColor sRefColor = { 255, 255, 255, 255 }; | ||||||
| static bool sLegacy = false; | static bool sLegacy = false; | ||||||
| 
 | 
 | ||||||
| f32 gDjuiHudUtilsZ = 0; | f32 gDjuiHudUtilsZ = 0; | ||||||
| u8 gDjuiHudLockMouse = false; | bool gDjuiHudLockMouse = false; | ||||||
| 
 | 
 | ||||||
| extern ALIGNED8 const u8 texture_hud_char_camera[]; | extern ALIGNED8 const u8 texture_hud_char_camera[]; | ||||||
| extern ALIGNED8 const u8 texture_hud_char_lakitu[]; | extern ALIGNED8 const u8 texture_hud_char_lakitu[]; | ||||||
|  | @ -297,6 +297,10 @@ f32 djui_hud_get_raw_mouse_y(void) { | ||||||
|     return mouse_y; |     return mouse_y; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | bool djui_hud_is_mouse_locked(void) { | ||||||
|  |     return gDjuiHudLockMouse; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void djui_hud_set_mouse_locked(bool locked) { | void djui_hud_set_mouse_locked(bool locked) { | ||||||
|     gDjuiHudLockMouse = locked; |     gDjuiHudLockMouse = locked; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -52,7 +52,7 @@ struct GlobalTextures { | ||||||
| 
 | 
 | ||||||
| extern struct GlobalTextures gGlobalTextures; | extern struct GlobalTextures gGlobalTextures; | ||||||
| extern f32 gDjuiHudUtilsZ; | extern f32 gDjuiHudUtilsZ; | ||||||
| extern u8 gDjuiHudLockMouse; | extern bool gDjuiHudLockMouse; | ||||||
| 
 | 
 | ||||||
| /* |description|Gets the current DJUI HUD resolution|descriptionEnd| */ | /* |description|Gets the current DJUI HUD resolution|descriptionEnd| */ | ||||||
| u8 djui_hud_get_resolution(void); | u8 djui_hud_get_resolution(void); | ||||||
|  | @ -92,7 +92,9 @@ f32 djui_hud_get_mouse_y(void); | ||||||
| f32 djui_hud_get_raw_mouse_x(void); | f32 djui_hud_get_raw_mouse_x(void); | ||||||
| /* |description|Returns the y coordinate of the mouse relative to the screen|descriptionEnd| */ | /* |description|Returns the y coordinate of the mouse relative to the screen|descriptionEnd| */ | ||||||
| f32 djui_hud_get_raw_mouse_y(void); | f32 djui_hud_get_raw_mouse_y(void); | ||||||
| /* |description|Sets if the cursor is hidden and constrainted to the window|descriptionEnd| */ | /* |description|Checks if the cursor is locked to the window|descriptionEnd| */ | ||||||
|  | bool djui_hud_is_mouse_locked(void); | ||||||
|  | /* |description|Locks (or unlocks) the cursor to the window|descriptionEnd| */ | ||||||
| void djui_hud_set_mouse_locked(bool locked); | void djui_hud_set_mouse_locked(bool locked); | ||||||
| /* |description|Returns the flags of the mouse buttons held down|descriptionEnd| */ | /* |description|Returns the flags of the mouse buttons held down|descriptionEnd| */ | ||||||
| u8 djui_hud_get_mouse_buttons_down(void); | u8 djui_hud_get_mouse_buttons_down(void); | ||||||
|  | @ -104,13 +106,13 @@ u8 djui_hud_get_mouse_buttons_released(void); | ||||||
| f32 djui_hud_get_mouse_scroll_x(void); | f32 djui_hud_get_mouse_scroll_x(void); | ||||||
| /* |description|Returns the amount scrolled vertically (-down/up+)|descriptionEnd| */ | /* |description|Returns the amount scrolled vertically (-down/up+)|descriptionEnd| */ | ||||||
| f32 djui_hud_get_mouse_scroll_y(void); | f32 djui_hud_get_mouse_scroll_y(void); | ||||||
| /* |description|Sets the viewport to the specified position and size, this will resize |descriptionEnd| */ | /* |description|Sets the viewport to the specified position and size, this will resize any subsequent DJUI graphics|descriptionEnd| */ | ||||||
| void djui_hud_set_viewport(f32 x, f32 y, f32 width, f32 height); | void djui_hud_set_viewport(f32 x, f32 y, f32 width, f32 height); | ||||||
| /* |description|put the description here|descriptionEnd| */ | /* |description|Resets the viewport to a fullscreen state|descriptionEnd| */ | ||||||
| void djui_hud_reset_viewport(void); | void djui_hud_reset_viewport(void); | ||||||
| /* |description|put the description here|descriptionEnd| */ | /* |description|Sets the scissor rectangle to the specified position and size, this will cut off any subsequent DJUI graphics not within the rectangle|descriptionEnd| */ | ||||||
| void djui_hud_set_scissor(f32 x, f32 y, f32 width, f32 height); | void djui_hud_set_scissor(f32 x, f32 y, f32 width, f32 height); | ||||||
| /* |description|put the description here|descriptionEnd| */ | /* |description|Resets the scissor rectangle to a fullscreen state|descriptionEnd| */ | ||||||
| void djui_hud_reset_scissor(void); | void djui_hud_reset_scissor(void); | ||||||
| 
 | 
 | ||||||
| /* |description|Measures the length of `message` in the current font|descriptionEnd| */ | /* |description|Measures the length of `message` in the current font|descriptionEnd| */ | ||||||
|  |  | ||||||
|  | @ -3,12 +3,14 @@ | ||||||
| #include "djui.h" | #include "djui.h" | ||||||
| #include "djui_unicode.h" | #include "djui_unicode.h" | ||||||
| #include "djui_hud_utils.h" | #include "djui_hud_utils.h" | ||||||
|  | #include "djui_chat_box.h" | ||||||
| #include "pc/gfx/gfx_window_manager_api.h" | #include "pc/gfx/gfx_window_manager_api.h" | ||||||
| #include "pc/pc_main.h" | #include "pc/pc_main.h" | ||||||
| #include "game/segment2.h" | #include "game/segment2.h" | ||||||
| #include "pc/controller/controller_keyboard.h" | #include "pc/controller/controller_keyboard.h" | ||||||
|  | #include "pc/configfile.h" | ||||||
| 
 | 
 | ||||||
| #define DJUI_INPUTBOX_YOFF (-3) | #define DJUI_INPUTBOX_YOFF (-2) | ||||||
| #define DJUI_INPUTBOX_MAX_BLINK 50 | #define DJUI_INPUTBOX_MAX_BLINK 50 | ||||||
| #define DJUI_INPUTBOX_MID_BLINK (DJUI_INPUTBOX_MAX_BLINK / 2) | #define DJUI_INPUTBOX_MID_BLINK (DJUI_INPUTBOX_MAX_BLINK / 2) | ||||||
| #define DJUI_INPUTBOX_CURSOR_WIDTH (2.0f / 32.0f) | #define DJUI_INPUTBOX_CURSOR_WIDTH (2.0f / 32.0f) | ||||||
|  | @ -20,6 +22,14 @@ static u8 sCursorBlink = 0; | ||||||
| 
 | 
 | ||||||
| static void djui_inputbox_update_style(struct DjuiBase* base) { | static void djui_inputbox_update_style(struct DjuiBase* base) { | ||||||
|     struct DjuiInputbox* inputbox = (struct DjuiInputbox*)base; |     struct DjuiInputbox* inputbox = (struct DjuiInputbox*)base; | ||||||
|  |     if (gDjuiChatBox != NULL && &gDjuiChatBox->chatInput->base == base) { | ||||||
|  |         djui_base_set_border_width(base, 0); | ||||||
|  |         djui_base_set_border_color(base, 0, 0, 0, 0); | ||||||
|  |         u8 alpha = gDjuiChatBoxFocus ? 200 : 150; | ||||||
|  |         djui_base_set_color(&inputbox->base, 0, 0, 0, alpha); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     if (!inputbox->base.enabled) { |     if (!inputbox->base.enabled) { | ||||||
|         djui_base_set_border_color(base, 90, 90, 90, 255); |         djui_base_set_border_color(base, 90, 90, 90, 255); | ||||||
|         djui_base_set_color(&inputbox->base, 140, 140, 140, 255); |         djui_base_set_color(&inputbox->base, 140, 140, 140, 255); | ||||||
|  | @ -447,8 +457,63 @@ static void djui_inputbox_render_char(struct DjuiInputbox* inputbox, char* c, f3 | ||||||
|     *additionalShift += charWidth; |     *additionalShift += charWidth; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void djui_inputbox_render_preview_text(struct DjuiInputbox* inputbox) { | ||||||
|  |     // Always show debug preview when focused (remove all conditions for testing)
 | ||||||
|  |     if (!djui_interactable_is_input_focus(&inputbox->base)) { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     const struct DjuiFont* font = gDjuiFonts[configDjuiThemeFont == 0 ? FONT_NORMAL : FONT_ALIASED]; | ||||||
|  |     struct DjuiBaseRect* comp = &inputbox->base.comp; | ||||||
|  |      | ||||||
|  |     // Calculate current text width
 | ||||||
|  |     f32 currentTextWidth = 0; | ||||||
|  |     char* c = inputbox->buffer; | ||||||
|  |     while (*c != '\0') { | ||||||
|  |         char* dc = inputbox->passwordChar[0] ? inputbox->passwordChar : c; | ||||||
|  |         currentTextWidth += font->char_width(dc) * font->defaultFontScale; | ||||||
|  |         c = djui_unicode_next_char(c); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     // Calculate preview position - use absolute positioning
 | ||||||
|  |     f32 previewX = comp->x + inputbox->viewX + currentTextWidth + 50; // Add 50px offset
 | ||||||
|  |     f32 previewY = comp->y + DJUI_INPUTBOX_YOFF + 30; // Move down 30px
 | ||||||
|  |      | ||||||
|  |     // Apply position translation
 | ||||||
|  |     djui_gfx_position_translate(&previewX, &previewY); | ||||||
|  |      | ||||||
|  |     // Create translation matrix for the preview text
 | ||||||
|  |     create_dl_translation_matrix(DJUI_MTX_PUSH, previewX, previewY, 0); | ||||||
|  |     f32 translatedFontSize = font->defaultFontScale; | ||||||
|  |     djui_gfx_size_translate(&translatedFontSize); | ||||||
|  |     create_dl_scale_matrix(DJUI_MTX_NOPUSH, translatedFontSize, translatedFontSize, 1.0f); | ||||||
|  |      | ||||||
|  |     // Set bright red color for debug visibility
 | ||||||
|  |     gDPSetEnvColor(gDisplayListHead++, 255, 0, 0, 255); | ||||||
|  |      | ||||||
|  |     // Begin font rendering
 | ||||||
|  |     if (font->textBeginDisplayList != NULL) { | ||||||
|  |         gSPDisplayList(gDisplayListHead++, font->textBeginDisplayList); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     // Render debug text
 | ||||||
|  |     char testText[] = "DEBUG"; | ||||||
|  |     char* testChar = testText; | ||||||
|  |     while (*testChar != '\0') { | ||||||
|  |         font->render_char(testChar); | ||||||
|  |         f32 charWidth = font->char_width(testChar); | ||||||
|  |         previewX += charWidth * font->defaultFontScale; | ||||||
|  |         testChar = djui_unicode_next_char(testChar); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     // Clean up matrices
 | ||||||
|  |     gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); | ||||||
|  |     gSPDisplayList(gDisplayListHead++, dl_ia_text_end); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static void djui_inputbox_render_selection(struct DjuiInputbox* inputbox) { | static void djui_inputbox_render_selection(struct DjuiInputbox* inputbox) { | ||||||
|     const struct DjuiFont* font = gDjuiFonts[configDjuiThemeFont == 0 ? FONT_NORMAL : FONT_ALIASED]; |     const struct DjuiFont* font = gDjuiFonts[configDjuiThemeFont == 0 ? FONT_NORMAL : FONT_ALIASED]; | ||||||
|  |     bool isChatInput = (gDjuiChatBox != NULL && &gDjuiChatBox->chatInput->base == &inputbox->base); | ||||||
| 
 | 
 | ||||||
|     // make selection well formed
 |     // make selection well formed
 | ||||||
|     u16 selection[2] = { 0 }; |     u16 selection[2] = { 0 }; | ||||||
|  | @ -486,7 +551,11 @@ static void djui_inputbox_render_selection(struct DjuiInputbox* inputbox) { | ||||||
|         if (sCursorBlink < DJUI_INPUTBOX_MID_BLINK && djui_interactable_is_input_focus(&inputbox->base)) { |         if (sCursorBlink < DJUI_INPUTBOX_MID_BLINK && djui_interactable_is_input_focus(&inputbox->base)) { | ||||||
|             create_dl_translation_matrix(DJUI_MTX_PUSH, renderX - DJUI_INPUTBOX_CURSOR_WIDTH / 2.0f, -0.1f, 0); |             create_dl_translation_matrix(DJUI_MTX_PUSH, renderX - DJUI_INPUTBOX_CURSOR_WIDTH / 2.0f, -0.1f, 0); | ||||||
|             create_dl_scale_matrix(DJUI_MTX_NOPUSH, DJUI_INPUTBOX_CURSOR_WIDTH, 0.8f, 1.0f); |             create_dl_scale_matrix(DJUI_MTX_NOPUSH, DJUI_INPUTBOX_CURSOR_WIDTH, 0.8f, 1.0f); | ||||||
|             gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 255); |             if (isChatInput) { | ||||||
|  |                 gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255); | ||||||
|  |             } else { | ||||||
|  |                 gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 255); | ||||||
|  |             } | ||||||
|             gSPDisplayList(gDisplayListHead++, dl_djui_simple_rect); |             gSPDisplayList(gDisplayListHead++, dl_djui_simple_rect); | ||||||
|             gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); |             gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); | ||||||
|         } |         } | ||||||
|  | @ -550,9 +619,15 @@ static bool djui_inputbox_render(struct DjuiBase* base) { | ||||||
|     const struct DjuiFont* font   = gDjuiFonts[configDjuiThemeFont == 0 ? FONT_NORMAL : FONT_ALIASED]; |     const struct DjuiFont* font   = gDjuiFonts[configDjuiThemeFont == 0 ? FONT_NORMAL : FONT_ALIASED]; | ||||||
|     djui_rect_render(base); |     djui_rect_render(base); | ||||||
| 
 | 
 | ||||||
|     // Shift the text away from the left side a tad
 |     bool isChatInput = (gDjuiChatBox != NULL && &gDjuiChatBox->chatInput->base == base); | ||||||
|     comp->x += 2; |     if (isChatInput) { | ||||||
|     comp->width -= 2; |         comp->x += 6; | ||||||
|  |         comp->y  -= 1; | ||||||
|  |         comp->width -= 6; | ||||||
|  |     } else { | ||||||
|  |         comp->x += 2; | ||||||
|  |         comp->width -= 2; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     // shift the viewing window to keep the selection in view
 |     // shift the viewing window to keep the selection in view
 | ||||||
|     djui_inputbox_keep_selection_in_view(inputbox); |     djui_inputbox_keep_selection_in_view(inputbox); | ||||||
|  | @ -560,6 +635,12 @@ static bool djui_inputbox_render(struct DjuiBase* base) { | ||||||
|     // translate position
 |     // translate position
 | ||||||
|     f32 translatedX = comp->x + inputbox->viewX; |     f32 translatedX = comp->x + inputbox->viewX; | ||||||
|     f32 translatedY = comp->y + DJUI_INPUTBOX_YOFF; |     f32 translatedY = comp->y + DJUI_INPUTBOX_YOFF; | ||||||
|  |     if (isChatInput) { | ||||||
|  |         f32 lineHeight = font->lineHeight * font->defaultFontScale; | ||||||
|  |         f32 innerHeight = comp->height - base->borderWidth.value * 2; | ||||||
|  |         f32 centerOffset = (innerHeight - lineHeight) * 0.5f; | ||||||
|  |         translatedY += fmaxf(centerOffset, 0.0f); | ||||||
|  |     } | ||||||
|     djui_gfx_position_translate(&translatedX, &translatedY); |     djui_gfx_position_translate(&translatedX, &translatedY); | ||||||
|     create_dl_translation_matrix(DJUI_MTX_PUSH, translatedX, translatedY, 0); |     create_dl_translation_matrix(DJUI_MTX_PUSH, translatedX, translatedY, 0); | ||||||
| 
 | 
 | ||||||
|  | @ -576,8 +657,14 @@ static bool djui_inputbox_render(struct DjuiBase* base) { | ||||||
|         gSPDisplayList(gDisplayListHead++, font->textBeginDisplayList); |         gSPDisplayList(gDisplayListHead++, font->textBeginDisplayList); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // set color
 |     // render preview text (for tab completion) - after font setup
 | ||||||
|     gDPSetEnvColor(gDisplayListHead++, inputbox->textColor.r, inputbox->textColor.g, inputbox->textColor.b, inputbox->textColor.a); |     // djui_inputbox_render_preview_text(inputbox);
 | ||||||
|  | 
 | ||||||
|  |     if (isChatInput) { | ||||||
|  |         gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255); | ||||||
|  |     } else { | ||||||
|  |         gDPSetEnvColor(gDisplayListHead++, inputbox->textColor.r, inputbox->textColor.g, inputbox->textColor.b, inputbox->textColor.a); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     // make selection well formed
 |     // make selection well formed
 | ||||||
|     u16 selection[2] = { 0 }; |     u16 selection[2] = { 0 }; | ||||||
|  | @ -608,7 +695,11 @@ static bool djui_inputbox_render(struct DjuiBase* base) { | ||||||
|             if (insideSelection && !wasInsideSelection) { |             if (insideSelection && !wasInsideSelection) { | ||||||
|                 gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255); |                 gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255); | ||||||
|             } else if (!insideSelection && wasInsideSelection) { |             } else if (!insideSelection && wasInsideSelection) { | ||||||
|                 gDPSetEnvColor(gDisplayListHead++, inputbox->textColor.r, inputbox->textColor.g, inputbox->textColor.b, inputbox->textColor.a); |                 if (isChatInput) { | ||||||
|  |                     gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255); | ||||||
|  |                 } else { | ||||||
|  |                     gDPSetEnvColor(gDisplayListHead++, inputbox->textColor.r, inputbox->textColor.g, inputbox->textColor.b, inputbox->textColor.a); | ||||||
|  |                 } | ||||||
|             } |             } | ||||||
|             wasInsideSelection = insideSelection; |             wasInsideSelection = insideSelection; | ||||||
|         } |         } | ||||||
|  | @ -617,9 +708,101 @@ static bool djui_inputbox_render(struct DjuiBase* base) { | ||||||
|         djui_inputbox_render_char(inputbox, c, &drawX, &additionalShift); |         djui_inputbox_render_char(inputbox, c, &drawX, &additionalShift); | ||||||
|         c = djui_unicode_next_char(c); |         c = djui_unicode_next_char(c); | ||||||
|     } |     } | ||||||
|  |      | ||||||
|  |     // Tab completion preview - show what would happen if TAB was pressed
 | ||||||
|  |     if (djui_interactable_is_input_focus(&inputbox->base) && inputbox->buffer[0] == '/') { | ||||||
|  |         // Get preview text from tab completion function
 | ||||||
|  |         extern char* get_next_tab_completion_preview(const char* input); | ||||||
|  |         char* previewText = get_next_tab_completion_preview(inputbox->buffer); | ||||||
|  |          | ||||||
|  |         if (previewText != NULL && strlen(previewText) > 0) { | ||||||
|  |             // Set gray color for preview text
 | ||||||
|  |             gDPSetEnvColor(gDisplayListHead++, 128, 128, 128, 128); | ||||||
|  |              | ||||||
|  |             // Render preview text at the current position
 | ||||||
|  |             char* previewChar = previewText; | ||||||
|  |             while (*previewChar != '\0') { | ||||||
|  |                 djui_inputbox_render_char(inputbox, previewChar, &drawX, &additionalShift); | ||||||
|  |                 previewChar = djui_unicode_next_char(previewChar); | ||||||
|  |             } | ||||||
|  |              | ||||||
|  |             // Free the preview text
 | ||||||
|  |             free(previewText); | ||||||
|  |              | ||||||
|  |             // Reset color back to normal
 | ||||||
|  |             gDPSetEnvColor(gDisplayListHead++, inputbox->textColor.r, inputbox->textColor.g, inputbox->textColor.b, inputbox->textColor.a); | ||||||
|  |         } | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); |     gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); | ||||||
|     gSPDisplayList(gDisplayListHead++, dl_ia_text_end); |     gSPDisplayList(gDisplayListHead++, dl_ia_text_end); | ||||||
|  | 
 | ||||||
|  |     if (isChatInput && djui_interactable_is_input_focus(&inputbox->base) && configChatCharCounter) { | ||||||
|  |         char charCountText[32]; | ||||||
|  |         int currentLength = djui_unicode_len(inputbox->buffer); | ||||||
|  |         snprintf(charCountText, sizeof(charCountText), "%d", currentLength); | ||||||
|  |          | ||||||
|  |         f32 originalX = comp->x; | ||||||
|  |         f32 originalY = comp->y; | ||||||
|  |         f32 originalWidth = comp->width; | ||||||
|  |          | ||||||
|  |         if (isChatInput) { | ||||||
|  |             originalX -= 6; | ||||||
|  |             originalY += 1; | ||||||
|  |             originalWidth += 6; | ||||||
|  |         } else { | ||||||
|  |             originalX -= 2; | ||||||
|  |             originalWidth += 2; | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         f32 counterX = originalX + originalWidth + 10 - 3; | ||||||
|  |         f32 counterY = originalY + (comp->height - font->lineHeight * font->defaultFontScale) * 0.5f - 3; | ||||||
|  |          | ||||||
|  |         djui_gfx_position_translate(&counterX, &counterY); | ||||||
|  |         create_dl_translation_matrix(DJUI_MTX_PUSH, counterX, counterY, 0); | ||||||
|  |          | ||||||
|  |         f32 translatedFontSize = font->defaultFontScale; | ||||||
|  |         djui_gfx_size_translate(&translatedFontSize); | ||||||
|  |         create_dl_scale_matrix(DJUI_MTX_NOPUSH, translatedFontSize, translatedFontSize, 1.0f); | ||||||
|  |          | ||||||
|  |         u8 colR = 255, colG = 255, colB = 255; | ||||||
|  |         if (currentLength >= 499) { | ||||||
|  |             colG = 0;  colB = 0; | ||||||
|  |         } else if (currentLength >= 256) { | ||||||
|  |             colG = 128;  colB = 64; | ||||||
|  |         } else if (currentLength >= 192) { | ||||||
|  |             colG = 192; colB = 64; | ||||||
|  |         } else if (currentLength >= 128) { | ||||||
|  |             colG = 255; colB = 64; | ||||||
|  |         } | ||||||
|  |         gDPSetEnvColor(gDisplayListHead++, colR, colG, colB, 255); | ||||||
|  |          | ||||||
|  |         if (font->textBeginDisplayList != NULL) { | ||||||
|  |             gSPDisplayList(gDisplayListHead++, font->textBeginDisplayList); | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         char* c = charCountText; | ||||||
|  |         while (*c != '\0') { | ||||||
|  |             font->render_char(c); | ||||||
|  |             f32 cw = font->char_width(c); | ||||||
|  |             create_dl_translation_matrix(DJUI_MTX_NOPUSH, cw, 0, 0); | ||||||
|  |             c = djui_unicode_next_char(c); | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         gSPDisplayList(gDisplayListHead++, dl_ia_text_end); | ||||||
|  |          | ||||||
|  |         gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (isChatInput) { | ||||||
|  |         comp->x -= 6; | ||||||
|  |         comp->y += 1; | ||||||
|  |         comp->width += 6; | ||||||
|  |     } else { | ||||||
|  |         comp->x -= 2; | ||||||
|  |         comp->width += 2; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -211,16 +211,23 @@ bool djui_interactable_on_key_down(int scancode) { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (gDjuiChatBox != NULL && !gDjuiChatBoxFocus) { |     if (gDjuiChatBox != NULL) { | ||||||
|         bool pressChat = false; |         bool pressChat = false; | ||||||
|  |         bool pressChatCommand = false; | ||||||
|         for (int i = 0; i < MAX_BINDS; i++) { |         for (int i = 0; i < MAX_BINDS; i++) { | ||||||
|             if (scancode == (int)configKeyChat[i]) { pressChat = true; } |             if (scancode == (int)configKeyChat[i]) { pressChat = true; } | ||||||
|  |             if (scancode == (int)configKeyChatCommand[i]) { pressChatCommand = true; } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (pressChat && !gDjuiConsoleFocus) { |         if (pressChat && !gDjuiConsoleFocus && !gDjuiChatBoxFocus) { | ||||||
|             djui_chat_box_toggle(); |             djui_chat_box_toggle(); | ||||||
|             return true; |             return true; | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         if (pressChatCommand && !gDjuiConsoleFocus) { | ||||||
|  |             djui_chat_box_open_with_text("/"); | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if ((gDjuiPlayerList != NULL || gDjuiModList != NULL)) { |     if ((gDjuiPlayerList != NULL || gDjuiModList != NULL)) { | ||||||
|  |  | ||||||
|  | @ -42,6 +42,32 @@ void djui_panel_controls_create(struct DjuiBase* caller) { | ||||||
| #endif | #endif | ||||||
|         djui_checkbox_create(body, DLANG(MISC, USE_STANDARD_KEY_BINDINGS_CHAT), &configUseStandardKeyBindingsChat, NULL); |         djui_checkbox_create(body, DLANG(MISC, USE_STANDARD_KEY_BINDINGS_CHAT), &configUseStandardKeyBindingsChat, NULL); | ||||||
| 
 | 
 | ||||||
|  |         djui_checkbox_create(body, DLANG(MISC, CHAT_CHAR_COUNTER), &configChatCharCounter, NULL); | ||||||
|  |         djui_checkbox_create(body, DLANG(MISC, DISABLE_CHAT_WHEN_CLOSED), &configDisableChatWhenClosed, NULL); | ||||||
|  | 
 | ||||||
|  |         static unsigned int sChatWidthIndex = 3; | ||||||
|  |         switch (configChatWidth) { | ||||||
|  |             case 500: sChatWidthIndex = 0; break; | ||||||
|  |             case 600: sChatWidthIndex = 1; break; | ||||||
|  |             case 700: sChatWidthIndex = 2; break; | ||||||
|  |             case 800: sChatWidthIndex = 3; break; | ||||||
|  |             case 900: sChatWidthIndex = 4; break; | ||||||
|  |             case 1000: sChatWidthIndex = 5; break; | ||||||
|  |             case 1100: sChatWidthIndex = 6; break; | ||||||
|  |             default: sChatWidthIndex = 3; break; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         char* chatWidthChoices[] = { DLANG(MISC, CHAT_WIDTH_TINY), DLANG(MISC, CHAT_WIDTH_VERY_SMALL), DLANG(MISC, CHAT_WIDTH_SMALL), DLANG(MISC, CHAT_WIDTH_NORMAL), DLANG(MISC, CHAT_WIDTH_BIG), DLANG(MISC, CHAT_WIDTH_VERY_BIG), DLANG(MISC, CHAT_WIDTH_HUGE) }; | ||||||
|  |         void on_chat_width_change(UNUSED struct DjuiBase* b) { | ||||||
|  |             unsigned int idx = sChatWidthIndex; | ||||||
|  |             unsigned int widths[] = {500,600,700,800,900,1000,1100}; | ||||||
|  |             configChatWidth = widths[idx]; | ||||||
|  |             if (gDjuiChatBox != NULL) { | ||||||
|  |                 djui_base_set_size(&gDjuiChatBox->base, configChatWidth, gDjuiChatBox->base.height.value); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         djui_selectionbox_create(body, DLANG(MISC, CHAT_WIDTH), chatWidthChoices, 7, &sChatWidthIndex, on_chat_width_change); | ||||||
|  | 
 | ||||||
| #ifdef HAVE_SDL2 | #ifdef HAVE_SDL2 | ||||||
|         int numJoys = SDL_NumJoysticks(); |         int numJoys = SDL_NumJoysticks(); | ||||||
|         if (numJoys == 0) { numJoys = 1; } |         if (numJoys == 0) { numJoys = 1; } | ||||||
|  |  | ||||||
|  | @ -15,18 +15,19 @@ void djui_panel_controls_extra_create(struct DjuiBase* caller) { | ||||||
|         djui_base_set_color(&bindBody->base, 0, 0, 0, 0); |         djui_base_set_color(&bindBody->base, 0, 0, 0, 0); | ||||||
|         djui_flow_layout_set_margin(bindBody, 1); |         djui_flow_layout_set_margin(bindBody, 1); | ||||||
|         { |         { | ||||||
|             djui_bind_create(&bindBody->base, DLANG(CONTROLS, CHAT),       configKeyChat); |             djui_bind_create(&bindBody->base, DLANG(CONTROLS, CHAT),         configKeyChat); | ||||||
|             djui_bind_create(&bindBody->base, DLANG(CONTROLS, PLAYERS),    configKeyPlayerList); |             djui_bind_create(&bindBody->base, DLANG(CONTROLS, CHAT_COMMAND), configKeyChatCommand); | ||||||
|             djui_bind_create(&bindBody->base, DLANG(CONTROLS, D_UP),       configKeyDUp); |             djui_bind_create(&bindBody->base, DLANG(CONTROLS, PLAYERS),      configKeyPlayerList); | ||||||
|             djui_bind_create(&bindBody->base, DLANG(CONTROLS, D_DOWN),     configKeyDDown); |             djui_bind_create(&bindBody->base, DLANG(CONTROLS, D_UP),         configKeyDUp); | ||||||
|             djui_bind_create(&bindBody->base, DLANG(CONTROLS, D_LEFT),     configKeyDLeft); |             djui_bind_create(&bindBody->base, DLANG(CONTROLS, D_DOWN),       configKeyDDown); | ||||||
|             djui_bind_create(&bindBody->base, DLANG(CONTROLS, D_RIGHT),    configKeyDRight); |             djui_bind_create(&bindBody->base, DLANG(CONTROLS, D_LEFT),       configKeyDLeft); | ||||||
|             djui_bind_create(&bindBody->base, DLANG(CONTROLS, X),          configKeyX); |             djui_bind_create(&bindBody->base, DLANG(CONTROLS, D_RIGHT),      configKeyDRight); | ||||||
|             djui_bind_create(&bindBody->base, DLANG(CONTROLS, Y),          configKeyY); |             djui_bind_create(&bindBody->base, DLANG(CONTROLS, X),            configKeyX); | ||||||
|             djui_bind_create(&bindBody->base, DLANG(CONTROLS, CONSOLE),    configKeyConsole); |             djui_bind_create(&bindBody->base, DLANG(CONTROLS, Y),            configKeyY); | ||||||
|             djui_bind_create(&bindBody->base, DLANG(CONTROLS, PREV),       configKeyPrevPage); |             djui_bind_create(&bindBody->base, DLANG(CONTROLS, CONSOLE),      configKeyConsole); | ||||||
|             djui_bind_create(&bindBody->base, DLANG(CONTROLS, NEXT),       configKeyNextPage); |             djui_bind_create(&bindBody->base, DLANG(CONTROLS, PREV),         configKeyPrevPage); | ||||||
|             djui_bind_create(&bindBody->base, DLANG(CONTROLS, DISCONNECT), configKeyDisconnect); |             djui_bind_create(&bindBody->base, DLANG(CONTROLS, NEXT),         configKeyNextPage); | ||||||
|  |             djui_bind_create(&bindBody->base, DLANG(CONTROLS, DISCONNECT),   configKeyDisconnect); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         djui_button_create(body, DLANG(MENU, BACK), DJUI_BUTTON_STYLE_BACK, djui_panel_menu_back); |         djui_button_create(body, DLANG(MENU, BACK), DJUI_BUTTON_STYLE_BACK, djui_panel_menu_back); | ||||||
|  |  | ||||||
|  | @ -12698,6 +12698,21 @@ int smlua_func_djui_hud_get_raw_mouse_y(UNUSED lua_State* L) { | ||||||
|     return 1; |     return 1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | int smlua_func_djui_hud_is_mouse_locked(UNUSED lua_State* L) { | ||||||
|  |     if (L == NULL) { return 0; } | ||||||
|  | 
 | ||||||
|  |     int top = lua_gettop(L); | ||||||
|  |     if (top != 0) { | ||||||
|  |         LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "djui_hud_is_mouse_locked", 0, top); | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     lua_pushboolean(L, djui_hud_is_mouse_locked()); | ||||||
|  | 
 | ||||||
|  |     return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| int smlua_func_djui_hud_set_mouse_locked(lua_State* L) { | int smlua_func_djui_hud_set_mouse_locked(lua_State* L) { | ||||||
|     if (L == NULL) { return 0; } |     if (L == NULL) { return 0; } | ||||||
| 
 | 
 | ||||||
|  | @ -37431,6 +37446,7 @@ void smlua_bind_functions_autogen(void) { | ||||||
|     smlua_bind_function(L, "djui_hud_get_mouse_y", smlua_func_djui_hud_get_mouse_y); |     smlua_bind_function(L, "djui_hud_get_mouse_y", smlua_func_djui_hud_get_mouse_y); | ||||||
|     smlua_bind_function(L, "djui_hud_get_raw_mouse_x", smlua_func_djui_hud_get_raw_mouse_x); |     smlua_bind_function(L, "djui_hud_get_raw_mouse_x", smlua_func_djui_hud_get_raw_mouse_x); | ||||||
|     smlua_bind_function(L, "djui_hud_get_raw_mouse_y", smlua_func_djui_hud_get_raw_mouse_y); |     smlua_bind_function(L, "djui_hud_get_raw_mouse_y", smlua_func_djui_hud_get_raw_mouse_y); | ||||||
|  |     smlua_bind_function(L, "djui_hud_is_mouse_locked", smlua_func_djui_hud_is_mouse_locked); | ||||||
|     smlua_bind_function(L, "djui_hud_set_mouse_locked", smlua_func_djui_hud_set_mouse_locked); |     smlua_bind_function(L, "djui_hud_set_mouse_locked", smlua_func_djui_hud_set_mouse_locked); | ||||||
|     smlua_bind_function(L, "djui_hud_get_mouse_buttons_down", smlua_func_djui_hud_get_mouse_buttons_down); |     smlua_bind_function(L, "djui_hud_get_mouse_buttons_down", smlua_func_djui_hud_get_mouse_buttons_down); | ||||||
|     smlua_bind_function(L, "djui_hud_get_mouse_buttons_pressed", smlua_func_djui_hud_get_mouse_buttons_pressed); |     smlua_bind_function(L, "djui_hud_get_mouse_buttons_pressed", smlua_func_djui_hud_get_mouse_buttons_pressed); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue