Compare commits

...

16 commits

Author SHA1 Message Date
iZePlayz
632977dea6
Merge b0ebaeed63 into 5fd55ffac1 2025-10-29 18:53:51 +01:00
Cooliokid956
5fd55ffac1
djui_hud_is_mouse_locked() (#986)
Some checks are pending
Build coop / build-linux (push) Waiting to run
Build coop / build-steamos (push) Waiting to run
Build coop / build-windows-opengl (push) Waiting to run
Build coop / build-windows-directx (push) Waiting to run
Build coop / build-macos-arm (push) Waiting to run
Build coop / build-macos-intel (push) Waiting to run
* djui_hud_get_mouse_locked()

Adds a total of 1 function:
# `bool djui_hud_get_mouse_locked()`
Returns the DJUI mouse lock status

Tip: This won't return the true state of mouse lock, so make sure to use `get_first_person_enabled()` and `camera_config_is_mouse_look_enabled()` as well

---
This also fills in some descriptions left out by Isaac in his viewport/scissor functions

* djui_hud_is_mouse_locked()

Same as before but is

* this is better imo
2025-10-29 18:41:27 +01:00
Emily♥
9f7ad0f93e
Some syncing fixes for Bowser and Heave Ho (#989)
* Fix Eyerok pounding in multiplayer

Eyerok now only enters the double pound state if ALL players stand on the pedestal rather than just one. Players standing on the pedestal will be ignored. I had to write a new function for this, I hope this is acceptable.

* Suggested changes

I didn't want to change the name of arg0 in eyerok_check_mario_relative_z because it was a vanilla function, but I suppose I can.

* Remove interaction limit for PVP

Fixes issues with certain mods

* Fixes for Bowser and Heave Ho

Hopefully this makes things a bit better.
2025-10-29 18:39:40 +01:00
iZePlayzYT
b0ebaeed63 Added hide chat setting and clearified chat width setting 2025-09-28 07:15:56 +02:00
iZePlayzYT
b2f029bea7 Added Chat Width Config Setting 2025-09-28 06:03:54 +02:00
iZePlayzYT
6c48a5c115 Fixed black text when selecting text in chat 2025-09-28 05:35:18 +02:00
iZePlayzYT
e16e2b4d5c Added char amount display to the chat input box 2025-09-28 05:10:56 +02:00
iZePlayzYT
5812dad90a Chat UI redesigned 2025-09-28 04:25:55 +02:00
iZePlayzYT
5c939c6ded Add tab completion preview for chat commands & subcommands 2025-09-27 22:44:13 +02:00
iZePlayzYT
88a7b246ab Improved chat controls setting checkbox text 2025-09-27 20:55:04 +02:00
iZePlayzYT
9138125c8a Enable classic chatbox controls by default 2025-09-27 20:43:29 +02:00
iZePlayzYT
2decea5693 Prevent duplicate messages in chat history 2025-09-27 20:40:24 +02:00
iZePlayzYT
1805004135 Add keybind to open chat with "/" pre-written 2025-09-25 22:56:27 +02:00
iZePlayzYT
09d29d8e98 Added translations keys 2025-09-24 20:45:01 +02:00
iZePlayzYT
7990d05ccb Added reverse tab completion logic 2025-09-24 20:41:52 +02:00
iZePlayzYT
f137f77826 Fixed the tab completion for the subcommands off the /psc command 2025-09-24 20:32:53 +02:00
33 changed files with 697 additions and 91 deletions

View file

@ -3914,8 +3914,14 @@ function djui_hud_get_raw_mouse_y()
-- ...
end
--- @return boolean
--- Checks if the cursor is locked to the window
function djui_hud_is_mouse_locked()
-- ...
end
--- @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)
-- ...
end
@ -3954,12 +3960,12 @@ end
--- @param y number
--- @param width 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)
-- ...
end
--- put the description here
--- Resets the viewport to a fullscreen state
function djui_hud_reset_viewport()
-- ...
end
@ -3968,12 +3974,12 @@ end
--- @param y number
--- @param width 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)
-- ...
end
--- put the description here
--- Resets the scissor rectangle to a fullscreen state
function djui_hud_reset_scissor()
-- ...
end
@ -6443,14 +6449,14 @@ end
--- @param m MarioState
--- @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)
-- ...
end
--- @param m MarioState
--- @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)
-- ...
end
@ -10029,7 +10035,7 @@ end
--- @param player integer
--- @return integer
--- Gets the tempo of `player`
--- Gets the `tempo` of `player`
function sequence_player_get_tempo(player)
-- ...
end
@ -10043,7 +10049,7 @@ end
--- @param player integer
--- @return integer
--- Gets the tempoAcc (tempo accumulation) of `player`
--- Gets the `tempoAcc` (tempo accumulation) of `player`
function sequence_player_get_tempo_acc(player)
-- ...
end
@ -10057,7 +10063,7 @@ end
--- @param player integer
--- @return integer
--- Gets the transposition (pitch) of `player`
--- Gets the `transposition` (pitch) of `player`
function sequence_player_get_transposition(player)
-- ...
end

