mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-12-01 16:27:27 +00:00
Merge branch 'coop' of github.com:sm64ex-coop-dev/sm64ex-coop into coop
This commit is contained in:
commit
5b5089dece
21 changed files with 331 additions and 71 deletions
4
Makefile
4
Makefile
|
@ -914,6 +914,10 @@ else
|
||||||
LDFLAGS := $(BITS) -march=$(TARGET_ARCH) -lm $(BACKEND_LDFLAGS) -no-pie -lpthread
|
LDFLAGS := $(BITS) -march=$(TARGET_ARCH) -lm $(BACKEND_LDFLAGS) -no-pie -lpthread
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(WINDOWS_BUILD),0)
|
||||||
|
LDFLAGS += -rdynamic
|
||||||
|
endif
|
||||||
|
|
||||||
# icon
|
# icon
|
||||||
ifeq ($(WINDOWS_BUILD),1)
|
ifeq ($(WINDOWS_BUILD),1)
|
||||||
ifeq ($(ICON),1)
|
ifeq ($(ICON),1)
|
||||||
|
|
|
@ -72,7 +72,7 @@ override_allowed_functions = {
|
||||||
"src/game/object_list_processor.h": [ "set_object_respawn_info_bits" ],
|
"src/game/object_list_processor.h": [ "set_object_respawn_info_bits" ],
|
||||||
"src/game/mario_misc.h": [ "bhv_toad.*", "bhv_unlock_door.*" ],
|
"src/game/mario_misc.h": [ "bhv_toad.*", "bhv_unlock_door.*" ],
|
||||||
"src/pc/utils/misc.h": [ "update_all_mario_stars" ],
|
"src/pc/utils/misc.h": [ "update_all_mario_stars" ],
|
||||||
"src/game/level_update.h": [ "level_trigger_warp" ],
|
"src/game/level_update.h": [ "level_trigger_warp", "get_painting_warp_node", "initiate_painting_warp" ],
|
||||||
"src/game/area.h": [ "area_get_warp_node" ],
|
"src/game/area.h": [ "area_get_warp_node" ],
|
||||||
"src/engine/level_script.h": [ "area_create_warp_node" ]
|
"src/engine/level_script.h": [ "area_create_warp_node" ]
|
||||||
}
|
}
|
||||||
|
|
|
@ -4101,6 +4101,17 @@ function area_create_warp_node(id, destLevel, destArea, destNode, checkpoint, o)
|
||||||
-- ...
|
-- ...
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @return WarpNode
|
||||||
|
function get_painting_warp_node()
|
||||||
|
-- ...
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @param paintingIndex integer
|
||||||
|
--- @return nil
|
||||||
|
function initiate_painting_warp(paintingIndex)
|
||||||
|
-- ...
|
||||||
|
end
|
||||||
|
|
||||||
--- @param m MarioState
|
--- @param m MarioState
|
||||||
--- @param warpOp integer
|
--- @param warpOp integer
|
||||||
--- @return integer
|
--- @return integer
|
||||||
|
|
|
@ -3567,6 +3567,44 @@
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
|
|
||||||
|
## [get_painting_warp_node](#get_painting_warp_node)
|
||||||
|
|
||||||
|
### Lua Example
|
||||||
|
`local WarpNodeValue = get_painting_warp_node()`
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
- None
|
||||||
|
|
||||||
|
### Returns
|
||||||
|
[WarpNode](structs.md#WarpNode)
|
||||||
|
|
||||||
|
### C Prototype
|
||||||
|
`struct WarpNode *get_painting_warp_node(void);`
|
||||||
|
|
||||||
|
[:arrow_up_small:](#)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## [initiate_painting_warp](#initiate_painting_warp)
|
||||||
|
|
||||||
|
### Lua Example
|
||||||
|
`initiate_painting_warp(paintingIndex)`
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
| Field | Type |
|
||||||
|
| ----- | ---- |
|
||||||
|
| paintingIndex | `integer` |
|
||||||
|
|
||||||
|
### Returns
|
||||||
|
- None
|
||||||
|
|
||||||
|
### C Prototype
|
||||||
|
`void initiate_painting_warp(s16 paintingIndex);`
|
||||||
|
|
||||||
|
[:arrow_up_small:](#)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
## [level_trigger_warp](#level_trigger_warp)
|
## [level_trigger_warp](#level_trigger_warp)
|
||||||
|
|
||||||
### Lua Example
|
### Lua Example
|
||||||
|
|
|
@ -816,6 +816,8 @@
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
- level_update.h
|
- level_update.h
|
||||||
|
- [get_painting_warp_node](functions-3.md#get_painting_warp_node)
|
||||||
|
- [initiate_painting_warp](functions-3.md#initiate_painting_warp)
|
||||||
- [level_trigger_warp](functions-3.md#level_trigger_warp)
|
- [level_trigger_warp](functions-3.md#level_trigger_warp)
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
|
@ -323,6 +323,7 @@ RASPBERRY = "Raspberry"
|
||||||
BUBBLEGUM = "Bubblegum"
|
BUBBLEGUM = "Bubblegum"
|
||||||
ICE_MARIO = "Ice Mario"
|
ICE_MARIO = "Ice Mario"
|
||||||
ICE_LUIGI = "Ice Luigi"
|
ICE_LUIGI = "Ice Luigi"
|
||||||
|
TOAD = "Toad"
|
||||||
CUSTOM = "Custom"
|
CUSTOM = "Custom"
|
||||||
|
|
||||||
[PLAYER_LIST]
|
[PLAYER_LIST]
|
||||||
|
|
|
@ -323,6 +323,7 @@ RASPBERRY = "Framboise"
|
||||||
BUBBLEGUM = "Bubblegum"
|
BUBBLEGUM = "Bubblegum"
|
||||||
ICE_MARIO = "Mario de glace"
|
ICE_MARIO = "Mario de glace"
|
||||||
ICE_LUIGI = "Luigi de glace"
|
ICE_LUIGI = "Luigi de glace"
|
||||||
|
TOAD = "Toad"
|
||||||
CUSTOM = "Personnalisée"
|
CUSTOM = "Personnalisée"
|
||||||
|
|
||||||
[PLAYER_LIST]
|
[PLAYER_LIST]
|
||||||
|
|
|
@ -323,6 +323,7 @@ RASPBERRY = "Himbeere"
|
||||||
BUBBLEGUM = "Kaugummi"
|
BUBBLEGUM = "Kaugummi"
|
||||||
ICE_MARIO = "Eis Mario"
|
ICE_MARIO = "Eis Mario"
|
||||||
ICE_LUIGI = "Eis Luigi"
|
ICE_LUIGI = "Eis Luigi"
|
||||||
|
TOAD = "Toad"
|
||||||
CUSTOM = "Selbstgemacht"
|
CUSTOM = "Selbstgemacht"
|
||||||
|
|
||||||
[PLAYER_LIST]
|
[PLAYER_LIST]
|
||||||
|
|
|
@ -320,6 +320,7 @@ RASPBERRY = "Mora"
|
||||||
BUBBLEGUM = "Gomma da Masticare"
|
BUBBLEGUM = "Gomma da Masticare"
|
||||||
ICE_MARIO = "Mario Ghiaccio"
|
ICE_MARIO = "Mario Ghiaccio"
|
||||||
ICE_LUIGI = "Luigi Ghiaccio"
|
ICE_LUIGI = "Luigi Ghiaccio"
|
||||||
|
TOAD = "Toad"
|
||||||
CUSTOM = "Personalizzato"
|
CUSTOM = "Personalizzato"
|
||||||
|
|
||||||
[PLAYER_LIST]
|
[PLAYER_LIST]
|
||||||
|
|
|
@ -323,6 +323,7 @@ RASPBERRY = "Framboesa"
|
||||||
BUBBLEGUM = "Chiclete"
|
BUBBLEGUM = "Chiclete"
|
||||||
ICE_MARIO = "Mario de Gelo"
|
ICE_MARIO = "Mario de Gelo"
|
||||||
ICE_LUIGI = "Luigi de Gelo"
|
ICE_LUIGI = "Luigi de Gelo"
|
||||||
|
TOAD = "Toad"
|
||||||
CUSTOM = "Customizado"
|
CUSTOM = "Customizado"
|
||||||
|
|
||||||
[PLAYER_LIST]
|
[PLAYER_LIST]
|
||||||
|
|
|
@ -322,6 +322,7 @@ RASPBERRY = "Малина"
|
||||||
BUBBLEGUM = "Жвачка"
|
BUBBLEGUM = "Жвачка"
|
||||||
ICE_MARIO = "Ледяной Марио"
|
ICE_MARIO = "Ледяной Марио"
|
||||||
ICE_LUIGI = "Ледяной Луиджи"
|
ICE_LUIGI = "Ледяной Луиджи"
|
||||||
|
TOAD = "Тоад"s
|
||||||
CUSTOM = "Свой"
|
CUSTOM = "Свой"
|
||||||
|
|
||||||
[PLAYER_LIST]
|
[PLAYER_LIST]
|
||||||
|
|
|
@ -323,6 +323,7 @@ RASPBERRY = "Frambuesa"
|
||||||
BUBBLEGUM = "Chicle"
|
BUBBLEGUM = "Chicle"
|
||||||
ICE_MARIO = "Mario de Hielo"
|
ICE_MARIO = "Mario de Hielo"
|
||||||
ICE_LUIGI = "Luigi de Hielo"
|
ICE_LUIGI = "Luigi de Hielo"
|
||||||
|
TOAD = "Toad"
|
||||||
CUSTOM = "Personalizada"
|
CUSTOM = "Personalizada"
|
||||||
|
|
||||||
[PLAYER_LIST]
|
[PLAYER_LIST]
|
||||||
|
|
|
@ -626,9 +626,9 @@ static void level_cmd_create_painting_warp_node(void) {
|
||||||
if (sCurrAreaIndex != -1) {
|
if (sCurrAreaIndex != -1) {
|
||||||
if (gAreas[sCurrAreaIndex].paintingWarpNodes == NULL) {
|
if (gAreas[sCurrAreaIndex].paintingWarpNodes == NULL) {
|
||||||
gAreas[sCurrAreaIndex].paintingWarpNodes =
|
gAreas[sCurrAreaIndex].paintingWarpNodes =
|
||||||
alloc_only_pool_alloc(sLevelPool, 45 * sizeof(struct WarpNode));
|
alloc_only_pool_alloc(sLevelPool, MAX_PAINTING_WARP_NODES * sizeof(struct WarpNode));
|
||||||
|
|
||||||
for (i = 0; i < 45; i++) {
|
for (i = 0; i < MAX_PAINTING_WARP_NODES; i++) {
|
||||||
gAreas[sCurrAreaIndex].paintingWarpNodes[i].id = 0;
|
gAreas[sCurrAreaIndex].paintingWarpNodes[i].id = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#include <PR/ultratypes.h>
|
#include <PR/ultratypes.h>
|
||||||
|
|
||||||
|
#define MAX_PAINTING_WARP_NODES 45
|
||||||
|
|
||||||
struct LevelCommand;
|
struct LevelCommand;
|
||||||
|
|
||||||
extern s32 gLevelScriptModIndex;
|
extern s32 gLevelScriptModIndex;
|
||||||
|
|
|
@ -363,8 +363,8 @@ const struct PlayerPalette gPalettePresets[PALETTE_PRESET_MAX] = {
|
||||||
/* ---- PANTS ----- ---- SHIRT ----- ---- GLOVES ---- ---- SHOES ----- ----- HAIR ----- ----- SKIN ----- ----- CAP ------ */
|
/* ---- PANTS ----- ---- SHIRT ----- ---- GLOVES ---- ---- SHOES ----- ----- HAIR ----- ----- SKIN ----- ----- CAP ------ */
|
||||||
{{{ 0x00, 0x00, 0xff }, { 0xff, 0x00, 0x00 }, { 0xff, 0xff, 0xff }, { 0x72, 0x1c, 0x0e }, { 0x73, 0x06, 0x00 }, { 0xfe, 0xc1, 0x79 }, { 0xff, 0x00, 0x00 }}}, // Mario
|
{{{ 0x00, 0x00, 0xff }, { 0xff, 0x00, 0x00 }, { 0xff, 0xff, 0xff }, { 0x72, 0x1c, 0x0e }, { 0x73, 0x06, 0x00 }, { 0xfe, 0xc1, 0x79 }, { 0xff, 0x00, 0x00 }}}, // Mario
|
||||||
{{{ 0x00, 0x00, 0xfe }, { 0x00, 0x98, 0x00 }, { 0xff, 0xff, 0xff }, { 0x72, 0x1c, 0x0e }, { 0x73, 0x06, 0x00 }, { 0xfe, 0xc1, 0x79 }, { 0x00, 0x98, 0x00 }}}, // Luigi
|
{{{ 0x00, 0x00, 0xfe }, { 0x00, 0x98, 0x00 }, { 0xff, 0xff, 0xff }, { 0x72, 0x1c, 0x0e }, { 0x73, 0x06, 0x00 }, { 0xfe, 0xc1, 0x79 }, { 0x00, 0x98, 0x00 }}}, // Luigi
|
||||||
{{{ 0x2c, 0x26, 0x3f }, { 0x6d, 0x3c, 0x9a }, { 0xff, 0xff, 0xff }, { 0x72, 0x1c, 0x0e }, { 0x73, 0x06, 0x00 }, { 0xfe, 0xc1, 0x79 }, { 0x6d, 0x3c, 0x9a }}}, // Waluigi
|
{{{ 0x2c, 0x26, 0x3f }, { 0x61, 0x26, 0xb0 }, { 0xff, 0xff, 0xff }, { 0xfe, 0x76, 0x00 }, { 0x73, 0x06, 0x00 }, { 0xfe, 0xc1, 0x79 }, { 0x61, 0x26, 0xb0 }}}, // Waluigi
|
||||||
{{{ 0x7f, 0x20, 0x7a }, { 0xf9, 0xeb, 0x30 }, { 0xff, 0xff, 0xff }, { 0x0e, 0x72, 0x1c }, { 0x73, 0x53, 0x00 }, { 0xfe, 0xc1, 0x79 }, { 0xf9, 0xeb, 0x30 }}}, // Wario
|
{{{ 0x7f, 0x20, 0x7a }, { 0xe3, 0xa9, 0x01 }, { 0xff, 0xff, 0xff }, { 0x0e, 0x72, 0x1c }, { 0x73, 0x53, 0x00 }, { 0xfe, 0xc1, 0x79 }, { 0xe3, 0xa9, 0x01 }}}, // Wario
|
||||||
{{{ 0xff, 0x00, 0x00 }, { 0x7b, 0x00, 0xde }, { 0xff, 0xff, 0xff }, { 0x72, 0x1c, 0x0e }, { 0x73, 0x06, 0x00 }, { 0xfe, 0xc1, 0x79 }, { 0x7b, 0x00, 0xde }}}, // Chuckya
|
{{{ 0xff, 0x00, 0x00 }, { 0x7b, 0x00, 0xde }, { 0xff, 0xff, 0xff }, { 0x72, 0x1c, 0x0e }, { 0x73, 0x06, 0x00 }, { 0xfe, 0xc1, 0x79 }, { 0x7b, 0x00, 0xde }}}, // Chuckya
|
||||||
{{{ 0xc6, 0xb1, 0x32 }, { 0x95, 0x43, 0x01 }, { 0xff, 0xff, 0xff }, { 0x72, 0x1c, 0x0e }, { 0x73, 0x06, 0x00 }, { 0xfe, 0xc1, 0x79 }, { 0x95, 0x43, 0x01 }}}, // Goomba
|
{{{ 0xc6, 0xb1, 0x32 }, { 0x95, 0x43, 0x01 }, { 0xff, 0xff, 0xff }, { 0x72, 0x1c, 0x0e }, { 0x73, 0x06, 0x00 }, { 0xfe, 0xc1, 0x79 }, { 0x95, 0x43, 0x01 }}}, // Goomba
|
||||||
{{{ 0x07, 0x09, 0x07 }, { 0x4c, 0x5f, 0x20 }, { 0xff, 0xff, 0xff }, { 0x72, 0x1c, 0x0e }, { 0x73, 0x06, 0x00 }, { 0xfe, 0xc1, 0x79 }, { 0x4c, 0x5f, 0x20 }}}, // Clover
|
{{{ 0x07, 0x09, 0x07 }, { 0x4c, 0x5f, 0x20 }, { 0xff, 0xff, 0xff }, { 0x72, 0x1c, 0x0e }, { 0x73, 0x06, 0x00 }, { 0xfe, 0xc1, 0x79 }, { 0x4c, 0x5f, 0x20 }}}, // Clover
|
||||||
|
@ -393,6 +393,7 @@ const struct PlayerPalette gPalettePresets[PALETTE_PRESET_MAX] = {
|
||||||
{{{ 0xd6, 0x35, 0x4d }, { 0xff, 0x8e, 0xb2 }, { 0xff, 0xff, 0xff }, { 0x72, 0x1c, 0x0e }, { 0x73, 0x06, 0x00 }, { 0xfe, 0xc1, 0x79 }, { 0xff, 0x8e, 0xb2 }}}, // Bubblegum
|
{{{ 0xd6, 0x35, 0x4d }, { 0xff, 0x8e, 0xb2 }, { 0xff, 0xff, 0xff }, { 0x72, 0x1c, 0x0e }, { 0x73, 0x06, 0x00 }, { 0xfe, 0xc1, 0x79 }, { 0xff, 0x8e, 0xb2 }}}, // Bubblegum
|
||||||
{{{ 0xb2, 0x28, 0x18 }, { 0x47, 0xc5, 0xff }, { 0xff, 0xff, 0xff }, { 0x72, 0x1c, 0x0e }, { 0x73, 0x06, 0x00 }, { 0xfe, 0xc1, 0x79 }, { 0x47, 0xc5, 0xff }}}, // Ice Mario
|
{{{ 0xb2, 0x28, 0x18 }, { 0x47, 0xc5, 0xff }, { 0xff, 0xff, 0xff }, { 0x72, 0x1c, 0x0e }, { 0x73, 0x06, 0x00 }, { 0xfe, 0xc1, 0x79 }, { 0x47, 0xc5, 0xff }}}, // Ice Mario
|
||||||
{{{ 0x00, 0x98, 0x00 }, { 0x47, 0xc5, 0xff }, { 0xff, 0xff, 0xff }, { 0x72, 0x1c, 0x0e }, { 0x73, 0x06, 0x00 }, { 0xfe, 0xc1, 0x79 }, { 0x47, 0xc5, 0xff }}}, // Ice Luigi
|
{{{ 0x00, 0x98, 0x00 }, { 0x47, 0xc5, 0xff }, { 0xff, 0xff, 0xff }, { 0x72, 0x1c, 0x0e }, { 0x73, 0x06, 0x00 }, { 0xfe, 0xc1, 0x79 }, { 0x47, 0xc5, 0xff }}}, // Ice Luigi
|
||||||
|
{{{ 0x4c, 0x2c, 0xd3 }, { 0xff, 0xff, 0xff }, { 0xff, 0xff, 0xff }, { 0x68, 0x40, 0x1b }, { 0x73, 0x06, 0x00 }, { 0xfe, 0xd5, 0xa1 }, { 0xff, 0x00, 0x00 }}}, // Toad
|
||||||
};
|
};
|
||||||
|
|
||||||
enum AnimType {
|
enum AnimType {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include "pc/configfile.h"
|
#include "pc/configfile.h"
|
||||||
// NOTE: do not include any additional headers
|
// NOTE: do not include any additional headers
|
||||||
|
|
||||||
#define PALETTE_PRESET_MAX 32
|
#define PALETTE_PRESET_MAX 33
|
||||||
|
|
||||||
enum PlayerParts {
|
enum PlayerParts {
|
||||||
PANTS, SHIRT, GLOVES, SHOES, HAIR, SKIN, CAP, PLAYER_PART_MAX, METAL = CAP
|
PANTS, SHIRT, GLOVES, SHOES, HAIR, SKIN, CAP, PLAYER_PART_MAX, METAL = CAP
|
||||||
|
|
|
@ -45,6 +45,8 @@
|
||||||
|
|
||||||
#include "game/screen_transition.h"
|
#include "game/screen_transition.h"
|
||||||
|
|
||||||
|
#include "engine/level_script.h"
|
||||||
|
|
||||||
#define WARP_NODE_F0 0xF0
|
#define WARP_NODE_F0 0xF0
|
||||||
#define WARP_NODE_DEATH 0xF1
|
#define WARP_NODE_DEATH 0xF1
|
||||||
#define WARP_NODE_F2 0xF2
|
#define WARP_NODE_F2 0xF2
|
||||||
|
@ -748,6 +750,8 @@ void initiate_warp(s16 destLevel, s16 destArea, s16 destWarpNode, s32 arg3) {
|
||||||
* corresponding warp node.
|
* corresponding warp node.
|
||||||
*/
|
*/
|
||||||
struct WarpNode *get_painting_warp_node(void) {
|
struct WarpNode *get_painting_warp_node(void) {
|
||||||
|
if (!gMarioState || !gMarioState->floor || !gCurrentArea || !gCurrentArea->paintingWarpNodes) { return NULL; }
|
||||||
|
|
||||||
struct WarpNode *warpNode = NULL;
|
struct WarpNode *warpNode = NULL;
|
||||||
s32 paintingIndex = gMarioState->floor->type - SURFACE_PAINTING_WARP_D3;
|
s32 paintingIndex = gMarioState->floor->type - SURFACE_PAINTING_WARP_D3;
|
||||||
|
|
||||||
|
@ -783,9 +787,9 @@ static void initiate_painting_warp_node(struct WarpNode *pWarpNode) {
|
||||||
/**
|
/**
|
||||||
* Check is Mario has entered a painting, and if so, initiate a warp.
|
* Check is Mario has entered a painting, and if so, initiate a warp.
|
||||||
*/
|
*/
|
||||||
void initiate_painting_warp(void) {
|
void initiate_painting_warp(s16 paintingIndex) {
|
||||||
if (gCurrentArea != NULL && gCurrentArea->paintingWarpNodes != NULL && gMarioState->floor != NULL) {
|
if (gCurrentArea && gCurrentArea->paintingWarpNodes && gMarioState && gMarioState->floor && paintingIndex >= 0 && paintingIndex < MAX_PAINTING_WARP_NODES) {
|
||||||
struct WarpNode *pWarpNode = get_painting_warp_node();
|
struct WarpNode *pWarpNode = paintingIndex == -1 ? get_painting_warp_node() : &gCurrentArea->paintingWarpNodes[paintingIndex];
|
||||||
|
|
||||||
if (pWarpNode != NULL) {
|
if (pWarpNode != NULL) {
|
||||||
if (gMarioState->action & ACT_FLAG_INTANGIBLE) {
|
if (gMarioState->action & ACT_FLAG_INTANGIBLE) {
|
||||||
|
@ -1229,7 +1233,7 @@ s32 play_mode_normal(void) {
|
||||||
update_camera(gCurrentArea->camera);
|
update_camera(gCurrentArea->camera);
|
||||||
}
|
}
|
||||||
|
|
||||||
initiate_painting_warp();
|
initiate_painting_warp(-1);
|
||||||
initiate_delayed_warp();
|
initiate_delayed_warp();
|
||||||
|
|
||||||
// If either initiate_painting_warp or initiate_delayed_warp initiated a
|
// If either initiate_painting_warp or initiate_delayed_warp initiated a
|
||||||
|
|
|
@ -151,6 +151,8 @@ u8 level_control_timer_running(void);
|
||||||
u16 level_control_timer(s32 timerOp);
|
u16 level_control_timer(s32 timerOp);
|
||||||
void fade_into_special_warp(u32 arg, u32 color);
|
void fade_into_special_warp(u32 arg, u32 color);
|
||||||
void load_level_init_text(u32 arg);
|
void load_level_init_text(u32 arg);
|
||||||
|
struct WarpNode *get_painting_warp_node(void);
|
||||||
|
void initiate_painting_warp(s16 paintingIndex);
|
||||||
s16 level_trigger_warp(struct MarioState *m, s32 warpOp);
|
s16 level_trigger_warp(struct MarioState *m, s32 warpOp);
|
||||||
void level_set_transition(s16 length, void (*updateFunction)(s16 *));
|
void level_set_transition(s16 length, void (*updateFunction)(s16 *));
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,14 @@
|
||||||
// Adapted from PeachyPeach's sm64pc-omm
|
// Adapted from PeachyPeach's sm64pc-omm (now sm64ex-omm)
|
||||||
#include "crash_handler.h"
|
#include "crash_handler.h"
|
||||||
|
|
||||||
#if defined(_WIN32) && !defined(WAPI_DUMMY)
|
#if (defined(_WIN32) || defined(__linux__)) && !defined(WAPI_DUMMY)
|
||||||
|
|
||||||
#ifdef HAVE_SDL2
|
#ifdef HAVE_SDL2
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <windows.h>
|
|
||||||
#include <dbghelp.h>
|
|
||||||
#include <PR/ultratypes.h>
|
#include <PR/ultratypes.h>
|
||||||
#include <PR/gbi.h>
|
#include <PR/gbi.h>
|
||||||
#include <crtdbg.h>
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "pc/gfx/gfx_window_manager_api.h"
|
#include "pc/gfx/gfx_window_manager_api.h"
|
||||||
#include "pc/gfx/gfx_dxgi.h"
|
#include "pc/gfx/gfx_dxgi.h"
|
||||||
|
@ -28,7 +24,23 @@
|
||||||
#include "pc/network/network.h"
|
#include "pc/network/network.h"
|
||||||
#include "pc/gfx/gfx_rendering_api.h"
|
#include "pc/gfx/gfx_rendering_api.h"
|
||||||
#include "pc/mods/mods.h"
|
#include "pc/mods/mods.h"
|
||||||
#include "dbghelp.h"
|
|
||||||
|
typedef struct {
|
||||||
|
s32 x, y;
|
||||||
|
u8 r, g, b;
|
||||||
|
char s[128];
|
||||||
|
} CrashHandlerText;
|
||||||
|
static CrashHandlerText sCrashHandlerText[128 + 256];
|
||||||
|
|
||||||
|
#define PTR long long unsigned int)(uintptr_t
|
||||||
|
|
||||||
|
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
|
||||||
|
#define MEMNEW(typ, cnt) calloc(sizeof(typ), cnt)
|
||||||
|
#define STRING(str, size, fmt, ...) char str[size]; snprintf(str, size, fmt, __VA_ARGS__);
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
#define OS_NAME "Windows"
|
||||||
|
|
||||||
#if IS_64_BIT
|
#if IS_64_BIT
|
||||||
#define CRASH_HANDLER_TYPE LONG
|
#define CRASH_HANDLER_TYPE LONG
|
||||||
|
@ -44,15 +56,11 @@
|
||||||
#define ARCHITECTURE_STR "32-bit"
|
#define ARCHITECTURE_STR "32-bit"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PTR long long unsigned int)(uintptr_t
|
#include <stdio.h>
|
||||||
|
#include <windows.h>
|
||||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
|
#include <dbghelp.h>
|
||||||
#define MEMNEW(typ, cnt) calloc(sizeof(typ), cnt)
|
#include <crtdbg.h>
|
||||||
#define STRING(str, size, fmt, ...) char str[size]; snprintf(str, size, fmt, __VA_ARGS__);
|
#include "dbghelp.h"
|
||||||
|
|
||||||
#define DEF(smex, smms, r96a, xalo, sm74, smsr) smex
|
|
||||||
#define load_gfx_memory_pool() DEF(config_gfx_pool(), config_gfx_pool(), config_gfx_pool(), select_gfx_pool(), select_gfx_pool(), select_gfx_pool())
|
|
||||||
#define init_scene_rendering() DEF(init_render_image(), init_render_image(), init_render_image(), init_rcp(), init_rcp(), init_rcp())
|
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
u32 code;
|
u32 code;
|
||||||
|
@ -79,12 +87,79 @@ static struct {
|
||||||
{ 0, "Unknown Exception", "An unknown exception occurred." },
|
{ 0, "Unknown Exception", "An unknown exception occurred." },
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
s32 x, y;
|
#if !IS_64_BIT
|
||||||
u8 r, g, b;
|
static ULONG CaptureStackWalkBackTrace(CONTEXT* ctx, DWORD FramesToSkip, DWORD FramesToCapture, void* BackTrace[]) {
|
||||||
char s[128];
|
|
||||||
} CrashHandlerText;
|
HANDLE process = GetCurrentProcess();
|
||||||
static CrashHandlerText sCrashHandlerText[128 + 256];
|
HANDLE thread = GetCurrentThread();
|
||||||
|
|
||||||
|
STACKFRAME64 stack;
|
||||||
|
memset(&stack, 0, sizeof(STACKFRAME64));
|
||||||
|
#if IS_64_BIT
|
||||||
|
stack.AddrPC.Offset = (*ctx).Rip;
|
||||||
|
stack.AddrPC.Mode = AddrModeFlat;
|
||||||
|
stack.AddrStack.Offset = (*ctx).Rsp;
|
||||||
|
stack.AddrStack.Mode = AddrModeFlat;
|
||||||
|
stack.AddrFrame.Offset = (*ctx).Rbp;
|
||||||
|
stack.AddrFrame.Mode = AddrModeFlat;
|
||||||
|
#else
|
||||||
|
stack.AddrPC.Offset = (*ctx).Eip;
|
||||||
|
stack.AddrPC.Mode = AddrModeFlat;
|
||||||
|
stack.AddrStack.Offset = (*ctx).Esp;
|
||||||
|
stack.AddrStack.Mode = AddrModeFlat;
|
||||||
|
stack.AddrFrame.Offset = (*ctx).Ebp;
|
||||||
|
stack.AddrFrame.Mode = AddrModeFlat;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ULONG frame = 0;
|
||||||
|
for (frame = 0; ; frame++)
|
||||||
|
{
|
||||||
|
if (!StackWalk64(MACHINE_TYPE, process, thread, &stack, ctx, NULL, NULL, NULL, NULL)) { break; }
|
||||||
|
if (frame < FramesToSkip || frame >= FramesToCapture) { continue; }
|
||||||
|
BackTrace[frame+1] = (void*)(intptr_t)stack.AddrPC.Offset;
|
||||||
|
}
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif __linux__
|
||||||
|
|
||||||
|
#define OS_NAME "Linux"
|
||||||
|
|
||||||
|
#if IS_64_BIT
|
||||||
|
#define CRASH_HANDLER_TYPE LONG
|
||||||
|
#define SYMBOL_INCREMENT 16
|
||||||
|
#define SYMBOL_SCAN_FORMAT "%ld"
|
||||||
|
#define MACHINE_TYPE IMAGE_FILE_MACHINE_AMD64
|
||||||
|
#define ARCHITECTURE_STR "64-bit"
|
||||||
|
#else
|
||||||
|
#define CRASH_HANDLER_TYPE LONG WINAPI
|
||||||
|
#define SYMBOL_INCREMENT 9
|
||||||
|
#define SYMBOL_SCAN_FORMAT "%ld"
|
||||||
|
#define MACHINE_TYPE IMAGE_FILE_MACHINE_I386
|
||||||
|
#define ARCHITECTURE_STR "32-bit"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define __USE_GNU
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
#include <execinfo.h>
|
||||||
|
#include <ucontext.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
u32 code;
|
||||||
|
const char *error;
|
||||||
|
const char *message;
|
||||||
|
} sCrashHandlerErrors[] = {
|
||||||
|
{ SIGBUS, "Bad Memory Access", "The game tried to access memory out of bounds." },
|
||||||
|
{ SIGFPE, "Floating Point Exception", "The game tried to perform illegal arithmetic on a floating point." },
|
||||||
|
{ SIGILL, "Illegal Instruction", "The game tried to execute an invalid instruction." },
|
||||||
|
{ SIGSEGV, "Segmentation Fault", "The game tried to %s at address 0x%016llX." },
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#define crash_handler_set_text(_x_, _y_, _r_, _g_, _b_, _fmt_, ...) \
|
#define crash_handler_set_text(_x_, _y_, _r_, _g_, _b_, _fmt_, ...) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -126,8 +201,8 @@ static void crash_handler_produce_one_frame() {
|
||||||
|
|
||||||
// Start frame
|
// Start frame
|
||||||
gfx_start_frame();
|
gfx_start_frame();
|
||||||
load_gfx_memory_pool();
|
config_gfx_pool();
|
||||||
init_scene_rendering();
|
init_render_image();
|
||||||
|
|
||||||
float minAspectRatio = 1.743468f;
|
float minAspectRatio = 1.743468f;
|
||||||
float aspectScale = 1.0f;
|
float aspectScale = 1.0f;
|
||||||
|
@ -202,41 +277,6 @@ static void crash_handler_produce_one_frame() {
|
||||||
gfx_end_frame();
|
gfx_end_frame();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !IS_64_BIT
|
|
||||||
static ULONG CaptureStackWalkBackTrace(CONTEXT* ctx, DWORD FramesToSkip, DWORD FramesToCapture, void* BackTrace[]) {
|
|
||||||
|
|
||||||
HANDLE process = GetCurrentProcess();
|
|
||||||
HANDLE thread = GetCurrentThread();
|
|
||||||
|
|
||||||
STACKFRAME64 stack;
|
|
||||||
memset(&stack, 0, sizeof(STACKFRAME64));
|
|
||||||
#if IS_64_BIT
|
|
||||||
stack.AddrPC.Offset = (*ctx).Rip;
|
|
||||||
stack.AddrPC.Mode = AddrModeFlat;
|
|
||||||
stack.AddrStack.Offset = (*ctx).Rsp;
|
|
||||||
stack.AddrStack.Mode = AddrModeFlat;
|
|
||||||
stack.AddrFrame.Offset = (*ctx).Rbp;
|
|
||||||
stack.AddrFrame.Mode = AddrModeFlat;
|
|
||||||
#else
|
|
||||||
stack.AddrPC.Offset = (*ctx).Eip;
|
|
||||||
stack.AddrPC.Mode = AddrModeFlat;
|
|
||||||
stack.AddrStack.Offset = (*ctx).Esp;
|
|
||||||
stack.AddrStack.Mode = AddrModeFlat;
|
|
||||||
stack.AddrFrame.Offset = (*ctx).Ebp;
|
|
||||||
stack.AddrFrame.Mode = AddrModeFlat;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ULONG frame = 0;
|
|
||||||
for (frame = 0; ; frame++)
|
|
||||||
{
|
|
||||||
if (!StackWalk64(MACHINE_TYPE, process, thread, &stack, ctx, NULL, NULL, NULL, NULL)) { break; }
|
|
||||||
if (frame < FramesToSkip || frame >= FramesToCapture) { continue; }
|
|
||||||
BackTrace[frame+1] = (void*)(intptr_t)stack.AddrPC.Offset;
|
|
||||||
}
|
|
||||||
return frame;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void crash_handler_add_info_str(CrashHandlerText** pTextP, f32 x, f32 y, char* title, char* value) {
|
static void crash_handler_add_info_str(CrashHandlerText** pTextP, f32 x, f32 y, char* title, char* value) {
|
||||||
CrashHandlerText* pText = *pTextP;
|
CrashHandlerText* pText = *pTextP;
|
||||||
crash_handler_set_text(x, y, 0xFF, 0xFF, 0x00, "%s", title);
|
crash_handler_set_text(x, y, 0xFF, 0xFF, 0x00, "%s", title);
|
||||||
|
@ -253,7 +293,11 @@ static void crash_handler_add_info_int(CrashHandlerText** pTextP, f32 x, f32 y,
|
||||||
*pTextP = pText;
|
*pTextP = pText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
static CRASH_HANDLER_TYPE crash_handler(EXCEPTION_POINTERS *ExceptionInfo) {
|
static CRASH_HANDLER_TYPE crash_handler(EXCEPTION_POINTERS *ExceptionInfo) {
|
||||||
|
#elif __linux__
|
||||||
|
static void crash_handler(const int signalNum, siginfo_t *info, ucontext_t *context) {
|
||||||
|
#endif
|
||||||
memset(sCrashHandlerText, 0, sizeof(sCrashHandlerText));
|
memset(sCrashHandlerText, 0, sizeof(sCrashHandlerText));
|
||||||
CrashHandlerText *pText = &sCrashHandlerText[0];
|
CrashHandlerText *pText = &sCrashHandlerText[0];
|
||||||
gDjuiDisabled = true;
|
gDjuiDisabled = true;
|
||||||
|
@ -262,6 +306,7 @@ static CRASH_HANDLER_TYPE crash_handler(EXCEPTION_POINTERS *ExceptionInfo) {
|
||||||
crash_handler_set_text(8, -4, 0xFF, 0x80, 0x00, "%s", "Please report this crash with a consistent way to reproduce it.");
|
crash_handler_set_text(8, -4, 0xFF, 0x80, 0x00, "%s", "Please report this crash with a consistent way to reproduce it.");
|
||||||
|
|
||||||
// Exception address, code, type and info
|
// Exception address, code, type and info
|
||||||
|
#ifdef _WIN32
|
||||||
if (ExceptionInfo && ExceptionInfo->ExceptionRecord) {
|
if (ExceptionInfo && ExceptionInfo->ExceptionRecord) {
|
||||||
PEXCEPTION_RECORD er = ExceptionInfo->ExceptionRecord;
|
PEXCEPTION_RECORD er = ExceptionInfo->ExceptionRecord;
|
||||||
crash_handler_set_text( 8, 4, 0xFF, 0x00, 0x00, "%s", "Exception occurred at address ");
|
crash_handler_set_text( 8, 4, 0xFF, 0x00, 0x00, "%s", "Exception occurred at address ");
|
||||||
|
@ -281,15 +326,45 @@ static CRASH_HANDLER_TYPE crash_handler(EXCEPTION_POINTERS *ExceptionInfo) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#elif __linux__
|
||||||
|
if (signalNum != 0 && info != NULL) {
|
||||||
|
crash_handler_set_text( 8, 4, 0xFF, 0x00, 0x00, "%s", "Exception occurred at address ");
|
||||||
|
crash_handler_set_text(-1, 4, 0xFF, 0xFF, 0x00, "0x%016llX", (u64) info->si_addr);
|
||||||
|
crash_handler_set_text(-1, 4, 0xFF, 0x00, 0x00, "%s", " with error code ");
|
||||||
|
crash_handler_set_text(-1, 4, 0xFF, 0x00, 0xFF, "0x%08X", (u32) signalNum);
|
||||||
|
crash_handler_set_text(-1, 4, 0xFF, 0x00, 0x00, "%s", ":");
|
||||||
|
for (s32 i = 0; i != ARRAY_SIZE(sCrashHandlerErrors); ++i) {
|
||||||
|
if (sCrashHandlerErrors[i].code == (u32) signalNum || sCrashHandlerErrors[i].code == 0) {
|
||||||
|
crash_handler_set_text( 8, 12, 0xFF, 0x00, 0x00, "%s", sCrashHandlerErrors[i].error);
|
||||||
|
crash_handler_set_text(-1, 12, 0xFF, 0xFF, 0xFF, "%s", " - ");
|
||||||
|
if (signalNum == SIGSEGV) {
|
||||||
|
char segFaultStr[255] = "";
|
||||||
|
if (info->si_code == SEGV_MAPERR) {
|
||||||
|
snprintf(segFaultStr, 255, "The game tried to read unmapped memory at address %p", info->si_addr);
|
||||||
|
} else if (info->si_code == SEGV_ACCERR) {
|
||||||
|
snprintf(segFaultStr, 255, "The game tried to %s at address %016llX", ((context->uc_mcontext.gregs[REG_ERR] & 0x2) != 0 ? "write" : "read"), (u64) info->si_addr);
|
||||||
|
} else {
|
||||||
|
snprintf(segFaultStr, 255, "Unknown segmentation fault at address %p", info->si_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
crash_handler_set_text(-1, 12, 0xFF, 0xFF, 0xFF, "%s", segFaultStr);
|
||||||
|
} else {
|
||||||
|
crash_handler_set_text(-1, 12, 0xFF, 0xFF, 0xFF, "%s", sCrashHandlerErrors[i].message);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
crash_handler_set_text(8, 4, 0xFF, 0x00, 0x00, "%s", "An unknown exception occurred somewhere in the game's code.");
|
crash_handler_set_text(8, 4, 0xFF, 0x00, 0x00, "%s", "An unknown exception occurred somewhere in the game's code.");
|
||||||
crash_handler_set_text(8, 12, 0x80, 0x80, 0x80, "%s", "Unable to retrieve the exception info.");
|
crash_handler_set_text(8, 12, 0x80, 0x80, 0x80, "%s", "Unable to retrieve the exception info.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Registers
|
// Registers
|
||||||
|
crash_handler_set_text(8, 22, 0xFF, 0xFF, 0xFF, "%s", "Registers:");
|
||||||
|
#ifdef _WIN32
|
||||||
if (ExceptionInfo && ExceptionInfo->ContextRecord) {
|
if (ExceptionInfo && ExceptionInfo->ContextRecord) {
|
||||||
PCONTEXT cr = ExceptionInfo->ContextRecord;
|
PCONTEXT cr = ExceptionInfo->ContextRecord;
|
||||||
crash_handler_set_text( 8, 22, 0xFF, 0xFF, 0xFF, "%s", "Registers:");
|
|
||||||
#if IS_64_BIT
|
#if IS_64_BIT
|
||||||
crash_handler_set_text( 8, 30, 0xFF, 0xFF, 0xFF, "RSP: 0x%016llX", (PTR)cr->Rsp);
|
crash_handler_set_text( 8, 30, 0xFF, 0xFF, 0xFF, "RSP: 0x%016llX", (PTR)cr->Rsp);
|
||||||
crash_handler_set_text(-1, 30, 0xFF, 0xFF, 0xFF, " RBP: 0x%016llX", (PTR)cr->Rbp);
|
crash_handler_set_text(-1, 30, 0xFF, 0xFF, 0xFF, " RBP: 0x%016llX", (PTR)cr->Rbp);
|
||||||
|
@ -326,14 +401,54 @@ static CRASH_HANDLER_TYPE crash_handler(EXCEPTION_POINTERS *ExceptionInfo) {
|
||||||
crash_handler_set_text(-1, 54, 0xFF, 0xFF, 0xFF, " SS: 0x%016llX", (PTR)cr->SegSs);
|
crash_handler_set_text(-1, 54, 0xFF, 0xFF, 0xFF, " SS: 0x%016llX", (PTR)cr->SegSs);
|
||||||
crash_handler_set_text( 8, 62, 0xFF, 0xFF, 0xFF, "DR0: 0x%016llX", (PTR)cr->Dr0);
|
crash_handler_set_text( 8, 62, 0xFF, 0xFF, 0xFF, "DR0: 0x%016llX", (PTR)cr->Dr0);
|
||||||
crash_handler_set_text(-1, 62, 0xFF, 0xFF, 0xFF, " DR1: 0x%016llX", (PTR)cr->Dr1);
|
crash_handler_set_text(-1, 62, 0xFF, 0xFF, 0xFF, " DR1: 0x%016llX", (PTR)cr->Dr1);
|
||||||
|
#endif
|
||||||
|
#elif __linux__
|
||||||
|
if (context->uc_mcontext.gregs[REG_RSP] != 0) {
|
||||||
|
#if IS_64_BIT
|
||||||
|
crash_handler_set_text( 8, 30, 0xFF, 0xFF, 0xFF, "RSP: 0x%016llX", context->uc_mcontext.gregs[REG_RSP]);
|
||||||
|
crash_handler_set_text(-1, 30, 0xFF, 0xFF, 0xFF, " RBP: 0x%016llX", context->uc_mcontext.gregs[REG_RBP]);
|
||||||
|
crash_handler_set_text(-1, 30, 0xFF, 0xFF, 0xFF, " RIP: 0x%016llX", context->uc_mcontext.gregs[REG_RIP]);
|
||||||
|
crash_handler_set_text( 8, 38, 0xFF, 0xFF, 0xFF, "RAX: 0x%016llX", context->uc_mcontext.gregs[REG_RAX]);
|
||||||
|
crash_handler_set_text(-1, 38, 0xFF, 0xFF, 0xFF, " RBX: 0x%016llX", context->uc_mcontext.gregs[REG_RBX]);
|
||||||
|
crash_handler_set_text(-1, 38, 0xFF, 0xFF, 0xFF, " RCX: 0x%016llX", context->uc_mcontext.gregs[REG_RCX]);
|
||||||
|
crash_handler_set_text(-1, 38, 0xFF, 0xFF, 0xFF, " RDX: 0x%016llX", context->uc_mcontext.gregs[REG_RDX]);
|
||||||
|
crash_handler_set_text( 8, 46, 0xFF, 0xFF, 0xFF, "R08: 0x%016llX", context->uc_mcontext.gregs[REG_R8]);
|
||||||
|
crash_handler_set_text(-1, 46, 0xFF, 0xFF, 0xFF, " R09: 0x%016llX", context->uc_mcontext.gregs[REG_R9]);
|
||||||
|
crash_handler_set_text(-1, 46, 0xFF, 0xFF, 0xFF, " R10: 0x%016llX", context->uc_mcontext.gregs[REG_R10]);
|
||||||
|
crash_handler_set_text(-1, 46, 0xFF, 0xFF, 0xFF, " R11: 0x%016llX", context->uc_mcontext.gregs[REG_R11]);
|
||||||
|
crash_handler_set_text( 8, 54, 0xFF, 0xFF, 0xFF, "R12: 0x%016llX", context->uc_mcontext.gregs[REG_R12]);
|
||||||
|
crash_handler_set_text(-1, 54, 0xFF, 0xFF, 0xFF, " R13: 0x%016llX", context->uc_mcontext.gregs[REG_R13]);
|
||||||
|
crash_handler_set_text(-1, 54, 0xFF, 0xFF, 0xFF, " R14: 0x%016llX", context->uc_mcontext.gregs[REG_R14]);
|
||||||
|
crash_handler_set_text(-1, 54, 0xFF, 0xFF, 0xFF, " R15: 0x%016llX", context->uc_mcontext.gregs[REG_R15]);
|
||||||
|
crash_handler_set_text( 8, 62, 0xFF, 0xFF, 0xFF, "RSI: 0x%016llX", context->uc_mcontext.gregs[REG_RSI]);
|
||||||
|
crash_handler_set_text(-1, 62, 0xFF, 0xFF, 0xFF, " RDI: 0x%016llX", context->uc_mcontext.gregs[REG_RDI]);
|
||||||
|
#else
|
||||||
|
crash_handler_set_text( 8, 30, 0xFF, 0xFF, 0xFF, "EAX: 0x%016llX", context->uc_mcontext.gregs[REG_EAX]);
|
||||||
|
crash_handler_set_text(-1, 30, 0xFF, 0xFF, 0xFF, " EBX: 0x%016llX", context->uc_mcontext.gregs[REG_EBX]);
|
||||||
|
crash_handler_set_text(-1, 30, 0xFF, 0xFF, 0xFF, " ECX: 0x%016llX", context->uc_mcontext.gregs[REG_ECX]);
|
||||||
|
crash_handler_set_text( 8, 38, 0xFF, 0xFF, 0xFF, "EDX: 0x%016llX", context->uc_mcontext.gregs[REG_EDX]);
|
||||||
|
crash_handler_set_text(-1, 38, 0xFF, 0xFF, 0xFF, " ESI: 0x%016llX", context->uc_mcontext.gregs[REG_ESI]);
|
||||||
|
crash_handler_set_text(-1, 38, 0xFF, 0xFF, 0xFF, " EDI: 0x%016llX", context->uc_mcontext.gregs[REG_EDI]);
|
||||||
|
crash_handler_set_text(-1, 38, 0xFF, 0xFF, 0xFF, " EBP: 0x%016llX", context->uc_mcontext.gregs[REG_EBP]);
|
||||||
|
crash_handler_set_text( 8, 46, 0xFF, 0xFF, 0xFF, "EIP: 0x%016llX", context->uc_mcontext.gregs[REG_EIP]);
|
||||||
|
crash_handler_set_text(-1, 46, 0xFF, 0xFF, 0xFF, " ESP: 0x%016llX", context->uc_mcontext.gregs[REG_ESP]);
|
||||||
|
crash_handler_set_text(-1, 46, 0xFF, 0xFF, 0xFF, " CS: 0x%016llX", context->uc_mcontext.gregs[REG_CS]);
|
||||||
|
crash_handler_set_text(-1, 46, 0xFF, 0xFF, 0xFF, " DS: 0x%016llX", context->uc_mcontext.gregs[REG_DS]);
|
||||||
|
crash_handler_set_text( 8, 54, 0xFF, 0xFF, 0xFF, " ES: 0x%016llX", context->uc_mcontext.gregs[REG_ES]);
|
||||||
|
crash_handler_set_text(-1, 54, 0xFF, 0xFF, 0xFF, " FS: 0x%016llX", context->uc_mcontext.gregs[REG_FS]);
|
||||||
|
crash_handler_set_text(-1, 54, 0xFF, 0xFF, 0xFF, " GS: 0x%016llX", context->uc_mcontext.gregs[REG_GS]);
|
||||||
|
crash_handler_set_text(-1, 54, 0xFF, 0xFF, 0xFF, " SS: 0x%016llX", context->uc_mcontext.gregs[REG_SS]);
|
||||||
|
crash_handler_set_text( 8, 62, 0xFF, 0xFF, 0xFF, "DR0: 0x%016llX", context->uc_mcontext.gregs[REG_RDI]);
|
||||||
|
crash_handler_set_text(-1, 62, 0xFF, 0xFF, 0xFF, " DR1: 0x%016llX", context->uc_mcontext.gregs[REG_RDX]);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
crash_handler_set_text(8, 22, 0xFF, 0xFF, 0xFF, "%s", "Registers:");
|
|
||||||
crash_handler_set_text(8, 30, 0x80, 0x80, 0x80, "%s", "Unable to access the registers.");
|
crash_handler_set_text(8, 30, 0x80, 0x80, 0x80, "%s", "Unable to access the registers.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stack trace
|
// Stack trace
|
||||||
crash_handler_set_text(8, 72, 0xFF, 0xFF, 0xFF, "%s", "Stack trace:");
|
crash_handler_set_text(8, 72, 0xFF, 0xFF, 0xFF, "%s", "Stack trace:");
|
||||||
|
#ifdef _WIN32
|
||||||
if (ExceptionInfo && ExceptionInfo->ContextRecord) {
|
if (ExceptionInfo && ExceptionInfo->ContextRecord) {
|
||||||
static const char sGlobalFunctionIdentifier[] = "(sec1)(fl0x00)(ty20)(scl2)(nx0)0x";
|
static const char sGlobalFunctionIdentifier[] = "(sec1)(fl0x00)(ty20)(scl2)(nx0)0x";
|
||||||
static const char sStaticFunctionIdentifier[] = "(sec1)(fl0x00)(ty20)(scl3)(nx0)0x";
|
static const char sStaticFunctionIdentifier[] = "(sec1)(fl0x00)(ty20)(scl3)(nx0)0x";
|
||||||
|
@ -436,6 +551,28 @@ static CRASH_HANDLER_TYPE crash_handler(EXCEPTION_POINTERS *ExceptionInfo) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#elif __linux__
|
||||||
|
void *trace[15];
|
||||||
|
int traceSize = backtrace(trace, 15);
|
||||||
|
|
||||||
|
if (traceSize > 0) {
|
||||||
|
// Unwind and print call stack
|
||||||
|
char **messages = backtrace_symbols(trace, traceSize);
|
||||||
|
for (s32 i = 1, j = 0; i < traceSize && j < 15; ++i) {
|
||||||
|
s32 y = 80 + j++ * 8;
|
||||||
|
crash_handler_set_text( 8, y, 0xFF, 0xFF, 0x00, "0x%016llX", (u64) strtoul(strstr(messages[i], "[") + 1, NULL, 16));
|
||||||
|
crash_handler_set_text(-1, y, 0xFF, 0xFF, 0xFF, "%s", ": ");
|
||||||
|
|
||||||
|
// dladdr gives us function names if -rdynamic/-export-dynamic is set in compiler flags
|
||||||
|
Dl_info info;
|
||||||
|
if (dladdr(trace[i], &info) && info.dli_sname) {
|
||||||
|
crash_handler_set_text(-1, y, 0x00, 0xFF, 0xFF, "%s", info.dli_sname);
|
||||||
|
crash_handler_set_text(-1, y, 0xFF, 0xFF, 0xFF, " + 0x%lX", trace[i] - info.dli_saddr);
|
||||||
|
} else {
|
||||||
|
crash_handler_set_text(-1, y, 0x00, 0xFF, 0xFF, "%s", "????");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
crash_handler_set_text(8, 116, 0x80, 0x80, 0x80, "%s", "Unable to unwind the call stack.");
|
crash_handler_set_text(8, 116, 0x80, 0x80, 0x80, "%s", "Unable to unwind the call stack.");
|
||||||
}
|
}
|
||||||
|
@ -459,6 +596,8 @@ static CRASH_HANDLER_TYPE crash_handler(EXCEPTION_POINTERS *ExceptionInfo) {
|
||||||
|
|
||||||
crash_handler_add_info_int(&pText, 380, -4 + (8 * 2), "Mods", gActiveMods.entryCount);
|
crash_handler_add_info_int(&pText, 380, -4 + (8 * 2), "Mods", gActiveMods.entryCount);
|
||||||
|
|
||||||
|
crash_handler_add_info_str(&pText, 380, -4 + (8 * 3), "OS", OS_NAME);
|
||||||
|
|
||||||
// Mods
|
// Mods
|
||||||
crash_handler_set_text(245, 64, 0xFF, 0xFF, 0xFF, "%s", "Mods:");
|
crash_handler_set_text(245, 64, 0xFF, 0xFF, 0xFF, "%s", "Mods:");
|
||||||
{
|
{
|
||||||
|
@ -525,7 +664,22 @@ static CRASH_HANDLER_TYPE crash_handler(EXCEPTION_POINTERS *ExceptionInfo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((constructor)) static void init_crash_handler() {
|
__attribute__((constructor)) static void init_crash_handler() {
|
||||||
|
#ifdef _WIN32
|
||||||
|
// Windows
|
||||||
SetUnhandledExceptionFilter(crash_handler);
|
SetUnhandledExceptionFilter(crash_handler);
|
||||||
|
#elif __linux__
|
||||||
|
// Linux
|
||||||
|
struct sigaction linux_crash_handler;
|
||||||
|
|
||||||
|
linux_crash_handler.sa_handler = (void *)crash_handler;
|
||||||
|
sigemptyset(&linux_crash_handler.sa_mask);
|
||||||
|
linux_crash_handler.sa_flags = SA_SIGINFO; // Get extra info about the crash
|
||||||
|
|
||||||
|
sigaction(SIGBUS, &linux_crash_handler, NULL);
|
||||||
|
sigaction(SIGFPE, &linux_crash_handler, NULL);
|
||||||
|
sigaction(SIGILL, &linux_crash_handler, NULL);
|
||||||
|
sigaction(SIGSEGV, &linux_crash_handler, NULL);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -298,6 +298,7 @@ void djui_panel_player_create(struct DjuiBase* caller) {
|
||||||
DLANG(PALETTE, BUBBLEGUM),
|
DLANG(PALETTE, BUBBLEGUM),
|
||||||
DLANG(PALETTE, ICE_MARIO),
|
DLANG(PALETTE, ICE_MARIO),
|
||||||
DLANG(PALETTE, ICE_LUIGI),
|
DLANG(PALETTE, ICE_LUIGI),
|
||||||
|
DLANG(PALETTE, TOAD),
|
||||||
DLANG(PALETTE, CUSTOM),
|
DLANG(PALETTE, CUSTOM),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -12899,6 +12899,38 @@ int smlua_func_area_create_warp_node(lua_State* L) {
|
||||||
// level_update.h //
|
// level_update.h //
|
||||||
////////////////////
|
////////////////////
|
||||||
|
|
||||||
|
int smlua_func_get_painting_warp_node(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", "get_painting_warp_node", 0, top);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
smlua_push_object(L, LOT_WARPNODE, get_painting_warp_node());
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int smlua_func_initiate_painting_warp(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", "initiate_painting_warp", 1, top);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s16 paintingIndex = smlua_to_integer(L, 1);
|
||||||
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "initiate_painting_warp"); return 0; }
|
||||||
|
|
||||||
|
initiate_painting_warp(paintingIndex);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int smlua_func_level_trigger_warp(lua_State* L) {
|
int smlua_func_level_trigger_warp(lua_State* L) {
|
||||||
if (L == NULL) { return 0; }
|
if (L == NULL) { return 0; }
|
||||||
|
|
||||||
|
@ -30135,6 +30167,8 @@ void smlua_bind_functions_autogen(void) {
|
||||||
smlua_bind_function(L, "area_create_warp_node", smlua_func_area_create_warp_node);
|
smlua_bind_function(L, "area_create_warp_node", smlua_func_area_create_warp_node);
|
||||||
|
|
||||||
// level_update.h
|
// level_update.h
|
||||||
|
smlua_bind_function(L, "get_painting_warp_node", smlua_func_get_painting_warp_node);
|
||||||
|
smlua_bind_function(L, "initiate_painting_warp", smlua_func_initiate_painting_warp);
|
||||||
smlua_bind_function(L, "level_trigger_warp", smlua_func_level_trigger_warp);
|
smlua_bind_function(L, "level_trigger_warp", smlua_func_level_trigger_warp);
|
||||||
|
|
||||||
// mario.h
|
// mario.h
|
||||||
|
|
Loading…
Reference in a new issue