mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2026-04-27 12:31:47 +00:00
Merge branch 'dev' into deadzone
This commit is contained in:
commit
457103bad2
55 changed files with 904 additions and 240 deletions
|
|
@ -8207,7 +8207,13 @@ HOOK_MARIO_OVERRIDE_FLOOR_CLASS = 56 --- @type LuaHookedEventType
|
|||
HOOK_ON_ADD_SURFACE = 57 --- @type LuaHookedEventType
|
||||
HOOK_ON_CLEAR_AREAS = 58 --- @type LuaHookedEventType
|
||||
HOOK_ON_PACKET_BYTESTRING_RECEIVE = 59 --- @type LuaHookedEventType
|
||||
HOOK_MAX = 60 --- @type LuaHookedEventType
|
||||
HOOK_ON_FIND_WALL_COLLISION = 60 --- @type LuaHookedEventType
|
||||
HOOK_ON_FIND_CEIL = 61 --- @type LuaHookedEventType
|
||||
HOOK_ON_FIND_FLOOR = 62 --- @type LuaHookedEventType
|
||||
HOOK_ON_FIND_WATER_LEVEL = 63 --- @type LuaHookedEventType
|
||||
HOOK_ON_FIND_POISON_GAS_LEVEL = 64 --- @type LuaHookedEventType
|
||||
HOOK_ON_FIND_SURFACE_ON_RAY = 65 --- @type LuaHookedEventType
|
||||
HOOK_MAX = 66 --- @type LuaHookedEventType
|
||||
|
||||
--- @alias LuaHookedEventType
|
||||
--- | `HOOK_UPDATE`
|
||||
|
|
@ -8270,6 +8276,12 @@ HOOK_MAX = 60 --- @type LuaHookedEventType
|
|||
--- | `HOOK_ON_ADD_SURFACE`
|
||||
--- | `HOOK_ON_CLEAR_AREAS`
|
||||
--- | `HOOK_ON_PACKET_BYTESTRING_RECEIVE`
|
||||
--- | `HOOK_ON_FIND_WALL_COLLISION`
|
||||
--- | `HOOK_ON_FIND_CEIL`
|
||||
--- | `HOOK_ON_FIND_FLOOR`
|
||||
--- | `HOOK_ON_FIND_WATER_LEVEL`
|
||||
--- | `HOOK_ON_FIND_POISON_GAS_LEVEL`
|
||||
--- | `HOOK_ON_FIND_SURFACE_ON_RAY`
|
||||
--- | `HOOK_MAX`
|
||||
|
||||
--- @type integer
|
||||
|
|
@ -11254,7 +11266,7 @@ COOP_OBJ_FLAG_NON_SYNC = (1 << 2)
|
|||
COOP_OBJ_FLAG_INITIALIZED = (1 << 3)
|
||||
|
||||
--- @type string
|
||||
SM64COOPDX_VERSION = "v1.4.1"
|
||||
SM64COOPDX_VERSION = "v1.4.2"
|
||||
|
||||
--- @type string
|
||||
VERSION_TEXT = "v"
|
||||
|
|
|
|||
|
|
@ -10208,6 +10208,12 @@ function smlua_audio_utils_replace_sequence(sequenceId, bankId, defaultVolume, m
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @return integer
|
||||
--- Allocates a new sequence ID
|
||||
function smlua_audio_utils_allocate_sequence()
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param filename string
|
||||
--- @return ModAudio
|
||||
--- Loads an `audio` stream by `filename` (with extension)
|
||||
|
|
@ -11647,6 +11653,14 @@ function get_active_mod()
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @param mod Mod
|
||||
--- @param subDirectory? string
|
||||
--- @return table
|
||||
--- Gets all files a mod contains
|
||||
function get_mod_files(mod, subDirectory)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param title string
|
||||
--- Sets the window title to a custom title
|
||||
function set_window_title(title)
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ function update_chat_command_description(command, description)
|
|||
end
|
||||
|
||||
--- @param hookEventType LuaHookedEventType When a function should run
|
||||
--- @param func fun(...: any): any The function to run
|
||||
--- @param func fun(...: any): any?, any? The function to run
|
||||
--- Different hooks can pass in different parameters and have different return values. Be sure to read the hooks guide for more information.
|
||||
function hook_event(hookEventType, func)
|
||||
-- ...
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@
|
|||
extern "C" {
|
||||
#include "include/surface_terrains.h"
|
||||
#include "include/level_misc_macros.h"
|
||||
#include "include/special_presets.h"
|
||||
#include "include/special_preset_names.h"
|
||||
#include "src/engine/surface_load.h"
|
||||
}
|
||||
|
||||
// Free data pointers, but keep nodes and tokens intact
|
||||
|
|
@ -34,12 +36,32 @@ struct CollisionValidationData {
|
|||
u32 vtxCount;
|
||||
u32 triAlloc;
|
||||
u32 triCount;
|
||||
s16 surfaceType;
|
||||
u32 specialAlloc;
|
||||
u32 specialCount;
|
||||
u32 waterBoxAlloc;
|
||||
u32 waterBoxCount;
|
||||
};
|
||||
|
||||
static u8 GetSpecialObjectType(u8 preset) {
|
||||
for (s32 i = 0; i < ARRAY_COUNT(SpecialObjectPresets); ++i) {
|
||||
if (SpecialObjectPresets[i].preset_id == preset) {
|
||||
return SpecialObjectPresets[i].type;
|
||||
}
|
||||
}
|
||||
return SPTYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
static const char *GetCorrectSpecialObjectCommand(u8 presetType) {
|
||||
switch (presetType) {
|
||||
case SPTYPE_NO_YROT_OR_PARAMS: return "SPECIAL_OBJECT";
|
||||
case SPTYPE_YROT_NO_PARAMS: return "SPECIAL_OBJECT_WITH_YAW";
|
||||
case SPTYPE_PARAMS_AND_YROT: return "SPECIAL_OBJECT_WITH_YAW_AND_PARAM";
|
||||
case SPTYPE_DEF_PARAM_AND_YROT: return "SPECIAL_OBJECT_WITH_YAW";
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
static void ValidateColSectionChange(GfxData* aGfxData, struct CollisionValidationData& aColValData, u8 section) {
|
||||
if (aColValData.section == COL_SECTION_END) {
|
||||
PrintDataError("Found new col section after COL_END");
|
||||
|
|
@ -67,51 +89,70 @@ static void ValidateColInit(GfxData* aGfxData, struct CollisionValidationData& a
|
|||
ValidateColSectionChange(aGfxData, aColValData, COL_SECTION_VTX);
|
||||
}
|
||||
|
||||
static void ValidateColVertexInit(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 arg0) {
|
||||
static void ValidateColVertexInit(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 vertexCount) {
|
||||
if (strcmp(aColValData.lastSymbol, "COL_INIT") != 0) {
|
||||
PrintDataError("COL_VERTEX_INIT found outside of vertex section");
|
||||
}
|
||||
if (arg0 < 0) {
|
||||
PrintDataError("COL_VERTEX_INIT with a negative count: %d", arg0);
|
||||
if (vertexCount < 0) {
|
||||
PrintDataError("COL_VERTEX_INIT with a negative count: %d", vertexCount);
|
||||
}
|
||||
aColValData.vtxAlloc = arg0;
|
||||
aColValData.vtxAlloc = vertexCount;
|
||||
aColValData.vtxCount = 0;
|
||||
}
|
||||
|
||||
static void ValidateColVertex(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 arg0, s16 arg1, s16 arg2) {
|
||||
static void ValidateColVertex(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 x, s16 y, s16 z) {
|
||||
if (aColValData.section != COL_SECTION_VTX) {
|
||||
PrintDataError("COL_VERTEX found outside of vertex section");
|
||||
}
|
||||
aColValData.vtxCount++;
|
||||
}
|
||||
|
||||
static void ValidateColTriInit(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 arg0, s16 arg1) {
|
||||
if (arg1 < 0) {
|
||||
PrintDataError("COL_TRI_INIT with a negative count: %d", arg1);
|
||||
static void ValidateColTriInit(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 surfaceType, s16 triangleCount) {
|
||||
if (triangleCount < 0) {
|
||||
PrintDataError("COL_TRI_INIT with a negative count: %d", triangleCount);
|
||||
}
|
||||
ValidateColSectionChange(aGfxData, aColValData, COL_SECTION_TRI);
|
||||
aColValData.triAlloc = arg1;
|
||||
aColValData.triAlloc = triangleCount;
|
||||
aColValData.triCount = 0;
|
||||
aColValData.surfaceType = surfaceType;
|
||||
}
|
||||
|
||||
static void ValidateColTri(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 arg0, s16 arg1, s16 arg2) {
|
||||
static void ValidateColTri(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 vertex0, s16 vertex1, s16 vertex2) {
|
||||
if (aColValData.section != COL_SECTION_TRI) {
|
||||
PrintDataError("COL_TRI found outside of triangle section");
|
||||
}
|
||||
if (arg0 < 0 || arg0 > aColValData.vtxCount) {
|
||||
PrintDataError("COL_TRI used vertex outside of known range for first param: %d", arg0);
|
||||
if (surface_has_force(aColValData.surfaceType)) {
|
||||
PrintDataError("COL_TRI cannot be used by surface types with a force parameter: %d (use COL_TRI_SPECIAL instead)", aColValData.surfaceType);
|
||||
}
|
||||
if (arg1 < 0 || arg1 > aColValData.vtxCount) {
|
||||
PrintDataError("COL_TRI used vertex outside of known range for second param: %d", arg1);
|
||||
if (vertex0 < 0 || vertex0 > aColValData.vtxCount) {
|
||||
PrintDataError("COL_TRI used vertex outside of known range for first param: %d", vertex0);
|
||||
}
|
||||
if (arg2 < 0 || arg2 > aColValData.vtxCount) {
|
||||
PrintDataError("COL_TRI used vertex outside of known range for third param: %d", arg2);
|
||||
if (vertex1 < 0 || vertex1 > aColValData.vtxCount) {
|
||||
PrintDataError("COL_TRI used vertex outside of known range for second param: %d", vertex1);
|
||||
}
|
||||
if (vertex2 < 0 || vertex2 > aColValData.vtxCount) {
|
||||
PrintDataError("COL_TRI used vertex outside of known range for third param: %d", vertex2);
|
||||
}
|
||||
aColValData.triCount++;
|
||||
}
|
||||
|
||||
static void ValidateColTriSpecial(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 arg0, s16 arg1, s16 arg2, s16 arg3) {
|
||||
ValidateColTri(aGfxData, aColValData, arg0, arg1, arg2);
|
||||
static void ValidateColTriSpecial(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 vertex0, s16 vertex1, s16 vertex2, s16 force) {
|
||||
if (aColValData.section != COL_SECTION_TRI) {
|
||||
PrintDataError("COL_TRI_SPECIAL found outside of triangle section");
|
||||
}
|
||||
if (!surface_has_force(aColValData.surfaceType)) {
|
||||
PrintDataError("COL_TRI_SPECIAL cannot be used by surface types with no force parameter: %d (use COL_TRI instead)", aColValData.surfaceType);
|
||||
}
|
||||
if (vertex0 < 0 || vertex0 > aColValData.vtxCount) {
|
||||
PrintDataError("COL_TRI_SPECIAL used vertex outside of known range for first param: %d", vertex0);
|
||||
}
|
||||
if (vertex1 < 0 || vertex1 > aColValData.vtxCount) {
|
||||
PrintDataError("COL_TRI_SPECIAL used vertex outside of known range for second param: %d", vertex1);
|
||||
}
|
||||
if (vertex2 < 0 || vertex2 > aColValData.vtxCount) {
|
||||
PrintDataError("COL_TRI_SPECIAL used vertex outside of known range for third param: %d", vertex2);
|
||||
}
|
||||
aColValData.triCount++;
|
||||
}
|
||||
|
||||
static void ValidateColStop(GfxData* aGfxData, struct CollisionValidationData& aColValData) {
|
||||
|
|
@ -122,49 +163,70 @@ static void ValidateColEnd(GfxData* aGfxData, struct CollisionValidationData& aC
|
|||
ValidateColSectionChange(aGfxData, aColValData, COL_SECTION_END);
|
||||
}
|
||||
|
||||
static void ValidateColSpecialInit(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 arg0) {
|
||||
if (arg0 < 0) {
|
||||
PrintDataError("COL_SPECIAL_INIT with a negative count: %d", arg0);
|
||||
static void ValidateColSpecialInit(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 specialCount) {
|
||||
if (specialCount < 0) {
|
||||
PrintDataError("COL_SPECIAL_INIT with a negative count: %d", specialCount);
|
||||
}
|
||||
ValidateColSectionChange(aGfxData, aColValData, COL_SECTION_SPECIAL);
|
||||
aColValData.specialAlloc = arg0;
|
||||
aColValData.specialAlloc = specialCount;
|
||||
aColValData.specialCount = 0;
|
||||
}
|
||||
|
||||
static void ValidateColWaterBoxInit(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 arg0) {
|
||||
if (arg0 < 0) {
|
||||
PrintDataError("COL_WATER_BOX_INIT with a negative count: %d", arg0);
|
||||
static void ValidateColWaterBoxInit(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 waterBoxCount) {
|
||||
if (waterBoxCount < 0) {
|
||||
PrintDataError("COL_WATER_BOX_INIT with a negative count: %d", waterBoxCount);
|
||||
}
|
||||
ValidateColSectionChange(aGfxData, aColValData, COL_SECTION_WATER_BOX);
|
||||
aColValData.waterBoxAlloc = arg0;
|
||||
aColValData.waterBoxAlloc = waterBoxCount;
|
||||
aColValData.waterBoxCount = 0;
|
||||
}
|
||||
|
||||
static void ValidateColWaterBox(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 arg0, s16 arg1, s16 arg2, s16 arg3, s16 arg4, s16 arg5) {
|
||||
static void ValidateColWaterBox(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 id, s16 x1, s16 z1, s16 x2, s16 z2, s16 y) {
|
||||
if (aColValData.section != COL_SECTION_WATER_BOX) {
|
||||
PrintDataError("COL_WATER_BOX found outside of water box section");
|
||||
}
|
||||
aColValData.waterBoxCount++;
|
||||
}
|
||||
|
||||
static void ValidateColSpecialObject(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 arg0, s16 arg1, s16 arg2, s16 arg3) {
|
||||
static void ValidateColSpecialObject(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 preset, s16 posX, s16 posY, s16 posZ) {
|
||||
if (aColValData.section != COL_SECTION_SPECIAL) {
|
||||
PrintDataError("SPECIAL_OBJECT found outside of special section");
|
||||
}
|
||||
aColValData.specialCount++;
|
||||
}
|
||||
|
||||
static void ValidateColSpecialObjectWithYaw(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 arg0, s16 arg1, s16 arg2, s16 arg3, s16 arg4) {
|
||||
if (aColValData.section != COL_SECTION_SPECIAL) {
|
||||
PrintDataError("SPECIAL_OBJECT_WITH_YAW found outside of special section");
|
||||
u8 presetType = GetSpecialObjectType(preset);
|
||||
if (presetType == SPTYPE_UNKNOWN) {
|
||||
PrintDataError("SPECIAL_OBJECT has invalid preset: %d", preset);
|
||||
}
|
||||
if (presetType != SPTYPE_NO_YROT_OR_PARAMS) {
|
||||
PrintDataError("SPECIAL_OBJECT cannot be used with preset: %d (use %s instead)", preset, GetCorrectSpecialObjectCommand(presetType));
|
||||
}
|
||||
aColValData.specialCount++;
|
||||
}
|
||||
|
||||
static void ValidateColSpecialObjectWithYawAndParam(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 arg0, s16 arg1, s16 arg2, s16 arg3, s16 arg4, s16 arg5) {
|
||||
static void ValidateColSpecialObjectWithYaw(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 preset, s16 posX, s16 posY, s16 posZ, s16 yaw) {
|
||||
if (aColValData.section != COL_SECTION_SPECIAL) {
|
||||
PrintDataError("SPECIAL_OBJECT_WITH_YAW found outside of special section");
|
||||
}
|
||||
u8 presetType = GetSpecialObjectType(preset);
|
||||
if (presetType == SPTYPE_UNKNOWN) {
|
||||
PrintDataError("SPECIAL_OBJECT_WITH_YAW has invalid preset: %d", preset);
|
||||
}
|
||||
if (presetType != SPTYPE_YROT_NO_PARAMS && presetType != SPTYPE_DEF_PARAM_AND_YROT) {
|
||||
PrintDataError("SPECIAL_OBJECT_WITH_YAW cannot be used with preset: %d (use %s instead)", preset, GetCorrectSpecialObjectCommand(presetType));
|
||||
}
|
||||
aColValData.specialCount++;
|
||||
}
|
||||
|
||||
static void ValidateColSpecialObjectWithYawAndParam(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 preset, s16 posX, s16 posY, s16 posZ, s16 yaw, s16 param) {
|
||||
if (aColValData.section != COL_SECTION_SPECIAL) {
|
||||
PrintDataError("SPECIAL_OBJECT_WITH_YAW_AND_PARAM found outside of special section");
|
||||
}
|
||||
u8 presetType = GetSpecialObjectType(preset);
|
||||
if (presetType == SPTYPE_UNKNOWN) {
|
||||
PrintDataError("SPECIAL_OBJECT_WITH_YAW_AND_PARAM has invalid preset: %d", preset);
|
||||
}
|
||||
if (presetType != SPTYPE_PARAMS_AND_YROT) {
|
||||
PrintDataError("SPECIAL_OBJECT_WITH_YAW_AND_PARAM cannot be used with preset: %d (use %s instead)", preset, GetCorrectSpecialObjectCommand(presetType));
|
||||
}
|
||||
aColValData.specialCount++;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ extern "C" {
|
|||
#include "behavior_data.h"
|
||||
#include "pc/lua/smlua_hooks.h"
|
||||
|
||||
s8 geo_get_processing_mario_index(void);
|
||||
s8 geo_get_processing_mario_index(struct Object *obj);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -77,7 +77,7 @@ void DynOS_Anim_Swap(void *aPtr) {
|
|||
|
||||
// Animation index
|
||||
s32 _AnimIndex = -1;
|
||||
s8 index = geo_get_processing_mario_index();
|
||||
s8 index = geo_get_processing_mario_index(_Object);
|
||||
if (index != -1) {
|
||||
_AnimIndex = RetrieveCurrentMarioAnimationIndex(index);
|
||||
|
||||
|
|
|
|||
|
|
@ -3537,7 +3537,13 @@
|
|||
| HOOK_ON_ADD_SURFACE | 57 |
|
||||
| HOOK_ON_CLEAR_AREAS | 58 |
|
||||
| HOOK_ON_PACKET_BYTESTRING_RECEIVE | 59 |
|
||||
| HOOK_MAX | 60 |
|
||||
| HOOK_ON_FIND_WALL_COLLISION | 60 |
|
||||
| HOOK_ON_FIND_CEIL | 61 |
|
||||
| HOOK_ON_FIND_FLOOR | 62 |
|
||||
| HOOK_ON_FIND_WATER_LEVEL | 63 |
|
||||
| HOOK_ON_FIND_POISON_GAS_LEVEL | 64 |
|
||||
| HOOK_ON_FIND_SURFACE_ON_RAY | 65 |
|
||||
| HOOK_MAX | 66 |
|
||||
- MAX_HOOKED_BEHAVIORS
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
|
|
|||
|
|
@ -5616,6 +5616,27 @@ Replaces the sequence corresponding to `sequenceId` with one called `m64Name`.m6
|
|||
|
||||
<br />
|
||||
|
||||
## [smlua_audio_utils_allocate_sequence](#smlua_audio_utils_allocate_sequence)
|
||||
|
||||
### Description
|
||||
Allocates a new sequence ID
|
||||
|
||||
### Lua Example
|
||||
`local integerValue = smlua_audio_utils_allocate_sequence()`
|
||||
|
||||
### Parameters
|
||||
- None
|
||||
|
||||
### Returns
|
||||
- `integer`
|
||||
|
||||
### C Prototype
|
||||
`u8 smlua_audio_utils_allocate_sequence(void);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [audio_stream_load](#audio_stream_load)
|
||||
|
||||
### Description
|
||||
|
|
|
|||
|
|
@ -2107,6 +2107,30 @@ Gets the mod currently being processed
|
|||
|
||||
<br />
|
||||
|
||||
## [get_mod_files](#get_mod_files)
|
||||
|
||||
### Description
|
||||
Gets all files a mod contains
|
||||
|
||||
### Lua Example
|
||||
`local tableValue = get_mod_files(mod, subDirectory)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| mod | [Mod](structs.md#Mod) |
|
||||
| subDirectory | `string` |
|
||||
|
||||
### Returns
|
||||
- `table`
|
||||
|
||||
### C Prototype
|
||||
`LuaTable get_mod_files(struct Mod* mod, OPTIONAL const char* subDirectory);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [set_window_title](#set_window_title)
|
||||
|
||||
### Description
|
||||
|
|
|
|||
|
|
@ -1828,6 +1828,7 @@
|
|||
- smlua_audio_utils.h
|
||||
- [smlua_audio_utils_reset_all](functions-6.md#smlua_audio_utils_reset_all)
|
||||
- [smlua_audio_utils_replace_sequence](functions-6.md#smlua_audio_utils_replace_sequence)
|
||||
- [smlua_audio_utils_allocate_sequence](functions-6.md#smlua_audio_utils_allocate_sequence)
|
||||
- [audio_stream_load](functions-6.md#audio_stream_load)
|
||||
- [audio_stream_destroy](functions-6.md#audio_stream_destroy)
|
||||
- [audio_stream_play](functions-6.md#audio_stream_play)
|
||||
|
|
@ -2071,6 +2072,7 @@
|
|||
- [set_environment_region](functions-7.md#set_environment_region)
|
||||
- [mod_file_exists](functions-7.md#mod_file_exists)
|
||||
- [get_active_mod](functions-7.md#get_active_mod)
|
||||
- [get_mod_files](functions-7.md#get_mod_files)
|
||||
- [set_window_title](functions-7.md#set_window_title)
|
||||
- [reset_window_title](functions-7.md#reset_window_title)
|
||||
- [get_os_name](functions-7.md#get_os_name)
|
||||
|
|
|
|||
|
|
@ -151,6 +151,12 @@ The lua functions sent to `hook_event()` will be automatically called by SM64 wh
|
|||
| HOOK_MARIO_OVERRIDE_FLOOR_CLASS | Called when Mario's floor class logic updates, return a `SURFACE_CLASS_*` constant to override the type. | [MarioState](../structs.md#MarioState) mario, `integer` surfaceClass |
|
||||
| HOOK_ON_ADD_SURFACE | Called when collision surfaces are added. | [Surface](../structs.md#Surface) surface, `boolean` dynamic |
|
||||
| HOOK_ON_CLEAR_AREAS | Called when a level's areas are unloaded. | None |
|
||||
| HOOK_ON_FIND_WALL_COLLISION | Called after wall collision detection completes. You can modify the `colData` fields directly. Return a number to override `numCollisions` | `number` posX, `number` posY, `number` posZ, [WallCollisionData](../structs.md#WallCollisionData) colData |
|
||||
| HOOK_ON_FIND_CEIL | Called after ceiling detection completes. Return `height` to override height, or `height, surface` to override both | `number` posX, `number` posY, `number` posZ, [Surface](../structs.md#Surface) ceil, `number` height |
|
||||
| HOOK_ON_FIND_FLOOR | Called after floor detection completes. Return `height` to override height, or `height, surface` to override both | `number` posX, `number` posY, `number` posZ, [Surface](../structs.md#Surface) floor, `number` height |
|
||||
| HOOK_ON_FIND_WATER_LEVEL | Called after water level detection completes. Return a number to override the water level | `number` x, `number` z, `number` waterLevel |
|
||||
| HOOK_ON_FIND_POISON_GAS_LEVEL | Called after poison gas level detection completes. Return a number to override the gas level | `number` x, `number` z, `number` gasLevel |
|
||||
| HOOK_ON_FIND_SURFACE_ON_RAY | Called after ray-surface intersection completes. Return `surface` to override the hit surface, or `surface, hitPos` to override both | `Vec3f` orig, `Vec3f` dir, [Surface](../structs.md#Surface) hitSurface, `Vec3f` hitPos |
|
||||
|
||||
### Parameters
|
||||
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ N64_BINDS = "N64 Ovládání"
|
|||
EXTRA_BINDS = "Extra Ovládání"
|
||||
BACKGROUND_GAMEPAD = "Ovladač v pozadí"
|
||||
DISABLE_GAMEPADS = "Zakažte gamepady"
|
||||
EXTENDED_REPORTS = "Rozšířené zprávy"
|
||||
GAMEPAD = "Použít ovladač"
|
||||
DEADZONE = "Deadzone"
|
||||
RUMBLE_STRENGTH = "Síla vibrace"
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ N64_BINDS = "N64 Toetsen"
|
|||
EXTRA_BINDS = "Extra Toetsen"
|
||||
BACKGROUND_GAMEPAD = "Achtergrond Gamepad"
|
||||
DISABLE_GAMEPADS = "Gamepads uitschakelen"
|
||||
EXTENDED_REPORTS = "Uitgebreide rapporten"
|
||||
GAMEPAD = "Gamepad"
|
||||
DEADZONE = "Doode-zone"
|
||||
RUMBLE_STRENGTH = "Rommel Kracht"
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ N64_BINDS = "N64 Binds"
|
|||
EXTRA_BINDS = "Extra Binds"
|
||||
BACKGROUND_GAMEPAD = "Background Gamepad"
|
||||
DISABLE_GAMEPADS = "Disable Gamepads"
|
||||
EXTENDED_REPORTS = "Extended Reports"
|
||||
GAMEPAD = "Gamepad"
|
||||
DEADZONE = "Deadzone"
|
||||
RUMBLE_STRENGTH = "Rumble Strength"
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ N64_BINDS = "Touches N64"
|
|||
EXTRA_BINDS = "Touches Supplémentaires"
|
||||
BACKGROUND_GAMEPAD = "Manette en arrière plan"
|
||||
DISABLE_GAMEPADS = "Désactiver les manettes de jeu"
|
||||
EXTENDED_REPORTS = "Rapports détaillés"
|
||||
GAMEPAD = "Manette"
|
||||
DEADZONE = "Zone Morte"
|
||||
RUMBLE_STRENGTH = "Vibrations"
|
||||
|
|
|
|||
|
|
@ -46,10 +46,10 @@ NAMETAGS_MISSING_PARAMETERS = "Fehlende Parameter: [OPTION]"
|
|||
SELF_KICK = "Du kannst dich nicht selbst kicken."
|
||||
SELF_BAN = "Du kannst dich nicht selbst bannen."
|
||||
SELF_MOD = "Du kannst dich nicht selbst zum Moderator machen."
|
||||
KICK_CONFIRM = "Bist du sicher, dass du '@' vom Server kicken möchtest?\nGib '\\#a0ffa0\\/bestätigen\\#fff982\\' ein, um fortzufahren."
|
||||
BAN_CONFIRM = "Bist du sicher, dass du '@' vom Server bannen möchtest?\nGib '\\#a0ffa0\\/bestätigen\\#fff982\\' ein, um fortzufahren."
|
||||
PERM_BAN_CONFIRM = "Bist du sicher, dass du '@' dauerhaft vom Server bannen möchtest?\nGib '\\#a0ffa0\\/bestätigen\\#fff982\\' ein, um fortzufahren."
|
||||
MOD_CONFIRM = "Bist du sicher, dass du '@' zum Moderator ernennen möchtest?\nGib '\\#a0ffa0\\/bestätigen\\#fff982\\' ein."
|
||||
KICK_CONFIRM = "Bist du sicher, dass du '@' vom Server kicken möchtest?\nGib '\\#a0ffa0\\/confirm\\#fff982\\' ein, um fortzufahren."
|
||||
BAN_CONFIRM = "Bist du sicher, dass du '@' vom Server bannen möchtest?\nGib '\\#a0ffa0\\/confirm\\#fff982\\' ein, um fortzufahren."
|
||||
PERM_BAN_CONFIRM = "Bist du sicher, dass du '@' dauerhaft vom Server bannen möchtest?\nGib '\\#a0ffa0\\/confirm\\#fff982\\' ein, um fortzufahren."
|
||||
MOD_CONFIRM = "Bist du sicher, dass du '@' zum Moderator ernennen möchtest?\nGib '\\#a0ffa0\\/confirm\\#fff982\\' ein."
|
||||
PLAYERS_DESC = "/players - Zeige alle Spieler und ihre IDs."
|
||||
KICK_DESC = "/kick [NAME|ID] - Kicke einen Spieler vom Server."
|
||||
BAN_DESC = "/ban [NAME|ID] - Banne einen Spieler vom Server."
|
||||
|
|
@ -99,6 +99,7 @@ CONTROLS = "STEUERUNG"
|
|||
N64_BINDS = "N64-Einstellungen"
|
||||
EXTRA_BINDS = "Zusätzliche Einstellungen"
|
||||
BACKGROUND_GAMEPAD = "Hintergrund-Gamepad"
|
||||
EXTENDED_REPORTS = "Erweiterte Berichte"
|
||||
DISABLE_GAMEPADS = "Gamepads deaktivieren"
|
||||
GAMEPAD = "Gamepad"
|
||||
DEADZONE = "Tote Zone"
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ CONTROLS = "CONTROLLI"
|
|||
N64_BINDS = "Comandi N64"
|
||||
EXTRA_BINDS = "Comandi Extra"
|
||||
BACKGROUND_GAMEPAD = "Attivi in Background"
|
||||
EXTENDED_REPORTS = "Rapporti estesi"
|
||||
DISABLE_GAMEPADS = "Disabilita i Gamepad"
|
||||
GAMEPAD = "Controller"
|
||||
DEADZONE = "Zona Morta"
|
||||
|
|
|
|||
|
|
@ -1,61 +1,61 @@
|
|||
[NOTIF]
|
||||
CONNECTED = "@が接続しました"
|
||||
DISCONNECTED = "@が切断しました。"
|
||||
LEFT_THIS_LEVEL = "@がこのコースから出ました。"
|
||||
ENTERED_THIS_LEVEL = "@がこのコースに入りました。"
|
||||
ENTERED = "@が\n#に入りました。"
|
||||
SERVER_CLOSED = "\\#ffa0a0\\切断されました:\\#dcdcdc\\ 部屋が閉じられました。"
|
||||
DISCORD_ERROR = "Discordエラーが発生しました。\n解決するには、\n1. ゲームを終了し、\n2. Discordを再起動してから、\n3. もう一度ゲームを開いてください。"
|
||||
CONNECTED = "@ が参加しました"
|
||||
DISCONNECTED = "@ が退出しました"
|
||||
LEFT_THIS_LEVEL = "@ がこのコースから出ました"
|
||||
ENTERED_THIS_LEVEL = "@ がこのコースに入りました"
|
||||
ENTERED = "@ が \n# に入りました"
|
||||
SERVER_CLOSED = "\\#ffa0a0\\切断されました:\\#dcdcdc\\ ルームが閉じられました。"
|
||||
DISCORD_ERROR = "Discordエラーが発生しました。\n解決するには、\n1. ゲームを終了する\n2. Discordを再起動する\n3. もう一度ゲームを開く\nの手順で進めてください。"
|
||||
DISCORD_DETECT = "\\#ffa0a0\\エラー:\\#dcdcdc\\ Discordを検出できませんでした。\n\\#a0a0a0\\ゲームを終了し、Discordを再起動してから、もう一度お試しください。"
|
||||
DISCONNECT_FULL = "\\#ffa0a0\\切断されました:\\#dcdcdc\\ ルームが満員です。"
|
||||
DISCONNECT_KICK = "\\#ffa0a0\\切断されました:\\#dcdcdc\\ キックされました。"
|
||||
DISCONNECT_BAN = "\\#ffa0a0\\切断されました:\\#dcdcdc\\ BANされました。"
|
||||
DISCONNECT_REJOIN = "\\#ffa0a0\\切断されました:\\#dcdcdc\\ 再参加中です…"
|
||||
DISCONNECT_CLOSED = "\\#ffa0a0\\切断されました:\\#dcdcdc\\ ホストが切断しました。"
|
||||
DISCONNECT_BIG_MOD = "MODの量が多すぎます!\n切断しました。"
|
||||
DIED = "@がやられた!"
|
||||
DEBUG_FLY = "@がデバッグ飛行モードに入りました!"
|
||||
IMPORT_MOD_SUCCESS = "'@'\n\\#a0ffa0\\MODを読み込みました\\#dcdcdc\\"
|
||||
IMPORT_DYNOS_SUCCESS = "'@'\n\\#a0ffa0\\DynOSのパックを読み込みました\\#dcdcdc\\"
|
||||
IMPORT_PALETTE_SUCCESS = "'@'\n\\#a0ffa0\\パレットのプリセットを読み込みました\\#dcdcdc\\"
|
||||
IMPORT_FAIL = "'@'\n\\#ffa0a0\\読み込みに失敗しました。\\#dcdcdc\\"
|
||||
IMPORT_FAIL_INGAME = "\\#ffa0a0\\ゲーム中はMODを読み込めません"
|
||||
DISCONNECT_BIG_MOD = "このルームはMODの量が多すぎます。\n切断しました。"
|
||||
DIED = "@がやられた"
|
||||
DEBUG_FLY = "@がデバッグ飛行モードに入った"
|
||||
IMPORT_MOD_SUCCESS = "\\#a0ffa0\\MODをインポートしました:\n\\#dcdcdc\\@"
|
||||
IMPORT_DYNOS_SUCCESS = "\\#a0ffa0\\DynOSパックをインポートしました:\n\\#dcdcdc\\@"
|
||||
IMPORT_PALETTE_SUCCESS = "\\#a0ffa0\\パレットプリセットをインポートしました:\n\\#dcdcdc\\@"
|
||||
IMPORT_FAIL = "\\#ffa0a0\\インポートに失敗しました:\n\\#dcdcdc\\@"
|
||||
IMPORT_FAIL_INGAME = "\\#ffa0a0\\ゲーム中はMODをインポートできません"
|
||||
COOPNET_CONNECTION_FAILED = "\\#ffa0a0\\CoopNetに接続できませんでした!"
|
||||
COOPNET_DISCONNECTED = "\\#ffa0a0\\CoopNetとの接続が途絶えました!"
|
||||
COOPNET_DISCONNECTED = "\\#ffa0a0\\CoopNetとの接続が失われました!"
|
||||
LOBBY_NOT_FOUND = "\\#ffa0a0\\エラー:\\#dcdcdc\\ ルームがすでに閉じられています!"
|
||||
LOBBY_JOIN_FAILED = "\\#ffa0a0\\ルームに参加できませんでした。"
|
||||
LOBBY_PASSWORD_INCORRECT = "\\#ffa0a0\\パスワードが間違っています。"
|
||||
COOPNET_VERSION = "\\#ffa0a0\\あなたのバージョンはCoopNetに対応していません。アップデートしましょう!"
|
||||
PEER_FAILED = "\\#ffa0a0\\'@'への接続に失敗しました。"
|
||||
LOBBY_JOIN_FAILED = "\\#ffa0a0\\ルームへの参加に失敗しました!"
|
||||
LOBBY_PASSWORD_INCORRECT = "\\#ffa0a0\\パスワードが間違っています!"
|
||||
COOPNET_VERSION = "\\#ffa0a0\\あなたのゲームバージョンはCoopNetに対応していません。アップデートしましょう!"
|
||||
PEER_FAILED = "\\#ffa0a0\\プレイヤー @ への接続に失敗しました。"
|
||||
UNKNOWN = "未知"
|
||||
LOBBY_HOST = "部屋主"
|
||||
LOBBY_HOST = "ルームのホスト"
|
||||
UPDATE_AVAILABLE = "アップデートが利用可能です!"
|
||||
LATEST_VERSION = "最新バージョン"
|
||||
LATEST_VERSION = "最新のバージョン"
|
||||
YOUR_VERSION = "あなたのバージョン"
|
||||
|
||||
[CHAT]
|
||||
KICKING = "'@'をキックしました!"
|
||||
BANNING = "'@'をBANしました!"
|
||||
KICKING = "@ をキックしました!"
|
||||
BANNING = "@ をBANしました!"
|
||||
SERVER_ONLY = "このコマンドはホストのみが実行できます。"
|
||||
PERM_BANNING = "'@'を永久BANしました!"
|
||||
ADD_MODERATOR = "'@'をモデレーターにしました!"
|
||||
PLAYERS = "プレイヤー"
|
||||
PERM_BANNING = "@ を永久BANしました!"
|
||||
ADD_MODERATOR = "@ をモデレーターにしました!"
|
||||
PLAYERS = "ルーム内のプレイヤー"
|
||||
NO_PERMS = "このコマンドを実行する権限がありません。"
|
||||
PLAYER_NOT_FOUND = "プレイヤーが見つかりませんでした。"
|
||||
NAMETAGS_MISSING_PARAMETERS = "引数が不足しています: [OPTION]が必要です。"
|
||||
NAMETAGS_MISSING_PARAMETERS = "引数が不足しています: [OPTION] が必要です。"
|
||||
SELF_KICK = "自分自身はキックできません。"
|
||||
SELF_BAN = "自分自身はBANできません。"
|
||||
SELF_MOD = "自分自身をモデレーターにすることはできません。"
|
||||
KICK_CONFIRM = "本当に'@'を強制退出させますか?\n実行するには'\\#a0ffa0\\/confirm\\#fff982\\' と入力して確定します。"
|
||||
BAN_CONFIRM = "本当に'@'をBANしますか?\nBANするには'\\#a0ffa0\\/confirm\\#fff982\\' と入力して確定します。"
|
||||
PERM_BAN_CONFIRM = "本当に'@'を永久BANしますか?\nBANするには'\\#a0ffa0\\/confirm\\#fff982\\' と入力して確定します。"
|
||||
MOD_CONFIRM = "本当に'@'をモデレーターにしますか?\n'\\#a0ffa0\\/confirm\\#fff982\\' と入力して確定します。"
|
||||
PLAYERS_DESC = "/players - プレイヤー名とID一覧を表示します。"
|
||||
KICK_DESC = "/kick [NAME|ID] - プレイヤーを現在のルームからキックします。"
|
||||
BAN_DESC = "/ban [NAME|ID] - プレイヤーを現在のルームからBANします。"
|
||||
PERM_BAN_DESC = "/permban [NAME|ID] - プレイヤーをあなたが今後ホストするすべてのルームからBANします。"
|
||||
MOD_DESC = "/moderator [NAME|ID] - プレイヤーに/kick、/ban、/permbanのようなコマンドの使用を許可します。"
|
||||
NAMETAGS_DESC = "/nametags [show-tag|show-health] - あなたの体力やネームタグの表示を変更します。"
|
||||
KICK_CONFIRM = "本当に @ をキックしますか?\n実行するには'\\#a0ffa0\\/confirm\\#fff982\\' と入力して確定します。"
|
||||
BAN_CONFIRM = "本当に @ をBANしますか?\nBANするには'\\#a0ffa0\\/confirm\\#fff982\\' と入力して確定します。"
|
||||
PERM_BAN_CONFIRM = "本当に @ を永久BANしますか?\nBANするには'\\#a0ffa0\\/confirm\\#fff982\\' と入力して確定します。"
|
||||
MOD_CONFIRM = "本当に @ をモデレーターにしますか?\n'\\#a0ffa0\\/confirm\\#fff982\\' と入力して確定します。"
|
||||
PLAYERS_DESC = "/players - ルーム内のプレイヤー名とIDの一覧を表示します。"
|
||||
KICK_DESC = "/kick [プレイヤー名|ID] - 指定したプレイヤーを現在のルームからキックします。"
|
||||
BAN_DESC = "/ban [プレイヤー名|ID] - 指定したプレイヤーを現在のルームからBANします。"
|
||||
PERM_BAN_DESC = "/permban [プレイヤー名|ID] - 指定したプレイヤーをあなたが今後ホストするすべてのルームからBANします。"
|
||||
MOD_DESC = "/moderator [プレイヤー名|ID] - 指定したプレイヤーに/kick、/ban、/permbanのようなコマンドの使用を許可します。"
|
||||
NAMETAGS_DESC = "/nametags [show-tag|show-health] - あなたのネームタグ/体力の表示を変更します。"
|
||||
UNRECOGNIZED = "未知のコマンドです。"
|
||||
MOD_GRANTED = "\\#fff982\\あなたはモデレーターになりました。"
|
||||
|
||||
|
|
@ -70,8 +70,8 @@ CAMERA = "CAMERA"
|
|||
FREE_CAMERA = "フリーカメラ"
|
||||
ANALOG_CAMERA = "アナログカメラ"
|
||||
FREE_CAMERA_TITLE = "FREE CAMERA"
|
||||
FREE_CAMERA_L_CENTERING = "Lセンタリング"
|
||||
FREE_CAMERA_USE_DPAD = "DPad の動作"
|
||||
FREE_CAMERA_L_CENTERING = "Lボタンで前を向く"
|
||||
FREE_CAMERA_USE_DPAD = "十字キー操作"
|
||||
FREE_CAMERA_COLLISION = "カメラの衝突"
|
||||
ROMHACK_CAMERA_TITLE = "ROMHACK\nCAMERA"
|
||||
ROMHACK_CAMERA = "ロムハックカメラ"
|
||||
|
|
@ -79,55 +79,55 @@ ROMHACK_CAMERA_AUTOMATIC = "自動"
|
|||
ROMHACK_CAMERA_ON = "オン"
|
||||
ROMHACK_CAMERA_OFF = "オフ"
|
||||
ROMHACK_CAMERA_IN_BOWSER = "クッパ戦で使用"
|
||||
ROMHACK_CAMERA_COLLISION = "カメラの衝突"
|
||||
ROMHACK_CAMERA_L_CENTERING = "Lセンタリング"
|
||||
ROMHACK_CAMERA_USE_DPAD = "DPad の動作"
|
||||
ROMHACK_CAMERA_SLOW_FALL = "スローフォール"
|
||||
CAMERA_TOXIC_GAS = "有毒ガスの調整"
|
||||
ROMHACK_CAMERA_COLLISION = "カメラの当たり判定"
|
||||
ROMHACK_CAMERA_L_CENTERING = "Lボタンで前を向く"
|
||||
ROMHACK_CAMERA_USE_DPAD = "十字キー操作"
|
||||
ROMHACK_CAMERA_SLOW_FALL = "低速落下"
|
||||
CAMERA_TOXIC_GAS = "有毒ガス内での調整"
|
||||
MOUSE_LOOK = "マウスでの操作"
|
||||
INVERT_X = "X方向のカメラ反転"
|
||||
INVERT_Y = "Y方向のカメラ反転"
|
||||
X_SENSITIVITY = "X方向の感度"
|
||||
Y_SENSITIVITY = "Y方向の感度"
|
||||
AGGRESSION = "かたさ"
|
||||
PAN_LEVEL = "カメラのずれ"
|
||||
DECELERATION = "カメラ減速"
|
||||
ROMHACK_CAMERA_OFF = "オフ"
|
||||
AGGRESSION = "カメラの追従性"
|
||||
PAN_LEVEL = "カメラの水平速度"
|
||||
DECELERATION = "カメラ減速の強さ"
|
||||
|
||||
[CONTROLS]
|
||||
CONTROLS = "CONTROLS"
|
||||
|
||||
N64_BINDS = "ニンテンドウ64の入力"
|
||||
EXTRA_BINDS = "追加の入力"
|
||||
N64_BINDS = "ニンテンドウ64のボタン割り当て"
|
||||
EXTRA_BINDS = "追加のボタン割り当て"
|
||||
BACKGROUND_GAMEPAD = "バックグラウンドでのコントローラー認識"
|
||||
EXTENDED_REPORTS = "拡張レポート"
|
||||
DISABLE_GAMEPADS = "コントローラーを無効化"
|
||||
GAMEPAD = "コントローラー"
|
||||
DEADZONE = "デッドゾーン"
|
||||
RUMBLE_STRENGTH = "振動の強さ"
|
||||
|
||||
CHAT = "チャット"
|
||||
PLAYERS = "プレイヤーリストの表示"
|
||||
PLAYERS = "プレイヤーリスト"
|
||||
D_UP = "十字キー 上"
|
||||
D_DOWN = "十字キー 下"
|
||||
D_LEFT = "十字キー 左"
|
||||
D_RIGHT = "十字キー 右"
|
||||
X = "X"
|
||||
Y = "Y"
|
||||
X = "Xボタン"
|
||||
Y = "Yボタン"
|
||||
CONSOLE = "コンソール"
|
||||
PREV = "前のページ"
|
||||
NEXT = "次のページ"
|
||||
DISCONNECT = "切断"
|
||||
DISCONNECT = "ゲームから切断"
|
||||
|
||||
UP = "上"
|
||||
DOWN = "下"
|
||||
LEFT = "左"
|
||||
RIGHT = "右"
|
||||
A = "A"
|
||||
B = "B"
|
||||
START = "スタート"
|
||||
L = "L"
|
||||
R = "R"
|
||||
Z = "Z"
|
||||
UP = "3Dスティック 上"
|
||||
DOWN = "3Dスティック 下"
|
||||
LEFT = "3Dスティック 左"
|
||||
RIGHT = "3Dスティック 右"
|
||||
A = "Aボタン"
|
||||
B = "Bボタン"
|
||||
START = "STARTボタン"
|
||||
L = "Lトリガー"
|
||||
R = "Rトリガー"
|
||||
Z = "Zトリガー"
|
||||
C_UP = "Cボタン 上"
|
||||
C_DOWN = "Cボタン 下"
|
||||
C_LEFT = "Cボタン 左"
|
||||
|
|
@ -135,7 +135,7 @@ C_RIGHT = "Cボタン 右"
|
|||
|
||||
ANALOG_STICK_OPTIONS = "アナログスティックのオプション"
|
||||
|
||||
ROTATE_LEFT = "左スティックを90度回転させる"
|
||||
ROTATE_LEFT = "左スティックを90度回転"
|
||||
INVERT_LEFT_X = "左スティックX軸の反転"
|
||||
INVERT_LEFT_Y = "左スティックY軸の反転"
|
||||
ROTATE_RIGHT = "右スティックを90度回転"
|
||||
|
|
@ -153,7 +153,7 @@ AUTO = "自動"
|
|||
MANUAL = "手動"
|
||||
UNCAPPED = "無制限"
|
||||
FRAME_LIMIT = "FPSの制限"
|
||||
FAST = "速い"
|
||||
FAST = "高速"
|
||||
ACCURATE = "正確"
|
||||
INTERPOLATION = "補間"
|
||||
NEAREST = "ニアレスト"
|
||||
|
|
@ -196,24 +196,24 @@ LOCAL_PLAYER_MODEL_ONLY = "ローカルのキャラモデルに限定"
|
|||
|
||||
[HOST_MESSAGE]
|
||||
INFO_TITLE = "INFO"
|
||||
WARN_DISCORD = "招待したいフレンドを右クリックしてn'\\#d0d0ff\\ゲームに招待\\#dcdcdc\\'.\n\nを押すと招待できます。サーバー内のチャンネルにも、チャット横の\\#d0d0ff\\プラス\\#dcdcdc\\マークから招待メッセージを送信できます。\n\nゲーム アクティビティを\\#ffa0a0\\必ず\\#dcdcdc\\有効にしてください。\n\n\nオフラインに設定していると、招待の送信を\\#ffa0a0\\妨げる\\#dcdcdc\\可能性があります。"
|
||||
WARN_DISCORD2 = "\\#ffa0a0\\エラー:\\#dcdcdc\\Discordを検出できませんでした。\n\\#a0a0a0\\ゲームを終了し、Discordを再起動してから、もう一度お試しください。"
|
||||
WARN_SOCKET = "ファイアウォール設定が正しく設定されている事をご確認ください。\n直接接続には、ルータのポート転送でIPv4インバウンド接続を受信するように設定する\\#ffa0a0\\必要\\#dcdcdc\\があります。\n\nUDPポート'%d'番を開放してください。IPv6にも対応しています。"
|
||||
WARN_DISCORD = "招待したいフレンドを右クリックしてn'\\#d0d0ff\\ゲームに招待\\#dcdcdc\\'.\n\nを押すと招待できます。サーバー内のチャンネルにも、チャット入力欄の横にある\\#d0d0ff\\+\\#dcdcdc\\マークから招待メッセージを送信できます。\n\nDiscordのユーザー設定からゲーム アクティビティを\\#ffa0a0\\必ず\\#dcdcdc\\有効にしてください。\n\n\nステータスをオフラインに設定していると、招待の送信が\\#ffa0a0\\妨げられる\\#dcdcdc\\可能性があります。"
|
||||
WARN_DISCORD2 = "\\#ffa0a0\\エラー:\\#dcdcdc\\Discordを検出できませんでした。\n\\#a0a0a0\\ゲームを終了してDiscordを再起動してから、もう一度お試しください。"
|
||||
WARN_SOCKET = "ファイアウォールの設定が正しく完了していることを確認してください。\nダイレクト接続には\\#ffa0a0\\あなた自身が\\#dcdcdc\\ルーターでIPv4の接続を受け入れるようにポートフォワーディング設定を行う必要があります。\n\nUDPポート'\\#d0d0ff\\%d\\#dcdcdc\\'を解放してください。IPv6も使用可能です。"
|
||||
HOST = "ルームを作る"
|
||||
|
||||
[HOST_MODS]
|
||||
MODS = "MODS"
|
||||
CATEGORIES = "カテゴリ一覧"
|
||||
WARNING = "\\#ffffa0\\<注意>\\#dcdcdc\\ MOD数が10個以上になっています。ラグや不安定を防ぐため、いくつか無効にしてください"
|
||||
NO_MODS_FOUND = "MODが見つかりませんでした。"
|
||||
WARNING = "\\#ffffa0\\<注意>\\#dcdcdc\\ MODの数が10個以上になっています。ラグや不安定を防ぐため、いくつか無効にしてください。"
|
||||
NO_MODS_FOUND = "MODは見つかりませんでした。"
|
||||
|
||||
[HOST_MOD_CATEGORIES]
|
||||
ALL = "すべて"
|
||||
MISC = "その他"
|
||||
ROMHACKS = "ハックロム"
|
||||
GAMEMODES = "ゲームモード"
|
||||
MOVESETS = "ムーブセット"
|
||||
CHARACTER_SELECT = "キャラクター選択"
|
||||
ROMHACKS = "ロムハック系"
|
||||
GAMEMODES = "ゲームモード系"
|
||||
MOVESETS = "ムーブセット系"
|
||||
CHARACTER_SELECT = "追加キャラクター系"
|
||||
|
||||
[HOST_SAVE]
|
||||
SAVE_TITLE = "SAVE"
|
||||
|
|
@ -222,7 +222,7 @@ CONFIRM = "本当に消しますか?"
|
|||
ERASE = "消す"
|
||||
EDIT = "編集"
|
||||
EDIT_TITLE = "EDIT"
|
||||
EDIT_NAME = "ファイル名を変更:"
|
||||
EDIT_NAME = "マリオ @のおなまえ変更:"
|
||||
|
||||
[HOST_SETTINGS]
|
||||
SETTINGS = "SETTINGS"
|
||||
|
|
@ -235,7 +235,7 @@ NORMAL = "普通"
|
|||
TOO_MUCH = "最強"
|
||||
KNOCKBACK_STRENGTH = "ノックバックの強さ"
|
||||
CLASSIC_PVP = "クラシック"
|
||||
REVAMPED_PVP = "改良"
|
||||
REVAMPED_PVP = "改良型"
|
||||
PVP_MODE = "PvPモード"
|
||||
LEAVE_LEVEL = "コースを出る"
|
||||
STAY_IN_LEVEL = "コースに留まる"
|
||||
|
|
@ -243,14 +243,14 @@ NONSTOP = "ノンストップ"
|
|||
ON_STAR_COLLECTION = "スター取得時の動作"
|
||||
SKIP_INTRO_CUTSCENE = "イントロをスキップ"
|
||||
ENABLE_CHEATS = "チートを有効にする"
|
||||
BUBBLE_ON_DEATH = "やられた時にシャボンで復活"
|
||||
BUBBLE_ON_DEATH = "ミス時にシャボンで復活"
|
||||
NAMETAGS = "ネームタグを有効にする"
|
||||
MOD_DEV_MODE = "MOD開発モード"
|
||||
BOUNCY_BOUNDS_ON_CAP = "オン(制限付き)"
|
||||
BOUNCY_BOUNDS_ON_CAP = "オン(速度制限)"
|
||||
BOUNCY_BOUNDS_ON = "オン"
|
||||
BOUNCY_BOUNDS_OFF = "オフ"
|
||||
BOUNCY_LEVEL_BOUNDS = "コース境界での跳ね返り"
|
||||
AMOUNT_OF_PLAYERS = "最大人数"
|
||||
AMOUNT_OF_PLAYERS = "最大ルーム人数"
|
||||
PAUSE_ANYWHERE = "どこでもポーズ"
|
||||
|
||||
[HOST]
|
||||
|
|
@ -275,7 +275,7 @@ JOINING = "JOINING"
|
|||
[JOIN]
|
||||
JOIN_TITLE = "JOIN"
|
||||
JOIN_DISCORD = "\\#d0d0ff\\Discord\\#dcdcdc\\ロビーへの参加:\n\nゲームを開いたまま、招待メッセージの参加ボタンを押してください。\n\n「ゲームは終了しました」と表示されている場合は、招待を送信した人の名前をクリックして更新してください。"
|
||||
JOIN_SOCKET = "\\#d0d0ff\\ダイレクト接続\\#dcdcdc\\のIPとポートを入力してください:"
|
||||
JOIN_SOCKET = "\\#d0d0ff\\ダイレクト接続先\\#dcdcdc\\のIPアドレスとポート番号を入力してください:"
|
||||
JOIN = "参加する"
|
||||
PUBLIC_LOBBIES = "公開ルーム"
|
||||
PRIVATE_LOBBIES = "非公開ルーム"
|
||||
|
|
@ -283,14 +283,14 @@ DIRECT = "ダイレクト接続"
|
|||
|
||||
[RULES]
|
||||
RULES_TITLE = "RULES"
|
||||
RULE_1 = "1. 13歳以上であること。"
|
||||
RULE_2 = "2. 不快な言葉、中傷、攻撃的な言葉を使わないこと。"
|
||||
RULE_3 = "3. 非公式ビルドを使わないこと。"
|
||||
RULE_4 = "4. ゲームをエクスプロイトする外部ツールを使用しないこと。"
|
||||
RULE_5 = "5. 作者の許可なく、非公開MODを公開しないこと。"
|
||||
RULE_6 = "6. 全てのNSFWコンテンツは禁止です。"
|
||||
SUBJECT_TO_CHANGE = "ルールはアップデートで変更される可能性があります。"
|
||||
NOTICE = "公開ルームではルールをお守りください。"
|
||||
RULE_1 = "1. CoopNetの利用は13歳以上に限ります。"
|
||||
RULE_2 = "2. ハラスメント(嫌がらせ)、ヘイトスピーチ、差別用語、その他攻撃的な言動は禁止です。"
|
||||
RULE_3 = "3. CoopNetでは改造(改ざん)されていない正規のsm64coopdxのみが使用可能です。"
|
||||
RULE_4 = "4. ゲームの脆弱性を悪用するための外部ツールの使用は禁止です。"
|
||||
RULE_5 = "5. 作者の許可なく、未公開MODでルームをホストしないでください。"
|
||||
RULE_6 = "6. ポルノやフェティッシュなコンテンツは一切禁止されています。これにはMOD、キャラクター、成人向けロールプレイなどが含まれますが、これらに限定されません。"
|
||||
SUBJECT_TO_CHANGE = "これらのルールは今後のアップデートで変更される可能性があります。"
|
||||
NOTICE = "公開ルームでプレイするためにCoopNetへ接続した時点で、あなたはこれらのルールを遵守することに同意したものとみなされます。"
|
||||
RULES = "ルールを見る"
|
||||
|
||||
[MAIN]
|
||||
|
|
@ -307,27 +307,27 @@ LEVEL = "コース"
|
|||
STAFF_ROLL = "スタッフロール"
|
||||
MUSIC = "BGM"
|
||||
RANDOM_STAGE = "ランダムなステージ"
|
||||
PLAY_VANILLA_DEMOS = "バニラゲームのデモを再生"
|
||||
PLAY_VANILLA_DEMOS = "オリジナルゲームのデモを再生"
|
||||
|
||||
[MISC]
|
||||
DEBUG_TITLE = "DEBUG"
|
||||
FIXED_COLLISIONS = "修正された当たり判定"
|
||||
LUA_PROFILER = "Luaのプロファイラー"
|
||||
CTX_PROFILER = "Ctxのプロファイラー"
|
||||
DEBUG_PRINT = "デバッグ情報の表示"
|
||||
DEBUG_INFO = "デバッグの情報"
|
||||
DEBUG_ERRORS = "デバッグのエラー"
|
||||
DEBUG_PRINT = "デバッグログの表示"
|
||||
DEBUG_INFO = "デバッグ情報の表示"
|
||||
DEBUG_ERRORS = "デバッグエラーの表示"
|
||||
MISC_TITLE = "MISC"
|
||||
PAUSE_IN_SINGLEPLAYER = "ソロプレイでの一時停止"
|
||||
PAUSE_IN_SINGLEPLAYER = "1人プレイ中にポーズで一時停止を有効化"
|
||||
DISABLE_POPUPS = "ポップアップを無効にする"
|
||||
USE_STANDARD_KEY_BINDINGS_CHAT = "初期のチャット操作"
|
||||
USE_STANDARD_KEY_BINDINGS_CHAT = "旧式チャット操作"
|
||||
MENU_OPTIONS = "メニューの設定"
|
||||
INFORMATION = "情報"
|
||||
DEBUG = "デバッグ"
|
||||
LANGUAGE = "言語"
|
||||
COOP_COMPATIBILITY = "sm64ex-coopとの互換性を有効にする"
|
||||
R_BUTTON = "Rボタン - 設定"
|
||||
L_BUTTON = "Lボタン - アクティブなMODを再読み込み"
|
||||
L_BUTTON = "Lボタン - 有効化されたMODを再読み込み"
|
||||
|
||||
[INFORMATION]
|
||||
INFORMATION_TITLE = "INFO"
|
||||
|
|
@ -371,7 +371,7 @@ PLAYER_TITLE = "PLAYER"
|
|||
OVERALLS = "オーバーオール"
|
||||
SHIRT = "シャツ"
|
||||
GLOVES = "手袋"
|
||||
SHOES = "くつ"
|
||||
SHOES = "クツ"
|
||||
HAIR = "髪"
|
||||
SKIN = "肌"
|
||||
CAP = "帽子"
|
||||
|
|
@ -408,8 +408,8 @@ MASTER_VOLUME = "主音量"
|
|||
MUSIC_VOLUME = "BGM音量"
|
||||
SFX_VOLUME = "SE音量"
|
||||
ENV_VOLUME = "環境音量"
|
||||
FADEOUT = "遠い音のフェードアウト"
|
||||
MUTE_FOCUS_LOSS = "非フォーカス時にミュート"
|
||||
FADEOUT = "音の距離減衰"
|
||||
MUTE_FOCUS_LOSS = "非フォーカス時に音をミュート"
|
||||
|
||||
[LANGUAGE]
|
||||
LANGUAGE = "LANGUAGE"
|
||||
|
|
@ -428,12 +428,11 @@ Spanish = "スペイン語 (Español)"
|
|||
[LOBBIES]
|
||||
PUBLIC_LOBBIES = "PUBLIC ROOMS"
|
||||
PRIVATE_LOBBIES = "PRIVATE ROOMS"
|
||||
REFRESH = "更新"
|
||||
REFRESH = "更新する"
|
||||
REFRESHING = "更新中…"
|
||||
ENTER_PASSWORD = "部屋のパスワードを入力してください:"
|
||||
ENTER_PASSWORD = "ルームのパスワードを入力してください:"
|
||||
SEARCH = "検索"
|
||||
NONE_FOUND = "部屋が見つかりませんでした"
|
||||
NO_LOBBIES_FOUND = "ロビーは見つからなかった。"
|
||||
NO_LOBBIES_FOUND = "ルームが見つかりませんでした。"
|
||||
|
||||
[CHANGELOG]
|
||||
CHANGELOG_TITLE = "CHANGELOG"
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ CONTROLS = "STEROWANIE"
|
|||
N64_BINDS = "Przypisania N64"
|
||||
EXTRA_BINDS = "Dodatkowe Przypisania"
|
||||
BACKGROUND_GAMEPAD = "Gamepad w Tle"
|
||||
EXTENDED_REPORTS = "Rozszerzone raporty"
|
||||
DISABLE_GAMEPADS = "Wyłącz Gamepady"
|
||||
GAMEPAD = "Gamepad"
|
||||
DEADZONE = "Martwa Strefa"
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ CONTROLS = "CONTROLES"
|
|||
N64_BINDS = "N64"
|
||||
EXTRA_BINDS = "Outros"
|
||||
BACKGROUND_GAMEPAD = "Controle de fundo"
|
||||
EXTENDED_REPORTS = "Relatórios detalhados"
|
||||
DISABLE_GAMEPADS = "Desativar controles"
|
||||
GAMEPAD = "Controle"
|
||||
DEADZONE = "Zona morta"
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ CONTROLS = "CONTROLS"
|
|||
N64_BINDS = "Кнопки N64"
|
||||
EXTRA_BINDS = "Дополнительные кнопки"
|
||||
BACKGROUND_GAMEPAD = "Фоновый ввод"
|
||||
EXTENDED_REPORTS = "Расширенные отчеты"
|
||||
DISABLE_GAMEPADS = "Отключить геймпады"
|
||||
GAMEPAD = "Геймпад"
|
||||
DEADZONE = "Mёртвая зона"
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ N64_BINDS = "Botones de N64"
|
|||
EXTRA_BINDS = "Botones Adicionales"
|
||||
BACKGROUND_GAMEPAD = "Mando en segundo plano"
|
||||
DISABLE_GAMEPADS = "Desactivar mandos"
|
||||
EXTENDED_REPORTS = "Informes ampliados"
|
||||
GAMEPAD = "Mando"
|
||||
DEADZONE = "Zona muerta"
|
||||
RUMBLE_STRENGTH = "Intensidad de vibración"
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ struct SequenceChannel *allocate_sequence_channel(void) {
|
|||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LOG_ERROR("RAN OUT OF SEQUENCE CHANNELS FOR ALLOCATION!");
|
||||
return &gSequenceChannelNone;
|
||||
}
|
||||
|
|
@ -281,7 +281,7 @@ void sequence_player_init_channels_extended(struct SequencePlayer* seqPlayer, u6
|
|||
if (!seqPlayer) { return; }
|
||||
u64 channelBits = channelBitsLower;
|
||||
LOG_DEBUG("Enabling channels (extended) with corresponding bits %llX", channelBits);
|
||||
|
||||
|
||||
for (u32 i = 0; i < CHANNELS_MAX; i++) {
|
||||
if (i == sizeof(u64) * 8) {
|
||||
channelBits = channelBitsUpper;
|
||||
|
|
@ -350,9 +350,9 @@ void sequence_player_disable_channels_extended(struct SequencePlayer* seqPlayer,
|
|||
|
||||
void sequence_player_disable_all_channels(struct SequencePlayer *seqPlayer) {
|
||||
if (!seqPlayer) { return; }
|
||||
|
||||
|
||||
MUTEX_LOCK(gAudioThread);
|
||||
|
||||
|
||||
eu_stubbed_printf_0("SUBTRACK DIM\n");
|
||||
for (u32 i = 0; i < CHANNELS_MAX; i++) {
|
||||
struct SequenceChannel *seqChannel = seqPlayer->channels[i];
|
||||
|
|
@ -371,16 +371,16 @@ void sequence_player_disable_all_channels(struct SequencePlayer *seqPlayer) {
|
|||
seqPlayer->channels[i] = &gSequenceChannelNone;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MUTEX_UNLOCK(gAudioThread);
|
||||
}
|
||||
|
||||
void sequence_channel_enable(struct SequencePlayer *seqPlayer, u8 channelIndex, void *script) {
|
||||
if (!seqPlayer) { return; }
|
||||
if (channelIndex >= CHANNELS_MAX) { return; }
|
||||
|
||||
|
||||
MUTEX_LOCK(gAudioThread);
|
||||
|
||||
|
||||
struct SequenceChannel *seqChannel = seqPlayer->channels[channelIndex];
|
||||
s32 i;
|
||||
if (IS_SEQUENCE_CHANNEL_VALID(seqChannel) == FALSE) {
|
||||
|
|
@ -409,19 +409,19 @@ void sequence_channel_enable(struct SequencePlayer *seqPlayer, u8 channelIndex,
|
|||
seq_channel_layer_free(seqChannel, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LOG_DEBUG("Enabled sequence channel %d with script entry of %p", channelIndex, script);
|
||||
}
|
||||
|
||||
|
||||
MUTEX_UNLOCK(gAudioThread);
|
||||
}
|
||||
|
||||
void sequence_player_disable(struct SequencePlayer *seqPlayer) {
|
||||
if (!seqPlayer) { return; }
|
||||
MUTEX_LOCK(gAudioThread);
|
||||
|
||||
|
||||
LOG_DEBUG("Disabling sequence player %p", seqPlayer);
|
||||
|
||||
|
||||
sequence_player_disable_all_channels(seqPlayer);
|
||||
note_pool_clear(&seqPlayer->notePool);
|
||||
seqPlayer->finished = TRUE;
|
||||
|
|
@ -1620,7 +1620,7 @@ u8 get_instrument(struct SequenceChannel *seqChannel, u8 instId, struct Instrume
|
|||
}
|
||||
|
||||
void set_instrument(struct SequenceChannel *seqChannel, u8 instId) {
|
||||
if (instId >= 0x80) {
|
||||
if (instId >= 0x80 && instId <= 0x83) {
|
||||
seqChannel->instOrWave = instId;
|
||||
seqChannel->instrument = NULL;
|
||||
} else if (instId == 0x7f) {
|
||||
|
|
|
|||
|
|
@ -508,7 +508,7 @@ struct GraphNodeBackground *init_graph_node_background(struct DynamicPool *pool,
|
|||
: (backgroundFunc && background >= BACKGROUND_CUSTOM);
|
||||
|
||||
if (invalidBackground) {
|
||||
LOG_ERROR("invalid background id");
|
||||
LOG_ERROR("invalid background id %d", background);
|
||||
background = BACKGROUND_HAUNTED;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -827,7 +827,7 @@ OPTIMIZE_O3 bool mtxf_inverse_non_affine(VEC_OUT Mat4 dest, Mat4 src) {
|
|||
if (fabsf(aug[i][k]) > fabsf(aug[piv][k])) { piv = i; }
|
||||
}
|
||||
|
||||
if (fabsf(aug[piv][k]) < FLT_EPSILON) { return false; }
|
||||
if (fabsf(aug[piv][k]) < __FLT_EPSILON__) { return false; }
|
||||
|
||||
// swap pivot row into place
|
||||
if (piv != k) {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include "game/hardcoded.h"
|
||||
#include "pc/utils/misc.h"
|
||||
#include "pc/network/network.h"
|
||||
#include "pc/lua/smlua_hooks.h"
|
||||
|
||||
Vec3f gFindWallDirection = { 0 };
|
||||
u8 gFindWallDirectionActive = false;
|
||||
|
|
@ -343,6 +344,9 @@ s32 find_wall_collisions(struct WallCollisionData *colData) {
|
|||
s32 numCollisions = 0;
|
||||
s16 x = colData->x;
|
||||
s16 z = colData->z;
|
||||
f32 posX = colData->x;
|
||||
f32 posY = colData->y;
|
||||
f32 posZ = colData->z;
|
||||
|
||||
colData->numWalls = 0;
|
||||
|
||||
|
|
@ -371,6 +375,8 @@ s32 find_wall_collisions(struct WallCollisionData *colData) {
|
|||
// Increment the debug tracker.
|
||||
gNumCalls.wall += 1;
|
||||
|
||||
smlua_call_event_hooks(HOOK_ON_FIND_WALL_COLLISION, posX, posY, posZ, colData, &numCollisions);
|
||||
|
||||
return numCollisions;
|
||||
}
|
||||
|
||||
|
|
@ -544,6 +550,8 @@ f32 find_ceil(f32 posX, f32 posY, f32 posZ, RET struct Surface **pceil) {
|
|||
// Increment the debug tracker.
|
||||
gNumCalls.ceil += 1;
|
||||
|
||||
smlua_call_event_hooks(HOOK_ON_FIND_CEIL, posX, posY, posZ, pceil, &height);
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
|
|
@ -882,6 +890,8 @@ f32 find_floor(f32 xPos, f32 yPos, f32 zPos, RET struct Surface **pfloor) {
|
|||
// Increment the debug tracker.
|
||||
gNumCalls.floor += 1;
|
||||
|
||||
smlua_call_event_hooks(HOOK_ON_FIND_FLOOR, xPos, yPos, zPos, pfloor, &height);
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
|
|
@ -922,6 +932,8 @@ f32 find_water_level(f32 x, f32 z) {
|
|||
}
|
||||
}
|
||||
|
||||
smlua_call_event_hooks(HOOK_ON_FIND_WATER_LEVEL, x, z, &waterLevel);
|
||||
|
||||
return waterLevel;
|
||||
}
|
||||
|
||||
|
|
@ -963,6 +975,8 @@ f32 find_poison_gas_level(f32 x, f32 z) {
|
|||
}
|
||||
}
|
||||
|
||||
smlua_call_event_hooks(HOOK_ON_FIND_POISON_GAS_LEVEL, x, z, &gasLevel);
|
||||
|
||||
return gasLevel;
|
||||
}
|
||||
|
||||
|
|
@ -1227,6 +1241,7 @@ void find_surface_on_ray(Vec3f orig, Vec3f dir, struct Surface **hit_surface, Ve
|
|||
if (normalized_dir[1] >= 1.0f || normalized_dir[1] <= -1.0f)
|
||||
{
|
||||
find_surface_on_ray_cell(cellX, cellZ, orig, normalized_dir, dir_length, hit_surface, hit_pos, &max_length);
|
||||
smlua_call_event_hooks(HOOK_ON_FIND_SURFACE_ON_RAY, orig, dir, hit_surface, hit_pos);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1249,4 +1264,6 @@ void find_surface_on_ray(Vec3f orig, Vec3f dir, struct Surface **hit_surface, Ve
|
|||
cellX = (s16)fCellX;
|
||||
cellZ = (s16)fCellZ;
|
||||
}
|
||||
|
||||
smlua_call_event_hooks(HOOK_ON_FIND_SURFACE_ON_RAY, orig, dir, hit_surface, hit_pos);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,13 +70,9 @@ static inline void shift_UV_NORMAL(struct ScrollTarget *scroll, u16 vertcount, s
|
|||
verts[0]->n.flag++;
|
||||
} else {
|
||||
if (bhv < SCROLL_UV_X) {
|
||||
for (i = 0; i < vertcount; i++) {
|
||||
scroll->prevF32[i] = scroll->interpF32[i];
|
||||
}
|
||||
memcpy(scroll->prevF32, scroll->interpF32, vertcount * sizeof(f32));
|
||||
} else {
|
||||
for (i = 0; i < vertcount; i++) {
|
||||
scroll->prevS16[i] = scroll->interpS16[i];
|
||||
}
|
||||
memcpy(scroll->prevS16, scroll->interpS16, vertcount * sizeof(s16));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -133,19 +129,31 @@ void uv_update_scroll(void) {
|
|||
scroll->hasInterpInit = true;
|
||||
scroll->bhv = bhv;
|
||||
if (bhv < SCROLL_UV_X) {
|
||||
scroll->interpF32 = calloc(scroll->size, sizeof(f32));
|
||||
scroll->prevF32 = calloc(scroll->size, sizeof(f32));
|
||||
scroll->interpF32 = malloc(scroll->size * sizeof(f32));
|
||||
scroll->prevF32 = malloc(scroll->size * sizeof(f32));
|
||||
if (!scroll->interpF32 || !scroll->prevF32) {
|
||||
free(scroll->interpF32);
|
||||
free(scroll->prevF32);
|
||||
scroll->interpF32 = scroll->prevF32 = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
u8 bhvIndex = MIN(bhv, 2);
|
||||
for (u16 k = 0; k < scroll->size; k++) {
|
||||
for (u32 k = 0; k < scroll->size; k++) {
|
||||
scroll->interpF32[k] = verts[k]->n.ob[bhvIndex];
|
||||
}
|
||||
} else {
|
||||
scroll->interpS16 = calloc(scroll->size, sizeof(s16));
|
||||
scroll->prevS16 = calloc(scroll->size, sizeof(s16));
|
||||
scroll->interpS16 = malloc(scroll->size * sizeof(s16));
|
||||
scroll->prevS16 = malloc(scroll->size * sizeof(s16));
|
||||
if (!scroll->interpS16 || !scroll->prevS16) {
|
||||
free(scroll->interpS16);
|
||||
free(scroll->prevS16);
|
||||
scroll->interpS16 = scroll->prevS16 = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
u8 bhvIndex = MIN(bhv-SCROLL_UV_X, 1);
|
||||
for (u16 k = 0; k < scroll->size; k++) {
|
||||
for (u32 k = 0; k < scroll->size; k++) {
|
||||
scroll->interpS16[k] = verts[k]->n.tc[bhvIndex];
|
||||
}
|
||||
}
|
||||
|
|
@ -153,15 +161,9 @@ void uv_update_scroll(void) {
|
|||
|
||||
// Prepare for interpolation
|
||||
if (bhv < SCROLL_UV_X) {
|
||||
u8 bhvIndex = MIN(bhv, 2);
|
||||
for (u16 i = 0; i < scroll->size; i++) {
|
||||
scroll->prevF32[i] = verts[i]->n.ob[bhvIndex];
|
||||
}
|
||||
memcpy(scroll->prevF32, scroll->interpF32, scroll->size * sizeof(f32));
|
||||
} else {
|
||||
u8 bhvIndex = MIN(bhv-SCROLL_UV_X, 1);
|
||||
for (u16 i = 0; i < scroll->size; i++) {
|
||||
scroll->prevS16[i] = verts[i]->n.tc[bhvIndex];
|
||||
}
|
||||
memcpy(scroll->prevS16, scroll->interpS16, scroll->size * sizeof(s16));
|
||||
}
|
||||
scroll->needInterp = true;
|
||||
|
||||
|
|
|
|||
|
|
@ -594,8 +594,6 @@ void thread5_game_loop(UNUSED void *arg) {
|
|||
play_music(SEQ_PLAYER_SFX, SEQUENCE_ARGS(0, SEQ_SOUND_PLAYER), 0);
|
||||
set_sound_mode(save_file_get_sound_mode());
|
||||
|
||||
thread6_rumble_loop(NULL);
|
||||
|
||||
gGlobalTimer++;
|
||||
}
|
||||
|
||||
|
|
@ -609,6 +607,7 @@ void game_loop_one_iteration(void) {
|
|||
osContStartReadData(&gSIEventMesgQueue);
|
||||
}
|
||||
|
||||
thread6_rumble_loop(NULL);
|
||||
audio_game_loop_tick();
|
||||
config_gfx_pool();
|
||||
read_controller_inputs();
|
||||
|
|
|
|||
|
|
@ -2445,7 +2445,7 @@ void check_death_barrier(struct MarioState *m) {
|
|||
smlua_call_event_hooks(HOOK_ON_DEATH, m, &allowDeath);
|
||||
if (!allowDeath) { return; }
|
||||
|
||||
if (mario_can_bubble(m)) {
|
||||
if ((mario_can_bubble(m) && m->numLives > 0)) {
|
||||
switch (gCurrCourseNum) {
|
||||
case COURSE_COTMC: // (20) Cavern of the Metal Cap
|
||||
case COURSE_TOTWC: // (21) Tower of the Wing Cap
|
||||
|
|
|
|||
|
|
@ -878,8 +878,7 @@ void verify_warp(struct MarioState *m, bool killMario) {
|
|||
return;
|
||||
}
|
||||
|
||||
m->numLives--;
|
||||
if (m->numLives < 0) {
|
||||
if (m->numLives <= 0) {
|
||||
sDelayedWarpOp = WARP_OP_GAME_OVER;
|
||||
} else {
|
||||
sSourceWarpNodeId = WARP_NODE_DEATH;
|
||||
|
|
@ -934,8 +933,7 @@ s16 level_trigger_warp(struct MarioState *m, s32 warpOp) {
|
|||
break;
|
||||
|
||||
case WARP_OP_DEATH:
|
||||
m->numLives--;
|
||||
if (m->numLives <= -1) {
|
||||
if (m->numLives <= 0) {
|
||||
sDelayedWarpOp = WARP_OP_GAME_OVER;
|
||||
}
|
||||
sDelayedWarpTimer = 48;
|
||||
|
|
|
|||
|
|
@ -447,7 +447,7 @@ void mario_set_bubbled(struct MarioState* m) {
|
|||
gLocalBubbleCounter = 20;
|
||||
|
||||
drop_and_set_mario_action(m, ACT_BUBBLED, 0);
|
||||
if (m->numLives > -1) {
|
||||
if (m->numLives > 0) {
|
||||
m->numLives--;
|
||||
}
|
||||
m->healCounter = 0;
|
||||
|
|
|
|||
|
|
@ -1734,7 +1734,7 @@ s32 act_lava_boost(struct MarioState *m) {
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (mario_can_bubble(m)) {
|
||||
if ((mario_can_bubble(m) && m->numLives > 0)) {
|
||||
m->health = 0xFF;
|
||||
mario_set_bubbled(m);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -849,7 +849,7 @@ s32 common_death_handler(struct MarioState *m, s32 animation, s32 frameToDeathWa
|
|||
smlua_call_event_hooks(HOOK_ON_DEATH, m, &allowDeath);
|
||||
if (!allowDeath) { return animFrame; }
|
||||
|
||||
if (mario_can_bubble(m)) {
|
||||
if ((mario_can_bubble(m) && m->numLives > 0)) {
|
||||
mario_set_bubbled(m);
|
||||
} else {
|
||||
level_trigger_warp(m, WARP_OP_DEATH);
|
||||
|
|
@ -922,8 +922,7 @@ s32 act_quicksand_death(struct MarioState *m) {
|
|||
bool allowDeath = true;
|
||||
smlua_call_event_hooks(HOOK_ON_DEATH, m, &allowDeath);
|
||||
if (!allowDeath) { return FALSE; }
|
||||
|
||||
if (mario_can_bubble(m)) {
|
||||
if ((mario_can_bubble(m) && m->numLives > 0)) {
|
||||
mario_set_bubbled(m);
|
||||
} else {
|
||||
level_trigger_warp(m, WARP_OP_DEATH);
|
||||
|
|
@ -947,7 +946,7 @@ s32 act_eaten_by_bubba(struct MarioState *m) {
|
|||
smlua_call_event_hooks(HOOK_ON_DEATH, m, &allowDeath);
|
||||
if (!allowDeath) { return FALSE; }
|
||||
|
||||
if (mario_can_bubble(m)) {
|
||||
if ((mario_can_bubble(m) && m->numLives > 0)) {
|
||||
m->health = 0xFF;
|
||||
mario_set_bubbled(m);
|
||||
} else {
|
||||
|
|
@ -1437,6 +1436,12 @@ s32 act_exit_land_save_dialog(struct MarioState *m) {
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static void lose_life_after_death_exit(struct MarioState *m) {
|
||||
if (sDelayedWarpArg != WARP_ARG_EXIT_COURSE) {
|
||||
m->numLives--;
|
||||
}
|
||||
}
|
||||
|
||||
s32 act_death_exit(struct MarioState *m) {
|
||||
if (!m) { return 0; }
|
||||
if (15 < m->actionTimer++
|
||||
|
|
@ -1447,6 +1452,7 @@ s32 act_death_exit(struct MarioState *m) {
|
|||
play_character_sound(m, CHAR_SOUND_OOOF2);
|
||||
#endif
|
||||
queue_rumble_data_mario(m, 5, 80);
|
||||
lose_life_after_death_exit(m);
|
||||
// restore 7.75 units of health
|
||||
m->healCounter = 31;
|
||||
}
|
||||
|
|
@ -1463,6 +1469,7 @@ s32 act_unused_death_exit(struct MarioState *m) {
|
|||
#else
|
||||
play_character_sound(m, CHAR_SOUND_OOOF2);
|
||||
#endif
|
||||
lose_life_after_death_exit(m);
|
||||
// restore 7.75 units of health
|
||||
m->healCounter = 31;
|
||||
}
|
||||
|
|
@ -1479,6 +1486,7 @@ s32 act_falling_death_exit(struct MarioState *m) {
|
|||
#else
|
||||
play_character_sound(m, CHAR_SOUND_OOOF2);
|
||||
#endif
|
||||
lose_life_after_death_exit(m);
|
||||
queue_rumble_data_mario(m, 5, 80);
|
||||
// restore 7.75 units of health
|
||||
m->healCounter = 31;
|
||||
|
|
@ -1526,6 +1534,7 @@ s32 act_special_death_exit(struct MarioState *m) {
|
|||
|
||||
if (launch_mario_until_land(m, ACT_HARD_BACKWARD_GROUND_KB, CHAR_ANIM_BACKWARD_AIR_KB, -24.0f)) {
|
||||
queue_rumble_data_mario(m, 5, 80);
|
||||
lose_life_after_death_exit(m);
|
||||
m->healCounter = 31;
|
||||
}
|
||||
// show Mario
|
||||
|
|
@ -1829,7 +1838,7 @@ s32 act_squished(struct MarioState *m) {
|
|||
smlua_call_event_hooks(HOOK_ON_DEATH, m, &allowDeath);
|
||||
if (!allowDeath) { return FALSE; }
|
||||
|
||||
if (mario_can_bubble(m)) {
|
||||
if ((mario_can_bubble(m) && m->numLives > 0)) {
|
||||
mario_set_bubbled(m);
|
||||
} else {
|
||||
level_trigger_warp(m, WARP_OP_DEATH);
|
||||
|
|
@ -1880,7 +1889,7 @@ s32 act_squished(struct MarioState *m) {
|
|||
smlua_call_event_hooks(HOOK_ON_DEATH, m, &allowDeath);
|
||||
if (!allowDeath) { return FALSE; }
|
||||
|
||||
if (mario_can_bubble(m)) {
|
||||
if ((mario_can_bubble(m) && m->numLives > 0)) {
|
||||
mario_set_bubbled(m);
|
||||
} else {
|
||||
// 0 units of health
|
||||
|
|
|
|||
|
|
@ -1003,7 +1003,7 @@ static s32 act_drowning(struct MarioState *m) {
|
|||
smlua_call_event_hooks(HOOK_ON_DEATH, m, &allowDeath);
|
||||
if (!allowDeath) { return FALSE; }
|
||||
|
||||
if (mario_can_bubble(m)) {
|
||||
if ((mario_can_bubble(m) && m->numLives > 0)) {
|
||||
mario_set_bubbled(m);
|
||||
} else {
|
||||
level_trigger_warp(m, WARP_OP_DEATH);
|
||||
|
|
@ -1038,7 +1038,7 @@ static s32 act_water_death(struct MarioState *m) {
|
|||
smlua_call_event_hooks(HOOK_ON_DEATH, m, &allowDeath);
|
||||
if (!allowDeath) { return FALSE; }
|
||||
|
||||
if (mario_can_bubble(m)) {
|
||||
if ((mario_can_bubble(m) && m->numLives > 0)) {
|
||||
mario_set_bubbled(m);
|
||||
} else {
|
||||
level_trigger_warp(m, WARP_OP_DEATH);
|
||||
|
|
@ -1164,7 +1164,7 @@ static s32 act_caught_in_whirlpool(struct MarioState *m) {
|
|||
smlua_call_event_hooks(HOOK_ON_DEATH, m, &allowDeath);
|
||||
if (!allowDeath) { reset_rumble_timers(m); return FALSE; }
|
||||
|
||||
if (mario_can_bubble(m)) {
|
||||
if ((mario_can_bubble(m) && m->numLives > 0)) {
|
||||
mario_set_bubbled(m);
|
||||
} else {
|
||||
level_trigger_warp(m, WARP_OP_DEATH);
|
||||
|
|
|
|||
|
|
@ -334,13 +334,13 @@ static Gfx *make_gfx_mario_alpha(struct GraphNodeGenerated *node, s16 alpha) {
|
|||
}
|
||||
|
||||
// Calculates if the processing geo is a mirror mario
|
||||
static s8 geo_get_processing_mirror_mario_index() {
|
||||
ptrdiff_t ptrDiff = (struct GraphNodeObject *) gCurGraphNodeProcessingObject - gMirrorMario;
|
||||
static s8 geo_get_processing_mirror_mario_index(struct Object *obj) {
|
||||
ptrdiff_t ptrDiff = (struct GraphNodeObject *) obj - gMirrorMario;
|
||||
return (ptrDiff >= 0 && ptrDiff < MAX_PLAYERS) ? ptrDiff : -1;
|
||||
}
|
||||
|
||||
static u8 geo_get_processing_object_index(void) {
|
||||
s8 index = geo_get_processing_mirror_mario_index();
|
||||
s8 index = geo_get_processing_mirror_mario_index(gCurGraphNodeProcessingObject);
|
||||
if (index != -1) {
|
||||
return index;
|
||||
}
|
||||
|
|
@ -351,19 +351,19 @@ static u8 geo_get_processing_object_index(void) {
|
|||
return (index >= MAX_PLAYERS) ? 0 : index;
|
||||
}
|
||||
|
||||
s8 geo_get_processing_mario_index(void) {
|
||||
if (gCurGraphNodeProcessingObject == NULL) { return -1; }
|
||||
s8 geo_get_processing_mario_index(struct Object *obj) {
|
||||
if (obj == NULL) { return -1; }
|
||||
|
||||
s8 index = geo_get_processing_mirror_mario_index();
|
||||
s8 index = geo_get_processing_mirror_mario_index(obj);
|
||||
if (index != -1) {
|
||||
return index;
|
||||
}
|
||||
|
||||
if (gCurGraphNodeProcessingObject->behavior != bhvMario) {
|
||||
if (obj->behavior != bhvMario) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
index = gCurGraphNodeProcessingObject->oBehParams - 1;
|
||||
index = obj->oBehParams - 1;
|
||||
return (index >= MAX_PLAYERS) ? -1 : index;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,19 +13,16 @@ struct ScrollTarget *get_scroll_targets(u32 id, u16 size, u16 offset) {
|
|||
if (scroll) {
|
||||
|
||||
// If we need to, realloc the block of vertices
|
||||
if ((!scroll->hasOffset && offset > 0) || size < scroll->size) {
|
||||
if (scroll->hasOffset) { return NULL; }
|
||||
if (!scroll->hasOffset && (offset > 0 || size < scroll->size)) {
|
||||
if (size > scroll->size) { size = scroll->size; } // Don't use an invalid size
|
||||
if (size + offset >= scroll->size) { return NULL; } // If the offset is invalid, Abort.
|
||||
scroll->hasOffset = true;
|
||||
Vtx* *newVtx = calloc(size, sizeof(Vtx*));
|
||||
if (offset > 0 && size + offset >= scroll->size) { return NULL; } // If the offset is invalid, Abort.
|
||||
Vtx* *newVtx = malloc(size * sizeof(Vtx*));
|
||||
if (!newVtx) { return NULL; }
|
||||
for (u32 i = 0; i < size; i++) {
|
||||
newVtx[i] = scroll->vertices[i + offset];
|
||||
}
|
||||
memcpy(newVtx, scroll->vertices + offset, size * sizeof(Vtx*));
|
||||
free(scroll->vertices);
|
||||
scroll->vertices = newVtx;
|
||||
scroll->size = size;
|
||||
scroll->hasOffset = true;
|
||||
}
|
||||
|
||||
return scroll;
|
||||
|
|
@ -51,11 +48,18 @@ struct ScrollTarget* find_or_create_scroll_targets(u32 id, bool hasOffset) {
|
|||
}
|
||||
|
||||
if (scroll == NULL) {
|
||||
scroll = calloc(1, sizeof(struct ScrollTarget));
|
||||
scroll = malloc(sizeof(struct ScrollTarget));
|
||||
scroll->id = id;
|
||||
scroll->size = 0;
|
||||
scroll->vertices = NULL;
|
||||
scroll->hasOffset = hasOffset;
|
||||
scroll->hasInterpInit = false;
|
||||
scroll->needInterp = false;
|
||||
scroll->interpF32 = NULL;
|
||||
scroll->prevF32 = NULL;
|
||||
scroll->interpS16 = NULL;
|
||||
scroll->prevS16 = NULL;
|
||||
scroll->bhv = 0;
|
||||
hmap_put(sScrollTargets, id, scroll);
|
||||
}
|
||||
|
||||
|
|
@ -77,8 +81,11 @@ void add_vtx_scroll_target(u32 id, Vtx *vtx, u32 size, bool hasOffset) {
|
|||
Vtx* *newArray = realloc(scroll->vertices, newSize);
|
||||
|
||||
if (!newArray) {
|
||||
newArray = calloc(1, newSize);
|
||||
memcpy(newArray, scroll->vertices, oldSize);
|
||||
newArray = malloc(newSize);
|
||||
if (!newArray) { return; }
|
||||
if (scroll->vertices && oldSize > 0) {
|
||||
memcpy(newArray, scroll->vertices, oldSize);
|
||||
}
|
||||
free(scroll->vertices);
|
||||
}
|
||||
|
||||
|
|
@ -133,13 +140,13 @@ void patch_scroll_targets_interpolated(f32 delta) {
|
|||
Vtx* *verts = scroll->vertices;
|
||||
if (scroll->bhv < SCROLL_UV_X) {
|
||||
u8 bhvIndex = MIN(scroll->bhv, 2);
|
||||
for (u16 k = 0; k < scroll->size; k++) {
|
||||
for (u32 k = 0; k < scroll->size; k++) {
|
||||
f32 diff = wrap_f32(scroll->interpF32[k] - scroll->prevF32[k]);
|
||||
verts[k]->n.ob[bhvIndex] = wrap_f32(scroll->prevF32[k] + diff * delta);
|
||||
}
|
||||
} else {
|
||||
u8 bhvIndex = MIN(scroll->bhv-SCROLL_UV_X, 1);
|
||||
for (u16 k = 0; k < scroll->size; k++) {
|
||||
for (u32 k = 0; k < scroll->size; k++) {
|
||||
s32 diff = wrap_s32(scroll->interpS16[k] - scroll->prevS16[k]);
|
||||
verts[k]->n.tc[bhvIndex] = wrap_s32(scroll->prevS16[k] + diff * delta);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,6 +127,7 @@ unsigned int configStickDeadzone = 16;
|
|||
unsigned int configRumbleStrength = 50;
|
||||
unsigned int configGamepadNumber = 0;
|
||||
bool configBackgroundGamepad = true;
|
||||
bool configExtendedReports = false;
|
||||
bool configDisableGamepads = false;
|
||||
bool configUseStandardKeyBindingsChat = false;
|
||||
bool configSmoothScrolling = false;
|
||||
|
|
@ -270,6 +271,7 @@ static const struct ConfigOption options[] = {
|
|||
{.name = "rumble_strength", .type = CONFIG_TYPE_UINT, .uintValue = &configRumbleStrength},
|
||||
{.name = "gamepad_number", .type = CONFIG_TYPE_UINT, .uintValue = &configGamepadNumber},
|
||||
{.name = "background_gamepad", .type = CONFIG_TYPE_UINT, .boolValue = &configBackgroundGamepad},
|
||||
{.name = "extended_reports", .type = CONFIG_TYPE_BOOL, .boolValue = &configExtendedReports},
|
||||
#ifndef HANDHELD
|
||||
{.name = "disable_gamepads", .type = CONFIG_TYPE_BOOL, .boolValue = &configDisableGamepads},
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ extern unsigned int configStickDeadzone;
|
|||
extern unsigned int configRumbleStrength;
|
||||
extern unsigned int configGamepadNumber;
|
||||
extern bool configBackgroundGamepad;
|
||||
extern bool configExtendedReports;
|
||||
extern bool configDisableGamepads;
|
||||
extern bool configUseStandardKeyBindingsChat;
|
||||
extern bool configSmoothScrolling;
|
||||
|
|
|
|||
|
|
@ -106,11 +106,17 @@ const char* translate_bind_to_name(int bind) {
|
|||
// mouse
|
||||
if (bind >= VK_BASE_SDL_MOUSE) {
|
||||
int mouse_button = (bind - VK_BASE_SDL_MOUSE);
|
||||
if (mouse_button == 1) { return "L Mouse"; }
|
||||
if (mouse_button == 2) { return "M Mouse"; }
|
||||
if (mouse_button == 3) { return "R Mouse"; }
|
||||
snprintf(name, 8, "Mouse %d", bind - VK_BASE_SDL_MOUSE);
|
||||
return name;
|
||||
switch (mouse_button) {
|
||||
case 1: return "L Mouse";
|
||||
case 2: return "M Mouse";
|
||||
case 3: return "R Mouse";
|
||||
case 6: return "Scroll Up";
|
||||
case 7: return "Scroll Down";
|
||||
default: {
|
||||
snprintf(name, 11, "Mouse %d", mouse_button);
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// gamepad
|
||||
|
|
|
|||
|
|
@ -116,6 +116,11 @@ void controller_mouse_read_relative(void) {
|
|||
#elif defined(CAPI_SDL1) || defined(CAPI_SDL2)
|
||||
mouse_buttons = SDL_GetRelativeMouseState(&mouse_x, &mouse_y);
|
||||
#endif
|
||||
if (mouse_scroll_y > 0) {
|
||||
mouse_buttons |= MWHEELUP;
|
||||
} else if (mouse_scroll_y < 0) {
|
||||
mouse_buttons |= MWHEELDOWN;
|
||||
}
|
||||
}
|
||||
|
||||
void controller_mouse_enter_relative(void) {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
// mouse buttons are also in the controller namespace, just offset 0x100
|
||||
#define VK_OFS_SDL_MOUSE 0x0100
|
||||
#define VK_BASE_SDL_MOUSE (VK_BASE_SDL_GAMEPAD + VK_OFS_SDL_MOUSE)
|
||||
#define MWHEELUP 0x20
|
||||
#define MWHEELDOWN 0x40
|
||||
|
||||
extern struct ControllerAPI controller_sdl;
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ static SDL_GameController *sdl_cntrl = NULL;
|
|||
static SDL_Joystick *sdl_joystick = NULL;
|
||||
static SDL_Haptic *sdl_haptic = NULL;
|
||||
|
||||
static bool sExtendedReports = false;
|
||||
static bool sBackgroundGamepad = false;
|
||||
|
||||
static u32 num_joy_binds = 0;
|
||||
|
|
@ -60,11 +61,11 @@ static s16 invert_s16(s16 val) {
|
|||
static inline void controller_add_binds(const u32 mask, const u32 *btns) {
|
||||
for (u32 i = 0; i < MAX_BINDS; ++i) {
|
||||
if (btns[i] >= VK_BASE_SDL_GAMEPAD && btns[i] <= VK_BASE_SDL_GAMEPAD + VK_SIZE) {
|
||||
if (btns[i] >= VK_BASE_SDL_MOUSE && num_joy_binds < MAX_JOYBINDS) {
|
||||
if (btns[i] >= VK_BASE_SDL_MOUSE && num_mouse_binds < MAX_JOYBINDS) {
|
||||
mouse_binds[num_mouse_binds][0] = btns[i] - VK_BASE_SDL_MOUSE;
|
||||
mouse_binds[num_mouse_binds][1] = mask;
|
||||
++num_mouse_binds;
|
||||
} else if (num_mouse_binds < MAX_JOYBINDS) {
|
||||
} else if (num_joy_binds < MAX_JOYBINDS) {
|
||||
joy_binds[num_joy_binds][0] = btns[i] - VK_BASE_SDL_GAMEPAD;
|
||||
joy_binds[num_joy_binds][1] = mask;
|
||||
++num_joy_binds;
|
||||
|
|
@ -102,6 +103,13 @@ static void controller_sdl_bind(void) {
|
|||
}
|
||||
|
||||
static void controller_sdl_init(void) {
|
||||
// Allows extended reports on PS4 and PS5 controllers
|
||||
if (configExtendedReports) {
|
||||
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, "1");
|
||||
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1");
|
||||
}
|
||||
sExtendedReports = configExtendedReports;
|
||||
|
||||
// Allows game to be controlled by gamepad when not in focus
|
||||
if (configBackgroundGamepad) {
|
||||
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
|
||||
|
|
@ -212,14 +220,23 @@ static void controller_sdl_read(OSContPad *pad) {
|
|||
controller_mouse_read_relative();
|
||||
u32 mouse = mouse_buttons;
|
||||
|
||||
u32 buttons_down = 0;
|
||||
if (!gInteractableOverridePad) {
|
||||
for (u32 i = 0; i < num_mouse_binds; ++i)
|
||||
if (mouse & SDL_BUTTON(mouse_binds[i][0]))
|
||||
pad->button |= mouse_binds[i][1];
|
||||
buttons_down |= mouse_binds[i][1];
|
||||
}
|
||||
pad->button |= buttons_down;
|
||||
// remember buttons that changed from 0 to 1
|
||||
last_mouse = (mouse_prev ^ mouse) & mouse;
|
||||
|
||||
if (configExtendedReports != sExtendedReports) {
|
||||
sExtendedReports = configExtendedReports;
|
||||
char* hint = sExtendedReports ? "1" : "0";
|
||||
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, hint);
|
||||
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, hint);
|
||||
}
|
||||
|
||||
if (configBackgroundGamepad != sBackgroundGamepad) {
|
||||
sBackgroundGamepad = configBackgroundGamepad;
|
||||
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, sBackgroundGamepad ? "1" : "0");
|
||||
|
|
@ -304,7 +321,6 @@ static void controller_sdl_read(OSContPad *pad) {
|
|||
update_button(VK_LTRIGGER - VK_BASE_SDL_GAMEPAD, ltrig > AXIS_THRESHOLD);
|
||||
update_button(VK_RTRIGGER - VK_BASE_SDL_GAMEPAD, rtrig > AXIS_THRESHOLD);
|
||||
|
||||
u32 buttons_down = 0;
|
||||
for (u32 i = 0; i < num_joy_binds; ++i)
|
||||
if (joy_buttons[joy_binds[i][0]])
|
||||
buttons_down |= joy_binds[i][1];
|
||||
|
|
|
|||
|
|
@ -533,8 +533,6 @@ static void djui_hud_print_text_internal(const char* message, f32 x, f32 y, f32
|
|||
if (message == NULL) { return; }
|
||||
gDjuiHudUtilsZ += 0.001f;
|
||||
|
||||
if (djui_hud_text_font_is_legacy()) { scale *= 0.5f; }
|
||||
|
||||
const struct DjuiFont* font = djui_hud_get_text_font();
|
||||
f32 fontScale = font->defaultFontScale * scale;
|
||||
|
||||
|
|
@ -654,13 +652,22 @@ static void djui_hud_print_text_internal(const char* message, f32 x, f32 y, f32
|
|||
}
|
||||
|
||||
void djui_hud_print_text(const char* message, f32 x, f32 y, f32 scale) {
|
||||
if (message == NULL) { return; }
|
||||
|
||||
if (djui_hud_text_font_is_legacy()) {
|
||||
scale *= 0.5f;
|
||||
}
|
||||
|
||||
djui_hud_print_text_internal(message, x, y, scale, NULL);
|
||||
}
|
||||
|
||||
void djui_hud_print_text_interpolated(const char* message, f32 prevX, f32 prevY, f32 prevScale, f32 x, f32 y, f32 scale) {
|
||||
if (message == NULL) { return; }
|
||||
|
||||
if (djui_hud_text_font_is_legacy()) { prevScale *= 0.5f; }
|
||||
if (djui_hud_text_font_is_legacy()) {
|
||||
scale *= 0.5f;
|
||||
prevScale *= 0.5f;
|
||||
}
|
||||
|
||||
struct InterpHud *interp = djui_hud_create_interp();
|
||||
if (interp) {
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@ void djui_panel_controls_create(struct DjuiBase* caller) {
|
|||
djui_checkbox_create(body, DLANG(MISC, USE_STANDARD_KEY_BINDINGS_CHAT), &configUseStandardKeyBindingsChat, NULL);
|
||||
|
||||
#ifdef HAVE_SDL2
|
||||
djui_checkbox_create(body, DLANG(CONTROLS, EXTENDED_REPORTS), &configExtendedReports, NULL);
|
||||
|
||||
int numJoys = SDL_NumJoysticks();
|
||||
if (numJoys == 0) { numJoys = 1; }
|
||||
|
||||
|
|
|
|||
|
|
@ -3547,7 +3547,13 @@ char gSmluaConstants[] = ""
|
|||
"HOOK_ON_ADD_SURFACE=57\n"
|
||||
"HOOK_ON_CLEAR_AREAS=58\n"
|
||||
"HOOK_ON_PACKET_BYTESTRING_RECEIVE=59\n"
|
||||
"HOOK_MAX=60\n"
|
||||
"HOOK_ON_FIND_WALL_COLLISION=60\n"
|
||||
"HOOK_ON_FIND_CEIL=61\n"
|
||||
"HOOK_ON_FIND_FLOOR=62\n"
|
||||
"HOOK_ON_FIND_WATER_LEVEL=63\n"
|
||||
"HOOK_ON_FIND_POISON_GAS_LEVEL=64\n"
|
||||
"HOOK_ON_FIND_SURFACE_ON_RAY=65\n"
|
||||
"HOOK_MAX=66\n"
|
||||
"MAX_HOOKED_BEHAVIORS=1024\n"
|
||||
"HUD_DISPLAY_LIVES=0\n"
|
||||
"HUD_DISPLAY_COINS=1\n"
|
||||
|
|
@ -4681,7 +4687,7 @@ char gSmluaConstants[] = ""
|
|||
"COOP_OBJ_FLAG_LUA=(1 << 1)\n"
|
||||
"COOP_OBJ_FLAG_NON_SYNC=(1 << 2)\n"
|
||||
"COOP_OBJ_FLAG_INITIALIZED=(1 << 3)\n"
|
||||
"SM64COOPDX_VERSION='v1.4.1'\n"
|
||||
"SM64COOPDX_VERSION='v1.4.2'\n"
|
||||
"VERSION_TEXT='v'\n"
|
||||
"VERSION_NUMBER=41\n"
|
||||
"MINOR_VERSION_NUMBER=1\n"
|
||||
|
|
|
|||
|
|
@ -815,6 +815,11 @@ int smlua_func_log_to_console(lua_State* L) {
|
|||
////////////////////
|
||||
|
||||
int smlua_func_add_scroll_target(lua_State* L) {
|
||||
if (gLuaLoadingMod == NULL) {
|
||||
LOG_LUA_LINE("add_scroll_target() can only be called on load.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// add_scroll_target used to require offset and size of the vertex buffer to be used
|
||||
if (!smlua_functions_valid_param_range(L, 2, 4)) { return 0; }
|
||||
int paramCount = lua_gettop(L);
|
||||
|
|
|
|||
|
|
@ -30424,6 +30424,21 @@ int smlua_func_smlua_audio_utils_replace_sequence(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_smlua_audio_utils_allocate_sequence(UNUSED lua_State* L) {
|
||||
if (L == NULL) { return 0; }
|
||||
|
||||
int top = lua_gettop(L);
|
||||
if (top != 0) {
|
||||
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "smlua_audio_utils_allocate_sequence", 0, top);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
lua_pushinteger(L, smlua_audio_utils_allocate_sequence());
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_audio_stream_load(lua_State* L) {
|
||||
if (L == NULL) { return 0; }
|
||||
|
||||
|
|
@ -34301,6 +34316,28 @@ int smlua_func_get_active_mod(UNUSED lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_get_mod_files(lua_State* L) {
|
||||
if (L == NULL) { return 0; }
|
||||
|
||||
int top = lua_gettop(L);
|
||||
if (top < 1 || top > 2) {
|
||||
LOG_LUA_LINE("Improper param count for '%s': Expected between %u and %u, Received %u", "get_mod_files", 1, 2, top);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct Mod* mod = (struct Mod*)smlua_to_cobject(L, 1, LOT_MOD);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "get_mod_files"); return 0; }
|
||||
const char* subDirectory = (const char*) NULL;
|
||||
if (top >= 2) {
|
||||
subDirectory = smlua_to_string(L, 2);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "get_mod_files"); return 0; }
|
||||
}
|
||||
|
||||
smlua_push_lua_table(L, get_mod_files(mod, subDirectory));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_set_window_title(lua_State* L) {
|
||||
if (L == NULL) { return 0; }
|
||||
|
||||
|
|
@ -38448,6 +38485,7 @@ void smlua_bind_functions_autogen(void) {
|
|||
// smlua_audio_utils.h
|
||||
smlua_bind_function(L, "smlua_audio_utils_reset_all", smlua_func_smlua_audio_utils_reset_all);
|
||||
smlua_bind_function(L, "smlua_audio_utils_replace_sequence", smlua_func_smlua_audio_utils_replace_sequence);
|
||||
smlua_bind_function(L, "smlua_audio_utils_allocate_sequence", smlua_func_smlua_audio_utils_allocate_sequence);
|
||||
smlua_bind_function(L, "audio_stream_load", smlua_func_audio_stream_load);
|
||||
smlua_bind_function(L, "audio_stream_destroy", smlua_func_audio_stream_destroy);
|
||||
smlua_bind_function(L, "audio_stream_play", smlua_func_audio_stream_play);
|
||||
|
|
@ -38685,6 +38723,7 @@ void smlua_bind_functions_autogen(void) {
|
|||
smlua_bind_function(L, "set_environment_region", smlua_func_set_environment_region);
|
||||
smlua_bind_function(L, "mod_file_exists", smlua_func_mod_file_exists);
|
||||
smlua_bind_function(L, "get_active_mod", smlua_func_get_active_mod);
|
||||
smlua_bind_function(L, "get_mod_files", smlua_func_get_mod_files);
|
||||
smlua_bind_function(L, "set_window_title", smlua_func_set_window_title);
|
||||
smlua_bind_function(L, "reset_window_title", smlua_func_reset_window_title);
|
||||
smlua_bind_function(L, "get_os_name", smlua_func_get_os_name);
|
||||
|
|
|
|||
|
|
@ -58,3 +58,9 @@ SMLUA_EVENT_HOOK(HOOK_MARIO_OVERRIDE_FLOOR_CLASS, HOOK_RETURN_ON_OUTPUT_SET, str
|
|||
SMLUA_EVENT_HOOK(HOOK_ON_ADD_SURFACE, HOOK_RETURN_NEVER, struct Surface *surface, bool dynamic)
|
||||
SMLUA_EVENT_HOOK(HOOK_ON_CLEAR_AREAS, HOOK_RETURN_NEVER)
|
||||
SMLUA_EVENT_HOOK(HOOK_ON_PACKET_BYTESTRING_RECEIVE, HOOK_RETURN_NEVER, s32 modIndex, s32 valueIndex)
|
||||
SMLUA_EVENT_HOOK(HOOK_ON_FIND_WALL_COLLISION, _, f32 posX, f32 posY, f32 posZ, struct WallCollisionData *colData, s32 *numCollisions) // Manually defined hook
|
||||
SMLUA_EVENT_HOOK(HOOK_ON_FIND_CEIL, _, f32 posX, f32 posY, f32 posZ, struct Surface **pceil, f32 *height) // Manually defined hook
|
||||
SMLUA_EVENT_HOOK(HOOK_ON_FIND_FLOOR, _, f32 posX, f32 posY, f32 posZ, struct Surface **pfloor, f32 *height) // Manually defined hook
|
||||
SMLUA_EVENT_HOOK(HOOK_ON_FIND_WATER_LEVEL, _, f32 x, f32 z, f32 *waterLevel) // Manually defined hook
|
||||
SMLUA_EVENT_HOOK(HOOK_ON_FIND_POISON_GAS_LEVEL, _, f32 x, f32 z, f32 *gasLevel) // Manually defined hook
|
||||
SMLUA_EVENT_HOOK(HOOK_ON_FIND_SURFACE_ON_RAY, _, Vec3f orig, Vec3f dir, struct Surface **hit_surface, Vec3f hit_pos) // Manually defined hook
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@
|
|||
#include "game/print.h"
|
||||
#include "gfx_dimensions.h"
|
||||
|
||||
extern void smlua_new_vec3f(Vec3f src);
|
||||
extern void smlua_get_vec3f(Vec3f dest, int index);
|
||||
|
||||
#define MAX_HOOKED_REFERENCES 64
|
||||
#define LUA_BEHAVIOR_FLAG (1 << 15)
|
||||
|
||||
|
|
@ -172,7 +175,6 @@ bool smlua_call_event_hooks_HOOK_ON_NAMETAGS_RENDER(s32 playerIndex, Vec3f pos,
|
|||
lua_pushinteger(L, playerIndex);
|
||||
|
||||
// push pos
|
||||
extern void smlua_new_vec3f(Vec3f src);
|
||||
smlua_new_vec3f(pos);
|
||||
|
||||
// call the callback
|
||||
|
|
@ -203,7 +205,6 @@ bool smlua_call_event_hooks_HOOK_ON_NAMETAGS_RENDER(s32 playerIndex, Vec3f pos,
|
|||
// pos
|
||||
lua_getfield(L, -1, "pos");
|
||||
if (lua_type(L, -1) == LUA_TTABLE) {
|
||||
extern void smlua_get_vec3f(Vec3f dest, int index);
|
||||
smlua_get_vec3f(pos, -1);
|
||||
override = true;
|
||||
}
|
||||
|
|
@ -220,6 +221,306 @@ bool smlua_call_event_hooks_HOOK_ON_NAMETAGS_RENDER(s32 playerIndex, Vec3f pos,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool smlua_call_event_hooks_HOOK_ON_FIND_WALL_COLLISION(f32 posX, f32 posY, f32 posZ, struct WallCollisionData *colData, s32 *numCollisions) {
|
||||
static bool sInHook = false;
|
||||
lua_State *L = gLuaState;
|
||||
if (L == NULL || sInHook) { return false; }
|
||||
sInHook = true;
|
||||
|
||||
struct LuaHookedEvent *hook = &sHookedEvents[HOOK_ON_FIND_WALL_COLLISION];
|
||||
for (int i = 0; i < hook->count; i++) {
|
||||
s32 prevTop = lua_gettop(L);
|
||||
|
||||
// push the callback onto the stack
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]);
|
||||
|
||||
// push posX, posY, posZ
|
||||
lua_pushnumber(L, posX);
|
||||
lua_pushnumber(L, posY);
|
||||
lua_pushnumber(L, posZ);
|
||||
|
||||
// push colData
|
||||
smlua_push_object(L, LOT_WALLCOLLISIONDATA, colData, NULL);
|
||||
|
||||
// call the callback (4 args, 1 result)
|
||||
if (0 != smlua_call_hook(L, 4, 1, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_FIND_WALL_COLLISION]);
|
||||
lua_settop(L, prevTop);
|
||||
continue;
|
||||
}
|
||||
|
||||
// return number overrides numCollisions
|
||||
if (lua_type(L, -1) == LUA_TNUMBER) {
|
||||
*numCollisions = smlua_to_integer(L, -1);
|
||||
lua_settop(L, prevTop);
|
||||
sInHook = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
lua_settop(L, prevTop);
|
||||
}
|
||||
sInHook = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool smlua_call_event_hooks_HOOK_ON_FIND_CEIL(f32 posX, f32 posY, f32 posZ, struct Surface **pceil, f32 *height) {
|
||||
static bool sInHook = false;
|
||||
lua_State *L = gLuaState;
|
||||
if (L == NULL || sInHook) { return false; }
|
||||
sInHook = true;
|
||||
|
||||
struct LuaHookedEvent *hook = &sHookedEvents[HOOK_ON_FIND_CEIL];
|
||||
for (int i = 0; i < hook->count; i++) {
|
||||
s32 prevTop = lua_gettop(L);
|
||||
|
||||
// push the callback onto the stack
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]);
|
||||
|
||||
// push posX, posY, posZ
|
||||
lua_pushnumber(L, posX);
|
||||
lua_pushnumber(L, posY);
|
||||
lua_pushnumber(L, posZ);
|
||||
|
||||
// push current ceil surface (or nil)
|
||||
if (pceil && *pceil) {
|
||||
smlua_push_object(L, LOT_SURFACE, *pceil, NULL);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
// push current height
|
||||
lua_pushnumber(L, *height);
|
||||
|
||||
// call the callback (5 args, 2 results)
|
||||
if (0 != smlua_call_hook(L, 5, 2, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_FIND_CEIL]);
|
||||
lua_settop(L, prevTop);
|
||||
continue;
|
||||
}
|
||||
|
||||
bool override = false;
|
||||
|
||||
// first return value: height (number)
|
||||
if (lua_type(L, -2) == LUA_TNUMBER) {
|
||||
*height = smlua_to_number(L, -2);
|
||||
override = true;
|
||||
}
|
||||
|
||||
// second return value: surface (userdata)
|
||||
if (lua_type(L, -1) == LUA_TUSERDATA) {
|
||||
struct Surface *surface = (struct Surface *)smlua_to_cobject(L, -1, LOT_SURFACE);
|
||||
if (surface && pceil) {
|
||||
*pceil = surface;
|
||||
override = true;
|
||||
}
|
||||
}
|
||||
|
||||
lua_settop(L, prevTop);
|
||||
if (override) { sInHook = false; return true; }
|
||||
}
|
||||
sInHook = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool smlua_call_event_hooks_HOOK_ON_FIND_FLOOR(f32 posX, f32 posY, f32 posZ, struct Surface **pfloor, f32 *height) {
|
||||
static bool sInHook = false;
|
||||
lua_State *L = gLuaState;
|
||||
if (L == NULL || sInHook) { return false; }
|
||||
sInHook = true;
|
||||
|
||||
struct LuaHookedEvent *hook = &sHookedEvents[HOOK_ON_FIND_FLOOR];
|
||||
for (int i = 0; i < hook->count; i++) {
|
||||
s32 prevTop = lua_gettop(L);
|
||||
|
||||
// push the callback onto the stack
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]);
|
||||
|
||||
// push posX, posY, posZ
|
||||
lua_pushnumber(L, posX);
|
||||
lua_pushnumber(L, posY);
|
||||
lua_pushnumber(L, posZ);
|
||||
|
||||
// push current floor surface (or nil)
|
||||
if (pfloor && *pfloor) {
|
||||
smlua_push_object(L, LOT_SURFACE, *pfloor, NULL);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
// push current height
|
||||
lua_pushnumber(L, *height);
|
||||
|
||||
// call the callback (5 args, 2 results)
|
||||
if (0 != smlua_call_hook(L, 5, 2, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_FIND_FLOOR]);
|
||||
lua_settop(L, prevTop);
|
||||
continue;
|
||||
}
|
||||
|
||||
bool override = false;
|
||||
|
||||
// first return value: height (number)
|
||||
if (lua_type(L, -2) == LUA_TNUMBER) {
|
||||
*height = smlua_to_number(L, -2);
|
||||
override = true;
|
||||
}
|
||||
|
||||
// second return value: surface (userdata)
|
||||
if (lua_type(L, -1) == LUA_TUSERDATA) {
|
||||
struct Surface *surface = (struct Surface *)smlua_to_cobject(L, -1, LOT_SURFACE);
|
||||
if (surface && pfloor) {
|
||||
*pfloor = surface;
|
||||
override = true;
|
||||
}
|
||||
}
|
||||
|
||||
lua_settop(L, prevTop);
|
||||
if (override) { sInHook = false; return true; }
|
||||
}
|
||||
sInHook = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool smlua_call_event_hooks_HOOK_ON_FIND_SURFACE_ON_RAY(Vec3f orig, Vec3f dir, struct Surface **hit_surface, Vec3f hit_pos) {
|
||||
static bool sInHook = false;
|
||||
lua_State *L = gLuaState;
|
||||
if (L == NULL || sInHook) { return false; }
|
||||
sInHook = true;
|
||||
|
||||
struct LuaHookedEvent *hook = &sHookedEvents[HOOK_ON_FIND_SURFACE_ON_RAY];
|
||||
for (int i = 0; i < hook->count; i++) {
|
||||
s32 prevTop = lua_gettop(L);
|
||||
|
||||
// push the callback onto the stack
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]);
|
||||
|
||||
// push orig, dir
|
||||
smlua_new_vec3f(orig);
|
||||
smlua_new_vec3f(dir);
|
||||
|
||||
// push hit_surface (or nil)
|
||||
if (hit_surface && *hit_surface) {
|
||||
smlua_push_object(L, LOT_SURFACE, *hit_surface, NULL);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
// push hit_pos
|
||||
smlua_new_vec3f(hit_pos);
|
||||
|
||||
// call the callback (4 args, 2 results)
|
||||
if (0 != smlua_call_hook(L, 4, 2, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_FIND_SURFACE_ON_RAY]);
|
||||
lua_settop(L, prevTop);
|
||||
continue;
|
||||
}
|
||||
|
||||
bool override = false;
|
||||
|
||||
// first return value: surface (userdata)
|
||||
if (lua_type(L, -2) == LUA_TUSERDATA) {
|
||||
struct Surface *surface = (struct Surface *)smlua_to_cobject(L, -2, LOT_SURFACE);
|
||||
if (surface && hit_surface) {
|
||||
*hit_surface = surface;
|
||||
override = true;
|
||||
}
|
||||
}
|
||||
|
||||
// second return value: hitPos (table {x, y, z})
|
||||
if (lua_type(L, -1) == LUA_TTABLE) {
|
||||
smlua_get_vec3f(hit_pos, -1);
|
||||
override = true;
|
||||
}
|
||||
|
||||
lua_settop(L, prevTop);
|
||||
if (override) { sInHook = false; return true; }
|
||||
}
|
||||
sInHook = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool smlua_call_event_hooks_HOOK_ON_FIND_WATER_LEVEL(f32 x, f32 z, f32 *waterLevel) {
|
||||
static bool sInHook = false;
|
||||
lua_State *L = gLuaState;
|
||||
if (L == NULL || sInHook) { return false; }
|
||||
sInHook = true;
|
||||
|
||||
struct LuaHookedEvent *hook = &sHookedEvents[HOOK_ON_FIND_WATER_LEVEL];
|
||||
for (int i = 0; i < hook->count; i++) {
|
||||
s32 prevTop = lua_gettop(L);
|
||||
|
||||
// push the callback onto the stack
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]);
|
||||
|
||||
// push x, z
|
||||
lua_pushnumber(L, x);
|
||||
lua_pushnumber(L, z);
|
||||
|
||||
// push current water level
|
||||
lua_pushnumber(L, *waterLevel);
|
||||
|
||||
// call the callback (3 args, 1 result)
|
||||
if (0 != smlua_call_hook(L, 3, 1, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_FIND_WATER_LEVEL]);
|
||||
lua_settop(L, prevTop);
|
||||
continue;
|
||||
}
|
||||
|
||||
// return number overrides waterLevel
|
||||
if (lua_type(L, -1) == LUA_TNUMBER) {
|
||||
*waterLevel = smlua_to_number(L, -1);
|
||||
lua_settop(L, prevTop);
|
||||
sInHook = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
lua_settop(L, prevTop);
|
||||
}
|
||||
sInHook = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool smlua_call_event_hooks_HOOK_ON_FIND_POISON_GAS_LEVEL(f32 x, f32 z, f32 *gasLevel) {
|
||||
static bool sInHook = false;
|
||||
lua_State *L = gLuaState;
|
||||
if (L == NULL || sInHook) { return false; }
|
||||
sInHook = true;
|
||||
|
||||
struct LuaHookedEvent *hook = &sHookedEvents[HOOK_ON_FIND_POISON_GAS_LEVEL];
|
||||
for (int i = 0; i < hook->count; i++) {
|
||||
s32 prevTop = lua_gettop(L);
|
||||
|
||||
// push the callback onto the stack
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]);
|
||||
|
||||
// push x, z
|
||||
lua_pushnumber(L, x);
|
||||
lua_pushnumber(L, z);
|
||||
|
||||
// push current gas level
|
||||
lua_pushnumber(L, *gasLevel);
|
||||
|
||||
// call the callback (3 args, 1 result)
|
||||
if (0 != smlua_call_hook(L, 3, 1, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_FIND_POISON_GAS_LEVEL]);
|
||||
lua_settop(L, prevTop);
|
||||
continue;
|
||||
}
|
||||
|
||||
// return number overrides gasLevel
|
||||
if (lua_type(L, -1) == LUA_TNUMBER) {
|
||||
*gasLevel = smlua_to_number(L, -1);
|
||||
lua_settop(L, prevTop);
|
||||
sInHook = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
lua_settop(L, prevTop);
|
||||
}
|
||||
sInHook = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////
|
||||
// hooked actions //
|
||||
////////////////////
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@
|
|||
// forward declare
|
||||
struct Camera;
|
||||
struct WarpDest;
|
||||
struct WallCollisionData;
|
||||
struct Surface;
|
||||
|
||||
// ! Hooks must be added at the end
|
||||
enum LuaHookedEventType {
|
||||
|
|
@ -74,6 +76,12 @@ enum LuaHookedEventType {
|
|||
HOOK_ON_ADD_SURFACE,
|
||||
HOOK_ON_CLEAR_AREAS,
|
||||
HOOK_ON_PACKET_BYTESTRING_RECEIVE,
|
||||
HOOK_ON_FIND_WALL_COLLISION,
|
||||
HOOK_ON_FIND_CEIL,
|
||||
HOOK_ON_FIND_FLOOR,
|
||||
HOOK_ON_FIND_WATER_LEVEL,
|
||||
HOOK_ON_FIND_POISON_GAS_LEVEL,
|
||||
HOOK_ON_FIND_SURFACE_ON_RAY,
|
||||
HOOK_MAX,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -173,6 +173,16 @@ void smlua_audio_utils_replace_sequence(u8 sequenceId, u8 bankId, u8 defaultVolu
|
|||
LOG_LUA_LINE("Could not find m64 at path: %s", m64path);
|
||||
}
|
||||
|
||||
u8 smlua_audio_utils_allocate_sequence(void) {
|
||||
for (u8 seqId = SEQ_COUNT + 1; seqId < MAX_AUDIO_OVERRIDE; seqId++) {
|
||||
if (!sAudioOverrides[seqId].enabled) {
|
||||
return seqId;
|
||||
}
|
||||
}
|
||||
LOG_ERROR("Cannot allocate more custom sequences.");
|
||||
return MAX_AUDIO_OVERRIDE;
|
||||
}
|
||||
|
||||
///////////////
|
||||
// mod audio //
|
||||
///////////////
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ void smlua_audio_utils_reset_all(void);
|
|||
bool smlua_audio_utils_override(u8 sequenceId, s32* bankId, void** seqData);
|
||||
/* |description|Replaces the sequence corresponding to `sequenceId` with one called `m64Name`.m64 with `bankId` and `defaultVolume`|descriptionEnd| */
|
||||
void smlua_audio_utils_replace_sequence(u8 sequenceId, u8 bankId, u8 defaultVolume, const char* m64Name);
|
||||
/* |description|Allocates a new sequence ID|descriptionEnd| */
|
||||
u8 smlua_audio_utils_allocate_sequence(void);
|
||||
|
||||
////////////////
|
||||
// mod sounds //
|
||||
|
|
|
|||
|
|
@ -607,6 +607,54 @@ struct Mod* get_active_mod(void) {
|
|||
return gLuaActiveMod;
|
||||
}
|
||||
|
||||
LuaTable get_mod_files(struct Mod* mod, OPTIONAL const char* subDirectory) {
|
||||
if (!mod) {
|
||||
struct lua_State *L = gLuaState;
|
||||
if (L) {
|
||||
lua_newtable(L);
|
||||
return smlua_to_lua_table(L, -1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char normalizedSubDir[SYS_MAX_PATH] = { 0 };
|
||||
snprintf(normalizedSubDir, SYS_MAX_PATH, "%s", subDirectory ? subDirectory : "");
|
||||
normalize_path(normalizedSubDir);
|
||||
|
||||
size_t subDirLen = strlen(normalizedSubDir);
|
||||
if (subDirLen > 0 && subDirLen + 1 < SYS_MAX_PATH && normalizedSubDir[subDirLen - 1] != '/') {
|
||||
strcat(normalizedSubDir, "/");
|
||||
subDirLen = strlen(normalizedSubDir);
|
||||
}
|
||||
|
||||
struct lua_State *L = gLuaState;
|
||||
if (!L) { return 0; }
|
||||
|
||||
LUA_STACK_CHECK_BEGIN_NUM(L, 1);
|
||||
|
||||
lua_newtable(L);
|
||||
|
||||
int luaTableIndex = 1;
|
||||
for (int i = 0; i < mod->fileCount; i++) {
|
||||
struct ModFile* file = &mod->files[i];
|
||||
char normalizedPath[SYS_MAX_PATH] = { 0 };
|
||||
if (snprintf(normalizedPath, SYS_MAX_PATH, "%s", file->relativePath) < 0) {
|
||||
LOG_ERROR("Failed to copy relativePath for normalization: %s", file->relativePath);
|
||||
continue;
|
||||
}
|
||||
normalize_path(normalizedPath);
|
||||
|
||||
if (strncmp(normalizedPath, normalizedSubDir, subDirLen) == 0) {
|
||||
lua_pushstring(L, file->relativePath);
|
||||
lua_rawseti(L, -2, luaTableIndex++);
|
||||
}
|
||||
}
|
||||
|
||||
LUA_STACK_CHECK_END(L);
|
||||
|
||||
return smlua_to_lua_table(L, -1);
|
||||
}
|
||||
|
||||
///
|
||||
|
||||
void set_window_title(const char* title) {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ enum ActSelectHudPart {
|
|||
ACT_SELECT_HUD_ACT_NAME = 1 << 3,
|
||||
ACT_SELECT_HUD_STAR_NUM = 1 << 4,
|
||||
ACT_SELECT_HUD_PLAYERS_IN_LEVEL = 1 << 5,
|
||||
|
||||
|
||||
ACT_SELECT_HUD_NONE = 0,
|
||||
ACT_SELECT_HUD_ALL = ACT_SELECT_HUD_SCORE | ACT_SELECT_HUD_LEVEL_NAME | ACT_SELECT_HUD_COURSE_NUM | ACT_SELECT_HUD_ACT_NAME |ACT_SELECT_HUD_STAR_NUM | ACT_SELECT_HUD_PLAYERS_IN_LEVEL
|
||||
};
|
||||
|
|
@ -246,6 +246,8 @@ void set_environment_region(u8 index, s16 value);
|
|||
bool mod_file_exists(const char* filename);
|
||||
/* |description|Gets the mod currently being processed|descriptionEnd| */
|
||||
struct Mod* get_active_mod(void);
|
||||
/* |description|Gets all files a mod contains|descriptionEnd| */
|
||||
LuaTable get_mod_files(struct Mod* mod, OPTIONAL const char* subDirectory);
|
||||
|
||||
/* |description|Sets the window title to a custom title|descriptionEnd| */
|
||||
void set_window_title(const char* title);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef VERSION_H
|
||||
#define VERSION_H
|
||||
|
||||
#define SM64COOPDX_VERSION "v1.4.1"
|
||||
#define SM64COOPDX_VERSION "v1.4.2"
|
||||
|
||||
// internal version
|
||||
#define VERSION_TEXT "v"
|
||||
|
|
|
|||
|
|
@ -411,4 +411,12 @@ static void sys_fatal_impl(const char *msg) {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
const char *sys_resource_path(void) {
|
||||
return ".";
|
||||
}
|
||||
|
||||
const char *sys_exe_path_dir(void) {
|
||||
return ".";
|
||||
}
|
||||
|
||||
#endif // platform switch
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue