Add `smlua_text_utils_allocate_dialog` (#896)
Some checks failed
Build coop / build-linux (push) Has been cancelled
Build coop / build-steamos (push) Has been cancelled
Build coop / build-windows-opengl (push) Has been cancelled
Build coop / build-windows-directx (push) Has been cancelled
Build coop / build-macos-arm (push) Has been cancelled
Build coop / build-macos-intel (push) Has been cancelled

* 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>
This commit is contained in:
Beckowl 2025-08-03 12:49:45 -03:00 committed by GitHub
parent f0a0a10544
commit 03b29489b1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
52 changed files with 461 additions and 285 deletions

View file

@ -202,6 +202,7 @@ def process_enum(filename, line, inIfBlock):
constants = [] constants = []
set_to = None set_to = None
set_to_val = None
index = 0 index = 0
fields = val.split(',') fields = val.split(',')
for field in fields: for field in fields:
@ -210,13 +211,24 @@ def process_enum(filename, line, inIfBlock):
continue continue
if '=' in field: if '=' in field:
ident, val = field.split('=', 2) ident, val = field.split('=', 1)
constants.append([ident.strip(), val.strip()]) 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 set_to = ident
index = 1 index = 1
continue continue
if set_to is not None: if set_to is not None:
if set_to_val is not None:
constants.append([field, str(set_to_val + index)])
else:
constants.append([field, '((%s) + %d)' % (set_to, index)]) constants.append([field, '((%s) + %d)' % (set_to, index)])
index += 1 index += 1
continue continue

View file

@ -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/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/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_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_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/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" ], "src/pc/network/lag_compensation.h": [ "lag_compensation_clear" ],

View file

@ -140,7 +140,7 @@ override_field_immutable = {
"FirstPersonCamera": [ "enabled" ], "FirstPersonCamera": [ "enabled" ],
"ModAudio": [ "isStream", "loaded" ], "ModAudio": [ "isStream", "loaded" ],
"Gfx": [ "w0", "w1" ], # to protect from invalid type conversions "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": [ "*" ], "ModFsFile": [ "*" ],
"ModFs": [ "*" ], "ModFs": [ "*" ],
} }

View file

