From 03b29489b15f5e6426f250a7fbeb048ac992b23f Mon Sep 17 00:00:00 2001
From: Beckowl <68874587+Beckowl@users.noreply.github.com>
Date: Sun, 3 Aug 2025 12:49:45 -0300
Subject: [PATCH] Add ``smlua_text_utils_allocate_dialog`` (#896)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* wip
* get rid of seg2_dialog_table and fix crashes
* remove unused include
* change more types to s32
* remove dialog tables from eu_translation.h
* fix dialog_table_get signature
* Change `oToadMessageDialogId` to s32
* remove exit from dialog_table_add
* warning
* calloc allocated dialogs
* avoid memcpy on allocation fail
* Move dialog entry text field init to dialog_table_init
* Free original dialog entries' text field
* Put all reset logic in one place
* Run autogen
* Remove ``get_dialog_text_ascii`` from autogen
* minor fix
* free dialog->str if replaced
* nevermind
* remove get_dialog_unmodified from autogen
* Change -1 to DIALOG_NONE
* update stuff to s32
* use growing array functions
* Change limit to something more reasonable
* add null check
* remove explicit cast
* Minor fixes
* more type fix
* peachy review
* Fix weird enums in autogen
* remove extra newline :p
* add dialog restore
* bump max dialogs just a lil bit 🥺
* add lua behavior params
* all OBJECT fields are now Lua variables
* Revert lua behavior params changes
* isaac review
* fix segfault
---------
Co-authored-by: PeachyPeachSM64 <72323920+PeachyPeachSM64@users.noreply.github.com>
---
autogen/convert_constants.py | 18 +++-
autogen/convert_functions.py | 2 +-
autogen/convert_structs.py | 2 +-
autogen/lua_definitions/constants.lua | 44 +++++-----
autogen/lua_definitions/functions.lua | 12 +++
autogen/lua_definitions/structs.lua | 1 +
bin/eu/translation_de.c | 1 -
bin/eu/translation_en.c | 1 -
bin/eu/translation_fr.c | 1 -
docs/lua/constants.md | 29 ++++---
docs/lua/functions-3.md | 12 +--
docs/lua/functions-6.md | 46 +++++++++-
docs/lua/functions.md | 2 +
docs/lua/structs.md | 1 +
include/dialog_ids.h | 1 +
include/eu_translation.h | 3 -
include/object_fields.h | 2 +-
include/types.h | 2 +-
src/audio/external.c | 6 +-
src/audio/external.h | 3 +-
src/game/behaviors/bobomb.inc.c | 2 +-
src/game/behaviors/bowser.inc.c | 8 +-
src/game/behaviors/intro_peach.inc.c | 2 +-
src/game/behaviors/koopa.inc.c | 10 +--
src/game/behaviors/mips.inc.c | 2 +-
src/game/behaviors/racing_penguin.inc.c | 6 +-
src/game/behaviors/wiggler.inc.c | 8 +-
src/game/camera.c | 26 +++---
src/game/camera.h | 2 +-
src/game/envfx_snow.c | 2 +-
src/game/ingame_menu.c | 98 +++++++--------------
src/game/ingame_menu.h | 22 ++---
src/game/level_update.c | 6 +-
src/game/mario.c | 4 +-
src/game/mario_actions_cutscene.c | 4 +-
src/game/mario_misc.c | 2 +-
src/game/obj_behaviors.c | 2 +-
src/game/obj_behaviors.h | 2 +-
src/game/obj_behaviors_2.c | 2 +-
src/game/object_helpers.c | 2 +-
src/game/segment2.h | 1 -
src/pc/dialog_table.c | 99 +++++++++++++++++++++
src/pc/dialog_table.h | 23 +++++
src/pc/lua/smlua_cobject_autogen.c | 7 +-
src/pc/lua/smlua_constants_autogen.c | 29 ++++---
src/pc/lua/smlua_functions_autogen.c | 46 ++++++++--
src/pc/lua/utils/smlua_misc_utils.h | 2 +-
src/pc/lua/utils/smlua_text_utils.c | 111 +++++++++++-------------
src/pc/lua/utils/smlua_text_utils.h | 8 ++
src/pc/network/packets/packet_player.c | 2 +-
src/pc/pc_main.c | 1 -
text/define_text.inc.c | 16 +---
52 files changed, 461 insertions(+), 285 deletions(-)
create mode 100644 src/pc/dialog_table.c
create mode 100644 src/pc/dialog_table.h
diff --git a/autogen/convert_constants.py b/autogen/convert_constants.py
index df0255d77..5e857ead2 100644
--- a/autogen/convert_constants.py
+++ b/autogen/convert_constants.py
@@ -202,6 +202,7 @@ def process_enum(filename, line, inIfBlock):
constants = []
set_to = None
+ set_to_val = None
index = 0
fields = val.split(',')
for field in fields:
@@ -210,14 +211,25 @@ def process_enum(filename, line, inIfBlock):
continue
if '=' in field:
- ident, val = field.split('=', 2)
- constants.append([ident.strip(), val.strip()])
+ ident, val = field.split('=', 1)
+ ident = ident.strip()
+ val = val.strip()
+
+ try:
+ set_to_val = int(eval(val, {}, {}))
+ except Exception:
+ set_to_val = None
+
+ constants.append([ident, val])
set_to = ident
index = 1
continue
if set_to is not None:
- constants.append([field, '((%s) + %d)' % (set_to, index)])
+ if set_to_val is not None:
+ constants.append([field, str(set_to_val + index)])
+ else:
+ constants.append([field, '((%s) + %d)' % (set_to, index)])
index += 1
continue
diff --git a/autogen/convert_functions.py b/autogen/convert_functions.py
index 9e8ef5368..8f0e8758a 100644
--- a/autogen/convert_functions.py
+++ b/autogen/convert_functions.py
@@ -131,7 +131,7 @@ override_disallowed_functions = {
"src/pc/lua/utils/smlua_audio_utils.h": [ "smlua_audio_utils_override", "audio_custom_shutdown", "smlua_audio_custom_deinit", "audio_sample_destroy_pending_copies", "audio_custom_update_volume" ],
"src/pc/djui/djui_hud_utils.h": [ "djui_hud_render_texture_raw", "djui_hud_render_texture_tile_raw" ],
"src/pc/lua/utils/smlua_level_utils.h": [ "smlua_level_util_reset" ],
- "src/pc/lua/utils/smlua_text_utils.h": [ "smlua_text_utils_init", "smlua_text_utils_shutdown" ],
+ "src/pc/lua/utils/smlua_text_utils.h": [ "smlua_text_utils_init", "smlua_text_utils_shutdown", "get_dialog_text_ascii", "smlua_text_utils_dialog_get_unmodified"],
"src/pc/lua/utils/smlua_anim_utils.h": [ "smlua_anim_util_reset", "smlua_anim_util_register_animation" ],
"src/pc/lua/utils/smlua_gfx_utils.h": [ "gfx_allocate_internal", "vtx_allocate_internal", "gfx_get_length_no_sentinel" ],
"src/pc/network/lag_compensation.h": [ "lag_compensation_clear" ],
diff --git a/autogen/convert_structs.py b/autogen/convert_structs.py
index a781e7ba0..0352b44f2 100644
--- a/autogen/convert_structs.py
+++ b/autogen/convert_structs.py
@@ -140,7 +140,7 @@ override_field_immutable = {
"FirstPersonCamera": [ "enabled" ],
"ModAudio": [ "isStream", "loaded" ],
"Gfx": [ "w0", "w1" ], # to protect from invalid type conversions
- "DialogEntry": [ "unused", "linesPerBox", "leftOffset", "width", "str", "text"],
+ "DialogEntry": [ "unused", "linesPerBox", "leftOffset", "width", "str", "text", "replaced"],
"ModFsFile": [ "*" ],
"ModFs": [ "*" ],
}
diff --git a/autogen/lua_definitions/constants.lua b/autogen/lua_definitions/constants.lua
index 9a03b12ba..4f814b1d4 100644
--- a/autogen/lua_definitions/constants.lua
+++ b/autogen/lua_definitions/constants.lua
@@ -2361,6 +2361,7 @@ M_MOUSE_BUTTON = MOUSE_BUTTON_2
--- @type integer
R_MOUSE_BUTTON = MOUSE_BUTTON_3
+DIALOG_NONE = -1 --- @type DialogId
DIALOG_000 = 0 --- @type DialogId
DIALOG_001 = 1 --- @type DialogId
DIALOG_002 = 2 --- @type DialogId
@@ -2534,6 +2535,7 @@ DIALOG_169 = 169 --- @type DialogId
DIALOG_COUNT = 170 --- @type DialogId
--- @alias DialogId
+--- | `DIALOG_NONE`
--- | `DIALOG_000`
--- | `DIALOG_001`
--- | `DIALOG_002`
@@ -3485,27 +3487,27 @@ SPECIAL_WARP_TITLE = -8
--- @type integer
SPECIAL_WARP_LEVEL_SELECT = -9
-MARIO_SPAWN_NONE = 0 --- @type MarioSpawnType
-MARIO_SPAWN_DOOR_WARP = 1 --- @type MarioSpawnType
-MARIO_SPAWN_IDLE = 2 --- @type MarioSpawnType
-MARIO_SPAWN_PIPE = 3 --- @type MarioSpawnType
-MARIO_SPAWN_TELEPORT = 4 --- @type MarioSpawnType
-MARIO_SPAWN_INSTANT_ACTIVE = 0x10 --- @type MarioSpawnType
-MARIO_SPAWN_SWIMMING = ((MARIO_SPAWN_INSTANT_ACTIVE ) + 1) --- @type MarioSpawnType
-MARIO_SPAWN_AIRBORNE = ((MARIO_SPAWN_INSTANT_ACTIVE ) + 2) --- @type MarioSpawnType
-MARIO_SPAWN_HARD_AIR_KNOCKBACK = ((MARIO_SPAWN_INSTANT_ACTIVE ) + 3) --- @type MarioSpawnType
-MARIO_SPAWN_SPIN_AIRBORNE_CIRCLE = ((MARIO_SPAWN_INSTANT_ACTIVE ) + 4) --- @type MarioSpawnType
-MARIO_SPAWN_DEATH = ((MARIO_SPAWN_INSTANT_ACTIVE ) + 5) --- @type MarioSpawnType
-MARIO_SPAWN_SPIN_AIRBORNE = ((MARIO_SPAWN_INSTANT_ACTIVE ) + 6) --- @type MarioSpawnType
-MARIO_SPAWN_FLYING = ((MARIO_SPAWN_INSTANT_ACTIVE ) + 7) --- @type MarioSpawnType
-MARIO_SPAWN_PAINTING_STAR_COLLECT = 0x20 --- @type MarioSpawnType
-MARIO_SPAWN_PAINTING_DEATH = ((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 1) --- @type MarioSpawnType
-MARIO_SPAWN_AIRBORNE_STAR_COLLECT = ((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 2) --- @type MarioSpawnType
-MARIO_SPAWN_AIRBORNE_DEATH = ((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 3) --- @type MarioSpawnType
-MARIO_SPAWN_LAUNCH_STAR_COLLECT = ((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 4) --- @type MarioSpawnType
-MARIO_SPAWN_LAUNCH_DEATH = ((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 5) --- @type MarioSpawnType
-MARIO_SPAWN_UNUSED_38 = ((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 6) --- @type MarioSpawnType
-MARIO_SPAWN_FADE_FROM_BLACK = ((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 7) --- @type MarioSpawnType
+MARIO_SPAWN_NONE = 0 --- @type MarioSpawnType
+MARIO_SPAWN_DOOR_WARP = 1 --- @type MarioSpawnType
+MARIO_SPAWN_IDLE = 2 --- @type MarioSpawnType
+MARIO_SPAWN_PIPE = 3 --- @type MarioSpawnType
+MARIO_SPAWN_TELEPORT = 4 --- @type MarioSpawnType
+MARIO_SPAWN_INSTANT_ACTIVE = 0x10 --- @type MarioSpawnType
+MARIO_SPAWN_SWIMMING = 17 --- @type MarioSpawnType
+MARIO_SPAWN_AIRBORNE = 18 --- @type MarioSpawnType
+MARIO_SPAWN_HARD_AIR_KNOCKBACK = 19 --- @type MarioSpawnType
+MARIO_SPAWN_SPIN_AIRBORNE_CIRCLE = 20 --- @type MarioSpawnType
+MARIO_SPAWN_DEATH = 21 --- @type MarioSpawnType
+MARIO_SPAWN_SPIN_AIRBORNE = 22 --- @type MarioSpawnType
+MARIO_SPAWN_FLYING = 23 --- @type MarioSpawnType
+MARIO_SPAWN_PAINTING_STAR_COLLECT = 0x20 --- @type MarioSpawnType
+MARIO_SPAWN_PAINTING_DEATH = 33 --- @type MarioSpawnType
+MARIO_SPAWN_AIRBORNE_STAR_COLLECT = 34 --- @type MarioSpawnType
+MARIO_SPAWN_AIRBORNE_DEATH = 35 --- @type MarioSpawnType
+MARIO_SPAWN_LAUNCH_STAR_COLLECT = 36 --- @type MarioSpawnType
+MARIO_SPAWN_LAUNCH_DEATH = 37 --- @type MarioSpawnType
+MARIO_SPAWN_UNUSED_38 = 38 --- @type MarioSpawnType
+MARIO_SPAWN_FADE_FROM_BLACK = 39 --- @type MarioSpawnType
--- @alias MarioSpawnType
--- | `MARIO_SPAWN_NONE`
diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua
index 937a787c2..cca3e4ab6 100644
--- a/autogen/lua_definitions/functions.lua
+++ b/autogen/lua_definitions/functions.lua
@@ -11887,6 +11887,12 @@ function smlua_text_utils_dialog_replace(dialogId, unused, linesPerBox, leftOffs
-- ...
end
+--- @param dialogId DialogId
+--- Restores a replaced DialogEntry to its original state.
+function smlua_text_utils_dialog_restore(dialogId)
+ -- ...
+end
+
--- @param dialogId DialogId
--- @return boolean
--- Returns whether the dialog with the given ID has been replaced
@@ -11894,6 +11900,12 @@ function smlua_text_utils_dialog_is_replaced(dialogId)
-- ...
end
+--- @return integer
+--- Allocates a new dialog entry
+function smlua_text_utils_allocate_dialog()
+ -- ...
+end
+
--- @param courseNum integer
--- @param courseName string
--- @param act1 string
diff --git a/autogen/lua_definitions/structs.lua b/autogen/lua_definitions/structs.lua
index 944a33d07..7012bfe3a 100644
--- a/autogen/lua_definitions/structs.lua
+++ b/autogen/lua_definitions/structs.lua
@@ -595,6 +595,7 @@
--- @class DialogEntry
--- @field public leftOffset integer
--- @field public linesPerBox integer
+--- @field public replaced boolean
--- @field public text string
--- @field public unused integer
--- @field public width integer
diff --git a/bin/eu/translation_de.c b/bin/eu/translation_de.c
index ba232c0d1..d19dd930b 100644
--- a/bin/eu/translation_de.c
+++ b/bin/eu/translation_de.c
@@ -12,7 +12,6 @@
#define seg2_course_name_table_original course_name_table_eu_de_original
#define seg2_act_name_table act_name_table_eu_de
#define seg2_act_name_table_original act_name_table_eu_de_original
-#define seg2_dialog_table dialog_table_eu_de
#define seg2_dialog_original dialog_table_eu_de_original
#include "text/de/define_text.inc.c"
diff --git a/bin/eu/translation_en.c b/bin/eu/translation_en.c
index 208e1b9a5..8f8452a69 100644
--- a/bin/eu/translation_en.c
+++ b/bin/eu/translation_en.c
@@ -12,7 +12,6 @@
#define seg2_course_name_table_original course_name_table_eu_en_original
#define seg2_act_name_table act_name_table_eu_en
#define seg2_act_name_table_original act_name_table_eu_en_original
-#define seg2_dialog_table dialog_table_eu_en
#define seg2_dialog_original dialog_table_eu_en_original
#include "text/us/define_text.inc.c"
diff --git a/bin/eu/translation_fr.c b/bin/eu/translation_fr.c
index e7217e285..1a7b98fc6 100644
--- a/bin/eu/translation_fr.c
+++ b/bin/eu/translation_fr.c
@@ -12,7 +12,6 @@
#define seg2_course_name_table_original course_name_table_eu_fr_original
#define seg2_act_name_table act_name_table_eu_fr
#define seg2_act_name_table_original act_name_table_eu_fr_original
-#define seg2_dialog_table dialog_table_eu_fr
#define seg2_dialog_original dialog_table_eu_fr_original
#include "text/fr/define_text.inc.c"
diff --git a/docs/lua/constants.md b/docs/lua/constants.md
index 39eb819da..f91d7a48b 100644
--- a/docs/lua/constants.md
+++ b/docs/lua/constants.md
@@ -958,6 +958,7 @@
### [enum DialogId](#DialogId)
| Identifier | Value |
| :--------- | :---- |
+| DIALOG_NONE | -1 |
| DIALOG_000 | 0 |
| DIALOG_001 | 1 |
| DIALOG_002 | 2 |
@@ -1579,21 +1580,21 @@
| MARIO_SPAWN_PIPE | 3 |
| MARIO_SPAWN_TELEPORT | 4 |
| MARIO_SPAWN_INSTANT_ACTIVE | 0x10 |
-| MARIO_SPAWN_SWIMMING | ((MARIO_SPAWN_INSTANT_ACTIVE ) + 1) |
-| MARIO_SPAWN_AIRBORNE | ((MARIO_SPAWN_INSTANT_ACTIVE ) + 2) |
-| MARIO_SPAWN_HARD_AIR_KNOCKBACK | ((MARIO_SPAWN_INSTANT_ACTIVE ) + 3) |
-| MARIO_SPAWN_SPIN_AIRBORNE_CIRCLE | ((MARIO_SPAWN_INSTANT_ACTIVE ) + 4) |
-| MARIO_SPAWN_DEATH | ((MARIO_SPAWN_INSTANT_ACTIVE ) + 5) |
-| MARIO_SPAWN_SPIN_AIRBORNE | ((MARIO_SPAWN_INSTANT_ACTIVE ) + 6) |
-| MARIO_SPAWN_FLYING | ((MARIO_SPAWN_INSTANT_ACTIVE ) + 7) |
+| MARIO_SPAWN_SWIMMING | 17 |
+| MARIO_SPAWN_AIRBORNE | 18 |
+| MARIO_SPAWN_HARD_AIR_KNOCKBACK | 19 |
+| MARIO_SPAWN_SPIN_AIRBORNE_CIRCLE | 20 |
+| MARIO_SPAWN_DEATH | 21 |
+| MARIO_SPAWN_SPIN_AIRBORNE | 22 |
+| MARIO_SPAWN_FLYING | 23 |
| MARIO_SPAWN_PAINTING_STAR_COLLECT | 0x20 |
-| MARIO_SPAWN_PAINTING_DEATH | ((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 1) |
-| MARIO_SPAWN_AIRBORNE_STAR_COLLECT | ((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 2) |
-| MARIO_SPAWN_AIRBORNE_DEATH | ((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 3) |
-| MARIO_SPAWN_LAUNCH_STAR_COLLECT | ((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 4) |
-| MARIO_SPAWN_LAUNCH_DEATH | ((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 5) |
-| MARIO_SPAWN_UNUSED_38 | ((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 6) |
-| MARIO_SPAWN_FADE_FROM_BLACK | ((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 7) |
+| MARIO_SPAWN_PAINTING_DEATH | 33 |
+| MARIO_SPAWN_AIRBORNE_STAR_COLLECT | 34 |
+| MARIO_SPAWN_AIRBORNE_DEATH | 35 |
+| MARIO_SPAWN_LAUNCH_STAR_COLLECT | 36 |
+| MARIO_SPAWN_LAUNCH_DEATH | 37 |
+| MARIO_SPAWN_UNUSED_38 | 38 |
+| MARIO_SPAWN_FADE_FROM_BLACK | 39 |
- MARIO_SPAWN_UNKNOWN_02
- MARIO_SPAWN_UNKNOWN_03
- MARIO_SPAWN_UNKNOWN_27
diff --git a/docs/lua/functions-3.md b/docs/lua/functions-3.md
index 1839566f6..271479817 100644
--- a/docs/lua/functions-3.md
+++ b/docs/lua/functions-3.md
@@ -2186,7 +2186,7 @@ Starts a cutscene involving an object and displays dialog during the sequence. T
- `integer`
### C Prototype
-`s16 cutscene_object_with_dialog(u8 cutscene, struct Object *o, s16 dialogID);`
+`s16 cutscene_object_with_dialog(u8 cutscene, struct Object *o, s32 dialogID);`
[:arrow_up_small:](#)
@@ -4056,7 +4056,7 @@ Plays a dialog sound corresponding to `dialogID`
- None
### C Prototype
-`void play_dialog_sound(u8 dialogID);`
+`void play_dialog_sound(s32 dialogID);`
[:arrow_up_small:](#)
@@ -4692,7 +4692,7 @@ Creates a dialog box with a dialog ID that rotates into view
- None
### C Prototype
-`void create_dialog_box(s16 dialog);`
+`void create_dialog_box(s32 dialog);`
[:arrow_up_small:](#)
@@ -4716,7 +4716,7 @@ Creates a dialog box with a dialog variable
- None
### C Prototype
-`void create_dialog_box_with_var(s16 dialog, s32 dialogVar);`
+`void create_dialog_box_with_var(s32 dialog, s32 dialogVar);`
[:arrow_up_small:](#)
@@ -4739,7 +4739,7 @@ Creates a dialog box with a dialog ID that zooms into view
- None
### C Prototype
-`void create_dialog_inverted_box(s16 dialog);`
+`void create_dialog_inverted_box(s32 dialog);`
[:arrow_up_small:](#)
@@ -4762,7 +4762,7 @@ Creates a dialog box with a response
- None
### C Prototype
-`void create_dialog_box_with_response(s16 dialog);`
+`void create_dialog_box_with_response(s32 dialog);`
[:arrow_up_small:](#)
diff --git a/docs/lua/functions-6.md b/docs/lua/functions-6.md
index ebefc2e88..5ad76c5cb 100644
--- a/docs/lua/functions-6.md
+++ b/docs/lua/functions-6.md
@@ -4464,7 +4464,7 @@ Gets the current dialog box ID
- `integer`
### C Prototype
-`s16 get_dialog_id(void);`
+`s32 get_dialog_id(void);`
[:arrow_up_small:](#)
@@ -7254,6 +7254,29 @@ Replaces `dialogId` with a custom one
+## [smlua_text_utils_dialog_restore](#smlua_text_utils_dialog_restore)
+
+### Description
+Restores a replaced DialogEntry to its original state.
+
+### Lua Example
+`smlua_text_utils_dialog_restore(dialogId)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| dialogId | [enum DialogId](constants.md#enum-DialogId) |
+
+### Returns
+- None
+
+### C Prototype
+`void smlua_text_utils_dialog_restore(enum DialogId dialogId);`
+
+[:arrow_up_small:](#)
+
+
+
## [smlua_text_utils_dialog_is_replaced](#smlua_text_utils_dialog_is_replaced)
### Description
@@ -7277,6 +7300,27 @@ Returns whether the dialog with the given ID has been replaced
+## [smlua_text_utils_allocate_dialog](#smlua_text_utils_allocate_dialog)
+
+### Description
+Allocates a new dialog entry
+
+### Lua Example
+`local integerValue = smlua_text_utils_allocate_dialog()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 smlua_text_utils_allocate_dialog(void);`
+
+[:arrow_up_small:](#)
+
+
+
## [smlua_text_utils_course_acts_replace](#smlua_text_utils_course_acts_replace)
### Description
diff --git a/docs/lua/functions.md b/docs/lua/functions.md
index 8656b5289..f1e0ae3a1 100644
--- a/docs/lua/functions.md
+++ b/docs/lua/functions.md
@@ -2112,7 +2112,9 @@
- [smlua_text_utils_reset_all](functions-6.md#smlua_text_utils_reset_all)
- [smlua_text_utils_dialog_get](functions-6.md#smlua_text_utils_dialog_get)
- [smlua_text_utils_dialog_replace](functions-6.md#smlua_text_utils_dialog_replace)
+ - [smlua_text_utils_dialog_restore](functions-6.md#smlua_text_utils_dialog_restore)
- [smlua_text_utils_dialog_is_replaced](functions-6.md#smlua_text_utils_dialog_is_replaced)
+ - [smlua_text_utils_allocate_dialog](functions-6.md#smlua_text_utils_allocate_dialog)
- [smlua_text_utils_course_acts_replace](functions-6.md#smlua_text_utils_course_acts_replace)
- [smlua_text_utils_secret_star_replace](functions-6.md#smlua_text_utils_secret_star_replace)
- [smlua_text_utils_course_name_replace](functions-6.md#smlua_text_utils_course_name_replace)
diff --git a/docs/lua/structs.md b/docs/lua/structs.md
index 81f13a28f..0c510030f 100644
--- a/docs/lua/structs.md
+++ b/docs/lua/structs.md
@@ -886,6 +886,7 @@
| ----- | ---- | ------ |
| leftOffset | `integer` | read-only |
| linesPerBox | `integer` | read-only |
+| replaced | `boolean` | read-only |
| text | `string` | read-only |
| unused | `integer` | read-only |
| width | `integer` | read-only |
diff --git a/include/dialog_ids.h b/include/dialog_ids.h
index 6feadafb2..2d9a24108 100644
--- a/include/dialog_ids.h
+++ b/include/dialog_ids.h
@@ -2,6 +2,7 @@
#define DIALOG_IDS_H
enum DialogId {
+ DIALOG_NONE = -1,
DIALOG_000,
DIALOG_001,
DIALOG_002,
diff --git a/include/eu_translation.h b/include/eu_translation.h
index 02611b37a..e61d7ddc8 100644
--- a/include/eu_translation.h
+++ b/include/eu_translation.h
@@ -11,21 +11,18 @@
#define LANGUAGE_ARRAY(cmd) cmd
#endif
-extern u8 *dialog_table_eu_en[];
extern u8 *course_name_table_eu_en[];
extern u8 *act_name_table_eu_en[];
extern u8 *dialog_table_eu_en_original[];
extern u8 *course_name_table_eu_en_original[];
extern u8 *act_name_table_eu_en_original[];
-extern u8 *dialog_table_eu_fr[];
extern u8 *course_name_table_eu_fr[];
extern u8 *act_name_table_eu_fr[];
extern u8 *dialog_table_eu_fr_original[];
extern u8 *course_name_table_eu_fr_original[];
extern u8 *act_name_table_eu_fr_original[];
-extern u8 *dialog_table_eu_de[];
extern u8 *course_name_table_eu_de[];
extern u8 *act_name_table_eu_de[];
extern u8 *dialog_table_eu_de_original[];
diff --git a/include/object_fields.h b/include/object_fields.h
index 66ebdcc13..11f07257d 100644
--- a/include/object_fields.h
+++ b/include/object_fields.h
@@ -970,7 +970,7 @@
#define /*0x10C*/ oTiltingPyramidMarioOnPlatform OBJECT_FIELD_S32(0x21)
/* Toad Message */
-#define /*0x108*/ oToadMessageDialogId OBJECT_FIELD_U32(0x20)
+#define /*0x108*/ oToadMessageDialogId OBJECT_FIELD_S32(0x20)
#define /*0x10C*/ oToadMessageRecentlyTalked OBJECT_FIELD_S32(0x21)
#define /*0x110*/ oToadMessageState OBJECT_FIELD_S32(0x22)
diff --git a/include/types.h b/include/types.h
index dc20060b2..c5cecc02f 100644
--- a/include/types.h
+++ b/include/types.h
@@ -498,7 +498,7 @@ struct MarioState
u8 visibleToEnemies;
u8 wasNetworkVisible;
- s16 dialogId;
+ s32 dialogId;
s16 prevNumStarsForDialog;
s16 unkB0;
diff --git a/src/audio/external.c b/src/audio/external.c
index 1d778db59..c411aee8b 100644
--- a/src/audio/external.c
+++ b/src/audio/external.c
@@ -18,6 +18,8 @@
#include "pc/debuglog.h"
#include "pc/lua/utils/smlua_level_utils.h"
#include "pc/lua/smlua_hooks.h"
+#include "pc/dialog_table.h"
+#include "dialog_ids.h"
#if defined(VERSION_EU) || defined(VERSION_SH)
#define EU_FLOAT(x) x##f
@@ -2455,10 +2457,10 @@ void set_sound_moving_speed(u8 bank, u8 speed) {
/**
* Called from threads: thread5_game_loop
*/
-void play_dialog_sound(u8 dialogID) {
+void play_dialog_sound(s32 dialogID) {
s32 speaker;
- if (dialogID >= DIALOG_COUNT) {
+ if (!IS_VALID_VANILLA_DIALOG(dialogID)) {
dialogID = 0;
}
diff --git a/src/audio/external.h b/src/audio/external.h
index e0381e2ae..ff6a41f47 100644
--- a/src/audio/external.h
+++ b/src/audio/external.h
@@ -4,6 +4,7 @@
#include
#include "types.h"
+#include "dialog_ids.h"
#define MAX_AUDIO_OVERRIDE 128
@@ -87,7 +88,7 @@ void sound_banks_enable(u8 player, u16 bankMask);
/* |description|Sets the `speed` of moving `bank`|descriptionEnd| */
void set_sound_moving_speed(u8 bank, u8 speed);
/* |description|Plays a dialog sound corresponding to `dialogID`|descriptionEnd| */
-void play_dialog_sound(u8 dialogID);
+void play_dialog_sound(s32 dialogID);
/* |description|Sets the `volume` of `player`|descriptionEnd| */
void set_sequence_player_volume(s32 player, f32 volume);
/* |description|Plays fading in music (`seqArgs`) on `player` over `fadeTimer`|descriptionEnd| */
diff --git a/src/game/behaviors/bobomb.inc.c b/src/game/behaviors/bobomb.inc.c
index fc85b46c6..762eaabb6 100644
--- a/src/game/behaviors/bobomb.inc.c
+++ b/src/game/behaviors/bobomb.inc.c
@@ -337,7 +337,7 @@ void bobomb_buddy_act_idle(void) {
* dialogSecondText is called after Bob-omb Buddy has the cannon(s) ready and
* then tells Mario that is "Ready for blastoff".
*/
-void bobomb_buddy_cannon_dialog(s16 dialogFirstText, s16 dialogSecondText) {
+void bobomb_buddy_cannon_dialog(s32 dialogFirstText, s32 dialogSecondText) {
struct Object *cannonClosed;
s16 buddyText, cutscene;
diff --git a/src/game/behaviors/bowser.inc.c b/src/game/behaviors/bowser.inc.c
index 754af163a..78a0daac8 100644
--- a/src/game/behaviors/bowser.inc.c
+++ b/src/game/behaviors/bowser.inc.c
@@ -38,10 +38,10 @@ s8 D_8032F4FC[] = { 7, 8, 9, 12, 13, 14, 15, 4, 3, 16, 17, 19, 3, 3, 3, 3 };
s16 D_8032F50C[] = { 60, 0 };
s16 D_8032F510[] = { 50, 0 };
s8 D_8032F514[] = { 24, 42, 60, -1 };
-s16* sBowserDefeatedDialogText[3] = {
- (s16*) &gBehaviorValues.dialogs.Bowser1DefeatedDialog,
- (s16*) &gBehaviorValues.dialogs.Bowser2DefeatedDialog,
- (s16*) &gBehaviorValues.dialogs.Bowser3DefeatedDialog
+enum DialogId* sBowserDefeatedDialogText[3] = {
+ &gBehaviorValues.dialogs.Bowser1DefeatedDialog,
+ &gBehaviorValues.dialogs.Bowser2DefeatedDialog,
+ &gBehaviorValues.dialogs.Bowser3DefeatedDialog
};
s16 D_8032F520[][3] = { { 1, 10, 40 }, { 0, 0, 74 }, { -1, -10, 114 }, { 1, -20, 134 },
{ -1, 20, 154 }, { 1, 40, 164 }, { -1, -40, 174 }, { 1, -80, 179 },
diff --git a/src/game/behaviors/intro_peach.inc.c b/src/game/behaviors/intro_peach.inc.c
index 2838a9105..37b403010 100644
--- a/src/game/behaviors/intro_peach.inc.c
+++ b/src/game/behaviors/intro_peach.inc.c
@@ -40,7 +40,7 @@ void bhv_intro_peach_loop(void) {
case 2:
intro_peach_set_pos_and_opacity(gCurrentObject, 255.f, 3.f);
- if ((gCurrentObject->oTimer > 100) && (get_dialog_id() == -1))
+ if ((gCurrentObject->oTimer > 100) && (get_dialog_id() == DIALOG_NONE))
gCurrentObject->oAction += 1;
break;
case 3:
diff --git a/src/game/behaviors/koopa.inc.c b/src/game/behaviors/koopa.inc.c
index 924f50299..e7d79b8cc 100644
--- a/src/game/behaviors/koopa.inc.c
+++ b/src/game/behaviors/koopa.inc.c
@@ -50,16 +50,16 @@ static u8 sKoopaShelledAttackHandlers[] = {
* Data to control the behavior of each instance of Koopa the Quick.
*/
struct KoopaTheQuickProperties {
- s16* initText;
- s16* winText;
+ enum DialogId* initText;
+ enum DialogId* winText;
};
/**
* Properties for the BoB race and the THI race.
*/
static struct KoopaTheQuickProperties sKoopaTheQuickProperties[] = {
- { (s16*) &gBehaviorValues.dialogs.KoopaQuickBobStartDialog, (s16*) &gBehaviorValues.dialogs.KoopaQuickBobWinDialog },
- { (s16*) &gBehaviorValues.dialogs.KoopaQuickThiStartDialog, (s16*) &gBehaviorValues.dialogs.KoopaQuickThiWinDialog }
+ { &gBehaviorValues.dialogs.KoopaQuickBobStartDialog, &gBehaviorValues.dialogs.KoopaQuickBobWinDialog },
+ { &gBehaviorValues.dialogs.KoopaQuickThiStartDialog, &gBehaviorValues.dialogs.KoopaQuickThiWinDialog }
};
static u32 koopaPathedStartWaypoint = 0;
@@ -872,7 +872,7 @@ static void koopa_the_quick_act_after_race(void) {
if (marioState && should_start_or_continue_dialog(marioState, o)) {
s32 dialogResponse = cur_obj_update_dialog_with_cutscene(&gMarioStates[0], 2, 1, CUTSCENE_DIALOG, o->parentObj->oKoopaRaceEndpointUnk100, koopa_the_quick_act_after_race_continue_dialog);
if (dialogResponse != 0) {
- o->parentObj->oKoopaRaceEndpointUnk100 = -1;
+ o->parentObj->oKoopaRaceEndpointUnk100 = DIALOG_NONE;
o->oTimer = 0;
}
}
diff --git a/src/game/behaviors/mips.inc.c b/src/game/behaviors/mips.inc.c
index aa60aaf32..451d1c8b7 100644
--- a/src/game/behaviors/mips.inc.c
+++ b/src/game/behaviors/mips.inc.c
@@ -265,7 +265,7 @@ static u8 bhv_mips_held_continue_dialog(void) {
* Handles MIPS being held by Mario.
*/
void bhv_mips_held(void) {
- s16 dialogID;
+ s32 dialogID;
if (o->heldByPlayerIndex >= MAX_PLAYERS) { return; }
struct Object* player = gMarioStates[o->heldByPlayerIndex].marioObj;
diff --git a/src/game/behaviors/racing_penguin.inc.c b/src/game/behaviors/racing_penguin.inc.c
index fd8d9cfad..28137e7b5 100644
--- a/src/game/behaviors/racing_penguin.inc.c
+++ b/src/game/behaviors/racing_penguin.inc.c
@@ -1,12 +1,12 @@
struct RacingPenguinData {
- s16* text;
+ enum DialogId* text;
f32* radius;
f32* height;
};
static struct RacingPenguinData sRacingPenguinData[] = {
- { (s16*) &gBehaviorValues.dialogs.RacingPenguinStartDialog, &gBehaviorValues.RacingPenguinRadius, &gBehaviorValues.RacingPenguinHeight },
- { (s16*) &gBehaviorValues.dialogs.RacingPenguinBigStartDialog, &gBehaviorValues.RacingPenguinBigRadius, &gBehaviorValues.RacingPenguinBigHeight },
+ { &gBehaviorValues.dialogs.RacingPenguinStartDialog, &gBehaviorValues.RacingPenguinRadius, &gBehaviorValues.RacingPenguinHeight },
+ { &gBehaviorValues.dialogs.RacingPenguinBigStartDialog, &gBehaviorValues.RacingPenguinBigRadius, &gBehaviorValues.RacingPenguinBigHeight },
};
static u32 penguinPathedStartWaypoint = 0;
diff --git a/src/game/behaviors/wiggler.inc.c b/src/game/behaviors/wiggler.inc.c
index 531df5531..59a4ac9b1 100644
--- a/src/game/behaviors/wiggler.inc.c
+++ b/src/game/behaviors/wiggler.inc.c
@@ -300,10 +300,10 @@ static void wiggler_act_jumped_on(void) {
struct MarioState* marioState = nearest_mario_state_to_object(o);
// Text to show on first, second, and third attack.
- s32* attackText[3] = {
- (s32*) &gBehaviorValues.dialogs.WigglerAttack1Dialog,
- (s32*) &gBehaviorValues.dialogs.WigglerAttack2Dialog,
- (s32*) &gBehaviorValues.dialogs.WigglerAttack3Dialog
+ enum DialogId* attackText[3] = {
+ &gBehaviorValues.dialogs.WigglerAttack1Dialog,
+ &gBehaviorValues.dialogs.WigglerAttack2Dialog,
+ &gBehaviorValues.dialogs.WigglerAttack3Dialog
};
// Shrink until the squish speed becomes 0, then unisquish
diff --git a/src/game/camera.c b/src/game/camera.c
index 54f713d81..f18325c50 100644
--- a/src/game/camera.c
+++ b/src/game/camera.c
@@ -172,7 +172,7 @@ extern s16 s2ndRotateFlags;
extern s16 unused8033B31A;
extern s16 sCameraSoundFlags;
extern u16 sCButtonsPressed;
-extern s16 sCutsceneDialogID;
+extern s32 sCutsceneDialogID;
extern struct LakituState gLakituState;
extern s16 unused8033B3E8;
extern s16 sAreaYaw;
@@ -304,7 +304,7 @@ u16 sCButtonsPressed;
/**
* A copy of gDialogID, the dialog displayed during the cutscene.
*/
-s16 sCutsceneDialogID;
+s32 sCutsceneDialogID;
/**
* The currently playing shot in the cutscene.
*/
@@ -7271,16 +7271,16 @@ s32 unused_dialog_cutscene_response(u8 cutscene) {
}
}
-s16 cutscene_object_with_dialog(u8 cutscene, struct Object *o, s16 dialogID) {
+s16 cutscene_object_with_dialog(u8 cutscene, struct Object *o, s32 dialogID) {
s16 response = 0;
if ((gCamera->cutscene == 0) && (sObjectCutscene == 0)) {
if (gRecentCutscene != cutscene) {
start_object_cutscene(cutscene, o);
- if (dialogID != -1) {
+ if (dialogID != DIALOG_NONE) {
sCutsceneDialogID = dialogID;
} else {
- sCutsceneDialogID = (s16) gBehaviorValues.dialogs.DefaultCutsceneDialog;
+ sCutsceneDialogID = (s32) gBehaviorValues.dialogs.DefaultCutsceneDialog;
}
} else {
response = sCutsceneDialogResponse;
@@ -8586,7 +8586,7 @@ BAD_RETURN(s32) cutscene_bowser_arena_start(struct Camera *c) {
* Create the dialog box depending on which bowser fight Mario is in.
*/
BAD_RETURN(s32) bowser_fight_intro_dialog(UNUSED struct Camera *c) {
- s16 dialog;
+ s32 dialog;
switch (gCurrLevelNum) {
case LEVEL_BOWSER_1:
@@ -8608,7 +8608,7 @@ BAD_RETURN(s32) bowser_fight_intro_dialog(UNUSED struct Camera *c) {
BAD_RETURN(s32) cutscene_bowser_arena_dialog(struct Camera *c) {
cutscene_event(bowser_fight_intro_dialog, c, 0, 0);
- if (get_dialog_id() == -1) {
+ if (get_dialog_id() == DIALOG_NONE) {
gCutsceneTimer = CUTSCENE_LOOP;
}
}
@@ -9486,7 +9486,7 @@ BAD_RETURN(s32) cutscene_dialog(struct Camera *c) {
sCutsceneDialogResponse = gDialogResponse;
}
- if ((get_dialog_id() == -1) && (sCutsceneVars[8].angle[0] != 0)) {
+ if ((get_dialog_id() == DIALOG_NONE) && (sCutsceneVars[8].angle[0] != 0)) {
if (c->cutscene != CUTSCENE_RACE_DIALOG) {
sCutsceneDialogResponse = 3;
}
@@ -9556,7 +9556,7 @@ BAD_RETURN(s32) cutscene_read_message(struct Camera *c) {
switch (sCutsceneVars[0].angle[0]) {
// Do nothing until message is gone.
case 0:
- if (get_dialog_id() != -1) {
+ if (get_dialog_id() != DIALOG_NONE) {
sCutsceneVars[0].angle[0] += 1;
//set_time_stop_flags(TIME_STOP_ENABLED | TIME_STOP_DIALOG);
}
@@ -9568,7 +9568,7 @@ BAD_RETURN(s32) cutscene_read_message(struct Camera *c) {
// This could cause softlocks. If a message starts one frame after another one closes, the
// cutscene will never end.
- if (get_dialog_id() == -1) {
+ if (get_dialog_id() == DIALOG_NONE) {
gCutsceneTimer = CUTSCENE_LOOP;
retrieve_info_star(c);
transition_next_state(c, 15);
@@ -9926,7 +9926,7 @@ BAD_RETURN(s32) cutscene_cap_switch_press(struct Camera *c) {
sCutsceneVars[4].angle[0] = gDialogResponse;
}
- if ((get_dialog_id() == -1) && (sCutsceneVars[4].angle[0] != 0)) {
+ if ((get_dialog_id() == DIALOG_NONE) && (sCutsceneVars[4].angle[0] != 0)) {
sCutsceneDialogResponse = sCutsceneVars[4].angle[0];
if (sCutsceneVars[4].angle[0] == 1 && gCutsceneFocus) {
cap_switch_save(gCutsceneFocus->oBehParams2ndByte);
@@ -10066,7 +10066,7 @@ BAD_RETURN(s32) cutscene_intro_peach_start_to_pipe_spline(struct Camera *c) {
*/
BAD_RETURN(s32) cutscene_intro_peach_dialog(struct Camera *c) {
if (!c) { return; }
- if (get_dialog_id() == -1) {
+ if (get_dialog_id() == DIALOG_NONE) {
vec3f_copy(gLakituState.goalPos, c->pos);
vec3f_copy(gLakituState.goalFocus, c->focus);
sStatusFlags |= (CAM_FLAG_SMOOTH_MOVEMENT | CAM_FLAG_UNUSED_CUTSCENE_ACTIVE);
@@ -10195,7 +10195,7 @@ BAD_RETURN(s32) cutscene_intro_peach_letter(struct Camera *c) {
cutscene_event(play_sound_peach_reading_letter, c, 83, 83);
#endif
- if ((gCutsceneTimer > 120) && (get_dialog_id() == -1)) {
+ if ((gCutsceneTimer > 120) && (get_dialog_id() == DIALOG_NONE)) {
// Start the next scene
gCutsceneTimer = CUTSCENE_LOOP;
}
diff --git a/src/game/camera.h b/src/game/camera.h
index bf611d1d3..c4992e5e1 100644
--- a/src/game/camera.h
+++ b/src/game/camera.h
@@ -1203,7 +1203,7 @@ u8 start_object_cutscene_without_focus(u8 cutscene);
Starts a cutscene involving an object and displays dialog during the sequence.
The camera focuses on the object while synchronizing dialog with the scene
|descriptionEnd| */
-s16 cutscene_object_with_dialog(u8 cutscene, struct Object *o, s16 dialogID);
+s16 cutscene_object_with_dialog(u8 cutscene, struct Object *o, s32 dialogID);
/* |description|
Starts a cutscene involving an object without dialog.
diff --git a/src/game/envfx_snow.c b/src/game/envfx_snow.c
index 0807ff451..6921bcd6d 100644
--- a/src/game/envfx_snow.c
+++ b/src/game/envfx_snow.c
@@ -531,7 +531,7 @@ Gfx *envfx_update_snow(s32 snowMode, Vec3s marioPos, Vec3s camFrom, Vec3s camTo)
Gfx *envfx_update_particles(s32 mode, Vec3s marioPos, Vec3s camTo, Vec3s camFrom) {
Gfx *gfx;
- if (get_dialog_id() != -1) {
+ if (get_dialog_id() != DIALOG_NONE) {
return NULL;
}
diff --git a/src/game/ingame_menu.c b/src/game/ingame_menu.c
index 637c099a2..3a555da56 100644
--- a/src/game/ingame_menu.c
+++ b/src/game/ingame_menu.c
@@ -38,6 +38,7 @@
#include "level_info.h"
#include "pc/lua/utils/smlua_text_utils.h"
#include "menu/ingame_text.h"
+#include "pc/dialog_table.h"
u16 gDialogColorFadeTimer;
s8 gLastDialogLineNum;
@@ -128,7 +129,7 @@ f32 gDialogBoxOpenTimer = DEFAULT_DIALOG_BOX_ANGLE;
f32 gDialogBoxScale = DEFAULT_DIALOG_BOX_SCALE;
s16 gDialogScrollOffsetY = 0;
s8 gDialogBoxType = DIALOG_TYPE_ROTATE;
-s16 gDialogID = -1;
+s32 gDialogID = DIALOG_NONE;
s16 gLastDialogPageStrPos = 0;
s16 gDialogTextPos = 0;
#ifdef VERSION_EU
@@ -1025,24 +1026,24 @@ void int_to_str(s32 num, u8 *dst) {
dst[pos] = DIALOG_CHAR_TERMINATOR;
}
-s16 get_dialog_id(void) {
+s32 get_dialog_id(void) {
return gDialogID;
}
-void handle_special_dialog_text(s16 dialogID) { // dialog ID tables, in order
+void handle_special_dialog_text(s32 dialogID) { // dialog ID tables, in order
// King Bob-omb (Start), Whomp (Start), King Bob-omb (throw him out), Eyerock (Start), Wiggler (Start)
- s16 dialogBossStart[] = { 17, 114, 128, 117, 150 };
+ enum DialogId dialogBossStart[] = { DIALOG_017, DIALOG_114, DIALOG_128, DIALOG_117, DIALOG_150 };
// Koopa the Quick (BOB), Koopa the Quick (THI), Penguin Race, Fat Penguin Race (120 stars)
- s16 dialogRaceSound[] = { 5, 9, 55, 164 };
+ enum DialogId dialogRaceSound[] = { DIALOG_005, DIALOG_009, DIALOG_055, DIALOG_164 };
// Red Switch, Green Switch, Blue Switch, 100 coins star, Bowser Red Coin Star
- s16 dialogStarSound[] = { 10, 11, 12, 13, 14 };
+ enum DialogId dialogStarSound[] = { DIALOG_010, DIALOG_011, DIALOG_012, DIALOG_013, DIALOG_014 };
// King Bob-omb (Start), Whomp (Defeated), King Bob-omb (Defeated, missing in JP), Eyerock (Defeated), Wiggler (Defeated)
#if BUGFIX_KING_BOB_OMB_FADE_MUSIC
- s16 dialogBossStop[] = { 17, 115, 116, 118, 152 };
+ enum DialogId dialogBossStop[] = { DIALOG_017, DIALOG_115, DIALOG_116, DIALOG_118, DIALOG_152 };
#else
//! @bug JP misses King Bob-omb defeated dialog "116", meaning that the boss music will still
//! play after King Bob-omb is defeated until BOB loads it's music after the star cutscene
- s16 dialogBossStop[] = { 17, 115, 118, 152 };
+ enum DialogId dialogBossStop[] = { DIALOG_017, DIALOG_115, DIALOG_118, DIALOG_152 };
#endif
s16 i;
@@ -1079,7 +1080,7 @@ void handle_special_dialog_text(s16 dialogID) { // dialog ID tables, in order
static u8 sHookString[255];
static bool sOverrideDialogString = false;
void convert_string_ascii_to_sm64(u8 *str64, const char *strAscii, bool menu);
-bool handle_dialog_hook(s16 dialogId) {
+bool handle_dialog_hook(s32 dialogId) {
bool openDialogBox = true;
const char *dialogTextOverride = NULL;
smlua_call_event_hooks(HOOK_ON_DIALOG, dialogId, &openDialogBox, &dialogTextOverride);
@@ -1092,30 +1093,30 @@ bool handle_dialog_hook(s16 dialogId) {
return true;
}
-void create_dialog_box(s16 dialog) {
- if (handle_dialog_hook(dialog) && gDialogID == -1) {
+void create_dialog_box(s32 dialog) {
+ if (handle_dialog_hook(dialog) && gDialogID == DIALOG_NONE) {
gDialogID = dialog;
gDialogBoxType = DIALOG_TYPE_ROTATE;
}
}
-void create_dialog_box_with_var(s16 dialog, s32 dialogVar) {
- if (handle_dialog_hook(dialog) && gDialogID == -1) {
+void create_dialog_box_with_var(s32 dialog, s32 dialogVar) {
+ if (handle_dialog_hook(dialog) && gDialogID == DIALOG_NONE) {
gDialogID = dialog;
gDialogVariable = dialogVar;
gDialogBoxType = DIALOG_TYPE_ROTATE;
}
}
-void create_dialog_inverted_box(s16 dialog) {
- if (handle_dialog_hook(dialog) && gDialogID == -1) {
+void create_dialog_inverted_box(s32 dialog) {
+ if (handle_dialog_hook(dialog) && gDialogID == DIALOG_NONE) {
gDialogID = dialog;
gDialogBoxType = DIALOG_TYPE_ZOOM;
}
}
-void create_dialog_box_with_response(s16 dialog) {
- if (handle_dialog_hook(dialog) && gDialogID == -1) {
+void create_dialog_box_with_response(s32 dialog) {
+ if (handle_dialog_hook(dialog) && gDialogID == DIALOG_NONE) {
gDialogID = dialog;
gDialogBoxType = DIALOG_TYPE_ROTATE;
gLastDialogResponse = 1;
@@ -1132,7 +1133,7 @@ void reset_dialog_render_state(void) {
gDialogBoxScale = 19.0f;
gDialogBoxOpenTimer = 90.0f;
gDialogBoxState = DIALOG_STATE_OPENING;
- gDialogID = -1;
+ gDialogID = DIALOG_NONE;
gDialogTextPos = 0;
gLastDialogResponse = 0;
gLastDialogPageStrPos = 0;
@@ -1877,36 +1878,14 @@ void render_dialog_entries(void) {
#ifdef VERSION_EU
s8 lowerBound = 0;
#endif
- void **dialogTable;
- struct DialogEntry *dialog;
+
#if defined(VERSION_US) || defined(VERSION_SH)
s8 lowerBound = 0;
#endif
-#ifdef VERSION_EU
- gInGameLanguage = eu_get_language();
- switch (gInGameLanguage) {
- case LANGUAGE_ENGLISH:
- dialogTable = segmented_to_virtual(dialog_table_eu_en);
- break;
- case LANGUAGE_FRENCH:
- dialogTable = segmented_to_virtual(dialog_table_eu_fr);
- break;
- case LANGUAGE_GERMAN:
- dialogTable = segmented_to_virtual(dialog_table_eu_de);
- break;
- }
-#else
- if (gDialogID >= DIALOG_COUNT || gDialogID < 0) {
- gDialogID = -1;
- return;
- }
- dialogTable = segmented_to_virtual(seg2_dialog_table);
-#endif
- dialog = segmented_to_virtual(dialogTable[gDialogID]);
+ struct DialogEntry *dialog = dialog_table_get(gDialogID);
- // if the dialog entry is invalid, set the ID to -1.
- if (segmented_to_virtual(NULL) == dialog) {
- gDialogID = -1;
+ if (dialog == NULL) {
+ gDialogID = DIALOG_NONE;
return;
}
@@ -1984,7 +1963,7 @@ void render_dialog_entries(void) {
if (gDialogBoxOpenTimer == DEFAULT_DIALOG_BOX_ANGLE) {
gDialogBoxState = DIALOG_STATE_OPENING;
- gDialogID = -1;
+ gDialogID = DIALOG_NONE;
gDialogTextPos = 0;
gLastDialogResponse = 0;
gLastDialogPageStrPos = 0;
@@ -2198,28 +2177,9 @@ void do_cutscene_handler(void) {
// "Dear Mario" message handler
void print_peach_letter_message(void) {
- void **dialogTable;
- struct DialogEntry *dialog;
- u8 *str;
-#ifdef VERSION_EU
- gInGameLanguage = eu_get_language();
- switch (gInGameLanguage) {
- case LANGUAGE_ENGLISH:
- dialogTable = segmented_to_virtual(dialog_table_eu_en);
- break;
- case LANGUAGE_FRENCH:
- dialogTable = segmented_to_virtual(dialog_table_eu_fr);
- break;
- case LANGUAGE_GERMAN:
- dialogTable = segmented_to_virtual(dialog_table_eu_de);
- break;
- }
-#else
- dialogTable = segmented_to_virtual(seg2_dialog_table);
-#endif
- dialog = segmented_to_virtual(dialogTable[gDialogID]);
+ struct DialogEntry *dialog = dialog_table_get(gDialogID);
- str = sOverrideDialogString ? sHookString : segmented_to_virtual(dialog->str);
+ const u8* str = sOverrideDialogString ? sHookString : dialog->str;
create_dl_translation_matrix(MENU_MTX_PUSH, 97.0f, 118.0f, 0);
@@ -2260,7 +2220,7 @@ void print_peach_letter_message(void) {
if (gCutsceneMsgTimer > (PEACH_MESSAGE_TIMER + 20)) {
gCutsceneMsgIndex = -1;
gCutsceneMsgFade = 0; //! uselessly reset since the next execution will just set it to 0 again.
- gDialogID = -1;
+ gDialogID = DIALOG_NONE;
gCutsceneMsgTimer = 0;
return; // return to avoid incrementing the timer
}
@@ -3472,9 +3432,9 @@ s16 render_menus_and_dialogs(void) {
}
gDialogColorFadeTimer = (s16) gDialogColorFadeTimer + 0x1000;
- } else if (gDialogID != -1) {
+ } else if (gDialogID != DIALOG_NONE) {
// The Peach "Dear Mario" message needs to be repositioned separately
- if (gDialogID == 20) {
+ if (gDialogID == DIALOG_020) {
print_peach_letter_message();
return mode;
}
diff --git a/src/game/ingame_menu.h b/src/game/ingame_menu.h
index a3816fc6f..6748a81a0 100644
--- a/src/game/ingame_menu.h
+++ b/src/game/ingame_menu.h
@@ -2,6 +2,7 @@
#define INGAME_MENU_H
#include
+#include
#define ASCII_TO_DIALOG(asc) \
(((asc) >= '0' && (asc) <= '9') ? ((asc) - '0') : \
@@ -39,12 +40,13 @@ extern s8 gHudFlash;
struct DialogEntry
{
- u32 unused; /*0x00*/
- s8 linesPerBox; /*0x04*/
- s16 leftOffset; /*0x06*/
- s16 width; /*0x08*/
- const u8 *str; /*0x0C*/
+ u32 unused;
+ s8 linesPerBox;
+ s16 leftOffset;
+ s16 width;
+ const u8 *str;
char* text;
+ bool replaced;
};
// EU only
@@ -158,15 +160,15 @@ s16 get_str_x_pos_from_center_scale(s16 centerPos, u8 *str, f32 scale);
#endif
void print_hud_my_score_coins(s32 useCourseCoinScore, s8 fileNum, s8 courseNum, s16 x, s16 y);
void int_to_str(s32 num, u8 *dst);
-s16 get_dialog_id(void);
+s32 get_dialog_id(void);
/* |description|Creates a dialog box with a dialog ID that rotates into view|descriptionEnd| */
-void create_dialog_box(s16 dialog);
+void create_dialog_box(s32 dialog);
/* |description|Creates a dialog box with a dialog variable|descriptionEnd| */
-void create_dialog_box_with_var(s16 dialog, s32 dialogVar);
+void create_dialog_box_with_var(s32 dialog, s32 dialogVar);
/* |description|Creates a dialog box with a dialog ID that zooms into view|descriptionEnd| */
-void create_dialog_inverted_box(s16 dialog);
+void create_dialog_inverted_box(s32 dialog);
/* |description|Creates a dialog box with a response|descriptionEnd| */
-void create_dialog_box_with_response(s16 dialog);
+void create_dialog_box_with_response(s32 dialog);
/* |description|Resets the dialog box's state including dialog ID and open state|descriptionEnd| */
void reset_dialog_render_state(void);
/* |description|
diff --git a/src/game/level_update.c b/src/game/level_update.c
index bccfeefaf..b9a828974 100644
--- a/src/game/level_update.c
+++ b/src/game/level_update.c
@@ -250,11 +250,11 @@ u16 level_control_timer(s32 timerOp) {
u32 pressed_pause(void) {
if (gServerSettings.pauseAnywhere) {
- if (get_dialog_id() < 0 && sCurrPlayMode == PLAY_MODE_NORMAL && sDelayedWarpOp == WARP_OP_NONE) {
+ if (get_dialog_id() == DIALOG_NONE && sCurrPlayMode == PLAY_MODE_NORMAL && sDelayedWarpOp == WARP_OP_NONE) {
return gPlayer1Controller->buttonPressed & START_BUTTON;
}
} else {
- u32 dialogActive = get_dialog_id() >= 0;
+ u32 dialogActive = get_dialog_id() != DIALOG_NONE;
u32 intangible = (gMarioState->action & ACT_FLAG_INTANGIBLE) != 0;
u32 firstPerson = gMarioState->action == ACT_FIRST_PERSON;
@@ -299,7 +299,7 @@ void stub_level_update_1(void) {
void load_level_init_text(u32 arg) {
s32 gotAchievement;
- u32 dialogID = gCurrentArea->dialog[arg];
+ s32 dialogID = gCurrentArea->dialog[arg];
if (dialogID == gBehaviorValues.dialogs.VanishCourseDialog) {
gotAchievement = save_file_get_flags() & SAVE_FLAG_HAVE_VANISH_CAP;
diff --git a/src/game/mario.c b/src/game/mario.c
index 7d0b3e69c..4dbd5b0e6 100644
--- a/src/game/mario.c
+++ b/src/game/mario.c
@@ -2063,9 +2063,9 @@ s32 execute_mario_action(UNUSED struct Object *o) {
// don't update mario when in a cutscene
if (gMarioState->playerIndex == 0) {
- extern s16 gDialogID;
+ extern s32 gDialogID;
if (gMarioState->freeze > 0) { gMarioState->freeze--; }
- if (gMarioState->freeze < 2 && gDialogID != -1) { gMarioState->freeze = 2; }
+ if (gMarioState->freeze < 2 && gDialogID != DIALOG_NONE) { gMarioState->freeze = 2; }
if (gMarioState->freeze < 2 && sCurrPlayMode == PLAY_MODE_PAUSED) { gMarioState->freeze = 2; }
}
diff --git a/src/game/mario_actions_cutscene.c b/src/game/mario_actions_cutscene.c
index 55296f7b8..bd660a2ce 100644
--- a/src/game/mario_actions_cutscene.c
+++ b/src/game/mario_actions_cutscene.c
@@ -238,7 +238,7 @@ s32 geo_switch_peach_eyes(s32 run, struct GraphNode *node, UNUSED s32 a2) {
// unused
static void stub_is_textbox_active(u16 *a0) {
- if (get_dialog_id() == -1) {
+ if (get_dialog_id() == DIALOG_NONE) {
*a0 = 0;
}
}
@@ -576,7 +576,7 @@ s32 act_reading_automatic_dialog(struct MarioState *m) {
}
}
} else if (m->actionState == 10) { // wait until dialog is done
- if ((m->playerIndex == 0 && get_dialog_id() >= 0) ||
+ if ((m->playerIndex == 0 && get_dialog_id() != DIALOG_NONE) ||
(m->playerIndex != 0 && m->dialogId != 0)) {
m->actionState--;
}
diff --git a/src/game/mario_misc.c b/src/game/mario_misc.c
index e3071cf7e..ff0c5d61f 100644
--- a/src/game/mario_misc.c
+++ b/src/game/mario_misc.c
@@ -139,7 +139,7 @@ static void toad_message_talking(void) {
gCurrentObject->oToadMessageRecentlyTalked = TRUE;
gCurrentObject->oToadMessageState = TOAD_MESSAGE_FADING;
- u32 dialogId = gCurrentObject->oToadMessageDialogId;
+ s32 dialogId = gCurrentObject->oToadMessageDialogId;
if (dialogId == TOAD_STAR_1_DIALOG) {
gCurrentObject->oToadMessageDialogId = TOAD_STAR_1_DIALOG_AFTER;
bhv_spawn_star_no_level_exit(gMarioStates[0].marioObj, 0, TRUE);
diff --git a/src/game/obj_behaviors.c b/src/game/obj_behaviors.c
index fc223d8dd..4860e72a1 100644
--- a/src/game/obj_behaviors.c
+++ b/src/game/obj_behaviors.c
@@ -850,7 +850,7 @@ s8 current_mario_room_check(s16 room) {
/**
* Triggers dialog when Mario is facing an object and controls it while in the dialog.
*/
-s16 trigger_obj_dialog_when_facing(struct MarioState* m, s32 *inDialog, s16 dialogID, f32 dist, s32 actionArg, u8 (*inContinueDialogFunction)(void)) {
+s16 trigger_obj_dialog_when_facing(struct MarioState* m, s32 *inDialog, s32 dialogID, f32 dist, s32 actionArg, u8 (*inContinueDialogFunction)(void)) {
if (!o) { return 0; }
if (!m || !inDialog) { return 0; }
s16 dialogueResponse;
diff --git a/src/game/obj_behaviors.h b/src/game/obj_behaviors.h
index 485ae20af..2595309af 100644
--- a/src/game/obj_behaviors.h
+++ b/src/game/obj_behaviors.h
@@ -40,7 +40,7 @@ void bhv_bobomb_loop(void);
void bhv_bobomb_fuse_smoke_init(void);
void bhv_bobomb_buddy_init(void);
void bobomb_buddy_act_idle(void);
-void bobomb_buddy_cannon_dialog(s16 dialogFirstText, s16 dialogSecondText);
+void bobomb_buddy_cannon_dialog(s32 dialogFirstText, s32 dialogSecondText);
void bobomb_buddy_act_talk(void);
void bobomb_buddy_act_turn_to_talk(void);
void bobomb_buddy_actions(void);
diff --git a/src/game/obj_behaviors_2.c b/src/game/obj_behaviors_2.c
index 819bf6d36..a4380e98e 100644
--- a/src/game/obj_behaviors_2.c
+++ b/src/game/obj_behaviors_2.c
@@ -105,7 +105,7 @@ s16 obj_get_pitch_from_vel(void) {
* If the player declines the race, then disable time stop and allow Mario to
* move again.
*/
-static s32 obj_update_race_proposition_dialog(struct MarioState* m, s16 dialogID, u8 (*inContinueDialogFunction)(void)) {
+static s32 obj_update_race_proposition_dialog(struct MarioState* m, s32 dialogID, u8 (*inContinueDialogFunction)(void)) {
s32 dialogResponse = cur_obj_update_dialog_with_cutscene(m, 2, DIALOG_UNK2_FLAG_0 | DIALOG_UNK2_LEAVE_TIME_STOP_ENABLED, CUTSCENE_RACE_DIALOG, dialogID, inContinueDialogFunction);
if (dialogResponse == 2) {
diff --git a/src/game/object_helpers.c b/src/game/object_helpers.c
index 10ea9cdc9..14269b2d5 100644
--- a/src/game/object_helpers.c
+++ b/src/game/object_helpers.c
@@ -3184,7 +3184,7 @@ s32 cur_obj_update_dialog(struct MarioState* m, s32 actionArg, s32 dialogFlags,
cur_obj_end_dialog(m, dialogFlags, gDialogResponse);
}
} else if (dialogFlags & DIALOG_UNK1_FLAG_DEFAULT) {
- if (get_dialog_id() == -1) {
+ if (get_dialog_id() == DIALOG_NONE) {
cur_obj_end_dialog(m, dialogFlags, 3);
}
} else {
diff --git a/src/game/segment2.h b/src/game/segment2.h
index 0a0bced19..e9e4f3345 100644
--- a/src/game/segment2.h
+++ b/src/game/segment2.h
@@ -57,7 +57,6 @@ extern u8* main_hud_camera_lut[6];
extern const Gfx dl_draw_text_bg_box[];
extern const Gfx dl_draw_triangle[];
extern const u8* seg2_dialog_original[];
-extern void *seg2_dialog_table[];
extern const Gfx dl_billboard_num_0[];
extern const Gfx dl_billboard_num_1[];
extern const Gfx dl_billboard_num_2[];
diff --git a/src/pc/dialog_table.c b/src/pc/dialog_table.c
new file mode 100644
index 000000000..7720d5292
--- /dev/null
+++ b/src/pc/dialog_table.c
@@ -0,0 +1,99 @@
+#include "dialog_table.h"
+#include "pc/lua/smlua.h"
+#include "dialog_ids.h"
+#include "PR/ultratypes.h"
+#include "game/segment2.h"
+#include "pc/lua/utils/smlua_text_utils.h"
+#include "game/memory.h"
+#include "pc/platform.h"
+#include
+
+DialogTable *gDialogTable = NULL;
+
+void dialog_table_init(void) {
+ gDialogTable = growing_array_init(gDialogTable, 256);
+
+ for (u32 i = 0; i < DIALOG_COUNT; i++) {
+ const struct DialogEntry* dialogOrig = smlua_text_utils_dialog_get_unmodified(i);
+ struct DialogEntry* dialog = dialog_table_alloc(NULL);
+
+ if (!dialog) {
+ sys_fatal("Failed to allocate DialogEntry for dialog ID %d", i);
+ }
+
+ memcpy(dialog, dialogOrig, sizeof(struct DialogEntry));
+ dialog->text = get_dialog_text_ascii(dialog);
+ }
+}
+
+struct DialogEntry* dialog_table_alloc(s32 *dialogId) {
+ DialogTable *table = gDialogTable;
+
+ if (table->count >= MAX_ALLOCATED_DIALOGS) {
+ LOG_LUA_LINE_WARNING("Dialog limit reached! (%d max)", MAX_ALLOCATED_DIALOGS);
+ if (dialogId) *dialogId = DIALOG_NONE;
+ return NULL;
+ }
+
+ struct DialogEntry* dialog = growing_array_alloc(table, sizeof(struct DialogEntry));
+
+ if (!dialog) {
+ LOG_LUA_LINE_WARNING("Failed to allocate DialogEntry");
+ if (dialogId) *dialogId = DIALOG_NONE;
+ return NULL;
+ }
+
+ if (dialogId) *dialogId = table->count - 1;
+
+ return dialog;
+}
+
+struct DialogEntry* dialog_table_get(s32 dialogId) {
+ if (!IS_VALID_DIALOG(dialogId)) {
+ return NULL;
+ }
+
+ return gDialogTable->buffer[dialogId];
+}
+
+void dialog_table_reset(void) {
+ DialogTable *table = gDialogTable;
+
+ if (!table) return;
+
+ for (u32 i = 0; i < table->count; i++) {
+ struct DialogEntry *dialog = table->buffer[i];
+
+ if (!dialog->replaced) continue;
+
+ if (!IS_CUSTOM_DIALOG(i)) {
+ smlua_text_utils_dialog_restore(i);
+ } else {
+ free((u8*)dialog->str);
+ free(dialog->text);
+ free(dialog);
+ table->buffer[i] = NULL;
+ }
+ }
+
+ table->count = DIALOG_COUNT;
+}
+
+void dialog_table_shutdown(void) {
+ DialogTable *table = gDialogTable;
+
+ if (!table) return;
+
+ dialog_table_reset();
+
+ for (u32 i = 0; i < DIALOG_COUNT; i++) {
+ struct DialogEntry *dialog = table->buffer[i];
+
+ free(dialog->text);
+ free(dialog);
+ }
+
+ free(table->buffer);
+ free(table);
+ gDialogTable = NULL;
+}
\ No newline at end of file
diff --git a/src/pc/dialog_table.h b/src/pc/dialog_table.h
new file mode 100644
index 000000000..c7fb5b47a
--- /dev/null
+++ b/src/pc/dialog_table.h
@@ -0,0 +1,23 @@
+#ifndef DIALOG_TABLE_H
+#define DIALOG_TABLE_H
+
+#include "PR/ultratypes.h"
+#include "game/ingame_menu.h"
+
+#define MAX_ALLOCATED_DIALOGS 0x8000
+
+typedef struct GrowingArray DialogTable;
+
+void dialog_table_init(void);
+struct DialogEntry* dialog_table_alloc(s32 *dialogId);
+struct DialogEntry* dialog_table_get(s32 dialogId);
+void dialog_table_reset(void);
+void dialog_table_shutdown(void);
+
+extern DialogTable *gDialogTable;
+
+#define IS_CUSTOM_DIALOG(dialogId) ((dialogId) >= DIALOG_COUNT)
+#define IS_VALID_DIALOG(dialogId) ((dialogId) >= 0 && (u32)(dialogId) < gDialogTable->count)
+#define IS_VALID_VANILLA_DIALOG(dialogId) ((dialogId) >= 0 && (dialogId) < DIALOG_COUNT)
+
+#endif
diff --git a/src/pc/lua/smlua_cobject_autogen.c b/src/pc/lua/smlua_cobject_autogen.c
index 23de2e9fe..da4895392 100644
--- a/src/pc/lua/smlua_cobject_autogen.c
+++ b/src/pc/lua/smlua_cobject_autogen.c
@@ -805,10 +805,11 @@ static struct LuaObjectField sDateTimeFields[LUA_DATE_TIME_FIELD_COUNT] = {
{ "year", LVT_S32, offsetof(struct DateTime, year), false, LOT_NONE, 1, sizeof(s32) },
};
-#define LUA_DIALOG_ENTRY_FIELD_COUNT 5
+#define LUA_DIALOG_ENTRY_FIELD_COUNT 6
static struct LuaObjectField sDialogEntryFields[LUA_DIALOG_ENTRY_FIELD_COUNT] = {
{ "leftOffset", LVT_S16, offsetof(struct DialogEntry, leftOffset), true, LOT_NONE, 1, sizeof(s16) },
{ "linesPerBox", LVT_S8, offsetof(struct DialogEntry, linesPerBox), true, LOT_NONE, 1, sizeof(s8) },
+ { "replaced", LVT_BOOL, offsetof(struct DialogEntry, replaced), true, LOT_NONE, 1, sizeof(bool) },
{ "text", LVT_STRING_P, offsetof(struct DialogEntry, text), true, LOT_NONE, 1, sizeof(char*) },
{ "unused", LVT_U32, offsetof(struct DialogEntry, unused), true, LOT_NONE, 1, sizeof(u32) },
{ "width", LVT_S16, offsetof(struct DialogEntry, width), true, LOT_NONE, 1, sizeof(s16) },
@@ -1507,7 +1508,7 @@ static struct LuaObjectField sMarioStateFields[LUA_MARIO_STATE_FIELD_COUNT] = {
{ "controller", LVT_COBJECT_P, offsetof(struct MarioState, controller), true, LOT_CONTROLLER, 1, sizeof(struct Controller*) },
{ "curAnimOffset", LVT_F32, offsetof(struct MarioState, curAnimOffset), false, LOT_NONE, 1, sizeof(f32) },
{ "currentRoom", LVT_S16, offsetof(struct MarioState, currentRoom), false, LOT_NONE, 1, sizeof(s16) },
- { "dialogId", LVT_S16, offsetof(struct MarioState, dialogId), true, LOT_NONE, 1, sizeof(s16) },
+ { "dialogId", LVT_S32, offsetof(struct MarioState, dialogId), true, LOT_NONE, 1, sizeof(s32) },
{ "doubleJumpTimer", LVT_U8, offsetof(struct MarioState, doubleJumpTimer), false, LOT_NONE, 1, sizeof(u8) },
{ "faceAngle", LVT_COBJECT, offsetof(struct MarioState, faceAngle), true, LOT_VEC3S, 1, sizeof(Vec3s) },
{ "fadeWarpOpacity", LVT_U8, offsetof(struct MarioState, fadeWarpOpacity), false, LOT_NONE, 1, sizeof(u8) },
@@ -2356,7 +2357,7 @@ static struct LuaObjectField sObjectFields[LUA_OBJECT_FIELD_COUNT] = {
{ "oTiltingPyramidNormalY", LVT_F32, offsetof(struct Object, oTiltingPyramidNormalY), false, LOT_NONE, 1, sizeof(f32) },
{ "oTiltingPyramidNormalZ", LVT_F32, offsetof(struct Object, oTiltingPyramidNormalZ), false, LOT_NONE, 1, sizeof(f32) },
{ "oTimer", LVT_S32, offsetof(struct Object, oTimer), false, LOT_NONE, 1, sizeof(s32) },
- { "oToadMessageDialogId", LVT_U32, offsetof(struct Object, oToadMessageDialogId), false, LOT_NONE, 1, sizeof(u32) },
+ { "oToadMessageDialogId", LVT_S32, offsetof(struct Object, oToadMessageDialogId), false, LOT_NONE, 1, sizeof(s32) },
{ "oToadMessageRecentlyTalked", LVT_S32, offsetof(struct Object, oToadMessageRecentlyTalked), false, LOT_NONE, 1, sizeof(s32) },
{ "oToadMessageState", LVT_S32, offsetof(struct Object, oToadMessageState), false, LOT_NONE, 1, sizeof(s32) },
// { "oToxBoxMovementPattern", LVT_???, offsetof(struct Object, oToxBoxMovementPattern), false, LOT_???, 1, sizeof(void*) }, <--- UNIMPLEMENTED
diff --git a/src/pc/lua/smlua_constants_autogen.c b/src/pc/lua/smlua_constants_autogen.c
index a318e3b3f..35995263c 100644
--- a/src/pc/lua/smlua_constants_autogen.c
+++ b/src/pc/lua/smlua_constants_autogen.c
@@ -1267,6 +1267,7 @@ char gSmluaConstants[] = ""
"L_MOUSE_BUTTON=MOUSE_BUTTON_1\n"
"M_MOUSE_BUTTON=MOUSE_BUTTON_2\n"
"R_MOUSE_BUTTON=MOUSE_BUTTON_3\n"
+"DIALOG_NONE=-1\n"
"DIALOG_000=0\n"
"DIALOG_001=1\n"
"DIALOG_002=2\n"
@@ -1737,21 +1738,21 @@ char gSmluaConstants[] = ""
"MARIO_SPAWN_PIPE=3\n"
"MARIO_SPAWN_TELEPORT=4\n"
"MARIO_SPAWN_INSTANT_ACTIVE=0x10\n"
-"MARIO_SPAWN_SWIMMING=((MARIO_SPAWN_INSTANT_ACTIVE ) + 1)\n"
-"MARIO_SPAWN_AIRBORNE=((MARIO_SPAWN_INSTANT_ACTIVE ) + 2)\n"
-"MARIO_SPAWN_HARD_AIR_KNOCKBACK=((MARIO_SPAWN_INSTANT_ACTIVE ) + 3)\n"
-"MARIO_SPAWN_SPIN_AIRBORNE_CIRCLE=((MARIO_SPAWN_INSTANT_ACTIVE ) + 4)\n"
-"MARIO_SPAWN_DEATH=((MARIO_SPAWN_INSTANT_ACTIVE ) + 5)\n"
-"MARIO_SPAWN_SPIN_AIRBORNE=((MARIO_SPAWN_INSTANT_ACTIVE ) + 6)\n"
-"MARIO_SPAWN_FLYING=((MARIO_SPAWN_INSTANT_ACTIVE ) + 7)\n"
+"MARIO_SPAWN_SWIMMING=17\n"
+"MARIO_SPAWN_AIRBORNE=18\n"
+"MARIO_SPAWN_HARD_AIR_KNOCKBACK=19\n"
+"MARIO_SPAWN_SPIN_AIRBORNE_CIRCLE=20\n"
+"MARIO_SPAWN_DEATH=21\n"
+"MARIO_SPAWN_SPIN_AIRBORNE=22\n"
+"MARIO_SPAWN_FLYING=23\n"
"MARIO_SPAWN_PAINTING_STAR_COLLECT=0x20\n"
-"MARIO_SPAWN_PAINTING_DEATH=((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 1)\n"
-"MARIO_SPAWN_AIRBORNE_STAR_COLLECT=((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 2)\n"
-"MARIO_SPAWN_AIRBORNE_DEATH=((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 3)\n"
-"MARIO_SPAWN_LAUNCH_STAR_COLLECT=((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 4)\n"
-"MARIO_SPAWN_LAUNCH_DEATH=((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 5)\n"
-"MARIO_SPAWN_UNUSED_38=((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 6)\n"
-"MARIO_SPAWN_FADE_FROM_BLACK=((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 7)\n"
+"MARIO_SPAWN_PAINTING_DEATH=33\n"
+"MARIO_SPAWN_AIRBORNE_STAR_COLLECT=34\n"
+"MARIO_SPAWN_AIRBORNE_DEATH=35\n"
+"MARIO_SPAWN_LAUNCH_STAR_COLLECT=36\n"
+"MARIO_SPAWN_LAUNCH_DEATH=37\n"
+"MARIO_SPAWN_UNUSED_38=38\n"
+"MARIO_SPAWN_FADE_FROM_BLACK=39\n"
"MARIO_SPAWN_UNKNOWN_02=0x02\n"
"MARIO_SPAWN_UNKNOWN_03=0x03\n"
"MARIO_SPAWN_UNKNOWN_27=0x27\n"
diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c
index 885815bc9..396739a18 100644
--- a/src/pc/lua/smlua_functions_autogen.c
+++ b/src/pc/lua/smlua_functions_autogen.c
@@ -11908,7 +11908,7 @@ int smlua_func_cutscene_object_with_dialog(lua_State* L) {
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "cutscene_object_with_dialog"); return 0; }
struct Object* o = (struct Object*)smlua_to_cobject(L, 2, LOT_OBJECT);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "cutscene_object_with_dialog"); return 0; }
- s16 dialogID = smlua_to_integer(L, 3);
+ s32 dialogID = smlua_to_integer(L, 3);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "cutscene_object_with_dialog"); return 0; }
lua_pushinteger(L, cutscene_object_with_dialog(cutscene, o, dialogID));
@@ -13463,7 +13463,7 @@ int smlua_func_play_dialog_sound(lua_State* L) {
return 0;
}
- u8 dialogID = smlua_to_integer(L, 1);
+ s32 dialogID = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "play_dialog_sound"); return 0; }
play_dialog_sound(dialogID);
@@ -13935,7 +13935,7 @@ int smlua_func_create_dialog_box(lua_State* L) {
return 0;
}
- s16 dialog = smlua_to_integer(L, 1);
+ s32 dialog = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "create_dialog_box"); return 0; }
create_dialog_box(dialog);
@@ -13952,7 +13952,7 @@ int smlua_func_create_dialog_box_with_var(lua_State* L) {
return 0;
}
- s16 dialog = smlua_to_integer(L, 1);
+ s32 dialog = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "create_dialog_box_with_var"); return 0; }
s32 dialogVar = smlua_to_integer(L, 2);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "create_dialog_box_with_var"); return 0; }
@@ -13971,7 +13971,7 @@ int smlua_func_create_dialog_inverted_box(lua_State* L) {
return 0;
}
- s16 dialog = smlua_to_integer(L, 1);
+ s32 dialog = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "create_dialog_inverted_box"); return 0; }
create_dialog_inverted_box(dialog);
@@ -13988,7 +13988,7 @@ int smlua_func_create_dialog_box_with_response(lua_State* L) {
return 0;
}
- s16 dialog = smlua_to_integer(L, 1);
+ s32 dialog = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "create_dialog_box_with_response"); return 0; }
create_dialog_box_with_response(dialog);
@@ -35273,6 +35273,23 @@ int smlua_func_smlua_text_utils_dialog_replace(lua_State* L) {
return 1;
}
+int smlua_func_smlua_text_utils_dialog_restore(lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 1) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "smlua_text_utils_dialog_restore", 1, top);
+ return 0;
+ }
+
+ int dialogId = smlua_to_integer(L, 1);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "smlua_text_utils_dialog_restore"); return 0; }
+
+ smlua_text_utils_dialog_restore(dialogId);
+
+ return 1;
+}
+
int smlua_func_smlua_text_utils_dialog_is_replaced(lua_State* L) {
if (L == NULL) { return 0; }
@@ -35290,6 +35307,21 @@ int smlua_func_smlua_text_utils_dialog_is_replaced(lua_State* L) {
return 1;
}
+int smlua_func_smlua_text_utils_allocate_dialog(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", "smlua_text_utils_allocate_dialog", 0, top);
+ return 0;
+ }
+
+
+ lua_pushinteger(L, smlua_text_utils_allocate_dialog());
+
+ return 1;
+}
+
int smlua_func_smlua_text_utils_course_acts_replace(lua_State* L) {
if (L == NULL) { return 0; }
@@ -38380,7 +38412,9 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "smlua_text_utils_reset_all", smlua_func_smlua_text_utils_reset_all);
smlua_bind_function(L, "smlua_text_utils_dialog_get", smlua_func_smlua_text_utils_dialog_get);
smlua_bind_function(L, "smlua_text_utils_dialog_replace", smlua_func_smlua_text_utils_dialog_replace);
+ smlua_bind_function(L, "smlua_text_utils_dialog_restore", smlua_func_smlua_text_utils_dialog_restore);
smlua_bind_function(L, "smlua_text_utils_dialog_is_replaced", smlua_func_smlua_text_utils_dialog_is_replaced);
+ smlua_bind_function(L, "smlua_text_utils_allocate_dialog", smlua_func_smlua_text_utils_allocate_dialog);
smlua_bind_function(L, "smlua_text_utils_course_acts_replace", smlua_func_smlua_text_utils_course_acts_replace);
smlua_bind_function(L, "smlua_text_utils_secret_star_replace", smlua_func_smlua_text_utils_secret_star_replace);
smlua_bind_function(L, "smlua_text_utils_course_name_replace", smlua_func_smlua_text_utils_course_name_replace);
diff --git a/src/pc/lua/utils/smlua_misc_utils.h b/src/pc/lua/utils/smlua_misc_utils.h
index 0469da92a..b8b5b198b 100644
--- a/src/pc/lua/utils/smlua_misc_utils.h
+++ b/src/pc/lua/utils/smlua_misc_utils.h
@@ -85,7 +85,7 @@ bool djui_is_playerlist_ping_visible(void);
/* |description|Gets the current state of the dialog box|descriptionEnd| */
s8 get_dialog_box_state(void);
/* |description|Gets the current dialog box ID|descriptionEnd| */
-s16 get_dialog_id(void);
+s32 get_dialog_id(void);
/* |description|Gets if the last objective collected was a star (0) or a key (1)|descriptionEnd| */
u8 get_last_star_or_key(void);
diff --git a/src/pc/lua/utils/smlua_text_utils.c b/src/pc/lua/utils/smlua_text_utils.c
index c0aac16ae..dbce0ed46 100644
--- a/src/pc/lua/utils/smlua_text_utils.c
+++ b/src/pc/lua/utils/smlua_text_utils.c
@@ -10,14 +10,13 @@
#include "../smlua.h"
#include "smlua_level_utils.h"
#include "smlua_text_utils.h"
+#include "pc/dialog_table.h"
#ifdef VERSION_EU
extern s32 gInGameLanguage;
#include "eu_translation.h"
#endif
-static bool sReplacedDialog[DIALOG_COUNT] = { 0 };
-
#define INVALID_COURSE_NUM(courseNum) (smlua_level_util_get_info_from_course_num(courseNum) == NULL && !COURSE_IS_VALID_COURSE(courseNum))
extern const struct { const char *str; u8 c; u8 menu; } sSm64CharMap[];
@@ -43,7 +42,7 @@ char* get_dialog_text_ascii(struct DialogEntry *dialog) {
size_t len = measure_converted_sm64_string(dialog->str);
char* asciiStr = malloc(len + 1);
- if (!asciiStr) return NULL;
+ if (!asciiStr) { return NULL; }
convert_string_sm64_to_ascii(asciiStr, dialog->str);
@@ -86,6 +85,7 @@ static bool sSmluaTextUtilsInited = false;
// Save all vanilla act names and course names
void smlua_text_utils_init(void) {
+ dialog_table_init();
memset(gReplacedCourseActNameTable, 0, sizeof(gReplacedCourseActNameTable));
// Vanilla courses
@@ -126,15 +126,6 @@ void smlua_text_utils_init(void) {
);
}
- for (s32 i = 0; i < DIALOG_COUNT; i++) {
- struct DialogEntry *dialog = smlua_text_utils_dialog_get(i);
- char* dialogText = get_dialog_text_ascii(dialog);
-
- free(dialog->text);
-
- dialog->text = dialogText;
- }
-
sSmluaTextUtilsInited = true;
}
@@ -186,40 +177,7 @@ static void smlua_text_utils_replace_course_or_act_name(struct ReplacedName *nam
}
void smlua_text_utils_reset_all(void) {
- void **dialogTable = NULL;
- void **dialogTableOrg = NULL;
-
-#ifdef VERSION_EU
- switch (gInGameLanguage) {
- case LANGUAGE_ENGLISH:
- dialogTable = segmented_to_virtual(dialog_table_eu_en);
- dialogTableOrg = segmented_to_virtual(dialog_table_eu_en_original);
- break;
- case LANGUAGE_FRENCH:
- dialogTable = segmented_to_virtual(dialog_table_eu_fr);
- dialogTableOrg = segmented_to_virtual(dialog_table_eu_fr_original);
- break;
- case LANGUAGE_GERMAN:
- dialogTable = segmented_to_virtual(dialog_table_eu_de);
- dialogTableOrg = segmented_to_virtual(dialog_table_eu_de_original);
- break;
- }
-#else
- dialogTable = segmented_to_virtual(seg2_dialog_table);
- dialogTableOrg = segmented_to_virtual(seg2_dialog_original);
-#endif
-
- for (s32 i = 0; i < DIALOG_COUNT; i++) {
- if (!sReplacedDialog[i]) { continue; }
- const struct DialogEntry *dialogOrig = segmented_to_virtual(dialogTableOrg[i]);
- struct DialogEntry *dialog = segmented_to_virtual(dialogTable[i]);
- free((u8*)dialog->str);
- free(dialog->text);
-
- memcpy(dialog, dialogOrig, sizeof(struct DialogEntry));
- dialog->text = get_dialog_text_ascii(dialog);
- sReplacedDialog[i] = false;
- }
+ dialog_table_reset();
if (sSmluaTextUtilsInited) {
for (s16 courseNum = 0; courseNum < COURSE_END; courseNum++) {
@@ -234,40 +192,48 @@ void smlua_text_utils_reset_all(void) {
smlua_text_utils_reset_course_or_act_name(actName);
}
}
+ } else {
+ dialog_table_shutdown();
}
}
-struct DialogEntry* smlua_text_utils_dialog_get(enum DialogId dialogId){
- if (dialogId >= DIALOG_COUNT) { return NULL; }
+struct DialogEntry* smlua_text_utils_dialog_get(enum DialogId dialogId) {
+ struct DialogEntry* dialog = dialog_table_get(dialogId);
+ return dialog;
+}
- void **dialogTable = NULL;
+const struct DialogEntry* smlua_text_utils_dialog_get_unmodified(enum DialogId dialogId) {
+ if (!IS_VALID_VANILLA_DIALOG(dialogId)) { return NULL; }
+
+ void **dialogTableOrg;
#ifdef VERSION_EU
switch (gInGameLanguage) {
case LANGUAGE_ENGLISH:
- dialogTable = segmented_to_virtual(dialog_table_eu_en);
+ dialogTableOrg = segmented_to_virtual(dialog_table_eu_en_original);
break;
case LANGUAGE_FRENCH:
- dialogTable = segmented_to_virtual(dialog_table_eu_fr);
+ dialogTableOrg = segmented_to_virtual(dialog_table_eu_fr_original);
break;
case LANGUAGE_GERMAN:
- dialogTable = segmented_to_virtual(dialog_table_eu_de);
+ dialogTableOrg = segmented_to_virtual(dialog_table_eu_de_original);
break;
}
#else
- dialogTable = segmented_to_virtual(seg2_dialog_table);
+ dialogTableOrg = segmented_to_virtual(seg2_dialog_original);
#endif
- struct DialogEntry *dialog = segmented_to_virtual(dialogTable[dialogId]);
- return dialog;
+ return segmented_to_virtual(dialogTableOrg[dialogId]);
}
void smlua_text_utils_dialog_replace(enum DialogId dialogId, UNUSED u32 unused, s8 linesPerBox, s16 leftOffset, s16 width, const char* str) {
+ if (!IS_VALID_DIALOG(dialogId)) { return; }
+
struct DialogEntry *dialog = smlua_text_utils_dialog_get(dialogId);
if (!dialog) { return; }
- if (sReplacedDialog[dialogId]) {
+ if (dialog->replaced) {
free((u8*)dialog->str);
}
@@ -279,16 +245,41 @@ void smlua_text_utils_dialog_replace(enum DialogId dialogId, UNUSED u32 unused,
dialog->width = width;
dialog->str = smlua_text_utils_convert(str);
dialog->text = strdup(str);
+ dialog->replaced = true;
+}
- sReplacedDialog[dialogId] = true;
+void smlua_text_utils_dialog_restore(enum DialogId dialogId) {
+ if (!IS_VALID_VANILLA_DIALOG(dialogId)) { return; }
+
+ struct DialogEntry *dialog = smlua_text_utils_dialog_get(dialogId);
+
+ if (!dialog->replaced) return;
+
+ const struct DialogEntry *dialogOrig = smlua_text_utils_dialog_get_unmodified(dialogId);
+
+ free((u8*)dialog->str);
+ free(dialog->text);
+
+ memcpy(dialog, dialogOrig, sizeof(struct DialogEntry));
+ dialog->text = get_dialog_text_ascii(dialog);
}
bool smlua_text_utils_dialog_is_replaced(enum DialogId dialogId) {
- if (dialogId >= DIALOG_COUNT) {
- return false;
+ if (!IS_VALID_DIALOG(dialogId)) { return false; }
+
+ struct DialogEntry *dialog = dialog_table_get(dialogId);
+ return dialog->replaced;
+}
+
+s32 smlua_text_utils_allocate_dialog(void) {
+ s32 dialogId;
+ struct DialogEntry* dialog = dialog_table_alloc(&dialogId);
+
+ if (dialog) {
+ dialog->replaced = true;
}
- return sReplacedDialog[dialogId];
+ return dialogId;
}
void smlua_text_utils_course_acts_replace(s16 courseNum, const char* courseName, const char* act1, const char* act2, const char* act3, const char* act4, const char* act5, const char* act6) {
diff --git a/src/pc/lua/utils/smlua_text_utils.h b/src/pc/lua/utils/smlua_text_utils.h
index 6d9d53a17..ea2b7bfa9 100644
--- a/src/pc/lua/utils/smlua_text_utils.h
+++ b/src/pc/lua/utils/smlua_text_utils.h
@@ -3,6 +3,7 @@
#include "types.h"
#include "dialog_ids.h"
+#include "game/ingame_menu.h"
#define MAX_ACTS 6
#define MAX_ACTS_AND_100_COINS 7
@@ -26,16 +27,23 @@ struct CourseActNames {
extern struct CourseActNames gReplacedCourseActNameTable[]; // indexed by COURSE_* constants
+char* get_dialog_text_ascii(struct DialogEntry *dialog);
+
void smlua_text_utils_init(void);
void smlua_text_utils_shutdown(void);
/* |description|Resets every modified dialog back to vanilla|descriptionEnd|*/
void smlua_text_utils_reset_all(void);
/* |description|Gets the DialogEntry struct for the given `dialogId`|descriptionEnd| */
struct DialogEntry* smlua_text_utils_dialog_get(enum DialogId dialogId);
+const struct DialogEntry* smlua_text_utils_dialog_get_unmodified(enum DialogId dialogId);
/* |description|Replaces `dialogId` with a custom one|descriptionEnd| */
void smlua_text_utils_dialog_replace(enum DialogId dialogId, u32 unused, s8 linesPerBox, s16 leftOffset, s16 width, const char* str);
+/* |description|Restores a replaced DialogEntry to its original state.|descriptionEnd| */
+void smlua_text_utils_dialog_restore(enum DialogId dialogId);
/* |description|Returns whether the dialog with the given ID has been replaced|descriptionEnd| */
bool smlua_text_utils_dialog_is_replaced(enum DialogId dialogId);
+/* |description|Allocates a new dialog entry|descriptionEnd|*/
+s32 smlua_text_utils_allocate_dialog(void);
/* |description|Replaces the act names of `courseNum`|descriptionEnd| */
void smlua_text_utils_course_acts_replace(s16 courseNum, const char* courseName, const char* act1, const char* act2, const char* act3, const char* act4, const char* act5, const char* act6);
/* |description|Replaces the secret star course name of `courseNum` with `courseName`|descriptionEnd| */
diff --git a/src/pc/network/packets/packet_player.c b/src/pc/network/packets/packet_player.c
index 8747963f6..793def2db 100644
--- a/src/pc/network/packets/packet_player.c
+++ b/src/pc/network/packets/packet_player.c
@@ -77,7 +77,7 @@ struct PacketPlayerData {
u8 areaSyncValid;
u8 knockbackTimer;
- s16 dialogId;
+ s32 dialogId;
};
#pragma pack()
diff --git a/src/pc/pc_main.c b/src/pc/pc_main.c
index 2ad21c964..ddcc6a734 100644
--- a/src/pc/pc_main.c
+++ b/src/pc/pc_main.c
@@ -52,7 +52,6 @@
#include "pc/djui/djui_lua_profiler.h"
#include "pc/debuglog.h"
#include "pc/utils/misc.h"
-
#include "pc/mods/mods.h"
#include "debug_context.h"
diff --git a/text/define_text.inc.c b/text/define_text.inc.c
index 4a932ffb5..0d2177ec0 100644
--- a/text/define_text.inc.c
+++ b/text/define_text.inc.c
@@ -9,15 +9,7 @@
#undef DEFINE_DIALOG
#define DEFINE_DIALOG(id, unused, linesPerBox, leftOffset, width, _) \
static const struct DialogEntry dialog_entry_orig_ ## id = { \
- unused, linesPerBox, leftOffset, width, dialog_text_ ## id, NULL \
- };
-
-#include "dialogs.h"
-
-#undef DEFINE_DIALOG
-#define DEFINE_DIALOG(id, unused, linesPerBox, leftOffset, width, _) \
- static struct DialogEntry dialog_entry_ ## id = { \
- unused, linesPerBox, leftOffset, width, dialog_text_ ## id, NULL \
+ unused, linesPerBox, leftOffset, width, dialog_text_ ## id, NULL, false \
};
#include "dialogs.h"
@@ -31,12 +23,6 @@ const struct DialogEntry *const seg2_dialog_original[] = {
};
#undef DEFINE_DIALOG
-#define DEFINE_DIALOG(id, _1, _2, _3, _4, _5) &dialog_entry_ ## id,
-
-const struct DialogEntry *const seg2_dialog_table[] = {
-#include "dialogs.h"
- NULL
-};
// == courses ==
// (defines en_course_name_table etc.)