View file

@ -3140,10 +3140,31 @@ Returns the y coordinate of the mouse relative to the screen
<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)
### Description
Sets if the cursor is hidden and constrainted to the window
Locks (or unlocks) the cursor to the window
### Lua Example
`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)
### 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
`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)
### Description
put the description here
Resets the viewport to a fullscreen state
### Lua Example
`djui_hud_reset_viewport()`
@ -3318,7 +3339,7 @@ put the description here
## [djui_hud_set_scissor](#djui_hud_set_scissor)
### 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
`djui_hud_set_scissor(x, y, width, height)`
@ -3344,7 +3365,7 @@ put the description here
## [djui_hud_reset_scissor](#djui_hud_reset_scissor)
### Description
put the description here
Resets the scissor rectangle to a fullscreen state
### Lua Example
`djui_hud_reset_scissor()`

View file

@ -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)
### 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
`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)
### 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
`local integerValue = perform_ground_step(m)`

View file

@ -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)
### Description
Gets the tempo of `player`
Gets the `tempo` of `player`
### Lua Example
`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)
### Description
Gets the tempoAcc (tempo accumulation) of `player`
Gets the `tempoAcc` (tempo accumulation) of `player`
### Lua Example
`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)
### Description
Gets the transposition (pitch) of `player`
Gets the `transposition` (pitch) of `player`
### Lua Example
`local integerValue = sequence_player_get_transposition(player)`

View file

@ -770,6 +770,7 @@
- [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_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_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)

View file

@ -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í"
UNRECOGNIZED = "Neznámý příkaz."
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]
BACK = "Zpět"
@ -105,6 +107,7 @@ DEADZONE = "Deadzone"
RUMBLE_STRENGTH = "Síla vibrace"
CHAT = "Chat"
CHAT_COMMAND = "Chat (Příkaz)"
PLAYERS = "Hráči"
D_UP = "D-Pad nahoru"
D_DOWN = "D-Pad dolů"
@ -319,7 +322,17 @@ DEBUG_ERRORS = "Debug Errors"
MISC_TITLE = "JINE"
PAUSE_IN_SINGLEPLAYER = "Pauza v hře s jedním hráčem"
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"
INFORMATION = "Informace"
DEBUG = "Debug"

View file

@ -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"
UNRECOGNIZED = "onbekent Chat commando."
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]
BACK = "Terug"
@ -105,6 +107,7 @@ DEADZONE = "Doode-zone"
RUMBLE_STRENGTH = "Rommel Kracht"
CHAT = "Chat"
CHAT_COMMAND = "Chat (Commando)"
PLAYERS = "Spelers"
D_UP = "D Omhoog"
D_DOWN = "D Naar Beneden"
@ -319,7 +322,17 @@ DEBUG_ERRORS = "Debug Errors"
MISC_TITLE = "MISC"
PAUSE_IN_SINGLEPLAYER = "Pauzeer in een speler"
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"
INFORMATION = "Informatie"
DEBUG = "Debug"

View file

@ -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"
UNRECOGNIZED = "Unrecognized chat command."
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]
BACK = "Back"
@ -105,6 +107,7 @@ DEADZONE = "Deadzone"
RUMBLE_STRENGTH = "Rumble Strength"
CHAT = "Chat"
CHAT_COMMAND = "Chat (Command)"
PLAYERS = "Players"
D_UP = "D-Up"
D_DOWN = "D-Down"
@ -319,7 +322,17 @@ DEBUG_ERRORS = "Debug Errors"
MISC_TITLE = "MISC"
PAUSE_IN_SINGLEPLAYER = "Pause In Singleplayer"
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"
INFORMATION = "Info"
DEBUG = "Debug"

View file

@ -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é"
UNRECOGNIZED = "Cette commande n'est pas reconnue."
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]
BACK = "Retour"
@ -105,6 +107,7 @@ DEADZONE = "Zone Morte"
RUMBLE_STRENGTH = "Vibrations"
CHAT = "Chat"
CHAT_COMMAND = "Chat (Commande)"
PLAYERS = "Joueurs"
D_UP = "D Haut"
D_DOWN = "D Bas"
@ -319,7 +322,17 @@ DEBUG_ERRORS = "Erreurs de Débogage"
MISC_TITLE = "AUTRES"
PAUSE_IN_SINGLEPLAYER = "Pause en Solo"
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"
INFORMATION = "Information"
DEBUG = "Débogage"

View file

@ -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 "
UNRECOGNIZED = "Unbekannter Befehl!"
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]
BACK = "Zurück"
@ -105,6 +107,7 @@ DEADZONE = "Tote Zone"
RUMBLE_STRENGTH = "Vibration-Stärke"
CHAT = "Chat"
CHAT_COMMAND = "Chat (Befehl)"
PLAYERS = "Spieler"
D_UP = "D-Hoch"
D_DOWN = "D-Unten"
@ -319,7 +322,17 @@ DEBUG_ERRORS = "Debug Fehler"
MISC_TITLE = "SONSTIGES"
PAUSE_IN_SINGLEPLAYER = "Pause im Einzelspieler"
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"
INFORMATION = "Info"
DEBUG = "Debug"

View file

@ -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"
UNRECOGNIZED = "Comando non riconosciuto."
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]
BACK = "Indietro"
@ -103,6 +105,7 @@ GAMEPAD = "Controller"
DEADZONE = "Zona Morta"
RUMBLE_STRENGTH = "Intesità Vibrazione"
CHAT = "Chat"
CHAT_COMMAND = "Chat (Comando)"
PLAYERS = "Giocatori"
D_UP = "D Su"
D_DOWN = "D Giù"
@ -317,7 +320,17 @@ DEBUG_ERRORS = "Errori di debug"
MISC_TITLE = "VARIE"
PAUSE_IN_SINGLEPLAYER = "Pausa in Giocatore Singolo"
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ù"
INFORMATION = "Informazione"
DEBUG = "Debug"

View file

@ -58,6 +58,8 @@ MOD_DESC = "/moderator [NAME|ID] - プレイヤーに/kick、/ban、/permbanの
NAMETAGS_DESC = "/nametags [show-tag|show-health] - あなたの体力やネームタグの表示を変更します。"
UNRECOGNIZED = "未知のコマンドです。"
MOD_GRANTED = "\\#fff982\\あなたはモデレーターになりました。"
ALL_COMMANDS = "すべてのコマンド"
TAB_COMPLETE_INFO = "TABキーでコマンドを自動補完、Shift+TABで逆方向に移動"
[MENU]
BACK = "戻る"
@ -106,6 +108,7 @@ DEADZONE = "デッドゾーン"
RUMBLE_STRENGTH = "振動の強さ"
CHAT = "チャット"
CHAT_COMMAND = "チャット(コマンド)"
PLAYERS = "プレイヤーリストの表示"
D_UP = "十字キー 上"
D_DOWN = "十字キー 下"
@ -320,7 +323,17 @@ DEBUG_ERRORS = "デバッグのエラー"
MISC_TITLE = "MISC"
PAUSE_IN_SINGLEPLAYER = "ソロプレイでの一時停止"
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 = "メニューの設定"
INFORMATION = "情報"
DEBUG = "デバッグ"

View file

@ -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"
UNRECOGNIZED = "Nieznane polecenie czatu."
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]
BACK = "Wróć"
@ -105,6 +107,7 @@ DEADZONE = "Martwa Strefa"
RUMBLE_STRENGTH = "Siła Wibracji"
CHAT = "Czat"
CHAT_COMMAND = "Czat (Komenda)"
PLAYERS = "Gracze"
D_UP = "Kierunek w Górę"
D_DOWN = "Kierunek w Dół"
@ -319,7 +322,17 @@ DEBUG_ERRORS = "Błędy z Debugowania"
MISC_TITLE = "POZOSTAŁE OPCJE"
PAUSE_IN_SINGLEPLAYER = "Pauza w Trybie Pojedynczego Gracza"
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"
INFORMATION = "Informacja"
DEBUG = "Debugowanie"

View file

@ -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"
UNRECOGNIZED = "Comando de chat desconhecido."
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]
BACK = "Voltar"
@ -105,6 +107,7 @@ DEADZONE = "Zona morta"
RUMBLE_STRENGTH = "Força de vibração"
CHAT = "Chat"
CHAT_COMMAND = "Chat (Comando)"
PLAYERS = "Jogadores"
D_UP = "D-Cima"
D_DOWN = "D-Baixo"
@ -319,7 +322,17 @@ DEBUG_ERRORS = "Erros de debug"
MISC_TITLE = "OUTROS"
PAUSE_IN_SINGLEPLAYER = "Pausar com apenas um jogador"
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"
INFORMATION = "Informações"
DEBUG = "Debug"

View file

@ -58,6 +58,8 @@ MOD_DESC = "/moderator [NAME|ID] - Разрешить игроку исполь
NAMETAGS_DESC = "/nametags [show-tag|show-health] - Измените, видите ли вы свой собственный тег и видите ли здоровье"
UNRECOGNIZED = "Неизвестная команда чата."
MOD_GRANTED = "\\#fff982\\Теперь вы модератор."
ALL_COMMANDS = "Все команды"
TAB_COMPLETE_INFO = "Нажми TAB для автодополнения команд, Shift+TAB — переход назад"
[MENU]
BACK = "Назад"
@ -104,6 +106,7 @@ DEADZONE = "Mёртвая зона"
RUMBLE_STRENGTH = "Вибрация"
CHAT = "Чат"
CHAT_COMMAND = "Чат (Команда)"
PLAYERS = "Игроки"
D_UP = "Крестовина вверх"
D_DOWN = "Крестовина вниз"
@ -318,7 +321,17 @@ DEBUG_ERRORS = "Ошибки отладки"
MISC_TITLE = "MISC"
PAUSE_IN_SINGLEPLAYER = "Пауза в одиночной игре"
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 = "Параметры меню"
INFORMATION = "Информация"
DEBUG = "Отладка"

View file

@ -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"
UNRECOGNIZED = "Comando desconocido."
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]
BACK = "Volver"
@ -105,6 +107,7 @@ DEADZONE = "Zona muerta"
RUMBLE_STRENGTH = "Intensidad de vibración"
CHAT = "Chat"
CHAT_COMMAND = "Chat (Comando)"
PLAYERS = "Jugadores"
D_UP = "Cruz Arriba"
D_DOWN = "Cruz Abajo"
@ -319,7 +322,17 @@ DEBUG_ERRORS = "Errores de Depuración"
MISC_TITLE = "OTROS"
PAUSE_IN_SINGLEPLAYER = "Pausa en modo de un jugador"
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ú"
INFORMATION = "Información"
DEBUG = "Depuración"

View file

@ -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_BEHIND, behind_hud_render_psc)
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
-- Created by PeachyPeach

View file

@ -15,15 +15,15 @@ void sequence_channel_set_volume(struct SequenceChannel *seqChannel, u8 volume);
void process_sequences(s32 iterationsRemaining);
void init_sequence_player(u32 player);
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);
/* |description|Sets the `tempo` of `player`. Resets when another sequence is played|descriptionEnd| */
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);
/* |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);
/* |description|Gets the transposition (pitch) of `player`|descriptionEnd| */
/* |description|Gets the `transposition` (pitch) of `player`|descriptionEnd| */
u16 sequence_player_get_transposition(u8 player);
/* |description|Sets the `transposition` (pitch) of `player`. Resets when another sequence is played|descriptionEnd| */
void sequence_player_set_transposition(u8 player, u16 transposition);

View file

@ -3,6 +3,7 @@ static u32 networkBowserAnimationIndex = 0;
static u8 bowserIsDying = FALSE;
static u8 bowserCutscenePlayed = FALSE;
static u8 bowserIsCutscenePlayer = FALSE;
static u8 bowserCutsceneGlobalIndex = UNKNOWN_GLOBAL_INDEX;
void bowser_tail_anchor_act_0(void) {
struct Object* bowser = o->parentObj;
@ -777,6 +778,10 @@ void bowser_act_thrown_dropped(void)
o->oAction = 4;
else
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();
}
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?
@ -1232,6 +1246,7 @@ void bowser_held_update(void) {
return;
}
o->parentObj = player;
o->oBowserUnkF4 &= ~0x20000;
cur_obj_become_intangible();
@ -1385,6 +1400,13 @@ static u8 bhv_bowser_ignore_if_true(void) {
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) {
bowserIsDying = FALSE;
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.
if (!is_other_player_active()) {
bowserIsCutscenePlayer = TRUE;
bowserCutsceneGlobalIndex = gNetworkPlayerLocal->globalIndex;
o->oAction = 5; // bowser_act_text_wait
} else { // If we aren't do nothing till we get our sync.
bowserIsCutscenePlayer = FALSE;
bowserCutsceneGlobalIndex = UNKNOWN_GLOBAL_INDEX;
o->oAction = 20; // bowser_act_nothing
}
@ -1419,9 +1443,11 @@ void bhv_bowser_init(void) {
if (so) {
so->override_ownership = bhv_bowser_override_ownership;
so->ignore_if_true = bhv_bowser_ignore_if_true;
so->on_received_post = bhv_bowser_on_received_post;
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.animInfo.animFrame, 16);
sync_object_init_field_with_size(o, &bowserCutsceneGlobalIndex, 8);
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[1]);

View file

@ -23,7 +23,7 @@ void bhv_heave_ho_throw_mario_loop(void) {
if (player) {
player->oInteractStatus |= INT_STATUS_MARIO_UNK2;
}
if (marioState) {
if (marioState && marioState->action == ACT_GRABBED) {
marioState->forwardVel = -45.0f;
marioState->vel[1] = 95.0f;
}

View file

@ -36,9 +36,9 @@ u32 mario_update_moving_sand(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| */
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);
/* |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);
/* |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);

View file

@ -4,6 +4,9 @@
#include <stdio.h>
#include <string.h>
#include <assert.h>
#ifdef _WIN32
#include <windows.h>
#endif
#include <ctype.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 configKeyStickRight[MAX_BINDS] = { 0x0020, 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 configKeyDUp[MAX_BINDS] = { 0x0147, 0x100b, VK_INVALID };
unsigned int configKeyDDown[MAX_BINDS] = { 0x014f, 0x100c, VK_INVALID };
@ -128,7 +132,10 @@ unsigned int configRumbleStrength = 50;
unsigned int configGamepadNumber = 0;
bool configBackgroundGamepad = true;
bool configDisableGamepads = false;
bool configUseStandardKeyBindingsChat = false;
bool configUseStandardKeyBindingsChat = true;
bool configChatCharCounter = true;
bool configDisableChatWhenClosed = false;
unsigned int configChatWidth = 800;
bool configSmoothScrolling = false;
// free camera settings
bool configEnableFreeCamera = false;
@ -257,6 +264,7 @@ static const struct ConfigOption options[] = {
{.name = "key_stickleft", .type = CONFIG_TYPE_BIND, .uintValue = configKeyStickLeft},
{.name = "key_stickright", .type = CONFIG_TYPE_BIND, .uintValue = configKeyStickRight},
{.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_dup", .type = CONFIG_TYPE_BIND, .uintValue = configKeyDUp},
{.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},
#endif
{.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 = "stick_rotate_left", .type = CONFIG_TYPE_BOOL, .boolValue = &configStick.rotateLeft},
{.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) {
// Create a new config file and save defaults
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);
return;
}
@ -777,6 +805,23 @@ NEXT_OPTION:
}
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 (configFrameLimit < 30) { configFrameLimit = 30; }

View file

@ -80,6 +80,7 @@ extern unsigned int configKeyStickDown[MAX_BINDS];
extern unsigned int configKeyStickLeft[MAX_BINDS];
extern unsigned int configKeyStickRight[MAX_BINDS];
extern unsigned int configKeyChat[MAX_BINDS];
extern unsigned int configKeyChatCommand[MAX_BINDS];
extern unsigned int configKeyPlayerList[MAX_BINDS];
extern unsigned int configKeyDUp[MAX_BINDS];
extern unsigned int configKeyDDown[MAX_BINDS];
@ -95,6 +96,9 @@ extern unsigned int configGamepadNumber;
extern bool configBackgroundGamepad;
extern bool configDisableGamepads;
extern bool configUseStandardKeyBindingsChat;
extern bool configChatCharCounter;
extern bool configDisableChatWhenClosed;
extern unsigned int configChatWidth;
extern bool configSmoothScrolling;
// free camera settings
extern bool configEnableFreeCamera;

View file

@ -54,6 +54,11 @@ void sent_history_init(ArrayList *arrayList) {
void sent_history_add_message(ArrayList *arrayList, const char *newMessage) {
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) {
for (s32 i = 1; i < MAX_HISTORY_SIZE; 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) {
struct DjuiChatBox* chatBox = (struct DjuiChatBox*)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) {
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);
@ -130,7 +135,12 @@ static void djui_chat_box_set_focus_style(void) {
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) {
@ -140,6 +150,10 @@ static void djui_chat_box_input_enter(struct DjuiInputbox* chatInput) {
sent_history_add_message(&sentHistory, chatInput->buffer);
if (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();
} else if (!exec_chat_command(chatInput->buffer)) {
char extendedUnknownCommandMessage[MAX_CHAT_MSG_LENGTH];
@ -176,7 +190,7 @@ static char* get_main_command_from_input(const char* input) {
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);
if (!subcommands || !subcommands[0]) {
@ -192,7 +206,13 @@ static bool complete_subcommand(const char* mainCommand, const char* subCommandP
bool completionSuccess = false;
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;
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));
}
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();
if (!playerNames || !playerNames[0]) {
if (playerNames) {
@ -291,7 +311,13 @@ static bool complete_player_name(const char* namePrefix) {
bool completionSuccess = false;
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;
for (s32 i = 0; playerNames[i] != NULL; i++) {
@ -314,14 +340,83 @@ static bool complete_player_name(const char* namePrefix) {
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;
if (gDjuiChatBox->chatInput->buffer[0] == '/') {
char* spacePosition = strrchr(sCommandsTabCompletionOriginalText, ' ');
if (spacePosition != NULL) {
char* mainCommand = get_main_command_from_input(sCommandsTabCompletionOriginalText);
if (mainCommand) {
if (!complete_subcommand(mainCommand + 1, spacePosition + 1)) {
if (!complete_subcommand(mainCommand + 1, spacePosition + 1, reverse)) {
reset_tab_completion_all();
} else {
alreadyTabCompleted = true;
@ -344,7 +439,13 @@ static void handle_tab_completion(void) {
}
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;
for (s32 i = 0; commands[i] != NULL; i++) {
@ -364,7 +465,7 @@ static void handle_tab_completion(void) {
if (spacePositionB != NULL) {
char* mainCommandB = get_main_command_from_input(sCommandsTabCompletionOriginalText);
if (mainCommandB) {
if (!complete_subcommand(mainCommandB + 1, spacePositionB + 1)) {
if (!complete_subcommand(mainCommandB + 1, spacePositionB + 1, reverse)) {
reset_tab_completion_all();
} else {
alreadyTabCompleted = true;
@ -404,7 +505,7 @@ static void handle_tab_completion(void) {
if (sPlayersTabCompletionIndex == -1) {
snprintf(sPlayersTabCompletionOriginalText, MAX_CHAT_MSG_LENGTH, "%s", wordInfo.word);
}
if (!complete_player_name(sPlayersTabCompletionOriginalText)) {
if (!complete_player_name(sPlayersTabCompletionOriginalText, reverse)) {
reset_tab_completion_players();
} else {
alreadyTabCompleted = true;
@ -457,7 +558,7 @@ static bool djui_chat_box_input_on_key_down(UNUSED struct DjuiBase* base, int sc
gDjuiChatBox->scrollY -= pageAmount;
break;
case SCANCODE_TAB:
handle_tab_completion();
handle_tab_completion(gDjuiInputHeldShift);
return true;
case SCANCODE_ENTER:
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;
}
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) {
if (gDjuiChatBox != NULL) {
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_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_color(base, 0, 0, 0, 0);
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 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(cfBase, 1.0f, 2);
djui_base_set_color(cfBase, 0, 0, 0, 128);
djui_base_set_padding(cfBase, 2, 2, 2, 2);
djui_flow_layout_set_margin(chatFlow, 2);
djui_base_set_color(cfBase, 0, 0, 0, 64);
djui_base_set_padding(cfBase, 0, 2, 0, 2);
djui_flow_layout_set_margin(chatFlow, 0);
djui_flow_layout_set_flow_direction(chatFlow, DJUI_FLOW_DIR_UP);
cfBase->addChildrenToHead = 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(ciBase, 1.0f, 32);
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_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);

View file

@ -14,4 +14,6 @@ extern struct DjuiChatBox* gDjuiChatBox;
extern bool gDjuiChatBoxFocus;
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);

View file

@ -24,14 +24,16 @@ static bool djui_chat_message_render(struct DjuiBase* base) {
}
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_size_type(base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
djui_base_set_size(base, 1.0f, chatMessage->base.height.value);
} else if (configDisableChatWhenClosed) {
return false;
} else if (f <= 0.1f) {
return false;
} 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_size_type(base, DJUI_SVT_ABSOLUTE, DJUI_SVT_ABSOLUTE);
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_set_size_type(base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
djui_base_set_size(base, 1.0f, 0);
djui_base_set_color(base, 0, 0, 0, 64);
djui_base_set_padding(base, 2, 4, 2, 4);
djui_base_set_color(base, 0, 0, 0, 0);
djui_base_set_padding(base, 0, 4, 0, 4);
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;

View file

@ -33,7 +33,7 @@ static struct DjuiColor sRefColor = { 255, 255, 255, 255 };
static bool sLegacy = false;
f32 gDjuiHudUtilsZ = 0;
u8 gDjuiHudLockMouse = false;
bool gDjuiHudLockMouse = false;
extern ALIGNED8 const u8 texture_hud_char_camera[];
extern ALIGNED8 const u8 texture_hud_char_lakitu[];
@ -297,6 +297,10 @@ f32 djui_hud_get_raw_mouse_y(void) {
return mouse_y;
}
bool djui_hud_is_mouse_locked(void) {
return gDjuiHudLockMouse;
}
void djui_hud_set_mouse_locked(bool locked) {
gDjuiHudLockMouse = locked;
}

View file

@ -52,7 +52,7 @@ struct GlobalTextures {
extern struct GlobalTextures gGlobalTextures;
extern f32 gDjuiHudUtilsZ;
extern u8 gDjuiHudLockMouse;
extern bool gDjuiHudLockMouse;
/* |description|Gets the current DJUI HUD resolution|descriptionEnd| */
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);
/* |description|Returns the y coordinate of the mouse relative to the screen|descriptionEnd| */
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);
/* |description|Returns the flags of the mouse buttons held down|descriptionEnd| */
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);
/* |description|Returns the amount scrolled vertically (-down/up+)|descriptionEnd| */
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);
/* |description|put the description here|descriptionEnd| */
/* |description|Resets the viewport to a fullscreen state|descriptionEnd| */
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);
/* |description|put the description here|descriptionEnd| */
/* |description|Resets the scissor rectangle to a fullscreen state|descriptionEnd| */
void djui_hud_reset_scissor(void);
/* |description|Measures the length of `message` in the current font|descriptionEnd| */

View file

@ -3,12 +3,14 @@
#include "djui.h"
#include "djui_unicode.h"
#include "djui_hud_utils.h"
#include "djui_chat_box.h"
#include "pc/gfx/gfx_window_manager_api.h"
#include "pc/pc_main.h"
#include "game/segment2.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_MID_BLINK (DJUI_INPUTBOX_MAX_BLINK / 2)
#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) {
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) {
djui_base_set_border_color(base, 90, 90, 90, 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;
}
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) {
const struct DjuiFont* font = gDjuiFonts[configDjuiThemeFont == 0 ? FONT_NORMAL : FONT_ALIASED];
bool isChatInput = (gDjuiChatBox != NULL && &gDjuiChatBox->chatInput->base == &inputbox->base);
// make selection well formed
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)) {
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);
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);
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];
djui_rect_render(base);
// Shift the text away from the left side a tad
comp->x += 2;
comp->width -= 2;
bool isChatInput = (gDjuiChatBox != NULL && &gDjuiChatBox->chatInput->base == base);
if (isChatInput) {
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
djui_inputbox_keep_selection_in_view(inputbox);
@ -560,6 +635,12 @@ static bool djui_inputbox_render(struct DjuiBase* base) {
// translate position
f32 translatedX = comp->x + inputbox->viewX;
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);
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);
}
// set color
gDPSetEnvColor(gDisplayListHead++, inputbox->textColor.r, inputbox->textColor.g, inputbox->textColor.b, inputbox->textColor.a);
// render preview text (for tab completion) - after font setup
// 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
u16 selection[2] = { 0 };
@ -608,7 +695,11 @@ static bool djui_inputbox_render(struct DjuiBase* base) {
if (insideSelection && !wasInsideSelection) {
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255);
} 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;
}
@ -617,9 +708,101 @@ static bool djui_inputbox_render(struct DjuiBase* base) {
djui_inputbox_render_char(inputbox, c, &drawX, &additionalShift);
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);
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;
}

View file

@ -211,16 +211,23 @@ bool djui_interactable_on_key_down(int scancode) {
}
}
if (gDjuiChatBox != NULL && !gDjuiChatBoxFocus) {
if (gDjuiChatBox != NULL) {
bool pressChat = false;
bool pressChatCommand = false;
for (int i = 0; i < MAX_BINDS; i++) {
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();
return true;
}
if (pressChatCommand && !gDjuiConsoleFocus) {
djui_chat_box_open_with_text("/");
return true;
}
}
if ((gDjuiPlayerList != NULL || gDjuiModList != NULL)) {

View file

@ -42,6 +42,32 @@ void djui_panel_controls_create(struct DjuiBase* caller) {
#endif
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
int numJoys = SDL_NumJoysticks();
if (numJoys == 0) { numJoys = 1; }

View file

@ -15,18 +15,19 @@ void djui_panel_controls_extra_create(struct DjuiBase* caller) {
djui_base_set_color(&bindBody->base, 0, 0, 0, 0);
djui_flow_layout_set_margin(bindBody, 1);
{
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, D_UP), configKeyDUp);
djui_bind_create(&bindBody->base, DLANG(CONTROLS, D_DOWN), configKeyDDown);
djui_bind_create(&bindBody->base, DLANG(CONTROLS, D_LEFT), configKeyDLeft);
djui_bind_create(&bindBody->base, DLANG(CONTROLS, D_RIGHT), configKeyDRight);
djui_bind_create(&bindBody->base, DLANG(CONTROLS, X), configKeyX);
djui_bind_create(&bindBody->base, DLANG(CONTROLS, Y), configKeyY);
djui_bind_create(&bindBody->base, DLANG(CONTROLS, CONSOLE), configKeyConsole);
djui_bind_create(&bindBody->base, DLANG(CONTROLS, PREV), configKeyPrevPage);
djui_bind_create(&bindBody->base, DLANG(CONTROLS, NEXT), configKeyNextPage);
djui_bind_create(&bindBody->base, DLANG(CONTROLS, DISCONNECT), configKeyDisconnect);
djui_bind_create(&bindBody->base, DLANG(CONTROLS, CHAT), configKeyChat);
djui_bind_create(&bindBody->base, DLANG(CONTROLS, CHAT_COMMAND), configKeyChatCommand);
djui_bind_create(&bindBody->base, DLANG(CONTROLS, PLAYERS), configKeyPlayerList);
djui_bind_create(&bindBody->base, DLANG(CONTROLS, D_UP), configKeyDUp);
djui_bind_create(&bindBody->base, DLANG(CONTROLS, D_DOWN), configKeyDDown);
djui_bind_create(&bindBody->base, DLANG(CONTROLS, D_LEFT), configKeyDLeft);
djui_bind_create(&bindBody->base, DLANG(CONTROLS, D_RIGHT), configKeyDRight);
djui_bind_create(&bindBody->base, DLANG(CONTROLS, X), configKeyX);
djui_bind_create(&bindBody->base, DLANG(CONTROLS, Y), configKeyY);
djui_bind_create(&bindBody->base, DLANG(CONTROLS, CONSOLE), configKeyConsole);
djui_bind_create(&bindBody->base, DLANG(CONTROLS, PREV), configKeyPrevPage);
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);

View file

@ -12698,6 +12698,21 @@ int smlua_func_djui_hud_get_raw_mouse_y(UNUSED lua_State* L) {
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) {
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_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_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_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);