Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
.public GetNotifyNote
.public GetPartyMembers
.public LoadScriptVariableRaw
.public LoadScriptVariableValue
.public MemcpySimple
.public RandInt
.public SCRIPT_VARS_VALUES
Expand Down
130 changes: 1 addition & 129 deletions asm/main_0204B4EC.s → asm/main_0204B678.s
Original file line number Diff line number Diff line change
@@ -1,136 +1,8 @@
.include "asm/macros.inc"
.include "main_0204B4EC.inc"
.include "main_0204B678.inc"

.text

arm_func_start LoadScriptVariableValue
LoadScriptVariableValue: ; 0x0204B4EC
stmdb sp!, {r4, lr}
sub sp, sp, #8
mov r2, r0
mov r4, r1
mov r1, r2
add r0, sp, #0
mov r2, r4
bl LoadScriptVariableRaw
ldr r1, [sp]
ldrsh r0, [r1]
cmp r0, #9
addls pc, pc, r0, lsl #2
b _0204B66C
_0204B520: ; jump table
b _0204B66C ; case 0
b _0204B548 ; case 1
b _0204B56C ; case 2
b _0204B56C ; case 3
b _0204B578 ; case 4
b _0204B584 ; case 5
b _0204B590 ; case 6
b _0204B59C ; case 7
b _0204B59C ; case 8
b _0204B5A8 ; case 9
_0204B548:
ldrsh r1, [r1, #6]
ldr r2, [sp, #4]
mov r0, #1
mov r1, r0, lsl r1
ldrb r2, [r2]
and r1, r1, #0xff
tst r2, r1
moveq r0, #0
b _0204B670
_0204B56C:
ldr r0, [sp, #4]
ldrb r0, [r0]
b _0204B670
_0204B578:
ldr r0, [sp, #4]
ldrsb r0, [r0]
b _0204B670
_0204B584:
ldr r0, [sp, #4]
ldrh r0, [r0]
b _0204B670
_0204B590:
ldr r0, [sp, #4]
ldrsh r0, [r0]
b _0204B670
_0204B59C:
ldr r0, [sp, #4]
ldr r0, [r0]
b _0204B670
_0204B5A8:
cmp r4, #0x48
bgt _0204B5E4
bge _0204B62C
cmp r4, #0x3d
bgt _0204B5D8
subs r0, r4, #0x3a
addpl pc, pc, r0, lsl #2
b _0204B66C
_0204B5C8: ; jump table
b _0204B600 ; case 0
b _0204B608 ; case 1
b _0204B614 ; case 2
b _0204B61C ; case 3
_0204B5D8:
cmp r4, #0x47
beq _0204B624
b _0204B66C
_0204B5E4:
cmp r4, #0x49
bgt _0204B5F4
beq _0204B634
b _0204B66C
_0204B5F4:
cmp r4, #0x70
beq _0204B664
b _0204B66C
_0204B600:
mov r0, #1
b _0204B670
_0204B608:
mov r0, #0
bl GetPartyMembers
b _0204B670
_0204B614:
bl GetMoneyCarried
b _0204B670
_0204B61C:
bl GetMoneyStored
b _0204B670
_0204B624:
bl GetLanguageType
b _0204B670
_0204B62C:
bl GetGameMode
b _0204B670
_0204B634:
bl GetGameMode
cmp r0, #1
beq _0204B64C
cmp r0, #3
beq _0204B654
b _0204B65C
_0204B64C:
bl sub_0204C918
b _0204B670
_0204B654:
bl GetSpecialEpisodeType
b _0204B670
_0204B65C:
mvn r0, #0
b _0204B670
_0204B664:
bl GetNotifyNote
b _0204B670
_0204B66C:
mov r0, #0
_0204B670:
add sp, sp, #8
ldmia sp!, {r4, pc}
arm_func_end LoadScriptVariableValue

arm_func_start LoadScriptVariableValueAtIndex
LoadScriptVariableValueAtIndex: ; 0x0204B678
stmdb sp!, {r3, r4, r5, lr}
Expand Down
52 changes: 50 additions & 2 deletions include/enums.h
Original file line number Diff line number Diff line change
Expand Up @@ -2961,8 +2961,56 @@ enum dungeon_restriction_flags {
// Remaining flags are unused
};

enum script_variables {
PLAYED_OLD_GAME = 0x6f
enum script_var_type {
VARTYPE_NONE = 0,
VARTYPE_BIT = 1,
// VARTYPE_STRING is an array of characters, and implementation-wise are treated exactly the
// same way as VARTYPE_UINT8
VARTYPE_STRING = 2,
VARTYPE_UINT8 = 3,
VARTYPE_INT8 = 4,
VARTYPE_UINT16 = 5,
VARTYPE_INT16 = 6,
VARTYPE_UINT32 = 7,
VARTYPE_INT32 = 8,
VARTYPE_SPECIAL = 9,
// This dummy value ensures compilation that matches the original assembly.
// Without it, the compiler reads the enum using ldrb instead of ldrsh
VARTYPE_DUMMY_PADDING = 256
};

enum script_var_id {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might as well bring over the whole enum since it is known.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see the rest of this enum yet. Did something go wrong with the commits?

VAR_FRIEND_SUM = 58,
VAR_UNIT_SUM = 59,
// The amount of money the player has on hand.
VAR_CARRY_GOLD = 60,
// The amount of money stored in Duskull Bank.
VAR_BANK_GOLD = 61,
// The language determined by the NDS firmware. Notably checked in some scripts to display
// different backgrounds or objects, such as in the intro.
// 0: Japanese
// 1: English
// 2: French
// 3: German
// 4: Italian
// 5: Spanish
PLAYED_OLD_GAME = 0x6f,
VAR_LANGUAGE_TYPE = 71,
// A value to distinguish the type of game being played. This mainly differentiates between maingame and Special Episodes, and the game
// checks for this value in numerous places (not necessarily in scripts) to differentiate
// maingame versus Special Episode behavior.
VAR_GAME_MODE = 72,
// Used to distinguish which Special Episode is currently being played.
VAR_EXECUTE_SPECIAL_EPISODE_TYPE = 73,
VAR_NOTE_MODIFY_FLAG = 112,
};

enum special_episode_type {
EPISODE_BIDOOFS_WISH = 0,
EPISODE_IGGLYBUFF_THE_PRODIGY = 1,
EPISODE_TODAYS_OH_MY_GOSH = 2,
EPISODE_HERE_COMES_TEAM_CHARM = 3,
EPISODE_IN_THE_FUTURE_OF_DARKNESS = 4,
};

#endif //PMDSKY_ENUMS_H
44 changes: 22 additions & 22 deletions include/scripting.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,37 @@
#include "enums.h"
#include "util.h"

struct script_var_definition {
s16 p1;
s16 p2;
s16 value_offset; // offset within SCRIPT_VAR_VALUES, or local script var values.
s16 p4;
s16 p5;
s16 p6;
s16 p7;
s16 p8;
struct script_var_def {
enum script_var_type type; // 0x0: type of data contained in this script variable
u16 field_0x1; // 0x2
// 0x4: value's offset into struct script_var_value_table, if type != VARTYPE_SPECIAL
s16 mem_offset;
s16 bitshift; // 0x6: bit position if type == VARTYPE_BIT
u16 n_values; // 0x8: number of values (>1 means this variable is an array)
// 0xA: 0 for every variable except VAR_VERSION, which has a default value of 1.
s16 default_val;
char* name; // 0xC: variable name
};

struct script_var_local_value {
u32 p1;
};

struct script_var_global_value {
u8 p1;
union script_var_value {
u8 u8;
u16 u16;
u32 u32;
s8 s8;
s16 s16;
};

struct script_var_raw {
struct script_var_definition* def;
union {
struct script_var_local_value* local;
struct script_var_global_value* global;
} value;
struct script_var_def* def;
union script_var_value *value;
};

const short LOCAL_SCRIPT_VAR_OFFSET = 0x400;

void LoadScriptVariableRaw(struct script_var_raw* sv_raw,
struct script_var_local_value sv_locals[],
const enum script_variables sv_id);
union script_var_value sv_val_local[],
const enum script_var_id sv_id);

s32 LoadScriptVariableValue(union script_var_value sv_local[], enum script_var_id sv_id);

#endif //PMDSKY_SCRIPTING_H
2 changes: 1 addition & 1 deletion main.lsf
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ Static main
Object src/main_0204AFF8.o
Object asm/main_0204B018.o
Object src/scripting.o
Object asm/main_0204B4EC.o
Object asm/main_0204B678.o
Object src/dungeon_recruitment_3.o
Object asm/main_0204CA94.o
Object src/main_0204DA2C.o
Expand Down
89 changes: 79 additions & 10 deletions src/scripting.c
Original file line number Diff line number Diff line change
@@ -1,22 +1,91 @@
#include "enums.h"
#include "scripting.h"

// Global script variable definitions
extern struct script_var_def SCRIPT_VARS[];
// Local script variable definitions
extern struct script_var_def SCRIPT_VARS_LOCALS[];
// Global script variable values
extern u8 SCRIPT_VARS_VALUES[];

extern struct script_var_definition SCRIPT_VARS[];
extern struct script_var_definition SCRIPT_VARS_LOCALS[];
extern struct script_var_global_value SCRIPT_VARS_VALUES[];
extern s32 GetPartyMembers(s32 param1);
extern s32 GetMoneyCarried();
extern s32 GetMoneyStored();
extern s32 GetLanguageType();
extern s32 GetGameMode();
extern s32 sub_0204C918();
extern s32 GetSpecialEpisodeType();
extern s32 GetNotifyNote();

void LoadScriptVariableRaw(struct script_var_raw* sv_raw,
struct script_var_local_value sv_locals[],
const enum script_variables sv_id)
{
union script_var_value sv_val_local[],
const enum script_var_id sv_id) {
if (sv_id < LOCAL_SCRIPT_VAR_OFFSET) {
// script var is global
// global script var
sv_raw->def = &SCRIPT_VARS[sv_id];
sv_raw->value.global = &SCRIPT_VARS_VALUES[sv_raw->def->value_offset];
sv_raw->value = (union script_var_value*)
&SCRIPT_VARS_VALUES[sv_raw->def->mem_offset];
} else {
// script var is local
// local script var
sv_raw->def = &SCRIPT_VARS_LOCALS[sv_id - LOCAL_SCRIPT_VAR_OFFSET];
sv_raw->value.local = &sv_locals[sv_raw->def->value_offset];
sv_raw->value = &sv_val_local[sv_raw->def->mem_offset];
}
}

s32 LoadScriptVariableValue(union script_var_value sv_local[], enum script_var_id sv_id)
{
struct script_var_raw result;
LoadScriptVariableRaw(&result, sv_local, sv_id);

switch((s16)result.def->type) {
case VARTYPE_NONE:
break;
case VARTYPE_BIT:
// Return true if the value has a particular bit set
if(result.value->u8 & (u8)(1 << result.def->bitshift)) {
return TRUE;
}
return FALSE;
case VARTYPE_STRING:
case VARTYPE_UINT8:
return result.value->u8;
case VARTYPE_INT8:
return result.value->s8;
case VARTYPE_UINT16:
return result.value->u16;
case VARTYPE_INT16:
return result.value->s16;
case VARTYPE_UINT32:
case VARTYPE_INT32:
return result.value->u32;
case VARTYPE_SPECIAL:
switch(sv_id) {
case VAR_FRIEND_SUM:
return 1;
case VAR_UNIT_SUM:
return GetPartyMembers(0);
case VAR_CARRY_GOLD:
return GetMoneyCarried();
case VAR_BANK_GOLD:
return GetMoneyStored();
case VAR_LANGUAGE_TYPE:
return GetLanguageType();
case VAR_GAME_MODE:
return GetGameMode();
case VAR_EXECUTE_SPECIAL_EPISODE_TYPE:
switch(GetGameMode()) {
case EPISODE_IGGLYBUFF_THE_PRODIGY:
return sub_0204C918();
case EPISODE_HERE_COMES_TEAM_CHARM:
return GetSpecialEpisodeType();
default:
return -1;
}
case VAR_NOTE_MODIFY_FLAG:
return GetNotifyNote();
}
}

return 0;
}