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 = []
set_to = None
set_to_val = None
index = 0
fields = val.split(',')
for field in fields:
@ -210,13 +211,24 @@ 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:
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

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/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" ],

View file

@ -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": [ "*" ],
}

View file

@ -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`
@ -3491,21 +3493,21 @@ MARIO_SPAWN_IDLE = 2 -
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_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 = ((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_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`

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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:](#)

View file

@ -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
<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)
### Description
@ -7277,6 +7300,27 @@ Returns whether the dialog with the given ID has been replaced
<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)
### Description

View file

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

View file

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

View file

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

View file

@ -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[];

View file

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

View file

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

View file

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

View file

@ -4,6 +4,7 @@
#include <PR/ultratypes.h>
#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| */

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
* 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;

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_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 },

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

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

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 *gfx;
if (get_dialog_id() != -1) {
if (get_dialog_id() != DIALOG_NONE) {
return NULL;
}

View file

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

View file

@ -2,6 +2,7 @@
#define INGAME_MENU_H
#include <PR/ultratypes.h>
#include <stdbool.h>
#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|

View file

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

View file

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

View file

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

View file

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

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.
*/
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;

View file

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

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
* 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) {

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);
}
} 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 {

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_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[];

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) },
};
#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

View file

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

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; }
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);

View file

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

View file

@ -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* 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;
}
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) {

View file

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

View file

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

View file

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

View file

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