@ -2361,6 +2361,7 @@ M_MOUSE_BUTTON = MOUSE_BUTTON_2
--- @type integer --- @type integer
R_MOUSE_BUTTON = MOUSE_BUTTON_3 R_MOUSE_BUTTON = MOUSE_BUTTON_3
DIALOG_NONE = -1 --- @type DialogId
DIALOG_000 = 0 --- @type DialogId DIALOG_000 = 0 --- @type DialogId
DIALOG_001 = 1 --- @type DialogId DIALOG_001 = 1 --- @type DialogId
DIALOG_002 = 2 --- @type DialogId DIALOG_002 = 2 --- @type DialogId
@ -2534,6 +2535,7 @@ DIALOG_169 = 169 --- @type DialogId
DIALOG_COUNT = 170 --- @type DialogId DIALOG_COUNT = 170 --- @type DialogId
--- @alias DialogId --- @alias DialogId
--- | `DIALOG_NONE`
--- | `DIALOG_000` --- | `DIALOG_000`
--- | `DIALOG_001` --- | `DIALOG_001`
--- | `DIALOG_002` --- | `DIALOG_002`
@ -3491,21 +3493,21 @@ MARIO_SPAWN_IDLE = 2 -
MARIO_SPAWN_PIPE = 3 --- @type MarioSpawnType MARIO_SPAWN_PIPE = 3 --- @type MarioSpawnType
MARIO_SPAWN_TELEPORT = 4 --- @type MarioSpawnType MARIO_SPAWN_TELEPORT = 4 --- @type MarioSpawnType
MARIO_SPAWN_INSTANT_ACTIVE = 0x10 --- @type MarioSpawnType MARIO_SPAWN_INSTANT_ACTIVE = 0x10 --- @type MarioSpawnType
MARIO_SPAWN_SWIMMING = ((MARIO_SPAWN_INSTANT_ACTIVE ) + 1) --- @type MarioSpawnType MARIO_SPAWN_SWIMMING = 17 --- @type MarioSpawnType
MARIO_SPAWN_AIRBORNE = ((MARIO_SPAWN_INSTANT_ACTIVE ) + 2) --- @type MarioSpawnType MARIO_SPAWN_AIRBORNE = 18 --- @type MarioSpawnType
MARIO_SPAWN_HARD_AIR_KNOCKBACK = ((MARIO_SPAWN_INSTANT_ACTIVE ) + 3) --- @type MarioSpawnType MARIO_SPAWN_HARD_AIR_KNOCKBACK = 19 --- @type MarioSpawnType
MARIO_SPAWN_SPIN_AIRBORNE_CIRCLE = ((MARIO_SPAWN_INSTANT_ACTIVE ) + 4) --- @type MarioSpawnType MARIO_SPAWN_SPIN_AIRBORNE_CIRCLE = 20 --- @type MarioSpawnType
MARIO_SPAWN_DEATH = ((MARIO_SPAWN_INSTANT_ACTIVE ) + 5) --- @type MarioSpawnType MARIO_SPAWN_DEATH = 21 --- @type MarioSpawnType
MARIO_SPAWN_SPIN_AIRBORNE = ((MARIO_SPAWN_INSTANT_ACTIVE ) + 6) --- @type MarioSpawnType MARIO_SPAWN_SPIN_AIRBORNE = 22 --- @type MarioSpawnType
MARIO_SPAWN_FLYING = ((MARIO_SPAWN_INSTANT_ACTIVE ) + 7) --- @type MarioSpawnType MARIO_SPAWN_FLYING = 23 --- @type MarioSpawnType
MARIO_SPAWN_PAINTING_STAR_COLLECT = 0x20 --- @type MarioSpawnType MARIO_SPAWN_PAINTING_STAR_COLLECT = 0x20 --- @type MarioSpawnType
MARIO_SPAWN_PAINTING_DEATH = ((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 1) --- @type MarioSpawnType MARIO_SPAWN_PAINTING_DEATH = 33 --- @type MarioSpawnType
MARIO_SPAWN_AIRBORNE_STAR_COLLECT = ((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 2) --- @type MarioSpawnType MARIO_SPAWN_AIRBORNE_STAR_COLLECT = 34 --- @type MarioSpawnType
MARIO_SPAWN_AIRBORNE_DEATH = ((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 3) --- @type MarioSpawnType MARIO_SPAWN_AIRBORNE_DEATH = 35 --- @type MarioSpawnType
MARIO_SPAWN_LAUNCH_STAR_COLLECT = ((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 4) --- @type MarioSpawnType MARIO_SPAWN_LAUNCH_STAR_COLLECT = 36 --- @type MarioSpawnType
MARIO_SPAWN_LAUNCH_DEATH = ((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 5) --- @type MarioSpawnType MARIO_SPAWN_LAUNCH_DEATH = 37 --- @type MarioSpawnType
MARIO_SPAWN_UNUSED_38 = ((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 6) --- @type MarioSpawnType MARIO_SPAWN_UNUSED_38 = 38 --- @type MarioSpawnType
MARIO_SPAWN_FADE_FROM_BLACK = ((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 7) --- @type MarioSpawnType MARIO_SPAWN_FADE_FROM_BLACK = 39 --- @type MarioSpawnType
--- @alias MarioSpawnType --- @alias MarioSpawnType
--- | `MARIO_SPAWN_NONE` --- | `MARIO_SPAWN_NONE`

View file

@ -11887,6 +11887,12 @@ function smlua_text_utils_dialog_replace(dialogId, unused, linesPerBox, leftOffs
-- ... -- ...
end end
--- @param dialogId DialogId
--- Restores a replaced DialogEntry to its original state.
function smlua_text_utils_dialog_restore(dialogId)
-- ...
end
--- @param dialogId DialogId --- @param dialogId DialogId
--- @return boolean --- @return boolean
--- Returns whether the dialog with the given ID has been replaced --- Returns whether the dialog with the given ID has been replaced
@ -11894,6 +11900,12 @@ function smlua_text_utils_dialog_is_replaced(dialogId)
-- ... -- ...
end end
--- @return integer
--- Allocates a new dialog entry
function smlua_text_utils_allocate_dialog()
-- ...
end
--- @param courseNum integer --- @param courseNum integer
--- @param courseName string --- @param courseName string
--- @param act1 string --- @param act1 string

View file

@ -595,6 +595,7 @@
--- @class DialogEntry --- @class DialogEntry
--- @field public leftOffset integer --- @field public leftOffset integer
--- @field public linesPerBox integer --- @field public linesPerBox integer
--- @field public replaced boolean
--- @field public text string --- @field public text string
--- @field public unused integer --- @field public unused integer
--- @field public width integer --- @field public width integer

View file

@ -12,7 +12,6 @@
#define seg2_course_name_table_original course_name_table_eu_de_original #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 act_name_table_eu_de
#define seg2_act_name_table_original act_name_table_eu_de_original #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 #define seg2_dialog_original dialog_table_eu_de_original
#include "text/de/define_text.inc.c" #include "text/de/define_text.inc.c"

View file

@ -12,7 +12,6 @@
#define seg2_course_name_table_original course_name_table_eu_en_original #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 act_name_table_eu_en
#define seg2_act_name_table_original act_name_table_eu_en_original #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 #define seg2_dialog_original dialog_table_eu_en_original
#include "text/us/define_text.inc.c" #include "text/us/define_text.inc.c"

View file

@ -12,7 +12,6 @@
#define seg2_course_name_table_original course_name_table_eu_fr_original #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 act_name_table_eu_fr
#define seg2_act_name_table_original act_name_table_eu_fr_original #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 #define seg2_dialog_original dialog_table_eu_fr_original
#include "text/fr/define_text.inc.c" #include "text/fr/define_text.inc.c"

View file

@ -958,6 +958,7 @@
### [enum DialogId](#DialogId) ### [enum DialogId](#DialogId)
| Identifier | Value | | Identifier | Value |
| :--------- | :---- | | :--------- | :---- |
| DIALOG_NONE | -1 |
| DIALOG_000 | 0 | | DIALOG_000 | 0 |
| DIALOG_001 | 1 | | DIALOG_001 | 1 |
| DIALOG_002 | 2 | | DIALOG_002 | 2 |
@ -1579,21 +1580,21 @@
| MARIO_SPAWN_PIPE | 3 | | MARIO_SPAWN_PIPE | 3 |
| MARIO_SPAWN_TELEPORT | 4 | | MARIO_SPAWN_TELEPORT | 4 |
| MARIO_SPAWN_INSTANT_ACTIVE | 0x10 | | MARIO_SPAWN_INSTANT_ACTIVE | 0x10 |
| MARIO_SPAWN_SWIMMING | ((MARIO_SPAWN_INSTANT_ACTIVE ) + 1) | | MARIO_SPAWN_SWIMMING | 17 |
| MARIO_SPAWN_AIRBORNE | ((MARIO_SPAWN_INSTANT_ACTIVE ) + 2) | | MARIO_SPAWN_AIRBORNE | 18 |
| MARIO_SPAWN_HARD_AIR_KNOCKBACK | ((MARIO_SPAWN_INSTANT_ACTIVE ) + 3) | | MARIO_SPAWN_HARD_AIR_KNOCKBACK | 19 |
| MARIO_SPAWN_SPIN_AIRBORNE_CIRCLE | ((MARIO_SPAWN_INSTANT_ACTIVE ) + 4) | | MARIO_SPAWN_SPIN_AIRBORNE_CIRCLE | 20 |
| MARIO_SPAWN_DEATH | ((MARIO_SPAWN_INSTANT_ACTIVE ) + 5) | | MARIO_SPAWN_DEATH | 21 |
| MARIO_SPAWN_SPIN_AIRBORNE | ((MARIO_SPAWN_INSTANT_ACTIVE ) + 6) | | MARIO_SPAWN_SPIN_AIRBORNE | 22 |
| MARIO_SPAWN_FLYING | ((MARIO_SPAWN_INSTANT_ACTIVE ) + 7) | | MARIO_SPAWN_FLYING | 23 |
| MARIO_SPAWN_PAINTING_STAR_COLLECT | 0x20 | | MARIO_SPAWN_PAINTING_STAR_COLLECT | 0x20 |
| MARIO_SPAWN_PAINTING_DEATH | ((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 1) | | MARIO_SPAWN_PAINTING_DEATH | 33 |
| MARIO_SPAWN_AIRBORNE_STAR_COLLECT | ((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 2) | | MARIO_SPAWN_AIRBORNE_STAR_COLLECT | 34 |
| MARIO_SPAWN_AIRBORNE_DEATH | ((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 3) | | MARIO_SPAWN_AIRBORNE_DEATH | 35 |
| MARIO_SPAWN_LAUNCH_STAR_COLLECT | ((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 4) | | MARIO_SPAWN_LAUNCH_STAR_COLLECT | 36 |
| MARIO_SPAWN_LAUNCH_DEATH | ((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 5) | | MARIO_SPAWN_LAUNCH_DEATH | 37 |
| MARIO_SPAWN_UNUSED_38 | ((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 6) | | MARIO_SPAWN_UNUSED_38 | 38 |
| MARIO_SPAWN_FADE_FROM_BLACK | ((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 7) | | MARIO_SPAWN_FADE_FROM_BLACK | 39 |
- MARIO_SPAWN_UNKNOWN_02 - MARIO_SPAWN_UNKNOWN_02
- MARIO_SPAWN_UNKNOWN_03 - MARIO_SPAWN_UNKNOWN_03
- MARIO_SPAWN_UNKNOWN_27 - MARIO_SPAWN_UNKNOWN_27

View file

@ -2186,7 +2186,7 @@ Starts a cutscene involving an object and displays dialog during the sequence. T
- `integer` - `integer`
### C Prototype ### 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:](#) [:arrow_up_small:](#)
@ -4056,7 +4056,7 @@ Plays a dialog sound corresponding to `dialogID`
- None - None
### C Prototype ### C Prototype
`void play_dialog_sound(u8 dialogID);` `void play_dialog_sound(s32 dialogID);`
[:arrow_up_small:](#) [:arrow_up_small:](#)
@ -4692,7 +4692,7 @@ Creates a dialog box with a dialog ID that rotates into view
- None - None
### C Prototype ### C Prototype
`void create_dialog_box(s16 dialog);` `void create_dialog_box(s32 dialog);`
[:arrow_up_small:](#) [:arrow_up_small:](#)
@ -4716,7 +4716,7 @@ Creates a dialog box with a dialog variable
- None - None
### C Prototype ### 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:](#) [:arrow_up_small:](#)
@ -4739,7 +4739,7 @@ Creates a dialog box with a dialog ID that zooms into view
- None - None
### C Prototype ### C Prototype
`void create_dialog_inverted_box(s16 dialog);` `void create_dialog_inverted_box(s32 dialog);`
[:arrow_up_small:](#) [:arrow_up_small:](#)
@ -4762,7 +4762,7 @@ Creates a dialog box with a response
- None - None
### C Prototype ### C Prototype
`void create_dialog_box_with_response(s16 dialog);` `void create_dialog_box_with_response(s32 dialog);`
[:arrow_up_small:](#) [:arrow_up_small:](#)

View file

@ -4464,7 +4464,7 @@ Gets the current dialog box ID
- `integer` - `integer`
### C Prototype ### C Prototype
`s16 get_dialog_id(void);` `s32 get_dialog_id(void);`
[:arrow_up_small:](#) [:arrow_up_small:](#)
@ -7254,6 +7254,29 @@ Replaces `dialogId` with a custom one
<br /> <br />
## [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:](#)
<br />
## [smlua_text_utils_dialog_is_replaced](#smlua_text_utils_dialog_is_replaced) ## [smlua_text_utils_dialog_is_replaced](#smlua_text_utils_dialog_is_replaced)
### Description ### Description
@ -7277,6 +7300,27 @@ Returns whether the dialog with the given ID has been replaced
<br /> <br />
## [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:](#)
<br />
## [smlua_text_utils_course_acts_replace](#smlua_text_utils_course_acts_replace) ## [smlua_text_utils_course_acts_replace](#smlua_text_utils_course_acts_replace)
### Description ### Description

View file

@ -2112,7 +2112,9 @@
- [smlua_text_utils_reset_all](functions-6.md#smlua_text_utils_reset_all) - [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_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_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_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_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_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) - [smlua_text_utils_course_name_replace](functions-6.md#smlua_text_utils_course_name_replace)

View file

@ -886,6 +886,7 @@
| ----- | ---- | ------ | | ----- | ---- | ------ |
| leftOffset | `integer` | read-only | | leftOffset | `integer` | read-only |
| linesPerBox | `integer` | read-only | | linesPerBox | `integer` | read-only |
| replaced | `boolean` | read-only |
| text | `string` | read-only | | text | `string` | read-only |
| unused | `integer` | read-only | | unused | `integer` | read-only |
| width | `integer` | read-only | | width | `integer` | read-only |

View file

@ -2,6 +2,7 @@
#define DIALOG_IDS_H #define DIALOG_IDS_H
enum DialogId { enum DialogId {
DIALOG_NONE = -1,
DIALOG_000, DIALOG_000,
DIALOG_001, DIALOG_001,
DIALOG_002, DIALOG_002,

View file

@ -11,21 +11,18 @@
#define LANGUAGE_ARRAY(cmd) cmd #define LANGUAGE_ARRAY(cmd) cmd
#endif #endif
extern u8 *dialog_table_eu_en[];
extern u8 *course_name_table_eu_en[]; extern u8 *course_name_table_eu_en[];
extern u8 *act_name_table_eu_en[]; extern u8 *act_name_table_eu_en[];
extern u8 *dialog_table_eu_en_original[]; extern u8 *dialog_table_eu_en_original[];
extern u8 *course_name_table_eu_en_original[]; extern u8 *course_name_table_eu_en_original[];
extern u8 *act_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 *course_name_table_eu_fr[];
extern u8 *act_name_table_eu_fr[]; extern u8 *act_name_table_eu_fr[];
extern u8 *dialog_table_eu_fr_original[]; extern u8 *dialog_table_eu_fr_original[];
extern u8 *course_name_table_eu_fr_original[]; extern u8 *course_name_table_eu_fr_original[];
extern u8 *act_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 *course_name_table_eu_de[];
extern u8 *act_name_table_eu_de[]; extern u8 *act_name_table_eu_de[];
extern u8 *dialog_table_eu_de_original[]; extern u8 *dialog_table_eu_de_original[];

View file

@ -970,7 +970,7 @@
#define /*0x10C*/ oTiltingPyramidMarioOnPlatform OBJECT_FIELD_S32(0x21) #define /*0x10C*/ oTiltingPyramidMarioOnPlatform OBJECT_FIELD_S32(0x21)
/* Toad Message */ /* Toad Message */
#define /*0x108*/ oToadMessageDialogId OBJECT_FIELD_U32(0x20) #define /*0x108*/ oToadMessageDialogId OBJECT_FIELD_S32(0x20)
#define /*0x10C*/ oToadMessageRecentlyTalked OBJECT_FIELD_S32(0x21) #define /*0x10C*/ oToadMessageRecentlyTalked OBJECT_FIELD_S32(0x21)
#define /*0x110*/ oToadMessageState OBJECT_FIELD_S32(0x22) #define /*0x110*/ oToadMessageState OBJECT_FIELD_S32(0x22)

View file

@ -498,7 +498,7 @@ struct MarioState
u8 visibleToEnemies; u8 visibleToEnemies;
u8 wasNetworkVisible; u8 wasNetworkVisible;
s16 dialogId; s32 dialogId;
s16 prevNumStarsForDialog; s16 prevNumStarsForDialog;
s16 unkB0; s16 unkB0;

View file

@ -18,6 +18,8 @@
#include "pc/debuglog.h" #include "pc/debuglog.h"
#include "pc/lua/utils/smlua_level_utils.h" #include "pc/lua/utils/smlua_level_utils.h"
#include "pc/lua/smlua_hooks.h" #include "pc/lua/smlua_hooks.h"
#include "pc/dialog_table.h"
#include "dialog_ids.h"
#if defined(VERSION_EU) || defined(VERSION_SH) #if defined(VERSION_EU) || defined(VERSION_SH)
#define EU_FLOAT(x) x##f #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 * Called from threads: thread5_game_loop
*/ */
void play_dialog_sound(u8 dialogID) { void play_dialog_sound(s32 dialogID) {
s32 speaker; s32 speaker;
if (dialogID >= DIALOG_COUNT) { if (!IS_VALID_VANILLA_DIALOG(dialogID)) {
dialogID = 0; dialogID = 0;
} }

View file

@ -4,6 +4,7 @@
#include <PR/ultratypes.h> #include <PR/ultratypes.h>
#include "types.h" #include "types.h"
#include "dialog_ids.h"
#define MAX_AUDIO_OVERRIDE 128 #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| */ /* |description|Sets the `speed` of moving `bank`|descriptionEnd| */
void set_sound_moving_speed(u8 bank, u8 speed); void set_sound_moving_speed(u8 bank, u8 speed);
/* |description|Plays a dialog sound corresponding to `dialogID`|descriptionEnd| */ /* |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| */ /* |description|Sets the `volume` of `player`|descriptionEnd| */
void set_sequence_player_volume(s32 player, f32 volume); void set_sequence_player_volume(s32 player, f32 volume);
/* |description|Plays fading in music (`seqArgs`) on `player` over `fadeTimer`|descriptionEnd| */ /* |description|Plays fading in music (`seqArgs`) on `player` over `fadeTimer`|descriptionEnd| */

View file

@ -337,7 +337,7 @@ void bobomb_buddy_act_idle(void) {
* dialogSecondText is called after Bob-omb Buddy has the cannon(s) ready and * dialogSecondText is called after Bob-omb Buddy has the cannon(s) ready and
* then tells Mario that is "Ready for blastoff". * 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; struct Object *cannonClosed;
s16 buddyText, cutscene; s16 buddyText, cutscene;

View file

@ -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_8032F50C[] = { 60, 0 };
s16 D_8032F510[] = { 50, 0 }; s16 D_8032F510[] = { 50, 0 };
s8 D_8032F514[] = { 24, 42, 60, -1 }; s8 D_8032F514[] = { 24, 42, 60, -1 };
s16* sBowserDefeatedDialogText[3] = { enum DialogId* sBowserDefeatedDialogText[3] = {
(s16*) &gBehaviorValues.dialogs.Bowser1DefeatedDialog, &gBehaviorValues.dialogs.Bowser1DefeatedDialog,
(s16*) &gBehaviorValues.dialogs.Bowser2DefeatedDialog, &gBehaviorValues.dialogs.Bowser2DefeatedDialog,
(s16*) &gBehaviorValues.dialogs.Bowser3DefeatedDialog &gBehaviorValues.dialogs.Bowser3DefeatedDialog
}; };
s16 D_8032F520[][3] = { { 1, 10, 40 }, { 0, 0, 74 }, { -1, -10, 114 }, { 1, -20, 134 }, 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 }, { -1, 20, 154 }, { 1, 40, 164 }, { -1, -40, 174 }, { 1, -80, 179 },

View file

@ -40,7 +40,7 @@ void bhv_intro_peach_loop(void) {
case 2: case 2:
intro_peach_set_pos_and_opacity(gCurrentObject, 255.f, 3.f); 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; gCurrentObject->oAction += 1;
break; break;
case 3: case 3:

View file

@ -50,16 +50,16 @@ static u8 sKoopaShelledAttackHandlers[] = {
* Data to control the behavior of each instance of Koopa the Quick. * Data to control the behavior of each instance of Koopa the Quick.
*/ */
struct KoopaTheQuickProperties { struct KoopaTheQuickProperties {
s16* initText; enum DialogId* initText;
s16* winText; enum DialogId* winText;
}; };
/** /**
* Properties for the BoB race and the THI race. * Properties for the BoB race and the THI race.
*/ */
static struct KoopaTheQuickProperties sKoopaTheQuickProperties[] = { static struct KoopaTheQuickProperties sKoopaTheQuickProperties[] = {
{ (s16*) &gBehaviorValues.dialogs.KoopaQuickBobStartDialog, (s16*) &gBehaviorValues.dialogs.KoopaQuickBobWinDialog }, { &gBehaviorValues.dialogs.KoopaQuickBobStartDialog, &gBehaviorValues.dialogs.KoopaQuickBobWinDialog },
{ (s16*) &gBehaviorValues.dialogs.KoopaQuickThiStartDialog, (s16*) &gBehaviorValues.dialogs.KoopaQuickThiWinDialog } { &gBehaviorValues.dialogs.KoopaQuickThiStartDialog, &gBehaviorValues.dialogs.KoopaQuickThiWinDialog }
}; };
static u32 koopaPathedStartWaypoint = 0; 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)) { 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); 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) { if (dialogResponse != 0) {
o->parentObj->oKoopaRaceEndpointUnk100 = -1; o->parentObj->oKoopaRaceEndpointUnk100 = DIALOG_NONE;
o->oTimer = 0; o->oTimer = 0;
} }
} }

View file

@ -265,7 +265,7 @@ static u8 bhv_mips_held_continue_dialog(void) {
* Handles MIPS being held by Mario. * Handles MIPS being held by Mario.
*/ */
void bhv_mips_held(void) { void bhv_mips_held(void) {
s16 dialogID; s32 dialogID;
if (o->heldByPlayerIndex >= MAX_PLAYERS) { return; } if (o->heldByPlayerIndex >= MAX_PLAYERS) { return; }
struct Object* player = gMarioStates[o->heldByPlayerIndex].marioObj; struct Object* player = gMarioStates[o->heldByPlayerIndex].marioObj;

View file

@ -1,12 +1,12 @@
struct RacingPenguinData { struct RacingPenguinData {
s16* text; enum DialogId* text;
f32* radius; f32* radius;
f32* height; f32* height;
}; };
static struct RacingPenguinData sRacingPenguinData[] = { static struct RacingPenguinData sRacingPenguinData[] = {
{ (s16*) &gBehaviorValues.dialogs.RacingPenguinStartDialog, &gBehaviorValues.RacingPenguinRadius, &gBehaviorValues.RacingPenguinHeight }, { &gBehaviorValues.dialogs.RacingPenguinStartDialog, &gBehaviorValues.RacingPenguinRadius, &gBehaviorValues.RacingPenguinHeight },
{ (s16*) &gBehaviorValues.dialogs.RacingPenguinBigStartDialog, &gBehaviorValues.RacingPenguinBigRadius, &gBehaviorValues.RacingPenguinBigHeight }, { &gBehaviorValues.dialogs.RacingPenguinBigStartDialog, &gBehaviorValues.RacingPenguinBigRadius, &gBehaviorValues.RacingPenguinBigHeight },
}; };
static u32 penguinPathedStartWaypoint = 0; static u32 penguinPathedStartWaypoint = 0;

View file

@ -300,10 +300,10 @@ static void wiggler_act_jumped_on(void) {
struct MarioState* marioState = nearest_mario_state_to_object(o); struct MarioState* marioState = nearest_mario_state_to_object(o);
// Text to show on first, second, and third attack. // Text to show on first, second, and third attack.
s32* attackText[3] = { enum DialogId* attackText[3] = {
(s32*) &gBehaviorValues.dialogs.WigglerAttack1Dialog, &gBehaviorValues.dialogs.WigglerAttack1Dialog,
(s32*) &gBehaviorValues.dialogs.WigglerAttack2Dialog, &gBehaviorValues.dialogs.WigglerAttack2Dialog,
(s32*) &gBehaviorValues.dialogs.WigglerAttack3Dialog &gBehaviorValues.dialogs.WigglerAttack3Dialog
}; };
// Shrink until the squish speed becomes 0, then unisquish // Shrink until the squish speed becomes 0, then unisquish

View file

@ -172,7 +172,7 @@ extern s16 s2ndRotateFlags;
extern s16 unused8033B31A; extern s16 unused8033B31A;
extern s16 sCameraSoundFlags; extern s16 sCameraSoundFlags;
extern u16 sCButtonsPressed; extern u16 sCButtonsPressed;
extern s16 sCutsceneDialogID; extern s32 sCutsceneDialogID;
extern struct LakituState gLakituState; extern struct LakituState gLakituState;
extern s16 unused8033B3E8; extern s16 unused8033B3E8;
extern s16 sAreaYaw; extern s16 sAreaYaw;
@ -304,7 +304,7 @@ u16 sCButtonsPressed;
/** /**
* A copy of gDialogID, the dialog displayed during the cutscene. * A copy of gDialogID, the dialog displayed during the cutscene.
*/ */
s16 sCutsceneDialogID; s32 sCutsceneDialogID;
/** /**
* The currently playing shot in the cutscene. * 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; s16 response = 0;
if ((gCamera->cutscene == 0) && (sObjectCutscene == 0)) { if ((gCamera->cutscene == 0) && (sObjectCutscene == 0)) {
if (gRecentCutscene != cutscene) { if (gRecentCutscene != cutscene) {
start_object_cutscene(cutscene, o); start_object_cutscene(cutscene, o);
if (dialogID != -1) { if (dialogID != DIALOG_NONE) {
sCutsceneDialogID = dialogID; sCutsceneDialogID = dialogID;
} else { } else {
sCutsceneDialogID = (s16) gBehaviorValues.dialogs.DefaultCutsceneDialog; sCutsceneDialogID = (s32) gBehaviorValues.dialogs.DefaultCutsceneDialog;
} }
} else { } else {
response = sCutsceneDialogResponse; 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. * Create the dialog box depending on which bowser fight Mario is in.
*/ */
BAD_RETURN(s32) bowser_fight_intro_dialog(UNUSED struct Camera *c) { BAD_RETURN(s32) bowser_fight_intro_dialog(UNUSED struct Camera *c) {
s16 dialog; s32 dialog;
switch (gCurrLevelNum) { switch (gCurrLevelNum) {
case LEVEL_BOWSER_1: 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) { BAD_RETURN(s32) cutscene_bowser_arena_dialog(struct Camera *c) {
cutscene_event(bowser_fight_intro_dialog, c, 0, 0); cutscene_event(bowser_fight_intro_dialog, c, 0, 0);
if (get_dialog_id() == -1) { if (get_dialog_id() == DIALOG_NONE) {
gCutsceneTimer = CUTSCENE_LOOP; gCutsceneTimer = CUTSCENE_LOOP;
} }
} }
@ -9486,7 +9486,7 @@ BAD_RETURN(s32) cutscene_dialog(struct Camera *c) {
sCutsceneDialogResponse = gDialogResponse; 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) { if (c->cutscene != CUTSCENE_RACE_DIALOG) {
sCutsceneDialogResponse = 3; sCutsceneDialogResponse = 3;
} }
@ -9556,7 +9556,7 @@ BAD_RETURN(s32) cutscene_read_message(struct Camera *c) {
switch (sCutsceneVars[0].angle[0]) { switch (sCutsceneVars[0].angle[0]) {
// Do nothing until message is gone. // Do nothing until message is gone.
case 0: case 0:
if (get_dialog_id() != -1) { if (get_dialog_id() != DIALOG_NONE) {
sCutsceneVars[0].angle[0] += 1; sCutsceneVars[0].angle[0] += 1;
//set_time_stop_flags(TIME_STOP_ENABLED | TIME_STOP_DIALOG); //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 // This could cause softlocks. If a message starts one frame after another one closes, the
// cutscene will never end. // cutscene will never end.
if (get_dialog_id() == -1) { if (get_dialog_id() == DIALOG_NONE) {
gCutsceneTimer = CUTSCENE_LOOP; gCutsceneTimer = CUTSCENE_LOOP;
retrieve_info_star(c); retrieve_info_star(c);
transition_next_state(c, 15); transition_next_state(c, 15);
@ -9926,7 +9926,7 @@ BAD_RETURN(s32) cutscene_cap_switch_press(struct Camera *c) {
sCutsceneVars[4].angle[0] = gDialogResponse; 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]; sCutsceneDialogResponse = sCutsceneVars[4].angle[0];
if (sCutsceneVars[4].angle[0] == 1 && gCutsceneFocus) { if (sCutsceneVars[4].angle[0] == 1 && gCutsceneFocus) {
cap_switch_save(gCutsceneFocus->oBehParams2ndByte); 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) { BAD_RETURN(s32) cutscene_intro_peach_dialog(struct Camera *c) {
if (!c) { return; } if (!c) { return; }
if (get_dialog_id() == -1) { if (get_dialog_id() == DIALOG_NONE) {
vec3f_copy(gLakituState.goalPos, c->pos); vec3f_copy(gLakituState.goalPos, c->pos);
vec3f_copy(gLakituState.goalFocus, c->focus); vec3f_copy(gLakituState.goalFocus, c->focus);
sStatusFlags |= (CAM_FLAG_SMOOTH_MOVEMENT | CAM_FLAG_UNUSED_CUTSCENE_ACTIVE); 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); cutscene_event(play_sound_peach_reading_letter, c, 83, 83);
#endif #endif
if ((gCutsceneTimer > 120) && (get_dialog_id() == -1)) { if ((gCutsceneTimer > 120) && (get_dialog_id() == DIALOG_NONE)) {
// Start the next scene // Start the next scene
gCutsceneTimer = CUTSCENE_LOOP; gCutsceneTimer = CUTSCENE_LOOP;
} }

View file

@ -1203,7 +1203,7 @@ u8 start_object_cutscene_without_focus(u8 cutscene);
Starts a cutscene involving an object and displays dialog during the sequence. Starts a cutscene involving an object and displays dialog during the sequence.
The camera focuses on the object while synchronizing dialog with the scene The camera focuses on the object while synchronizing dialog with the scene
|descriptionEnd| */ |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| /* |description|
Starts a cutscene involving an object without dialog. Starts a cutscene involving an object without dialog.

View file

@ -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 *envfx_update_particles(s32 mode, Vec3s marioPos, Vec3s camTo, Vec3s camFrom) {
Gfx *gfx; Gfx *gfx;
if (get_dialog_id() != -1) { if (get_dialog_id() != DIALOG_NONE) {
return NULL; return NULL;
} }

View file

@ -38,6 +38,7 @@
#include "level_info.h" #include "level_info.h"
#include "pc/lua/utils/smlua_text_utils.h" #include "pc/lua/utils/smlua_text_utils.h"
#include "menu/ingame_text.h" #include "menu/ingame_text.h"
#include "pc/dialog_table.h"
u16 gDialogColorFadeTimer; u16 gDialogColorFadeTimer;
s8 gLastDialogLineNum; s8 gLastDialogLineNum;
@ -128,7 +129,7 @@ f32 gDialogBoxOpenTimer = DEFAULT_DIALOG_BOX_ANGLE;
f32 gDialogBoxScale = DEFAULT_DIALOG_BOX_SCALE; f32 gDialogBoxScale = DEFAULT_DIALOG_BOX_SCALE;
s16 gDialogScrollOffsetY = 0; s16 gDialogScrollOffsetY = 0;
s8 gDialogBoxType = DIALOG_TYPE_ROTATE; s8 gDialogBoxType = DIALOG_TYPE_ROTATE;
s16 gDialogID = -1; s32 gDialogID = DIALOG_NONE;
s16 gLastDialogPageStrPos = 0; s16 gLastDialogPageStrPos = 0;
s16 gDialogTextPos = 0; s16 gDialogTextPos = 0;
#ifdef VERSION_EU #ifdef VERSION_EU
@ -1025,24 +1026,24 @@ void int_to_str(s32 num, u8 *dst) {
dst[pos] = DIALOG_CHAR_TERMINATOR; dst[pos] = DIALOG_CHAR_TERMINATOR;
} }
s16 get_dialog_id(void) { s32 get_dialog_id(void) {
return gDialogID; 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) // 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) // 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 // 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) // King Bob-omb (Start), Whomp (Defeated), King Bob-omb (Defeated, missing in JP), Eyerock (Defeated), Wiggler (Defeated)
#if BUGFIX_KING_BOB_OMB_FADE_MUSIC #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 #else
//! @bug JP misses King Bob-omb defeated dialog "116", meaning that the boss music will still //! @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 //! 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 #endif
s16 i; s16 i;
@ -1079,7 +1080,7 @@ void handle_special_dialog_text(s16 dialogID) { // dialog ID tables, in order
static u8 sHookString[255]; static u8 sHookString[255];
static bool sOverrideDialogString = false; static bool sOverrideDialogString = false;
void convert_string_ascii_to_sm64(u8 *str64, const char *strAscii, bool menu); 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; bool openDialogBox = true;
const char *dialogTextOverride = NULL; const char *dialogTextOverride = NULL;
smlua_call_event_hooks(HOOK_ON_DIALOG, dialogId, &openDialogBox, &dialogTextOverride); smlua_call_event_hooks(HOOK_ON_DIALOG, dialogId, &openDialogBox, &dialogTextOverride);
@ -1092,30 +1093,30 @@ bool handle_dialog_hook(s16 dialogId) {
return true; return true;
} }
void create_dialog_box(s16 dialog) { void create_dialog_box(s32 dialog) {
if (handle_dialog_hook(dialog) && gDialogID == -1) { if (handle_dialog_hook(dialog) && gDialogID == DIALOG_NONE) {
gDialogID = dialog; gDialogID = dialog;
gDialogBoxType = DIALOG_TYPE_ROTATE; gDialogBoxType = DIALOG_TYPE_ROTATE;
} }
} }
void create_dialog_box_with_var(s16 dialog, s32 dialogVar) { void create_dialog_box_with_var(s32 dialog, s32 dialogVar) {
if (handle_dialog_hook(dialog) && gDialogID == -1) { if (handle_dialog_hook(dialog) && gDialogID == DIALOG_NONE) {
gDialogID = dialog; gDialogID = dialog;
gDialogVariable = dialogVar; gDialogVariable = dialogVar;
gDialogBoxType = DIALOG_TYPE_ROTATE; gDialogBoxType = DIALOG_TYPE_ROTATE;
} }
} }
void create_dialog_inverted_box(s16 dialog) { void create_dialog_inverted_box(s32 dialog) {
if (handle_dialog_hook(dialog) && gDialogID == -1) { if (handle_dialog_hook(dialog) && gDialogID == DIALOG_NONE) {
gDialogID = dialog; gDialogID = dialog;
gDialogBoxType = DIALOG_TYPE_ZOOM; gDialogBoxType = DIALOG_TYPE_ZOOM;
} }
} }
void create_dialog_box_with_response(s16 dialog) { void create_dialog_box_with_response(s32 dialog) {
if (handle_dialog_hook(dialog) && gDialogID == -1) { if (handle_dialog_hook(dialog) && gDialogID == DIALOG_NONE) {
gDialogID = dialog; gDialogID = dialog;
gDialogBoxType = DIALOG_TYPE_ROTATE; gDialogBoxType = DIALOG_TYPE_ROTATE;
gLastDialogResponse = 1; gLastDialogResponse = 1;
@ -1132,7 +1133,7 @@ void reset_dialog_render_state(void) {
gDialogBoxScale = 19.0f; gDialogBoxScale = 19.0f;
gDialogBoxOpenTimer = 90.0f; gDialogBoxOpenTimer = 90.0f;
gDialogBoxState = DIALOG_STATE_OPENING; gDialogBoxState = DIALOG_STATE_OPENING;
gDialogID = -1; gDialogID = DIALOG_NONE;
gDialogTextPos = 0; gDialogTextPos = 0;
gLastDialogResponse = 0; gLastDialogResponse = 0;
gLastDialogPageStrPos = 0; gLastDialogPageStrPos = 0;
@ -1877,36 +1878,14 @@ void render_dialog_entries(void) {
#ifdef VERSION_EU #ifdef VERSION_EU
s8 lowerBound = 0; s8 lowerBound = 0;
#endif #endif
void **dialogTable;
struct DialogEntry *dialog;
#if defined(VERSION_US) || defined(VERSION_SH) #if defined(VERSION_US) || defined(VERSION_SH)
s8 lowerBound = 0; s8 lowerBound = 0;
#endif #endif
#ifdef VERSION_EU struct DialogEntry *dialog = dialog_table_get(gDialogID);
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]);
// if the dialog entry is invalid, set the ID to -1. if (dialog == NULL) {
if (segmented_to_virtual(NULL) == dialog) { gDialogID = DIALOG_NONE;
gDialogID = -1;
return; return;
} }
@ -1984,7 +1963,7 @@ void render_dialog_entries(void) {
if (gDialogBoxOpenTimer == DEFAULT_DIALOG_BOX_ANGLE) { if (gDialogBoxOpenTimer == DEFAULT_DIALOG_BOX_ANGLE) {
gDialogBoxState = DIALOG_STATE_OPENING; gDialogBoxState = DIALOG_STATE_OPENING;
gDialogID = -1; gDialogID = DIALOG_NONE;
gDialogTextPos = 0; gDialogTextPos = 0;
gLastDialogResponse = 0; gLastDialogResponse = 0;
gLastDialogPageStrPos = 0; gLastDialogPageStrPos = 0;
@ -2198,28 +2177,9 @@ void do_cutscene_handler(void) {
// "Dear Mario" message handler // "Dear Mario" message handler
void print_peach_letter_message(void) { void print_peach_letter_message(void) {
void **dialogTable; struct DialogEntry *dialog = dialog_table_get(gDialogID);
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]);
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); 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)) { if (gCutsceneMsgTimer > (PEACH_MESSAGE_TIMER + 20)) {
gCutsceneMsgIndex = -1; gCutsceneMsgIndex = -1;
gCutsceneMsgFade = 0; //! uselessly reset since the next execution will just set it to 0 again. gCutsceneMsgFade = 0; //! uselessly reset since the next execution will just set it to 0 again.
gDialogID = -1; gDialogID = DIALOG_NONE;
gCutsceneMsgTimer = 0; gCutsceneMsgTimer = 0;
return; // return to avoid incrementing the timer return; // return to avoid incrementing the timer
} }
@ -3472,9 +3432,9 @@ s16 render_menus_and_dialogs(void) {
} }
gDialogColorFadeTimer = (s16) gDialogColorFadeTimer + 0x1000; gDialogColorFadeTimer = (s16) gDialogColorFadeTimer + 0x1000;
} else if (gDialogID != -1) { } else if (gDialogID != DIALOG_NONE) {
// The Peach "Dear Mario" message needs to be repositioned separately // The Peach "Dear Mario" message needs to be repositioned separately
if (gDialogID == 20) { if (gDialogID == DIALOG_020) {
print_peach_letter_message(); print_peach_letter_message();
return mode; return mode;
} }

View file

@ -2,6 +2,7 @@
#define INGAME_MENU_H #define INGAME_MENU_H
#include <PR/ultratypes.h> #include <PR/ultratypes.h>
#include <stdbool.h>
#define ASCII_TO_DIALOG(asc) \ #define ASCII_TO_DIALOG(asc) \
(((asc) >= '0' && (asc) <= '9') ? ((asc) - '0') : \ (((asc) >= '0' && (asc) <= '9') ? ((asc) - '0') : \
@ -39,12 +40,13 @@ extern s8 gHudFlash;
struct DialogEntry struct DialogEntry
{ {
u32 unused; /*0x00*/ u32 unused;
s8 linesPerBox; /*0x04*/ s8 linesPerBox;
s16 leftOffset; /*0x06*/ s16 leftOffset;
s16 width; /*0x08*/ s16 width;
const u8 *str; /*0x0C*/ const u8 *str;
char* text; char* text;
bool replaced;
}; };
// EU only // EU only
@ -158,15 +160,15 @@ s16 get_str_x_pos_from_center_scale(s16 centerPos, u8 *str, f32 scale);
#endif #endif
void print_hud_my_score_coins(s32 useCourseCoinScore, s8 fileNum, s8 courseNum, s16 x, s16 y); void print_hud_my_score_coins(s32 useCourseCoinScore, s8 fileNum, s8 courseNum, s16 x, s16 y);
void int_to_str(s32 num, u8 *dst); 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| */ /* |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| */ /* |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| */ /* |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| */ /* |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| */ /* |description|Resets the dialog box's state including dialog ID and open state|descriptionEnd| */
void reset_dialog_render_state(void); void reset_dialog_render_state(void);
/* |description| /* |description|

View file

@ -250,11 +250,11 @@ u16 level_control_timer(s32 timerOp) {
u32 pressed_pause(void) { u32 pressed_pause(void) {
if (gServerSettings.pauseAnywhere) { 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; return gPlayer1Controller->buttonPressed & START_BUTTON;
} }
} else { } else {
u32 dialogActive = get_dialog_id() >= 0; u32 dialogActive = get_dialog_id() != DIALOG_NONE;
u32 intangible = (gMarioState->action & ACT_FLAG_INTANGIBLE) != 0; u32 intangible = (gMarioState->action & ACT_FLAG_INTANGIBLE) != 0;
u32 firstPerson = gMarioState->action == ACT_FIRST_PERSON; u32 firstPerson = gMarioState->action == ACT_FIRST_PERSON;
@ -299,7 +299,7 @@ void stub_level_update_1(void) {
void load_level_init_text(u32 arg) { void load_level_init_text(u32 arg) {
s32 gotAchievement; s32 gotAchievement;
u32 dialogID = gCurrentArea->dialog[arg]; s32 dialogID = gCurrentArea->dialog[arg];
if (dialogID == gBehaviorValues.dialogs.VanishCourseDialog) { if (dialogID == gBehaviorValues.dialogs.VanishCourseDialog) {
gotAchievement = save_file_get_flags() & SAVE_FLAG_HAVE_VANISH_CAP; gotAchievement = save_file_get_flags() & SAVE_FLAG_HAVE_VANISH_CAP;

View file

@ -2063,9 +2063,9 @@ s32 execute_mario_action(UNUSED struct Object *o) {
// don't update mario when in a cutscene // don't update mario when in a cutscene
if (gMarioState->playerIndex == 0) { if (gMarioState->playerIndex == 0) {
extern s16 gDialogID; extern s32 gDialogID;
if (gMarioState->freeze > 0) { gMarioState->freeze--; } 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; } if (gMarioState->freeze < 2 && sCurrPlayMode == PLAY_MODE_PAUSED) { gMarioState->freeze = 2; }
} }

View file

@ -238,7 +238,7 @@ s32 geo_switch_peach_eyes(s32 run, struct GraphNode *node, UNUSED s32 a2) {
// unused // unused
static void stub_is_textbox_active(u16 *a0) { static void stub_is_textbox_active(u16 *a0) {
if (get_dialog_id() == -1) { if (get_dialog_id() == DIALOG_NONE) {
*a0 = 0; *a0 = 0;
} }
} }
@ -576,7 +576,7 @@ s32 act_reading_automatic_dialog(struct MarioState *m) {
} }
} }
} else if (m->actionState == 10) { // wait until dialog is done } 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->playerIndex != 0 && m->dialogId != 0)) {
m->actionState--; m->actionState--;
} }

View file

@ -139,7 +139,7 @@ static void toad_message_talking(void) {
gCurrentObject->oToadMessageRecentlyTalked = TRUE; gCurrentObject->oToadMessageRecentlyTalked = TRUE;
gCurrentObject->oToadMessageState = TOAD_MESSAGE_FADING; gCurrentObject->oToadMessageState = TOAD_MESSAGE_FADING;
u32 dialogId = gCurrentObject->oToadMessageDialogId; s32 dialogId = gCurrentObject->oToadMessageDialogId;
if (dialogId == TOAD_STAR_1_DIALOG) { if (dialogId == TOAD_STAR_1_DIALOG) {
gCurrentObject->oToadMessageDialogId = TOAD_STAR_1_DIALOG_AFTER; gCurrentObject->oToadMessageDialogId = TOAD_STAR_1_DIALOG_AFTER;
bhv_spawn_star_no_level_exit(gMarioStates[0].marioObj, 0, TRUE); bhv_spawn_star_no_level_exit(gMarioStates[0].marioObj, 0, TRUE);

View file

@ -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. * 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 (!o) { return 0; }
if (!m || !inDialog) { return 0; } if (!m || !inDialog) { return 0; }
s16 dialogueResponse; s16 dialogueResponse;

View file

@ -40,7 +40,7 @@ void bhv_bobomb_loop(void);
void bhv_bobomb_fuse_smoke_init(void); void bhv_bobomb_fuse_smoke_init(void);
void bhv_bobomb_buddy_init(void); void bhv_bobomb_buddy_init(void);
void bobomb_buddy_act_idle(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_talk(void);
void bobomb_buddy_act_turn_to_talk(void); void bobomb_buddy_act_turn_to_talk(void);
void bobomb_buddy_actions(void); void bobomb_buddy_actions(void);

View file

@ -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 * If the player declines the race, then disable time stop and allow Mario to
* move again. * 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); 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) { if (dialogResponse == 2) {

View file

@ -3184,7 +3184,7 @@ s32 cur_obj_update_dialog(struct MarioState* m, s32 actionArg, s32 dialogFlags,
cur_obj_end_dialog(m, dialogFlags, gDialogResponse); cur_obj_end_dialog(m, dialogFlags, gDialogResponse);
} }
} else if (dialogFlags & DIALOG_UNK1_FLAG_DEFAULT) { } 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); cur_obj_end_dialog(m, dialogFlags, 3);
} }
} else { } else {

View file

@ -57,7 +57,6 @@ extern u8* main_hud_camera_lut[6];
extern const Gfx dl_draw_text_bg_box[]; extern const Gfx dl_draw_text_bg_box[];
extern const Gfx dl_draw_triangle[]; extern const Gfx dl_draw_triangle[];
extern const u8* seg2_dialog_original[]; extern const u8* seg2_dialog_original[];
extern void *seg2_dialog_table[];
extern const Gfx dl_billboard_num_0[]; extern const Gfx dl_billboard_num_0[];
extern const Gfx dl_billboard_num_1[]; extern const Gfx dl_billboard_num_1[];
extern const Gfx dl_billboard_num_2[]; extern const Gfx dl_billboard_num_2[];

99
src/pc/dialog_table.c Normal file
View file

@ -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 <stdlib.h>
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;
}

23
src/pc/dialog_table.h Normal file
View file

@ -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

View file

@ -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) }, { "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] = { static struct LuaObjectField sDialogEntryFields[LUA_DIALOG_ENTRY_FIELD_COUNT] = {
{ "leftOffset", LVT_S16, offsetof(struct DialogEntry, leftOffset), true, LOT_NONE, 1, sizeof(s16) }, { "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) }, { "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*) }, { "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) }, { "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) }, { "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*) }, { "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) }, { "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) }, { "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) }, { "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) }, { "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) }, { "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) }, { "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) }, { "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) }, { "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) }, { "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) }, { "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 // { "oToxBoxMovementPattern", LVT_???, offsetof(struct Object, oToxBoxMovementPattern), false, LOT_???, 1, sizeof(void*) }, <--- UNIMPLEMENTED

View file

@ -1267,6 +1267,7 @@ char gSmluaConstants[] = ""
"L_MOUSE_BUTTON=MOUSE_BUTTON_1\n" "L_MOUSE_BUTTON=MOUSE_BUTTON_1\n"
"M_MOUSE_BUTTON=MOUSE_BUTTON_2\n" "M_MOUSE_BUTTON=MOUSE_BUTTON_2\n"
"R_MOUSE_BUTTON=MOUSE_BUTTON_3\n" "R_MOUSE_BUTTON=MOUSE_BUTTON_3\n"
"DIALOG_NONE=-1\n"
"DIALOG_000=0\n" "DIALOG_000=0\n"
"DIALOG_001=1\n" "DIALOG_001=1\n"
"DIALOG_002=2\n" "DIALOG_002=2\n"
@ -1737,21 +1738,21 @@ char gSmluaConstants[] = ""
"MARIO_SPAWN_PIPE=3\n" "MARIO_SPAWN_PIPE=3\n"
"MARIO_SPAWN_TELEPORT=4\n" "MARIO_SPAWN_TELEPORT=4\n"
"MARIO_SPAWN_INSTANT_ACTIVE=0x10\n" "MARIO_SPAWN_INSTANT_ACTIVE=0x10\n"
"MARIO_SPAWN_SWIMMING=((MARIO_SPAWN_INSTANT_ACTIVE ) + 1)\n" "MARIO_SPAWN_SWIMMING=17\n"
"MARIO_SPAWN_AIRBORNE=((MARIO_SPAWN_INSTANT_ACTIVE ) + 2)\n" "MARIO_SPAWN_AIRBORNE=18\n"
"MARIO_SPAWN_HARD_AIR_KNOCKBACK=((MARIO_SPAWN_INSTANT_ACTIVE ) + 3)\n" "MARIO_SPAWN_HARD_AIR_KNOCKBACK=19\n"
"MARIO_SPAWN_SPIN_AIRBORNE_CIRCLE=((MARIO_SPAWN_INSTANT_ACTIVE ) + 4)\n" "MARIO_SPAWN_SPIN_AIRBORNE_CIRCLE=20\n"
"MARIO_SPAWN_DEATH=((MARIO_SPAWN_INSTANT_ACTIVE ) + 5)\n" "MARIO_SPAWN_DEATH=21\n"
"MARIO_SPAWN_SPIN_AIRBORNE=((MARIO_SPAWN_INSTANT_ACTIVE ) + 6)\n" "MARIO_SPAWN_SPIN_AIRBORNE=22\n"
"MARIO_SPAWN_FLYING=((MARIO_SPAWN_INSTANT_ACTIVE ) + 7)\n" "MARIO_SPAWN_FLYING=23\n"
"MARIO_SPAWN_PAINTING_STAR_COLLECT=0x20\n" "MARIO_SPAWN_PAINTING_STAR_COLLECT=0x20\n"
"MARIO_SPAWN_PAINTING_DEATH=((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 1)\n" "MARIO_SPAWN_PAINTING_DEATH=33\n"
"MARIO_SPAWN_AIRBORNE_STAR_COLLECT=((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 2)\n" "MARIO_SPAWN_AIRBORNE_STAR_COLLECT=34\n"
"MARIO_SPAWN_AIRBORNE_DEATH=((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 3)\n" "MARIO_SPAWN_AIRBORNE_DEATH=35\n"
"MARIO_SPAWN_LAUNCH_STAR_COLLECT=((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 4)\n" "MARIO_SPAWN_LAUNCH_STAR_COLLECT=36\n"
"MARIO_SPAWN_LAUNCH_DEATH=((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 5)\n" "MARIO_SPAWN_LAUNCH_DEATH=37\n"
"MARIO_SPAWN_UNUSED_38=((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 6)\n" "MARIO_SPAWN_UNUSED_38=38\n"
"MARIO_SPAWN_FADE_FROM_BLACK=((MARIO_SPAWN_PAINTING_STAR_COLLECT ) + 7)\n" "MARIO_SPAWN_FADE_FROM_BLACK=39\n"
"MARIO_SPAWN_UNKNOWN_02=0x02\n" "MARIO_SPAWN_UNKNOWN_02=0x02\n"
"MARIO_SPAWN_UNKNOWN_03=0x03\n" "MARIO_SPAWN_UNKNOWN_03=0x03\n"
"MARIO_SPAWN_UNKNOWN_27=0x27\n" "MARIO_SPAWN_UNKNOWN_27=0x27\n"

View file

@ -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; } 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); 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; } 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; } 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)); 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; 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; } if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "play_dialog_sound"); return 0; }
play_dialog_sound(dialogID); play_dialog_sound(dialogID);
@ -13935,7 +13935,7 @@ int smlua_func_create_dialog_box(lua_State* L) {
return 0; 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; } if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "create_dialog_box"); return 0; }
create_dialog_box(dialog); create_dialog_box(dialog);
@ -13952,7 +13952,7 @@ int smlua_func_create_dialog_box_with_var(lua_State* L) {
return 0; 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; } 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); 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; } 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; 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; } if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "create_dialog_inverted_box"); return 0; }
create_dialog_inverted_box(dialog); create_dialog_inverted_box(dialog);
@ -13988,7 +13988,7 @@ int smlua_func_create_dialog_box_with_response(lua_State* L) {
return 0; 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; } 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); create_dialog_box_with_response(dialog);
@ -35273,6 +35273,23 @@ int smlua_func_smlua_text_utils_dialog_replace(lua_State* L) {
return 1; 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) { int smlua_func_smlua_text_utils_dialog_is_replaced(lua_State* L) {
if (L == NULL) { return 0; } if (L == NULL) { return 0; }
@ -35290,6 +35307,21 @@ int smlua_func_smlua_text_utils_dialog_is_replaced(lua_State* L) {
return 1; 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) { int smlua_func_smlua_text_utils_course_acts_replace(lua_State* L) {
if (L == NULL) { return 0; } 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_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_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_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_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_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_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); smlua_bind_function(L, "smlua_text_utils_course_name_replace", smlua_func_smlua_text_utils_course_name_replace);

View file

@ -85,7 +85,7 @@ bool djui_is_playerlist_ping_visible(void);
/* |description|Gets the current state of the dialog box|descriptionEnd| */ /* |description|Gets the current state of the dialog box|descriptionEnd| */
s8 get_dialog_box_state(void); s8 get_dialog_box_state(void);
/* |description|Gets the current dialog box ID|descriptionEnd| */ /* |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| */ /* |description|Gets if the last objective collected was a star (0) or a key (1)|descriptionEnd| */
u8 get_last_star_or_key(void); u8 get_last_star_or_key(void);

View file

@ -10,14 +10,13 @@
#include "../smlua.h" #include "../smlua.h"
#include "smlua_level_utils.h" #include "smlua_level_utils.h"
#include "smlua_text_utils.h" #include "smlua_text_utils.h"
#include "pc/dialog_table.h"
#ifdef VERSION_EU #ifdef VERSION_EU
extern s32 gInGameLanguage; extern s32 gInGameLanguage;
#include "eu_translation.h" #include "eu_translation.h"
#endif #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)) #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[]; 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); size_t len = measure_converted_sm64_string(dialog->str);
char* asciiStr = malloc(len + 1); char* asciiStr = malloc(len + 1);
if (!asciiStr) return NULL; if (!asciiStr) { return NULL; }
convert_string_sm64_to_ascii(asciiStr, dialog->str); convert_string_sm64_to_ascii(asciiStr, dialog->str);
@ -86,6 +85,7 @@ static bool sSmluaTextUtilsInited = false;
// Save all vanilla act names and course names // Save all vanilla act names and course names
void smlua_text_utils_init(void) { void smlua_text_utils_init(void) {
dialog_table_init();
memset(gReplacedCourseActNameTable, 0, sizeof(gReplacedCourseActNameTable)); memset(gReplacedCourseActNameTable, 0, sizeof(gReplacedCourseActNameTable));
// Vanilla courses // 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; 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 smlua_text_utils_reset_all(void) {
void **dialogTable = NULL; dialog_table_reset();
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;
}
if (sSmluaTextUtilsInited) { if (sSmluaTextUtilsInited) {
for (s16 courseNum = 0; courseNum < COURSE_END; courseNum++) { 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); smlua_text_utils_reset_course_or_act_name(actName);
} }
} }
} else {
dialog_table_shutdown();
} }
} }
struct DialogEntry* smlua_text_utils_dialog_get(enum DialogId dialogId) { struct DialogEntry* smlua_text_utils_dialog_get(enum DialogId dialogId) {
if (dialogId >= DIALOG_COUNT) { return NULL; } 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 #ifdef VERSION_EU
switch (gInGameLanguage) { switch (gInGameLanguage) {
case LANGUAGE_ENGLISH: case LANGUAGE_ENGLISH:
dialogTable = segmented_to_virtual(dialog_table_eu_en); dialogTableOrg = segmented_to_virtual(dialog_table_eu_en_original);
break; break;
case LANGUAGE_FRENCH: case LANGUAGE_FRENCH:
dialogTable = segmented_to_virtual(dialog_table_eu_fr); dialogTableOrg = segmented_to_virtual(dialog_table_eu_fr_original);
break; break;
case LANGUAGE_GERMAN: case LANGUAGE_GERMAN:
dialogTable = segmented_to_virtual(dialog_table_eu_de); dialogTableOrg = segmented_to_virtual(dialog_table_eu_de_original);
break; break;
} }
#else #else
dialogTable = segmented_to_virtual(seg2_dialog_table); dialogTableOrg = segmented_to_virtual(seg2_dialog_original);
#endif #endif
struct DialogEntry *dialog = segmented_to_virtual(dialogTable[dialogId]); return segmented_to_virtual(dialogTableOrg[dialogId]);
return dialog;
} }
void smlua_text_utils_dialog_replace(enum DialogId dialogId, UNUSED u32 unused, s8 linesPerBox, s16 leftOffset, s16 width, const char* str) { 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); struct DialogEntry *dialog = smlua_text_utils_dialog_get(dialogId);
if (!dialog) { return; } if (!dialog) { return; }
if (sReplacedDialog[dialogId]) { if (dialog->replaced) {
free((u8*)dialog->str); free((u8*)dialog->str);
} }
@ -279,16 +245,41 @@ void smlua_text_utils_dialog_replace(enum DialogId dialogId, UNUSED u32 unused,
dialog->width = width; dialog->width = width;
dialog->str = smlua_text_utils_convert(str); dialog->str = smlua_text_utils_convert(str);
dialog->text = strdup(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) { bool smlua_text_utils_dialog_is_replaced(enum DialogId dialogId) {
if (dialogId >= DIALOG_COUNT) { if (!IS_VALID_DIALOG(dialogId)) { return false; }
return false;
struct DialogEntry *dialog = dialog_table_get(dialogId);
return dialog->replaced;
} }
return sReplacedDialog[dialogId]; s32 smlua_text_utils_allocate_dialog(void) {
s32 dialogId;
struct DialogEntry* dialog = dialog_table_alloc(&dialogId);
if (dialog) {
dialog->replaced = true;
}
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) { 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) {

View file

@ -3,6 +3,7 @@
#include "types.h" #include "types.h"
#include "dialog_ids.h" #include "dialog_ids.h"
#include "game/ingame_menu.h"
#define MAX_ACTS 6 #define MAX_ACTS 6
#define MAX_ACTS_AND_100_COINS 7 #define MAX_ACTS_AND_100_COINS 7
@ -26,16 +27,23 @@ struct CourseActNames {
extern struct CourseActNames gReplacedCourseActNameTable[]; // indexed by COURSE_* constants 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_init(void);
void smlua_text_utils_shutdown(void); void smlua_text_utils_shutdown(void);
/* |description|Resets every modified dialog back to vanilla|descriptionEnd|*/ /* |description|Resets every modified dialog back to vanilla|descriptionEnd|*/
void smlua_text_utils_reset_all(void); void smlua_text_utils_reset_all(void);
/* |description|Gets the DialogEntry struct for the given `dialogId`|descriptionEnd| */ /* |description|Gets the DialogEntry struct for the given `dialogId`|descriptionEnd| */
struct DialogEntry* smlua_text_utils_dialog_get(enum DialogId dialogId); 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| */ /* |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); 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| */ /* |description|Returns whether the dialog with the given ID has been replaced|descriptionEnd| */
bool smlua_text_utils_dialog_is_replaced(enum DialogId dialogId); 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| */ /* |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); 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| */ /* |description|Replaces the secret star course name of `courseNum` with `courseName`|descriptionEnd| */

View file

@ -77,7 +77,7 @@ struct PacketPlayerData {
u8 areaSyncValid; u8 areaSyncValid;
u8 knockbackTimer; u8 knockbackTimer;
s16 dialogId; s32 dialogId;
}; };
#pragma pack() #pragma pack()

View file

@ -52,7 +52,6 @@
#include "pc/djui/djui_lua_profiler.h" #include "pc/djui/djui_lua_profiler.h"
#include "pc/debuglog.h" #include "pc/debuglog.h"
#include "pc/utils/misc.h" #include "pc/utils/misc.h"
#include "pc/mods/mods.h" #include "pc/mods/mods.h"
#include "debug_context.h" #include "debug_context.h"

View file

@ -9,15 +9,7 @@
#undef DEFINE_DIALOG #undef DEFINE_DIALOG
#define DEFINE_DIALOG(id, unused, linesPerBox, leftOffset, width, _) \ #define DEFINE_DIALOG(id, unused, linesPerBox, leftOffset, width, _) \
static const struct DialogEntry dialog_entry_orig_ ## id = { \ static const struct DialogEntry dialog_entry_orig_ ## id = { \
unused, linesPerBox, leftOffset, width, dialog_text_ ## id, NULL \ unused, linesPerBox, leftOffset, width, dialog_text_ ## id, NULL, false \
};
#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 \
}; };
#include "dialogs.h" #include "dialogs.h"
@ -31,12 +23,6 @@ const struct DialogEntry *const seg2_dialog_original[] = {
}; };
#undef DEFINE_DIALOG #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 == // == courses ==
// (defines en_course_name_table etc.) // (defines en_course_name_table etc.)