mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-29 07:23:01 +00:00
Merge branch 'unstable' of github.com:sm64ex-coop-dev/sm64ex-coop into unstable
This commit is contained in:
commit
2d85ba5a35
21 changed files with 821 additions and 150 deletions
|
@ -3198,6 +3198,9 @@ GEO_CONTEXT_RENDER = 1
|
|||
--- @type integer
|
||||
GFX_NUM_MASTER_LISTS = 8
|
||||
|
||||
--- @type integer
|
||||
GRAPH_EXTRA_FORCE_3D = (1 << 0)
|
||||
|
||||
--- @type integer
|
||||
GRAPH_NODE_TYPE_400 = 0x400
|
||||
|
||||
|
|
|
@ -3860,6 +3860,47 @@ function get_level_name(courseNum, levelNum, areaIndex)
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @param courseNum integer
|
||||
--- @param levelNum integer
|
||||
--- @param areaIndex integer
|
||||
--- @param charCase integer
|
||||
--- @return string
|
||||
function get_level_name_ascii(courseNum, levelNum, areaIndex, charCase)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param courseNum integer
|
||||
--- @param levelNum integer
|
||||
--- @param areaIndex integer
|
||||
--- @param charCase integer
|
||||
--- @return Pointer_integer
|
||||
function get_level_name_sm64(courseNum, levelNum, areaIndex, charCase)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param courseNum integer
|
||||
--- @param starNum integer
|
||||
--- @return string
|
||||
function get_star_name(courseNum, starNum)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param courseNum integer
|
||||
--- @param starNum integer
|
||||
--- @param charCase integer
|
||||
--- @return string
|
||||
function get_star_name_ascii(courseNum, starNum, charCase)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param courseNum integer
|
||||
--- @param starNum integer
|
||||
--- @param charCase integer
|
||||
--- @return Pointer_integer
|
||||
function get_star_name_sm64(courseNum, starNum, charCase)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param m MarioState
|
||||
--- @return nil
|
||||
function adjust_sound_for_speed(m)
|
||||
|
@ -7149,6 +7190,16 @@ function movtexqc_register(name, level, area, type)
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @param transType integer
|
||||
--- @param time integer
|
||||
--- @param red integer
|
||||
--- @param green integer
|
||||
--- @param blue integer
|
||||
--- @return nil
|
||||
function play_transition(transType, time, red, green, blue)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param usingBackupSlot boolean
|
||||
--- @return nil
|
||||
function save_file_set_using_backup_slot(usingBackupSlot)
|
||||
|
@ -7211,6 +7262,12 @@ function obj_check_hitbox_overlap(o1, o2)
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @param behaviorId BehaviorId
|
||||
--- @return integer
|
||||
function obj_count_objects_with_behavior_id(behaviorId)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param objList ObjectList
|
||||
--- @return Object
|
||||
function obj_get_first(objList)
|
||||
|
@ -7239,6 +7296,13 @@ function obj_get_first_with_behavior_id_and_field_s32(behaviorId, fieldIndex, va
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @param o Object
|
||||
--- @param behaviorId BehaviorId
|
||||
--- @return Object
|
||||
function obj_get_nearest_object_with_behavior_id(o, behaviorId)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param o Object
|
||||
--- @return Object
|
||||
function obj_get_next(o)
|
||||
|
|
|
@ -488,6 +488,7 @@
|
|||
|
||||
--- @class GraphNode
|
||||
--- @field public children GraphNode
|
||||
--- @field public extraFlags integer
|
||||
--- @field public flags integer
|
||||
--- @field public next GraphNode
|
||||
--- @field public parent GraphNode
|
||||
|
|
|
@ -1058,6 +1058,7 @@
|
|||
- GEO_CONTEXT_HELD_OBJ
|
||||
- GEO_CONTEXT_RENDER
|
||||
- GFX_NUM_MASTER_LISTS
|
||||
- GRAPH_EXTRA_FORCE_3D
|
||||
- GRAPH_NODE_TYPE_400
|
||||
- GRAPH_NODE_TYPE_ANIMATED_PART
|
||||
- GRAPH_NODE_TYPE_BACKGROUND
|
||||
|
|
|
@ -2924,6 +2924,117 @@
|
|||
|
||||
<br />
|
||||
|
||||
## [get_level_name_ascii](#get_level_name_ascii)
|
||||
|
||||
### Lua Example
|
||||
`local stringValue = get_level_name_ascii(courseNum, levelNum, areaIndex, charCase)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| courseNum | `integer` |
|
||||
| levelNum | `integer` |
|
||||
| areaIndex | `integer` |
|
||||
| charCase | `integer` |
|
||||
|
||||
### Returns
|
||||
- `string`
|
||||
|
||||
### C Prototype
|
||||
`const char *get_level_name_ascii(s16 courseNum, s16 levelNum, s16 areaIndex, s16 charCase);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [get_level_name_sm64](#get_level_name_sm64)
|
||||
|
||||
### Lua Example
|
||||
`local PointerValue = get_level_name_sm64(courseNum, levelNum, areaIndex, charCase)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| courseNum | `integer` |
|
||||
| levelNum | `integer` |
|
||||
| areaIndex | `integer` |
|
||||
| charCase | `integer` |
|
||||
|
||||
### Returns
|
||||
- `Pointer` <`integer`>
|
||||
|
||||
### C Prototype
|
||||
`const u8 *get_level_name_sm64(s16 courseNum, s16 levelNum, s16 areaIndex, s16 charCase);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [get_star_name](#get_star_name)
|
||||
|
||||
### Lua Example
|
||||
`local stringValue = get_star_name(courseNum, starNum)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| courseNum | `integer` |
|
||||
| starNum | `integer` |
|
||||
|
||||
### Returns
|
||||
- `string`
|
||||
|
||||
### C Prototype
|
||||
`const char *get_star_name(s16 courseNum, s16 starNum);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [get_star_name_ascii](#get_star_name_ascii)
|
||||
|
||||
### Lua Example
|
||||
`local stringValue = get_star_name_ascii(courseNum, starNum, charCase)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| courseNum | `integer` |
|
||||
| starNum | `integer` |
|
||||
| charCase | `integer` |
|
||||
|
||||
### Returns
|
||||
- `string`
|
||||
|
||||
### C Prototype
|
||||
`const char *get_star_name_ascii(s16 courseNum, s16 starNum, s16 charCase);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [get_star_name_sm64](#get_star_name_sm64)
|
||||
|
||||
### Lua Example
|
||||
`local PointerValue = get_star_name_sm64(courseNum, starNum, charCase)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| courseNum | `integer` |
|
||||
| starNum | `integer` |
|
||||
| charCase | `integer` |
|
||||
|
||||
### Returns
|
||||
- `Pointer` <`integer`>
|
||||
|
||||
### C Prototype
|
||||
`const u8 *get_star_name_sm64(s16 courseNum, s16 starNum, s16 charCase);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
---
|
||||
# functions from mario.h
|
||||
|
||||
|
|
|
@ -4919,6 +4919,30 @@
|
|||
|
||||
<br />
|
||||
|
||||
## [play_transition](#play_transition)
|
||||
|
||||
### Lua Example
|
||||
`play_transition(transType, time, red, green, blue)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| transType | `integer` |
|
||||
| time | `integer` |
|
||||
| red | `integer` |
|
||||
| green | `integer` |
|
||||
| blue | `integer` |
|
||||
|
||||
### Returns
|
||||
- None
|
||||
|
||||
### C Prototype
|
||||
`void play_transition(s16 transType, s16 time, u8 red, u8 green, u8 blue);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [save_file_set_using_backup_slot](#save_file_set_using_backup_slot)
|
||||
|
||||
### Lua Example
|
||||
|
@ -5131,6 +5155,26 @@
|
|||
|
||||
<br />
|
||||
|
||||
## [obj_count_objects_with_behavior_id](#obj_count_objects_with_behavior_id)
|
||||
|
||||
### Lua Example
|
||||
`local integerValue = obj_count_objects_with_behavior_id(behaviorId)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) |
|
||||
|
||||
### Returns
|
||||
- `integer`
|
||||
|
||||
### C Prototype
|
||||
`s32 obj_count_objects_with_behavior_id(enum BehaviorId behaviorId);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [obj_get_first](#obj_get_first)
|
||||
|
||||
### Lua Example
|
||||
|
@ -5215,6 +5259,27 @@
|
|||
|
||||
<br />
|
||||
|
||||
## [obj_get_nearest_object_with_behavior_id](#obj_get_nearest_object_with_behavior_id)
|
||||
|
||||
### Lua Example
|
||||
`local ObjectValue = obj_get_nearest_object_with_behavior_id(o, behaviorId)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| o | [Object](structs.md#Object) |
|
||||
| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) |
|
||||
|
||||
### Returns
|
||||
[Object](structs.md#Object)
|
||||
|
||||
### C Prototype
|
||||
`struct Object *obj_get_nearest_object_with_behavior_id(struct Object *o, enum BehaviorId behaviorId);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [obj_get_next](#obj_get_next)
|
||||
|
||||
### Lua Example
|
||||
|
|
|
@ -759,6 +759,11 @@
|
|||
|
||||
- level_info.h
|
||||
- [get_level_name](functions-3.md#get_level_name)
|
||||
- [get_level_name_ascii](functions-3.md#get_level_name_ascii)
|
||||
- [get_level_name_sm64](functions-3.md#get_level_name_sm64)
|
||||
- [get_star_name](functions-3.md#get_star_name)
|
||||
- [get_star_name_ascii](functions-3.md#get_star_name_ascii)
|
||||
- [get_star_name_sm64](functions-3.md#get_star_name_sm64)
|
||||
|
||||
<br />
|
||||
|
||||
|
@ -1339,6 +1344,7 @@
|
|||
- [hud_hide](functions-4.md#hud_hide)
|
||||
- [hud_show](functions-4.md#hud_show)
|
||||
- [movtexqc_register](functions-4.md#movtexqc_register)
|
||||
- [play_transition](functions-4.md#play_transition)
|
||||
- [save_file_set_using_backup_slot](functions-4.md#save_file_set_using_backup_slot)
|
||||
- [set_environment_region](functions-4.md#set_environment_region)
|
||||
- [warp_exit_level](functions-4.md#warp_exit_level)
|
||||
|
@ -1357,10 +1363,12 @@
|
|||
- [get_temp_object_hitbox](functions-4.md#get_temp_object_hitbox)
|
||||
- [get_trajectory](functions-4.md#get_trajectory)
|
||||
- [obj_check_hitbox_overlap](functions-4.md#obj_check_hitbox_overlap)
|
||||
- [obj_count_objects_with_behavior_id](functions-4.md#obj_count_objects_with_behavior_id)
|
||||
- [obj_get_first](functions-4.md#obj_get_first)
|
||||
- [obj_get_first_with_behavior_id](functions-4.md#obj_get_first_with_behavior_id)
|
||||
- [obj_get_first_with_behavior_id_and_field_f32](functions-4.md#obj_get_first_with_behavior_id_and_field_f32)
|
||||
- [obj_get_first_with_behavior_id_and_field_s32](functions-4.md#obj_get_first_with_behavior_id_and_field_s32)
|
||||
- [obj_get_nearest_object_with_behavior_id](functions-4.md#obj_get_nearest_object_with_behavior_id)
|
||||
- [obj_get_next](functions-4.md#obj_get_next)
|
||||
- [obj_get_next_with_same_behavior_id](functions-4.md#obj_get_next_with_same_behavior_id)
|
||||
- [obj_get_next_with_same_behavior_id_and_field_f32](functions-4.md#obj_get_next_with_same_behavior_id_and_field_f32)
|
||||
|
|
|
@ -709,6 +709,7 @@
|
|||
| Field | Type | Access |
|
||||
| ----- | ---- | ------ |
|
||||
| children | [GraphNode](structs.md#GraphNode) | |
|
||||
| extraFlags | `integer` | |
|
||||
| flags | `integer` | |
|
||||
| next | [GraphNode](structs.md#GraphNode) | |
|
||||
| parent | [GraphNode](structs.md#GraphNode) | |
|
||||
|
|
|
@ -803,7 +803,10 @@ void create_next_audio_buffer(s16 *samples, u32 num_samples) {
|
|||
/**
|
||||
* Called from threads: thread5_game_loop
|
||||
*/
|
||||
extern f32 *smlua_get_vec3f_for_play_sound(f32 *pos);
|
||||
|
||||
void play_sound(s32 soundBits, f32 *pos) {
|
||||
pos = smlua_get_vec3f_for_play_sound(pos);
|
||||
sSoundRequests[sSoundRequestCount].soundBits = soundBits;
|
||||
sSoundRequests[sSoundRequestCount].position = pos;
|
||||
sSoundRequests[sSoundRequestCount].customFreqScale = 0;
|
||||
|
@ -811,6 +814,7 @@ void play_sound(s32 soundBits, f32 *pos) {
|
|||
}
|
||||
|
||||
void play_sound_with_freq_scale(s32 soundBits, f32* pos, f32 freqScale) {
|
||||
pos = smlua_get_vec3f_for_play_sound(pos);
|
||||
sSoundRequests[sSoundRequestCount].soundBits = soundBits;
|
||||
sSoundRequests[sSoundRequestCount].position = pos;
|
||||
sSoundRequests[sSoundRequestCount].customFreqScale = freqScale;
|
||||
|
|
|
@ -7,150 +7,283 @@
|
|||
#include "level_table.h"
|
||||
#include "types.h"
|
||||
|
||||
extern u8* seg2_course_name_table[];
|
||||
#ifdef VERSION_EU
|
||||
extern u8 *course_name_table_eu_en[];
|
||||
extern u8 *course_name_table_eu_fr[];
|
||||
extern u8 *course_name_table_eu_de[];
|
||||
extern u8 *act_name_table_eu_en[];
|
||||
extern u8 *act_name_table_eu_fr[];
|
||||
extern u8 *act_name_table_eu_de[];
|
||||
#else
|
||||
extern u8 *seg2_course_name_table[];
|
||||
extern u8 *seg2_act_name_table[];
|
||||
#endif
|
||||
|
||||
static const char charset[0xFF + 1] = {
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 7
|
||||
' ', ' ', 'a', 'b', 'c', 'd', 'e', 'f', // 15
|
||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', // 23
|
||||
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', // 31
|
||||
'w', 'x', 'y', 'z', ' ', ' ', ' ', ' ', // 39
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 49
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 55
|
||||
' ', ' ', ' ', ' ', ' ', ' ', '\'', ' ', // 63
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 71
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 79
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 87
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 95
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 103
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ',', // 111
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 119
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 127
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 135
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 143
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 151
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', '-', // 159
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 167
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 175
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 183
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 192
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 199
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 207
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 215
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 223
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 231
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 239
|
||||
' ', ' ', '!', ' ', ' ', ' ', ' ', ' ', // 247
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' // 255
|
||||
static const struct { const char *str; u8 c; } sSm64CharMap[] = {
|
||||
|
||||
// Digits
|
||||
{ "0", 0x00 }, { "1", 0x01 }, { "2", 0x02 }, { "3", 0x03 }, { "4", 0x04 },
|
||||
{ "5", 0x05 }, { "6", 0x06 }, { "7", 0x07 }, { "8", 0x08 }, { "9", 0x09 },
|
||||
|
||||
// Capital letters
|
||||
{ "A", 0x0A }, { "B", 0x0B }, { "C", 0x0C }, { "D", 0x0D }, { "E", 0x0E },
|
||||
{ "F", 0x0F }, { "G", 0x10 }, { "H", 0x11 }, { "I", 0x12 }, { "J", 0x13 },
|
||||
{ "K", 0x14 }, { "L", 0x15 }, { "M", 0x16 }, { "N", 0x17 }, { "O", 0x18 },
|
||||
{ "P", 0x19 }, { "Q", 0x1A }, { "R", 0x1B }, { "S", 0x1C }, { "T", 0x1D },
|
||||
{ "U", 0x1E }, { "V", 0x1F }, { "W", 0x20 }, { "X", 0x21 }, { "Y", 0x22 },
|
||||
{ "Z", 0x23 },
|
||||
|
||||
// Letters
|
||||
{ "a", 0x24 }, { "b", 0x25 }, { "c", 0x26 }, { "d", 0x27 }, { "e", 0x28 },
|
||||
{ "f", 0x29 }, { "g", 0x2A }, { "h", 0x2B }, { "i", 0x2C }, { "j", 0x2D },
|
||||
{ "k", 0x2E }, { "l", 0x2F }, { "m", 0x30 }, { "n", 0x31 }, { "o", 0x32 },
|
||||
{ "p", 0x33 }, { "q", 0x34 }, { "r", 0x35 }, { "s", 0x36 }, { "t", 0x37 },
|
||||
{ "u", 0x38 }, { "v", 0x39 }, { "w", 0x3A }, { "x", 0x3B }, { "y", 0x3C },
|
||||
{ "z", 0x3D },
|
||||
|
||||
// Punctuation
|
||||
{ "...", 0xE6 }, // ellipsis
|
||||
{ ")(", 0xE2 }, // close-open parentheses
|
||||
{ "<<", 0xF5 }, // double quote open
|
||||
{ ">>", 0xF6 }, // double quote close
|
||||
{ "\'", 0x3E }, // apostrophe
|
||||
{ ".", 0x3F }, // period
|
||||
{ ",", 0x6F }, // comma
|
||||
{ " ", 0x9E }, // space
|
||||
{ "-", 0x9F }, // dash
|
||||
{ "(", 0xE1 }, // open parentheses
|
||||
{ ")", 0xE3 }, // close parentheses
|
||||
{ "&", 0xE5 }, // ampersand
|
||||
{ "!", 0xF2 }, // exclamation mark
|
||||
{ "%", 0xF3 }, // percent
|
||||
{ "?", 0xF4 }, // question mark
|
||||
{ "~", 0xF7 }, // tilde
|
||||
|
||||
// Symbols
|
||||
{ "[A]", 0x54 }, // bold A
|
||||
{ "[B]", 0x55 }, // bold B
|
||||
{ "[C]", 0x56 }, // bold C
|
||||
{ "[Z]", 0x57 }, // bold Z
|
||||
{ "[R]", 0x58 }, // bold R
|
||||
{ "<->", 0xE4 }, // left-right arrow
|
||||
{ "^", 0x50 }, // up arrow
|
||||
{ "|", 0x51 }, // down arrow
|
||||
{ "<", 0x52 }, // left arrow
|
||||
{ ">", 0x53 }, // right arrow
|
||||
{ "+", 0xF9 }, // coin
|
||||
{ "@", 0xFA }, // star filled
|
||||
{ "*", 0xFB }, // multiply
|
||||
{ "$", 0xFD }, // star empty
|
||||
{ "\n", 0xFE }, // New line
|
||||
{ NULL, 0xFF }, // Null terminator
|
||||
};
|
||||
|
||||
static void convert_string(const u8* str, char* output) {
|
||||
s32 strPos = 0;
|
||||
bool capitalizeChar = true;
|
||||
static const char *ascii_to_sm64_char(u8 *str64, const char *strAscii) {
|
||||
for (s32 i = 0; sSm64CharMap[i].str != NULL; ++i) {
|
||||
if (strstr(strAscii, sSm64CharMap[i].str) == strAscii) {
|
||||
*str64 = sSm64CharMap[i].c;
|
||||
return strAscii + strlen(sSm64CharMap[i].str);
|
||||
}
|
||||
}
|
||||
*str64 = 0x9E;
|
||||
return strAscii + 1;
|
||||
}
|
||||
|
||||
while (str[strPos] != 0xFF) {
|
||||
if (str[strPos] < 0xFF) {
|
||||
output[strPos] = charset[str[strPos]];
|
||||
static char *sm64_to_ascii_char(char *strAscii, const u8 *str64) {
|
||||
for (s32 i = 0; sSm64CharMap[i].str != NULL; ++i) {
|
||||
if (sSm64CharMap[i].c == *str64) {
|
||||
s32 l = strlen(sSm64CharMap[i].str);
|
||||
memcpy(strAscii, sSm64CharMap[i].str, l);
|
||||
return strAscii + l;
|
||||
}
|
||||
}
|
||||
*strAscii = ' ';
|
||||
return strAscii + 1;
|
||||
}
|
||||
|
||||
// if the char is a letter we can capatalize it
|
||||
if (capitalizeChar && 0x0A <= str[strPos] && str[strPos] <= 0x23) {
|
||||
output[strPos] -= ('a' - 'A');
|
||||
capitalizeChar = false;
|
||||
static void convert_string_ascii_to_sm64(u8 *str64, const char *strAscii) {
|
||||
for (; *strAscii != 0; str64++) {
|
||||
strAscii = ascii_to_sm64_char(str64, strAscii);
|
||||
}
|
||||
*str64 = 0xFF;
|
||||
}
|
||||
|
||||
static void convert_string_sm64_to_ascii(char *strAscii, const u8 *str64) {
|
||||
for (; *str64 != 0xFF; str64++) {
|
||||
strAscii = sm64_to_ascii_char(strAscii, str64);
|
||||
}
|
||||
*strAscii = 0;
|
||||
}
|
||||
|
||||
static void capitalize_string_ascii(char *strAscii) {
|
||||
for (; *strAscii != 0; strAscii++) {
|
||||
if (*strAscii >= 'a' && *strAscii <= 'z') {
|
||||
*strAscii += ('A' - 'a');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void capitalize_string_sm64(u8 *str64) {
|
||||
for (; *str64 != 0xFF; str64++) {
|
||||
if (*str64 >= 0x24 && *str64 <= 0x3D) {
|
||||
*str64 -= 26;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void decapitalize_string_ascii(char *strAscii) {
|
||||
for (bool decap = false; *strAscii != 0; strAscii++) {
|
||||
if (*strAscii >= 'A' && *strAscii <= 'Z') {
|
||||
if (decap) {
|
||||
*strAscii += ('a' - 'A');
|
||||
} else {
|
||||
decap = true;
|
||||
}
|
||||
} else if (*strAscii < '0' && *strAscii != '\'') {
|
||||
decap = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void decapitalize_string_sm64(u8 *str64) {
|
||||
for (bool decap = false; *str64 != 0xFF; str64++) {
|
||||
if (*str64 >= 0x0A && *str64 <= 0x23) {
|
||||
if (decap) {
|
||||
*str64 += 26;
|
||||
} else {
|
||||
decap = true;
|
||||
}
|
||||
} else if (*str64 >= 0x3F) {
|
||||
decap = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char *get_level_name_ascii(s16 courseNum, s16 levelNum, s16 areaIndex, s16 charCase) {
|
||||
static char output[256];
|
||||
|
||||
// Valid course: BOB to RR, Bowser stages and Secret courses
|
||||
// There is no course name for Cake Ending, make it defaults to "Peach's Castle"
|
||||
if (courseNum >= COURSE_MIN && courseNum < COURSE_MAX) {
|
||||
void **courseNameTbl = NULL;
|
||||
#ifdef VERSION_EU
|
||||
switch (gInGameLanguage) {
|
||||
case LANGUAGE_ENGLISH: courseNameTbl = segmented_to_virtual(course_name_table_eu_en); break;
|
||||
case LANGUAGE_FRENCH: courseNameTbl = segmented_to_virtual(course_name_table_eu_fr); break;
|
||||
case LANGUAGE_GERMAN: courseNameTbl = segmented_to_virtual(course_name_table_eu_de); break;
|
||||
}
|
||||
#else
|
||||
courseNameTbl = segmented_to_virtual(seg2_course_name_table);
|
||||
#endif
|
||||
const u8 *courseName = segmented_to_virtual(courseNameTbl[courseNum - COURSE_BOB]);
|
||||
convert_string_sm64_to_ascii(output, courseName + 3);
|
||||
}
|
||||
|
||||
// Castle level
|
||||
else if (courseNum == COURSE_NONE) {
|
||||
switch (levelNum) {
|
||||
case LEVEL_CASTLE: {
|
||||
switch (areaIndex) {
|
||||
case 1: snprintf(output, 256, "Castle Main Floor"); break;
|
||||
case 2: snprintf(output, 256, "Castle Upper Floor"); break;
|
||||
case 3: snprintf(output, 256, "Castle Basement"); break;
|
||||
default: snprintf(output, 256, "Castle Purgatory"); break;
|
||||
}
|
||||
} break;
|
||||
case LEVEL_CASTLE_GROUNDS: snprintf(output, 256, "Castle Grounds"); break;
|
||||
case LEVEL_CASTLE_COURTYARD: snprintf(output, 256, "Castle Courtyard"); break;
|
||||
default: snprintf(output, 256, "Peach's Castle");
|
||||
}
|
||||
}
|
||||
|
||||
// Default
|
||||
else {
|
||||
output[strPos] = ' ';
|
||||
snprintf(output, 256, "Peach's Castle");
|
||||
}
|
||||
|
||||
// decide if the next character should be capitalized
|
||||
switch (output[strPos]) {
|
||||
case ' ':
|
||||
//if (str[strPos] != 158)
|
||||
//fprintf(stdout, "Unknown Character (%i)\n", str[strPos]); // inform that an unknown char was found
|
||||
case '-':
|
||||
capitalizeChar = true;
|
||||
break;
|
||||
default:
|
||||
capitalizeChar = false;
|
||||
break;
|
||||
// Capitalize or decapitalize text
|
||||
if (charCase == -1) {
|
||||
decapitalize_string_ascii(output);
|
||||
} else if (charCase == +1) {
|
||||
capitalize_string_ascii(output);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
strPos++;
|
||||
}
|
||||
|
||||
output[strPos] = '\0';
|
||||
const u8 *get_level_name_sm64(s16 courseNum, s16 levelNum, s16 areaIndex, s16 charCase) {
|
||||
static u8 output[256];
|
||||
const char *levelName = get_level_name_ascii(courseNum, levelNum, areaIndex, charCase);
|
||||
convert_string_ascii_to_sm64(output, levelName);
|
||||
return output;
|
||||
}
|
||||
|
||||
const char *get_level_name(s16 courseNum, s16 levelNum, s16 areaIndex) {
|
||||
static char stage[188] = { 0 };
|
||||
|
||||
//printf("get_level_name: %i %i %i, COURSE_MAX: %u COURSE_MIN: %u.\n", courseNum, levelNum, areaIndex, COURSE_MAX, COURSE_MIN);
|
||||
|
||||
// Overrides for non-course based locations.
|
||||
if (courseNum == COURSE_NONE) {
|
||||
// A switch case is much more effective here
|
||||
// then a if statement, It allows for the
|
||||
// same results for a different level much easier.
|
||||
// It also auto-covers if none of the cases match
|
||||
// with a default.
|
||||
switch (levelNum) {
|
||||
case LEVEL_CASTLE_GROUNDS:
|
||||
strcpy(stage, "Castle Grounds");
|
||||
break;
|
||||
case LEVEL_CASTLE:
|
||||
// Switch case inside a switch case,
|
||||
// I think it looks ugly but it works.
|
||||
switch (areaIndex) {
|
||||
case 1:
|
||||
strcpy(stage, "Castle Main Floor");
|
||||
break;
|
||||
case 2:
|
||||
strcpy(stage, "Castle Upper Floor");
|
||||
break;
|
||||
case 3:
|
||||
strcpy(stage, "Castle Basement");
|
||||
break;
|
||||
default: // If we don't have a proper corresponding area, We return the default.
|
||||
strcpy(stage, "Castle Purgatory");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case LEVEL_CASTLE_COURTYARD:
|
||||
strcpy(stage, "Castle Courtyard");
|
||||
break;
|
||||
default: // If we don't have a proper corresponding level, We return the default.
|
||||
strcpy(stage, "Peach's Castle");
|
||||
break;
|
||||
}
|
||||
return stage;
|
||||
}
|
||||
|
||||
// If we are in in Course 0 we are in the castle which doesn't have a string.
|
||||
if (COURSE_IS_VALID_COURSE(courseNum)) {
|
||||
void **courseNameTbl = NULL;
|
||||
|
||||
#ifndef VERSION_EU
|
||||
courseNameTbl = segmented_to_virtual(seg2_course_name_table);
|
||||
#else
|
||||
switch (gInGameLanguage) {
|
||||
case LANGUAGE_ENGLISH:
|
||||
courseNameTbl = segmented_to_virtual(course_name_table_eu_en);
|
||||
break;
|
||||
case LANGUAGE_FRENCH:
|
||||
courseNameTbl = segmented_to_virtual(course_name_table_eu_fr);
|
||||
break;
|
||||
case LANGUAGE_GERMAN:
|
||||
courseNameTbl = segmented_to_virtual(course_name_table_eu_de);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
u8 *courseName = segmented_to_virtual(courseNameTbl[courseNum - 1]);
|
||||
|
||||
convert_string(&courseName[3], stage);
|
||||
} else {
|
||||
strcpy(stage, "Peach's Castle");
|
||||
}
|
||||
|
||||
return stage;
|
||||
return get_level_name_ascii(courseNum, levelNum, areaIndex, -1);
|
||||
}
|
||||
|
||||
const char *get_star_name_ascii(s16 courseNum, s16 starNum, s16 charCase) {
|
||||
static char output[256];
|
||||
|
||||
// Main courses: BOB to RR
|
||||
if (COURSE_IS_MAIN_COURSE(courseNum)) {
|
||||
if (starNum >= 1 && starNum <= 6) {
|
||||
void **actNameTable = NULL;
|
||||
#ifdef VERSION_EU
|
||||
switch (gInGameLanguage) {
|
||||
case LANGUAGE_ENGLISH: actNameTable = segmented_to_virtual(act_name_table_eu_en); break;
|
||||
case LANGUAGE_FRENCH: actNameTable = segmented_to_virtual(act_name_table_eu_fr); break;
|
||||
case LANGUAGE_GERMAN: actNameTable = segmented_to_virtual(act_name_table_eu_de); break;
|
||||
}
|
||||
#else
|
||||
actNameTable = segmented_to_virtual(seg2_act_name_table);
|
||||
#endif
|
||||
const u8 *starName = segmented_to_virtual(actNameTable[(courseNum - COURSE_BOB) * 6 + (starNum - 1)]);
|
||||
convert_string_sm64_to_ascii(output, starName);
|
||||
} else if (starNum == 7) {
|
||||
snprintf(output, 256, "100 Coins Star");
|
||||
} else {
|
||||
snprintf(output, 256, "A Secret Star!");
|
||||
}
|
||||
}
|
||||
|
||||
// Castle stars: Toads' and Mips'
|
||||
else if (courseNum == COURSE_NONE) {
|
||||
switch (starNum) {
|
||||
case 1: snprintf(output, 256, "Toad Star 1"); break;
|
||||
case 2: snprintf(output, 256, "Toad Star 2"); break;
|
||||
case 3: snprintf(output, 256, "Toad Star 3"); break;
|
||||
case 4: snprintf(output, 256, "Mips Star 1"); break;
|
||||
case 5: snprintf(output, 256, "Mips Star 2"); break;
|
||||
default: snprintf(output, 256, "A Secret Star!");
|
||||
}
|
||||
}
|
||||
|
||||
// Bonus courses: Bowser stages and Secret courses
|
||||
else if (courseNum <= COURSE_MAX) {
|
||||
snprintf(output, 256, "Star %d", starNum);
|
||||
}
|
||||
|
||||
// Default
|
||||
else {
|
||||
snprintf(output, 256, "A Secret Star!");
|
||||
}
|
||||
|
||||
// Capitalize or decapitalize text
|
||||
if (charCase == -1) {
|
||||
decapitalize_string_ascii(output);
|
||||
} else if (charCase == +1) {
|
||||
capitalize_string_ascii(output);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
const u8 *get_star_name_sm64(s16 courseNum, s16 starNum, s16 charCase) {
|
||||
static u8 output[256];
|
||||
const char *starName = get_star_name_ascii(courseNum, starNum, charCase);
|
||||
convert_string_ascii_to_sm64(output, starName);
|
||||
return output;
|
||||
}
|
||||
|
||||
const char *get_star_name(s16 courseNum, s16 starNum) {
|
||||
return get_star_name_ascii(courseNum, starNum, -1);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,11 @@
|
|||
|
||||
#include <PR/ultratypes.h>
|
||||
|
||||
const char *get_level_name_ascii(s16 courseNum, s16 levelNum, s16 areaIndex, s16 charCase);
|
||||
const u8 *get_level_name_sm64(s16 courseNum, s16 levelNum, s16 areaIndex, s16 charCase);
|
||||
const char *get_level_name(s16 courseNum, s16 levelNum, s16 areaIndex);
|
||||
const char *get_star_name_ascii(s16 courseNum, s16 starNum, s16 charCase);
|
||||
const u8 *get_star_name_sm64(s16 courseNum, s16 starNum, s16 charCase);
|
||||
const char *get_star_name(s16 courseNum, s16 starNum);
|
||||
|
||||
#endif // LEVEL_INFO_H
|
||||
|
|
|
@ -929,7 +929,7 @@ static void bubbled_offset_visual(struct MarioState* m) {
|
|||
}
|
||||
|
||||
s32 act_bubbled(struct MarioState* m) {
|
||||
if (m->playerIndex == 0) {
|
||||
if (m->playerIndex == 0 && m->area->camera->mode == CAMERA_MODE_WATER_SURFACE) {
|
||||
set_camera_mode(m->area->camera, CAMERA_MODE_FREE_ROAM, 1);
|
||||
}
|
||||
struct MarioState* targetMarioState = nearest_mario_state_to_object(m->marioObj);
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "game/level_update.h"
|
||||
#include "pc/lua/smlua_hooks.h"
|
||||
#include "pc/utils/misc.h"
|
||||
#include "pc/debuglog.h"
|
||||
|
||||
/**
|
||||
* This file contains the code that processes the scene graph for rendering.
|
||||
|
@ -264,7 +265,7 @@ void patch_mtx_interpolated(f32 delta) {
|
|||
static u8 increment_mat_stack() {
|
||||
Mtx *mtx = alloc_display_list(sizeof(*mtx));
|
||||
Mtx *mtxPrev = alloc_display_list(sizeof(*mtxPrev));
|
||||
if (mtx == NULL || mtxPrev == NULL) { return FALSE; }
|
||||
if (mtx == NULL || mtxPrev == NULL) { LOG_ERROR("Failed to allocate our matrices for the matrix stack."); return FALSE; }
|
||||
|
||||
gMatStackIndex++;
|
||||
mtxf_to_mtx(mtx, gMatStack[gMatStackIndex]);
|
||||
|
@ -460,7 +461,7 @@ static void geo_process_camera(struct GraphNodeCamera *node) {
|
|||
Mat4 cameraTransform;
|
||||
|
||||
// Sanity check our stack index, If we above or equal to our stack size. Return to prevent OOB.
|
||||
if (gMatStackIndex >= MATRIX_STACK_SIZE) { return; }
|
||||
if (gMatStackIndex >= MATRIX_STACK_SIZE) { LOG_ERROR("Preventing attempt to exceed the maximum size %i for our matrix stack with size of %i.", MATRIX_STACK_SIZE - 1, gMatStackIndex); return; }
|
||||
|
||||
Mtx *rollMtx = alloc_display_list(sizeof(*rollMtx));
|
||||
if (rollMtx == NULL) { return; }
|
||||
|
@ -511,7 +512,7 @@ static void geo_process_translation_rotation(struct GraphNodeTranslationRotation
|
|||
Vec3f translation;
|
||||
|
||||
// Sanity check our stack index, If we above or equal to our stack size. Return top prevent OOB.
|
||||
if (gMatStackIndex >= MATRIX_STACK_SIZE) { return; }
|
||||
if (gMatStackIndex >= MATRIX_STACK_SIZE) { LOG_ERROR("Preventing attempt to exceed the maximum size %i for our matrix stack with size of %i.", MATRIX_STACK_SIZE - 1, gMatStackIndex); return; }
|
||||
|
||||
vec3s_to_vec3f(translation, node->translation);
|
||||
mtxf_rotate_zxy_and_translate(mtxf, translation, node->rotation);
|
||||
|
@ -540,7 +541,7 @@ static void geo_process_translation(struct GraphNodeTranslation *node) {
|
|||
Vec3f translation;
|
||||
|
||||
// Sanity check our stack index, If we above or equal to our stack size. Return top prevent OOB.
|
||||
if (gMatStackIndex >= MATRIX_STACK_SIZE) { return; }
|
||||
if (gMatStackIndex >= MATRIX_STACK_SIZE) { LOG_ERROR("Preventing attempt to exceed the maximum size %i for our matrix stack with size of %i.", MATRIX_STACK_SIZE - 1, gMatStackIndex); return; }
|
||||
|
||||
vec3s_to_vec3f(translation, node->translation);
|
||||
mtxf_rotate_zxy_and_translate(mtxf, translation, gVec3sZero);
|
||||
|
@ -568,7 +569,7 @@ static void geo_process_rotation(struct GraphNodeRotation *node) {
|
|||
Mat4 mtxf;
|
||||
|
||||
// Sanity check our stack index, If we above or equal to our stack size. Return top prevent OOB.
|
||||
if (gMatStackIndex >= MATRIX_STACK_SIZE) { return; }
|
||||
if (gMatStackIndex >= MATRIX_STACK_SIZE) { LOG_ERROR("Preventing attempt to exceed the maximum size %i for our matrix stack with size of %i.", MATRIX_STACK_SIZE - 1, gMatStackIndex); return; }
|
||||
|
||||
mtxf_rotate_zxy_and_translate(mtxf, gVec3fZero, node->rotation);
|
||||
mtxf_mul(gMatStack[gMatStackIndex + 1], mtxf, gMatStack[gMatStackIndex]);
|
||||
|
@ -604,7 +605,7 @@ static void geo_process_scale(struct GraphNodeScale *node) {
|
|||
Vec3f prevScaleVec;
|
||||
|
||||
// Sanity check our stack index, If we above or equal to our stack size. Return top prevent OOB.
|
||||
if (gMatStackIndex >= MATRIX_STACK_SIZE) { return; }
|
||||
if (gMatStackIndex >= MATRIX_STACK_SIZE) { LOG_ERROR("Preventing attempt to exceed the maximum size %i for our matrix stack with size of %i.", MATRIX_STACK_SIZE - 1, gMatStackIndex); return; }
|
||||
|
||||
vec3f_set(scaleVec, node->scale, node->scale, node->scale);
|
||||
mtxf_scale_vec3f(gMatStack[gMatStackIndex + 1], gMatStack[gMatStackIndex], scaleVec);
|
||||
|
@ -635,7 +636,7 @@ static void geo_process_billboard(struct GraphNodeBillboard *node) {
|
|||
Vec3f translation;
|
||||
|
||||
// Sanity check our stack index, If we above or equal to our stack size. Return top prevent OOB.
|
||||
if (gMatStackIndex >= MATRIX_STACK_SIZE) { return; }
|
||||
if (gMatStackIndex >= MATRIX_STACK_SIZE) { LOG_ERROR("Preventing attempt to exceed the maximum size %i for our matrix stack with size of %i.", MATRIX_STACK_SIZE - 1, gMatStackIndex); return; }
|
||||
|
||||
s16 nextMatStackIndex = gMatStackIndex + 1;
|
||||
|
||||
|
@ -654,6 +655,8 @@ static void geo_process_billboard(struct GraphNodeBillboard *node) {
|
|||
gCurGraphNodeObject->scale);
|
||||
mtxf_scale_vec3f(gMatStackPrev[nextMatStackIndex], gMatStackPrev[nextMatStackIndex],
|
||||
gCurGraphNodeObject->scale);
|
||||
} else {
|
||||
//LOG_ERROR("gCurGraphNodeObject and gCurGraphNodeHeldObject are both NULL!");
|
||||
}
|
||||
|
||||
// Increment the matrix stack, If we fail to do so. Just return.
|
||||
|
@ -805,7 +808,7 @@ static void geo_process_animated_part(struct GraphNodeAnimatedPart *node) {
|
|||
Vec3f translationPrev;
|
||||
|
||||
// Sanity check our stack index, If we above or equal to our stack size. Return top prevent OOB.
|
||||
if (gMatStackIndex >= MATRIX_STACK_SIZE) { return; }
|
||||
if (gMatStackIndex >= MATRIX_STACK_SIZE) { LOG_ERROR("Preventing attempt to exceed the maximum size %i for our matrix stack with size of %i.", MATRIX_STACK_SIZE - 1, gMatStackIndex); return; }
|
||||
|
||||
u16 *animAttribute = gCurrAnimAttribute;
|
||||
u8 animType = gCurAnimType;
|
||||
|
@ -899,7 +902,7 @@ static void geo_process_shadow(struct GraphNodeShadow *node) {
|
|||
f32 shadowScale;
|
||||
|
||||
// Sanity check our stack index, If we above or equal to our stack size. Return top prevent OOB.
|
||||
if (gMatStackIndex >= MATRIX_STACK_SIZE) { return; }
|
||||
if (gMatStackIndex >= MATRIX_STACK_SIZE) { LOG_ERROR("Preventing attempt to exceed the maximum size %i for our matrix stack with size of %i.", MATRIX_STACK_SIZE - 1, gMatStackIndex); return; }
|
||||
|
||||
if (gCurGraphNodeCamera != NULL && gCurGraphNodeObject != NULL) {
|
||||
if (gCurGraphNodeHeldObject != NULL) {
|
||||
|
@ -1284,7 +1287,7 @@ void geo_process_held_object(struct GraphNodeHeldObject *node) {
|
|||
Vec3f scalePrev;
|
||||
|
||||
// Sanity check our stack index, If we above or equal to our stack size. Return top prevent OOB.
|
||||
if (gMatStackIndex >= MATRIX_STACK_SIZE) { return; }
|
||||
if (gMatStackIndex >= MATRIX_STACK_SIZE) { LOG_ERROR("Preventing attempt to exceed the maximum size %i for our matrix stack with size of %i.", MATRIX_STACK_SIZE - 1, gMatStackIndex); return; }
|
||||
|
||||
#ifdef F3DEX_GBI_2
|
||||
gSPLookAt(gDisplayListHead++, &lookAt);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "chat_commands.h"
|
||||
#include "pc/network/ban_list.h"
|
||||
#include "pc/debuglog.h"
|
||||
#include "level_table.h"
|
||||
|
||||
enum ChatConfirmCommand {
|
||||
CCC_NONE,
|
||||
|
@ -181,6 +182,88 @@ bool exec_chat_command(char* command) {
|
|||
return true;
|
||||
}
|
||||
|
||||
#if defined(DEBUG) && defined(DEVELOPMENT)
|
||||
if (gNetworkSystem == &gNetworkSystemSocket && str_starts_with("/warp ", command)) {
|
||||
static const struct { const char *name; s32 num; } sLevelNumByName[] = {
|
||||
#undef STUB_LEVEL
|
||||
#undef DEFINE_LEVEL
|
||||
#define STUB_LEVEL(...)
|
||||
#define DEFINE_LEVEL(_0, levelnum, _2, levelname, ...) { #levelname, levelnum },
|
||||
#include "levels/level_defines.h"
|
||||
#undef STUB_LEVEL
|
||||
#undef DEFINE_LEVEL
|
||||
};
|
||||
|
||||
// Params
|
||||
char *paramLevel = command + 6;
|
||||
if (*paramLevel == 0 || *paramLevel == ' ') {
|
||||
djui_chat_message_create("Missing parameters: [LEVEL] [AREA] [ACT]");
|
||||
return true;
|
||||
}
|
||||
char *paramArea = strchr(paramLevel, ' ');
|
||||
if (paramArea++ == NULL || *paramArea == 0 || *paramArea == ' ') {
|
||||
djui_chat_message_create("Missing parameters: [AREA] [ACT]");
|
||||
return true;
|
||||
}
|
||||
char *paramAct = strchr(paramArea, ' ');
|
||||
if (paramAct++ == NULL || *paramAct == 0 || *paramAct == ' ') {
|
||||
djui_chat_message_create("Missing parameters: [ACT]");
|
||||
return true;
|
||||
}
|
||||
*(paramArea - 1) = 0;
|
||||
*(paramAct - 1) = 0;
|
||||
|
||||
// Level
|
||||
s32 level = -1;
|
||||
if (sscanf(paramLevel, "%d", &level) <= 0) {
|
||||
for (s32 i = 0; i != (s32) (sizeof(sLevelNumByName) / sizeof(sLevelNumByName[0])); ++i) {
|
||||
if (strstr(paramLevel, sLevelNumByName[i].name) == paramLevel) {
|
||||
level = sLevelNumByName[i].num;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (level == -1) {
|
||||
char message[256];
|
||||
snprintf(message, 256, "Invalid [LEVEL] parameter: %s", paramLevel);
|
||||
djui_chat_message_create(message);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Area
|
||||
s32 area = -1;
|
||||
if (sscanf(paramArea, "%d", &area) <= 0) {
|
||||
char message[256];
|
||||
snprintf(message, 256, "Invalid [AREA] parameter: %s", paramArea);
|
||||
djui_chat_message_create(message);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Act
|
||||
s32 act = -1;
|
||||
if (sscanf(paramAct, "%d", &act) <= 0) {
|
||||
char message[256];
|
||||
snprintf(message, 256, "Invalid [ACT] parameter: %s", paramAct);
|
||||
djui_chat_message_create(message);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Warp
|
||||
if (!dynos_warp_to_level(level, area, act)) {
|
||||
char message[256];
|
||||
snprintf(message, 256, "Unable to warp to: %s %s %s", paramLevel, paramArea, paramAct);
|
||||
djui_chat_message_create(message);
|
||||
return true;
|
||||
}
|
||||
|
||||
// OK
|
||||
char message[256];
|
||||
snprintf(message, 256, "Warping to: %s %s %s...", paramLevel, paramArea, paramAct);
|
||||
djui_chat_message_create(message);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return smlua_call_chat_command_hook(command);
|
||||
}
|
||||
|
||||
|
@ -191,6 +274,9 @@ void display_chat_commands(void) {
|
|||
djui_chat_message_create("/ban [NAME|ID] - Ban this player from the current game");
|
||||
djui_chat_message_create("/permban [NAME|ID] - Ban this player from any game you host");
|
||||
}
|
||||
#if defined(DEBUG) && defined(DEVELOPMENT)
|
||||
djui_chat_message_create("/warp [LEVEL] [AREA] [ACT] - Level can be either a numeric value or a shorthand name");
|
||||
#endif
|
||||
if (sConfirming != CCC_NONE) { djui_chat_message_create("/confirm"); }
|
||||
smlua_display_chat_commands();
|
||||
}
|
|
@ -563,9 +563,10 @@ static struct LuaObjectField sGlobalTexturesFields[LUA_GLOBAL_TEXTURES_FIELD_COU
|
|||
{ "star", LVT_COBJECT, offsetof(struct GlobalTextures, star), true, LOT_TEXTUREINFO },
|
||||
};
|
||||
|
||||
#define LUA_GRAPH_NODE_FIELD_COUNT 6
|
||||
#define LUA_GRAPH_NODE_FIELD_COUNT 7
|
||||
static struct LuaObjectField sGraphNodeFields[LUA_GRAPH_NODE_FIELD_COUNT] = {
|
||||
{ "children", LVT_COBJECT_P, offsetof(struct GraphNode, children), false, LOT_GRAPHNODE },
|
||||
{ "extraFlags", LVT_U8, offsetof(struct GraphNode, extraFlags), false, LOT_NONE },
|
||||
{ "flags", LVT_S16, offsetof(struct GraphNode, flags), false, LOT_NONE },
|
||||
// { "georef", LVT_???, offsetof(struct GraphNode, georef), true, LOT_??? }, <--- UNIMPLEMENTED
|
||||
{ "next", LVT_COBJECT_P, offsetof(struct GraphNode, next), false, LOT_GRAPHNODE },
|
||||
|
|
|
@ -1258,6 +1258,7 @@ char gSmluaConstants[] = ""
|
|||
"GRAPH_RENDER_HAS_ANIMATION = (1 << 5)\n"
|
||||
"GRAPH_RENDER_CYLBOARD = (1 << 6)\n"
|
||||
"GRAPH_RENDER_PLAYER = (1 << 7)\n"
|
||||
"GRAPH_EXTRA_FORCE_3D = (1 << 0)\n"
|
||||
"GRAPH_NODE_TYPE_FUNCTIONAL = 0x100\n"
|
||||
"GRAPH_NODE_TYPE_400 = 0x400\n"
|
||||
"GRAPH_NODE_TYPE_ROOT = 0x001\n"
|
||||
|
|
|
@ -7764,6 +7764,83 @@ int smlua_func_get_level_name(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_get_level_name_ascii(lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 4)) { return 0; }
|
||||
|
||||
s16 courseNum = smlua_to_integer(L, 1);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1"); return 0; }
|
||||
s16 levelNum = smlua_to_integer(L, 2);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 2"); return 0; }
|
||||
s16 areaIndex = smlua_to_integer(L, 3);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 3"); return 0; }
|
||||
s16 charCase = smlua_to_integer(L, 4);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 4"); return 0; }
|
||||
|
||||
lua_pushstring(L, get_level_name_ascii(courseNum, levelNum, areaIndex, charCase));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_get_level_name_sm64(lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 4)) { return 0; }
|
||||
|
||||
s16 courseNum = smlua_to_integer(L, 1);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1"); return 0; }
|
||||
s16 levelNum = smlua_to_integer(L, 2);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 2"); return 0; }
|
||||
s16 areaIndex = smlua_to_integer(L, 3);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 3"); return 0; }
|
||||
s16 charCase = smlua_to_integer(L, 4);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 4"); return 0; }
|
||||
|
||||
smlua_push_pointer(L, LVT_U8_P, (void*)get_level_name_sm64(courseNum, levelNum, areaIndex, charCase));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_get_star_name(lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 2)) { return 0; }
|
||||
|
||||
s16 courseNum = smlua_to_integer(L, 1);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1"); return 0; }
|
||||
s16 starNum = smlua_to_integer(L, 2);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 2"); return 0; }
|
||||
|
||||
lua_pushstring(L, get_star_name(courseNum, starNum));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_get_star_name_ascii(lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 3)) { return 0; }
|
||||
|
||||
s16 courseNum = smlua_to_integer(L, 1);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1"); return 0; }
|
||||
s16 starNum = smlua_to_integer(L, 2);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 2"); return 0; }
|
||||
s16 charCase = smlua_to_integer(L, 3);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 3"); return 0; }
|
||||
|
||||
lua_pushstring(L, get_star_name_ascii(courseNum, starNum, charCase));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_get_star_name_sm64(lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 3)) { return 0; }
|
||||
|
||||
s16 courseNum = smlua_to_integer(L, 1);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1"); return 0; }
|
||||
s16 starNum = smlua_to_integer(L, 2);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 2"); return 0; }
|
||||
s16 charCase = smlua_to_integer(L, 3);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 3"); return 0; }
|
||||
|
||||
smlua_push_pointer(L, LVT_U8_P, (void*)get_star_name_sm64(courseNum, starNum, charCase));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/////////////
|
||||
// mario.h //
|
||||
/////////////
|
||||
|
@ -14727,6 +14804,25 @@ int smlua_func_movtexqc_register(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_play_transition(lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 5)) { return 0; }
|
||||
|
||||
s16 transType = smlua_to_integer(L, 1);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1"); return 0; }
|
||||
s16 time = smlua_to_integer(L, 2);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 2"); return 0; }
|
||||
u8 red = smlua_to_integer(L, 3);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 3"); return 0; }
|
||||
u8 green = smlua_to_integer(L, 4);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 4"); return 0; }
|
||||
u8 blue = smlua_to_integer(L, 5);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 5"); return 0; }
|
||||
|
||||
play_transition(transType, time, red, green, blue);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_save_file_set_using_backup_slot(lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
||||
|
||||
|
@ -14849,6 +14945,17 @@ int smlua_func_obj_check_hitbox_overlap(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_obj_count_objects_with_behavior_id(lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
||||
|
||||
int behaviorId = smlua_to_integer(L, 1);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1"); return 0; }
|
||||
|
||||
lua_pushinteger(L, obj_count_objects_with_behavior_id(behaviorId));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_obj_get_first(lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
||||
|
||||
|
@ -14901,6 +15008,19 @@ int smlua_func_obj_get_first_with_behavior_id_and_field_s32(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_obj_get_nearest_object_with_behavior_id(lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 2)) { return 0; }
|
||||
|
||||
struct Object* o = (struct Object*)smlua_to_cobject(L, 1, LOT_OBJECT);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1"); return 0; }
|
||||
int behaviorId = smlua_to_integer(L, 2);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 2"); return 0; }
|
||||
|
||||
smlua_push_object(L, LOT_OBJECT, obj_get_nearest_object_with_behavior_id(o, behaviorId));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_obj_get_next(lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
||||
|
||||
|
@ -16398,6 +16518,11 @@ void smlua_bind_functions_autogen(void) {
|
|||
|
||||
// level_info.h
|
||||
smlua_bind_function(L, "get_level_name", smlua_func_get_level_name);
|
||||
smlua_bind_function(L, "get_level_name_ascii", smlua_func_get_level_name_ascii);
|
||||
smlua_bind_function(L, "get_level_name_sm64", smlua_func_get_level_name_sm64);
|
||||
smlua_bind_function(L, "get_star_name", smlua_func_get_star_name);
|
||||
smlua_bind_function(L, "get_star_name_ascii", smlua_func_get_star_name_ascii);
|
||||
smlua_bind_function(L, "get_star_name_sm64", smlua_func_get_star_name_sm64);
|
||||
|
||||
// mario.h
|
||||
smlua_bind_function(L, "adjust_sound_for_speed", smlua_func_adjust_sound_for_speed);
|
||||
|
@ -16953,6 +17078,7 @@ void smlua_bind_functions_autogen(void) {
|
|||
smlua_bind_function(L, "hud_hide", smlua_func_hud_hide);
|
||||
smlua_bind_function(L, "hud_show", smlua_func_hud_show);
|
||||
smlua_bind_function(L, "movtexqc_register", smlua_func_movtexqc_register);
|
||||
smlua_bind_function(L, "play_transition", smlua_func_play_transition);
|
||||
smlua_bind_function(L, "save_file_set_using_backup_slot", smlua_func_save_file_set_using_backup_slot);
|
||||
smlua_bind_function(L, "set_environment_region", smlua_func_set_environment_region);
|
||||
smlua_bind_function(L, "warp_exit_level", smlua_func_warp_exit_level);
|
||||
|
@ -16967,10 +17093,12 @@ void smlua_bind_functions_autogen(void) {
|
|||
smlua_bind_function(L, "get_temp_object_hitbox", smlua_func_get_temp_object_hitbox);
|
||||
smlua_bind_function(L, "get_trajectory", smlua_func_get_trajectory);
|
||||
smlua_bind_function(L, "obj_check_hitbox_overlap", smlua_func_obj_check_hitbox_overlap);
|
||||
smlua_bind_function(L, "obj_count_objects_with_behavior_id", smlua_func_obj_count_objects_with_behavior_id);
|
||||
smlua_bind_function(L, "obj_get_first", smlua_func_obj_get_first);
|
||||
smlua_bind_function(L, "obj_get_first_with_behavior_id", smlua_func_obj_get_first_with_behavior_id);
|
||||
smlua_bind_function(L, "obj_get_first_with_behavior_id_and_field_f32", smlua_func_obj_get_first_with_behavior_id_and_field_f32);
|
||||
smlua_bind_function(L, "obj_get_first_with_behavior_id_and_field_s32", smlua_func_obj_get_first_with_behavior_id_and_field_s32);
|
||||
smlua_bind_function(L, "obj_get_nearest_object_with_behavior_id", smlua_func_obj_get_nearest_object_with_behavior_id);
|
||||
smlua_bind_function(L, "obj_get_next", smlua_func_obj_get_next);
|
||||
smlua_bind_function(L, "obj_get_next_with_same_behavior_id", smlua_func_obj_get_next_with_same_behavior_id);
|
||||
smlua_bind_function(L, "obj_get_next_with_same_behavior_id_and_field_f32", smlua_func_obj_get_next_with_same_behavior_id_and_field_f32);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "smlua.h"
|
||||
#include "src/pc/mods/mods.h"
|
||||
#include "audio/external.h"
|
||||
|
||||
u8 gSmLuaConvertSuccess = false;
|
||||
|
||||
|
@ -21,6 +22,21 @@ s16* smlua_get_vec3s_from_buffer(void) {
|
|||
return sVec3sBuffer[sVec3sBufferIndex++];
|
||||
}
|
||||
|
||||
f32 *smlua_get_vec3f_for_play_sound(f32 *pos) {
|
||||
if (pos < (f32 *) sVec3fBuffer || pos >= (f32 *) (sVec3fBuffer + VEC3F_BUFFER_COUNT)) {
|
||||
return pos;
|
||||
}
|
||||
if (memcmp(pos, gGlobalSoundSource, sizeof(Vec3f)) == 0) {
|
||||
return gGlobalSoundSource;
|
||||
}
|
||||
for (s32 i = 0; i != MAX_PLAYERS; ++i) {
|
||||
if (gMarioStates[i].marioObj && memcmp(pos, gMarioStates[i].marioObj->header.gfx.cameraToObject, sizeof(Vec3f)) == 0) {
|
||||
return gMarioStates[i].marioObj->header.gfx.cameraToObject;
|
||||
}
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void smlua_bind_function(lua_State* L, const char* name, void* func) {
|
||||
|
|
|
@ -29,4 +29,6 @@ void movtexqc_register(const char* name, s16 level, s16 area, s16 type);
|
|||
f32 get_environment_region(u8 index);
|
||||
void set_environment_region(u8 index, s32 value);
|
||||
|
||||
void play_transition(s16 transType, s16 time, u8 red, u8 green, u8 blue);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -156,6 +156,40 @@ struct Object *obj_get_first_with_behavior_id_and_field_f32(enum BehaviorId beha
|
|||
return NULL;
|
||||
}
|
||||
|
||||
struct Object *obj_get_nearest_object_with_behavior_id(struct Object *o, enum BehaviorId behaviorId) {
|
||||
f32 minDist = 0x20000;
|
||||
const BehaviorScript *behavior = get_behavior_from_id(behaviorId);
|
||||
struct Object *closestObj = NULL;
|
||||
|
||||
if (behavior) {
|
||||
enum ObjectList objList = get_object_list_from_behavior(behavior);
|
||||
for (struct Object *obj = obj_get_first(objList); obj != NULL; obj = obj_get_next(obj)) {
|
||||
if (obj->behavior == behavior && obj->activeFlags != ACTIVE_FLAG_DEACTIVATED) {
|
||||
f32 objDist = dist_between_objects(o, obj);
|
||||
if (objDist < minDist) {
|
||||
closestObj = obj;
|
||||
minDist = objDist;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return closestObj;
|
||||
}
|
||||
|
||||
s32 obj_count_objects_with_behavior_id(enum BehaviorId behaviorId) {
|
||||
const BehaviorScript *behavior = get_behavior_from_id(behaviorId);
|
||||
s32 count = 0;
|
||||
|
||||
if (behavior) {
|
||||
enum ObjectList objList = get_object_list_from_behavior(behavior);
|
||||
for (struct Object *obj = obj_get_first(objList); obj != NULL; obj = obj_get_next(obj)) {
|
||||
if (obj->behavior == behavior) { count++; }
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
struct Object *obj_get_next(struct Object *o) {
|
||||
if (gObjectLists && o) {
|
||||
enum ObjectList objList = get_object_list_from_behavior(o->behavior);
|
||||
|
|
|
@ -28,6 +28,10 @@ struct Object *obj_get_next_with_same_behavior_id(struct Object *o);
|
|||
struct Object *obj_get_next_with_same_behavior_id_and_field_s32(struct Object *o, s32 fieldIndex, s32 value);
|
||||
struct Object *obj_get_next_with_same_behavior_id_and_field_f32(struct Object *o, s32 fieldIndex, f32 value);
|
||||
|
||||
struct Object *obj_get_nearest_object_with_behavior_id(struct Object *o, enum BehaviorId behaviorId);
|
||||
|
||||
s32 obj_count_objects_with_behavior_id(enum BehaviorId behaviorId);
|
||||
|
||||
// misc obj helpers
|
||||
|
||||
struct SpawnParticlesInfo* obj_get_temp_spawn_particles_info(enum ModelExtendedId modelId);
|
||||
|
|
Loading…
Reference in a new issue