mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-29 07:23:01 +00:00
Merge branch 'unstable' into level-scripts
This commit is contained in:
commit
52e705c9d8
24 changed files with 2358 additions and 1599 deletions
17
Makefile
17
Makefile
|
@ -58,9 +58,6 @@ DISCORD_SDK ?= 1
|
||||||
# Enable docker build workarounds
|
# Enable docker build workarounds
|
||||||
DOCKERBUILD ?= 0
|
DOCKERBUILD ?= 0
|
||||||
|
|
||||||
# Should It compile with windows Icon
|
|
||||||
ICON ?= 1
|
|
||||||
|
|
||||||
# Various workarounds for weird toolchains
|
# Various workarounds for weird toolchains
|
||||||
|
|
||||||
NO_BZERO_BCOPY ?= 0
|
NO_BZERO_BCOPY ?= 0
|
||||||
|
@ -832,20 +829,6 @@ else
|
||||||
# endif
|
# endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Icon
|
|
||||||
ifeq ($(WINDOWS_BUILD),1)
|
|
||||||
ifeq ($(ICON),1)
|
|
||||||
|
|
||||||
Command := mkdir $(BUILD_DIR)/res
|
|
||||||
Reponse := $(shell $(call Command))
|
|
||||||
|
|
||||||
Command := windres -o $(BUILD_DIR)/res/icon.o -i res/icon.rc
|
|
||||||
Reponse := $(shell $(call Command))
|
|
||||||
|
|
||||||
LDFLAGS += $(BUILD_DIR)/res/icon.o
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Coop specific libraries
|
# Coop specific libraries
|
||||||
|
|
||||||
# Lua
|
# Lua
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -6,12 +6,30 @@ function get_behavior_from_id(id)
|
||||||
-- ...
|
-- ...
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @param id BehaviorId
|
||||||
|
--- @return string
|
||||||
|
function get_behavior_name_from_id(id)
|
||||||
|
-- ...
|
||||||
|
end
|
||||||
|
|
||||||
--- @param behavior Pointer_BehaviorScript
|
--- @param behavior Pointer_BehaviorScript
|
||||||
--- @return BehaviorId
|
--- @return BehaviorId
|
||||||
function get_id_from_behavior(behavior)
|
function get_id_from_behavior(behavior)
|
||||||
-- ...
|
-- ...
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @param name string
|
||||||
|
--- @return BehaviorId
|
||||||
|
function get_id_from_behavior_name(name)
|
||||||
|
-- ...
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @param behavior Pointer_BehaviorScript
|
||||||
|
--- @return BehaviorId
|
||||||
|
function get_id_from_vanilla_behavior(behavior)
|
||||||
|
-- ...
|
||||||
|
end
|
||||||
|
|
||||||
--- @param c Camera
|
--- @param c Camera
|
||||||
--- @param goal number
|
--- @param goal number
|
||||||
--- @param inc number
|
--- @param inc number
|
||||||
|
@ -4135,6 +4153,12 @@ function allocate_mario_action(actFlags)
|
||||||
-- ...
|
-- ...
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @param index integer
|
||||||
|
--- @return number
|
||||||
|
function get_environment_region(index)
|
||||||
|
-- ...
|
||||||
|
end
|
||||||
|
|
||||||
--- @param m MarioState
|
--- @param m MarioState
|
||||||
--- @param index integer
|
--- @param index integer
|
||||||
--- @return number
|
--- @return number
|
||||||
|
@ -4171,6 +4195,13 @@ function hud_show()
|
||||||
-- ...
|
-- ...
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @param index integer
|
||||||
|
--- @param value integer
|
||||||
|
--- @return nil
|
||||||
|
function set_environment_region(index, value)
|
||||||
|
-- ...
|
||||||
|
end
|
||||||
|
|
||||||
--- @param name string
|
--- @param name string
|
||||||
--- @return Pointer_LevelScript
|
--- @return Pointer_LevelScript
|
||||||
function smlua_level_util_get(name)
|
function smlua_level_util_get(name)
|
||||||
|
|
|
@ -9,7 +9,9 @@ Developers:
|
||||||
theclashingfritz
|
theclashingfritz
|
||||||
|
|
||||||
Contributors:
|
Contributors:
|
||||||
|
Agent X
|
||||||
AloXado320
|
AloXado320
|
||||||
|
Altiami
|
||||||
Amy54Desu
|
Amy54Desu
|
||||||
anzz1
|
anzz1
|
||||||
Avery
|
Avery
|
||||||
|
|
37
data/dynos_col_load.cpp
Normal file
37
data/dynos_col_load.cpp
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
#include "dynos.cpp.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Load collision from binary
|
||||||
|
//
|
||||||
|
|
||||||
|
static DataNode<Collision>* LoadCollisionData(FILE *aFile) {
|
||||||
|
DataNode<Collision> *_Node = New<DataNode<Collision>>();
|
||||||
|
|
||||||
|
// Name
|
||||||
|
_Node->mName.Read(aFile);
|
||||||
|
|
||||||
|
// Data
|
||||||
|
_Node->mSize = ReadBytes<u32>(aFile);
|
||||||
|
_Node->mData = New<Collision>(_Node->mSize);
|
||||||
|
for (u32 i = 0; i != _Node->mSize; ++i) {
|
||||||
|
_Node->mData[i] = ReadBytes<Collision>(aFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _Node;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataNode<Collision>* DynOS_Col_LoadFromBinary(const SysPath &aPackFolder, const char *aCollisionName) {
|
||||||
|
// Load data from binary file
|
||||||
|
DataNode<Collision>* collisionNode = NULL;
|
||||||
|
SysPath _Filename = fstring("%s/%s.col", aPackFolder.begin(), aCollisionName);
|
||||||
|
FILE *_File = fopen(_Filename.c_str(), "rb");
|
||||||
|
if (_File) {
|
||||||
|
u8 type = ReadBytes<u8>(_File);
|
||||||
|
if (type == DATA_TYPE_COLLISION) {
|
||||||
|
collisionNode = LoadCollisionData(_File);
|
||||||
|
}
|
||||||
|
fclose(_File);
|
||||||
|
}
|
||||||
|
|
||||||
|
return collisionNode;
|
||||||
|
}
|
32
data/dynos_col_write.cpp
Normal file
32
data/dynos_col_write.cpp
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
#include "dynos.cpp.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Collisions
|
||||||
|
//
|
||||||
|
|
||||||
|
static void WriteCollisionData(FILE* aFile, GfxData* aGfxData, DataNode<Collision> *aNode) {
|
||||||
|
if (!aNode->mData) return;
|
||||||
|
|
||||||
|
// Name
|
||||||
|
WriteBytes<u8>(aFile, DATA_TYPE_COLLISION);
|
||||||
|
aNode->mName.Write(aFile);
|
||||||
|
|
||||||
|
// Data
|
||||||
|
WriteBytes<u32>(aFile, aNode->mSize);
|
||||||
|
for (u32 i = 0; i != aNode->mSize; ++i) {
|
||||||
|
WriteBytes<Collision>(aFile, aNode->mData[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DynOS_Col_WriteBinary(const SysPath &aOutputFilename, GfxData *aGfxData, DataNode<Collision>* _Node) {
|
||||||
|
FILE *_File = fopen(aOutputFilename.c_str(), "wb");
|
||||||
|
if (!_File) {
|
||||||
|
PrintError(" ERROR: Unable to create file \"%s\"", aOutputFilename.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteCollisionData(_File, aGfxData, _Node);
|
||||||
|
|
||||||
|
fclose(_File);
|
||||||
|
return true;
|
||||||
|
}
|
322
data/dynos_gfx_write.cpp
Normal file
322
data/dynos_gfx_write.cpp
Normal file
|
@ -0,0 +1,322 @@
|
||||||
|
#include "dynos.cpp.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Pointers
|
||||||
|
//
|
||||||
|
|
||||||
|
typedef Pair<String, u32> PointerData;
|
||||||
|
static PointerData GetDataFromPointer(const void* aPtr, GfxData* aGfxData) {
|
||||||
|
|
||||||
|
// Lights
|
||||||
|
for (auto& _Node : aGfxData->mLights) {
|
||||||
|
if (&_Node->mData->l[0] == aPtr) { // Light *, not Lights1 *
|
||||||
|
return { _Node->mName, 1 };
|
||||||
|
}
|
||||||
|
if (&_Node->mData->a == aPtr) { // Ambient *, not Lights1 *
|
||||||
|
return { _Node->mName, 2 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Textures
|
||||||
|
for (auto& _Node : aGfxData->mTextures) {
|
||||||
|
if (_Node == aPtr) {
|
||||||
|
return { _Node->mName, 0 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display lists
|
||||||
|
for (auto& _Node : aGfxData->mDisplayLists) {
|
||||||
|
if (_Node == aPtr) {
|
||||||
|
return { _Node->mName, 0 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Geo layouts
|
||||||
|
for (auto& _Node : aGfxData->mGeoLayouts) {
|
||||||
|
if (_Node->mData == aPtr) {
|
||||||
|
return { _Node->mName, 0 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vertices
|
||||||
|
String _VtxArrayName = "";
|
||||||
|
uintptr_t _VtxArrayStart = 0;
|
||||||
|
for (auto& _Node : aGfxData->mVertices) {
|
||||||
|
if (_Node->mData == aPtr) {
|
||||||
|
return { _Node->mName, 0 };
|
||||||
|
}
|
||||||
|
if ((uintptr_t)_Node->mData <= (uintptr_t)aPtr &&
|
||||||
|
(uintptr_t)_Node->mData >= _VtxArrayStart) {
|
||||||
|
_VtxArrayName = _Node->mName;
|
||||||
|
_VtxArrayStart = (uintptr_t)_Node->mData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { _VtxArrayName, (u32)((const Vtx*)aPtr - (const Vtx*)_VtxArrayStart) };
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WritePointer(FILE* aFile, const void* aPtr, GfxData* aGfxData) {
|
||||||
|
|
||||||
|
// NULL
|
||||||
|
if (!aPtr) {
|
||||||
|
WriteBytes<u32>(aFile, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Geo function
|
||||||
|
s32 _GeoFunctionIndex = DynOS_Geo_GetFunctionIndex(aPtr);
|
||||||
|
if (_GeoFunctionIndex != -1) {
|
||||||
|
WriteBytes<u32>(aFile, FUNCTION_CODE);
|
||||||
|
WriteBytes<s32>(aFile, _GeoFunctionIndex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pointer
|
||||||
|
PointerData _PtrData = GetDataFromPointer(aPtr, aGfxData);
|
||||||
|
WriteBytes<u32>(aFile, POINTER_CODE);
|
||||||
|
_PtrData.first.Write(aFile);
|
||||||
|
WriteBytes<u32>(aFile, _PtrData.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Lights
|
||||||
|
//
|
||||||
|
|
||||||
|
static void WriteLightData(FILE* aFile, GfxData* aGfxData, DataNode<Lights1> *aNode) {
|
||||||
|
if (!aNode->mData) return;
|
||||||
|
|
||||||
|
// Header
|
||||||
|
WriteBytes<u8>(aFile, DATA_TYPE_LIGHT);
|
||||||
|
aNode->mName.Write(aFile);
|
||||||
|
|
||||||
|
// Data
|
||||||
|
WriteBytes<Lights1>(aFile, *aNode->mData);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Textures
|
||||||
|
//
|
||||||
|
|
||||||
|
static void WriteTextureData(FILE* aFile, GfxData* aGfxData, DataNode<TexData> *aNode) {
|
||||||
|
if (!aNode->mData) return;
|
||||||
|
|
||||||
|
// Header
|
||||||
|
WriteBytes<u8>(aFile, DATA_TYPE_TEXTURE);
|
||||||
|
aNode->mName.Write(aFile);
|
||||||
|
|
||||||
|
// Data
|
||||||
|
aNode->mData->mPngData.Write(aFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Vertices
|
||||||
|
//
|
||||||
|
|
||||||
|
static void WriteVertexData(FILE* aFile, GfxData* aGfxData, DataNode<Vtx> *aNode) {
|
||||||
|
if (!aNode->mData) return;
|
||||||
|
|
||||||
|
// Header
|
||||||
|
WriteBytes<u8>(aFile, DATA_TYPE_VERTEX);
|
||||||
|
aNode->mName.Write(aFile);
|
||||||
|
|
||||||
|
// Data
|
||||||
|
WriteBytes<u32>(aFile, aNode->mSize);
|
||||||
|
for (u32 i = 0; i != aNode->mSize; ++i) {
|
||||||
|
WriteBytes<s16>(aFile, aNode->mData[i].n.ob[0]);
|
||||||
|
WriteBytes<s16>(aFile, aNode->mData[i].n.ob[1]);
|
||||||
|
WriteBytes<s16>(aFile, aNode->mData[i].n.ob[2]);
|
||||||
|
WriteBytes<s16>(aFile, aNode->mData[i].n.flag);
|
||||||
|
WriteBytes<s16>(aFile, aNode->mData[i].n.tc[0]);
|
||||||
|
WriteBytes<s16>(aFile, aNode->mData[i].n.tc[1]);
|
||||||
|
WriteBytes<s8> (aFile, aNode->mData[i].n.n[0]);
|
||||||
|
WriteBytes<s8> (aFile, aNode->mData[i].n.n[1]);
|
||||||
|
WriteBytes<s8> (aFile, aNode->mData[i].n.n[2]);
|
||||||
|
WriteBytes<u8> (aFile, aNode->mData[i].n.a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Display lists
|
||||||
|
//
|
||||||
|
|
||||||
|
static void WriteDisplayListData(FILE *aFile, GfxData *aGfxData, DataNode<Gfx> *aNode) {
|
||||||
|
if (!aNode->mData) return;
|
||||||
|
|
||||||
|
// Header
|
||||||
|
WriteBytes<u8>(aFile, DATA_TYPE_DISPLAY_LIST);
|
||||||
|
aNode->mName.Write(aFile);
|
||||||
|
|
||||||
|
// Data
|
||||||
|
WriteBytes<u32>(aFile, aNode->mSize);
|
||||||
|
for (u32 i = 0; i != aNode->mSize; ++i) {
|
||||||
|
Gfx *_Head = &aNode->mData[i];
|
||||||
|
if (aGfxData->mPointerList.Find((void *) _Head) != -1) {
|
||||||
|
WriteBytes<u32>(aFile, _Head->words.w0);
|
||||||
|
WritePointer(aFile, (const void *) _Head->words.w1, aGfxData);
|
||||||
|
} else {
|
||||||
|
WriteBytes<u32>(aFile, _Head->words.w0);
|
||||||
|
WriteBytes<u32>(aFile, _Head->words.w1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Geo layouts
|
||||||
|
//
|
||||||
|
|
||||||
|
static void WriteGeoLayoutData(FILE *aFile, GfxData *aGfxData, DataNode<GeoLayout> *aNode) {
|
||||||
|
if (!aNode->mData) return;
|
||||||
|
|
||||||
|
// Header
|
||||||
|
WriteBytes<u8>(aFile, DATA_TYPE_GEO_LAYOUT);
|
||||||
|
aNode->mName.Write(aFile);
|
||||||
|
|
||||||
|
// Data
|
||||||
|
WriteBytes<u32>(aFile, aNode->mSize);
|
||||||
|
for (u32 i = 0; i != aNode->mSize; ++i) {
|
||||||
|
GeoLayout *_Head = &aNode->mData[i];
|
||||||
|
if (aGfxData->mPointerList.Find((void *) _Head) != -1) {
|
||||||
|
WritePointer(aFile, (const void *) (*_Head), aGfxData);
|
||||||
|
} else {
|
||||||
|
WriteBytes<u32>(aFile, *((u32 *) _Head));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Animation data
|
||||||
|
//
|
||||||
|
|
||||||
|
static void WriteAnimationData(FILE* aFile, GfxData* aGfxData) {
|
||||||
|
for (auto& _Node : aGfxData->mAnimations) {
|
||||||
|
|
||||||
|
// Value buffer
|
||||||
|
s32 _ValueBufferIdx = aGfxData->mAnimValues.FindIf([&_Node](const AnimBuffer<s16> *aAnimBuffer) { return aAnimBuffer->first == _Node->mData->mValues.first; });
|
||||||
|
if (_ValueBufferIdx == -1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Index buffer
|
||||||
|
s32 _IndexBufferIdx = aGfxData->mAnimIndices.FindIf([&_Node](const AnimBuffer<u16> *aAnimBuffer) { return aAnimBuffer->first == _Node->mData->mIndex.first; });
|
||||||
|
if (_IndexBufferIdx == -1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unk0A buffer
|
||||||
|
s32 _Unk0ABufferIdx = aGfxData->mAnimIndices.FindIf([&_Node](const AnimBuffer<u16> *aAnimBuffer) { return aAnimBuffer->first == _Node->mData->mUnk0A.first; });
|
||||||
|
if (_Unk0ABufferIdx == -1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Header
|
||||||
|
WriteBytes<u8>(aFile, DATA_TYPE_ANIMATION);
|
||||||
|
_Node->mName.Write(aFile);
|
||||||
|
|
||||||
|
// Data
|
||||||
|
WriteBytes<s16>(aFile, _Node->mData->mFlags);
|
||||||
|
WriteBytes<s16>(aFile, _Node->mData->mUnk02);
|
||||||
|
WriteBytes<s16>(aFile, _Node->mData->mUnk04);
|
||||||
|
WriteBytes<s16>(aFile, _Node->mData->mUnk06);
|
||||||
|
WriteBytes<s16>(aFile, _Node->mData->mUnk08);
|
||||||
|
WriteBytes<s16>(aFile, (aGfxData->mAnimIndices[_Unk0ABufferIdx]->second.Count() / 6) - 1);
|
||||||
|
WriteBytes<u32>(aFile, _Node->mData->mLength);
|
||||||
|
aGfxData->mAnimValues[_ValueBufferIdx]->second.Write(aFile);
|
||||||
|
aGfxData->mAnimIndices[_IndexBufferIdx]->second.Write(aFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Animation table
|
||||||
|
//
|
||||||
|
|
||||||
|
static void WriteAnimationTable(FILE* aFile, GfxData* aGfxData) {
|
||||||
|
for (auto& _AnimName : aGfxData->mAnimationTable) {
|
||||||
|
|
||||||
|
// Header
|
||||||
|
WriteBytes<u8>(aFile, DATA_TYPE_ANIMATION_TABLE);
|
||||||
|
|
||||||
|
// Data
|
||||||
|
_AnimName.first.Write(aFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Write
|
||||||
|
//
|
||||||
|
|
||||||
|
bool DynOS_Gfx_WriteBinary(const SysPath &aOutputFilename, GfxData *aGfxData) {
|
||||||
|
FILE *_File = fopen(aOutputFilename.c_str(), "wb");
|
||||||
|
if (!_File) {
|
||||||
|
PrintError(" ERROR: Unable to create file \"%s\"", aOutputFilename.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (u64 i = 0; i != aGfxData->mLoadIndex; ++i) {
|
||||||
|
for (auto &_Node : aGfxData->mLights) {
|
||||||
|
if (_Node->mLoadIndex == i) {
|
||||||
|
WriteLightData(_File, aGfxData, _Node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto &_Node : aGfxData->mTextures) {
|
||||||
|
if (_Node->mLoadIndex == i) {
|
||||||
|
WriteTextureData(_File, aGfxData, _Node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto &_Node : aGfxData->mVertices) {
|
||||||
|
if (_Node->mLoadIndex == i) {
|
||||||
|
WriteVertexData(_File, aGfxData, _Node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto &_Node : aGfxData->mDisplayLists) {
|
||||||
|
if (_Node->mLoadIndex == i) {
|
||||||
|
WriteDisplayListData(_File, aGfxData, _Node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto &_Node : aGfxData->mGeoLayouts) {
|
||||||
|
if (_Node->mLoadIndex == i) {
|
||||||
|
WriteGeoLayoutData(_File, aGfxData, _Node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WriteAnimationData(_File, aGfxData);
|
||||||
|
WriteAnimationTable(_File, aGfxData);
|
||||||
|
fclose(_File);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Free
|
||||||
|
//
|
||||||
|
|
||||||
|
void DynOS_Gfx_Free(GfxData* aGfxData) {
|
||||||
|
if (aGfxData) {
|
||||||
|
for (auto& _Node : aGfxData->mLights) {
|
||||||
|
Delete(_Node->mData);
|
||||||
|
Delete(_Node);
|
||||||
|
}
|
||||||
|
for (auto& _Node : aGfxData->mTextures) {
|
||||||
|
Delete(_Node->mData);
|
||||||
|
Delete(_Node);
|
||||||
|
}
|
||||||
|
for (auto& _Node : aGfxData->mVertices) {
|
||||||
|
Delete(_Node->mData);
|
||||||
|
Delete(_Node);
|
||||||
|
}
|
||||||
|
for (auto& _Node : aGfxData->mDisplayLists) {
|
||||||
|
Delete(_Node->mData);
|
||||||
|
Delete(_Node);
|
||||||
|
}
|
||||||
|
for (auto& _Node : aGfxData->mGeoLayouts) {
|
||||||
|
Delete(_Node->mData);
|
||||||
|
Delete(_Node);
|
||||||
|
}
|
||||||
|
for (auto& _Node : aGfxData->mAnimations) {
|
||||||
|
Delete(_Node->mData);
|
||||||
|
Delete(_Node);
|
||||||
|
}
|
||||||
|
for (auto& _Node : aGfxData->mCollisions) {
|
||||||
|
Delete(_Node->mData);
|
||||||
|
Delete(_Node);
|
||||||
|
}
|
||||||
|
Delete(aGfxData);
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load diff
Binary file not shown.
28
docs/lua/examples/water-level.lua
Normal file
28
docs/lua/examples/water-level.lua
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
-- name: Water Height Changer
|
||||||
|
-- description: Use /waterset and /waterget to manipulate water height.
|
||||||
|
|
||||||
|
function on_get_command(msg)
|
||||||
|
if not network_is_server() then
|
||||||
|
djui_chat_message_create("You need to be the host!")
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
djui_chat_message_create(tostring(get_environment_region(1)))
|
||||||
|
djui_chat_message_create(tostring(get_environment_region(2)))
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function on_set_command(msg)
|
||||||
|
if not network_is_server() then
|
||||||
|
djui_chat_message_create("You need to be the host!")
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local num = tonumber(msg)
|
||||||
|
set_environment_region(1, num)
|
||||||
|
set_environment_region(2, num)
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
hook_chat_command("waterset", "to set the first two water levels", on_set_command)
|
||||||
|
hook_chat_command("waterget", "to get the first two water levels", on_get_command)
|
|
@ -11,7 +11,10 @@
|
||||||
|
|
||||||
- behavior_table.h
|
- behavior_table.h
|
||||||
- [get_behavior_from_id](#get_behavior_from_id)
|
- [get_behavior_from_id](#get_behavior_from_id)
|
||||||
|
- [get_behavior_name_from_id](#get_behavior_name_from_id)
|
||||||
- [get_id_from_behavior](#get_id_from_behavior)
|
- [get_id_from_behavior](#get_id_from_behavior)
|
||||||
|
- [get_id_from_behavior_name](#get_id_from_behavior_name)
|
||||||
|
- [get_id_from_vanilla_behavior](#get_id_from_vanilla_behavior)
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
|
@ -727,12 +730,14 @@
|
||||||
|
|
||||||
- smlua_misc_utils.h
|
- smlua_misc_utils.h
|
||||||
- [allocate_mario_action](#allocate_mario_action)
|
- [allocate_mario_action](#allocate_mario_action)
|
||||||
|
- [get_environment_region](#get_environment_region)
|
||||||
- [get_hand_foot_pos_x](#get_hand_foot_pos_x)
|
- [get_hand_foot_pos_x](#get_hand_foot_pos_x)
|
||||||
- [get_hand_foot_pos_y](#get_hand_foot_pos_y)
|
- [get_hand_foot_pos_y](#get_hand_foot_pos_y)
|
||||||
- [get_hand_foot_pos_z](#get_hand_foot_pos_z)
|
- [get_hand_foot_pos_z](#get_hand_foot_pos_z)
|
||||||
- [get_network_area_timer](#get_network_area_timer)
|
- [get_network_area_timer](#get_network_area_timer)
|
||||||
- [hud_hide](#hud_hide)
|
- [hud_hide](#hud_hide)
|
||||||
- [hud_show](#hud_show)
|
- [hud_show](#hud_show)
|
||||||
|
- [set_environment_region](#set_environment_region)
|
||||||
- [smlua_level_util_get](#smlua_level_util_get)
|
- [smlua_level_util_get](#smlua_level_util_get)
|
||||||
- [warp_exit_level](#warp_exit_level)
|
- [warp_exit_level](#warp_exit_level)
|
||||||
- [warp_restart_level](#warp_restart_level)
|
- [warp_restart_level](#warp_restart_level)
|
||||||
|
@ -913,6 +918,26 @@ The `reliable` field will ensure that the packet arrives, but should be used spa
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
|
## [get_behavior_name_from_id](#get_behavior_name_from_id)
|
||||||
|
|
||||||
|
### Lua Example
|
||||||
|
`local stringValue = get_behavior_name_from_id(id)`
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
| Field | Type |
|
||||||
|
| ----- | ---- |
|
||||||
|
| id | [enum BehaviorId](constants.md#enum-BehaviorId) |
|
||||||
|
|
||||||
|
### Returns
|
||||||
|
- `string`
|
||||||
|
|
||||||
|
### C Prototype
|
||||||
|
`const char* get_behavior_name_from_id(enum BehaviorId id);`
|
||||||
|
|
||||||
|
[:arrow_up_small:](#)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
## [get_id_from_behavior](#get_id_from_behavior)
|
## [get_id_from_behavior](#get_id_from_behavior)
|
||||||
|
|
||||||
### Lua Example
|
### Lua Example
|
||||||
|
@ -933,6 +958,46 @@ The `reliable` field will ensure that the packet arrives, but should be used spa
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
|
## [get_id_from_behavior_name](#get_id_from_behavior_name)
|
||||||
|
|
||||||
|
### Lua Example
|
||||||
|
`local enumValue = get_id_from_behavior_name(name)`
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
| Field | Type |
|
||||||
|
| ----- | ---- |
|
||||||
|
| name | `string` |
|
||||||
|
|
||||||
|
### Returns
|
||||||
|
[enum BehaviorId](constants.md#enum-BehaviorId)
|
||||||
|
|
||||||
|
### C Prototype
|
||||||
|
`enum BehaviorId get_id_from_behavior_name(const char* name);`
|
||||||
|
|
||||||
|
[:arrow_up_small:](#)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## [get_id_from_vanilla_behavior](#get_id_from_vanilla_behavior)
|
||||||
|
|
||||||
|
### Lua Example
|
||||||
|
`local enumValue = get_id_from_vanilla_behavior(behavior)`
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
| Field | Type |
|
||||||
|
| ----- | ---- |
|
||||||
|
| behavior | `Pointer` <`BehaviorScript`> |
|
||||||
|
|
||||||
|
### Returns
|
||||||
|
[enum BehaviorId](constants.md#enum-BehaviorId)
|
||||||
|
|
||||||
|
### C Prototype
|
||||||
|
`enum BehaviorId get_id_from_vanilla_behavior(const BehaviorScript* behavior);`
|
||||||
|
|
||||||
|
[:arrow_up_small:](#)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
---
|
---
|
||||||
# functions from camera.h
|
# functions from camera.h
|
||||||
|
|
||||||
|
@ -13659,6 +13724,26 @@ The `reliable` field will ensure that the packet arrives, but should be used spa
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
|
## [get_environment_region](#get_environment_region)
|
||||||
|
|
||||||
|
### Lua Example
|
||||||
|
`local numberValue = get_environment_region(index)`
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
| Field | Type |
|
||||||
|
| ----- | ---- |
|
||||||
|
| index | `integer` |
|
||||||
|
|
||||||
|
### Returns
|
||||||
|
- `number`
|
||||||
|
|
||||||
|
### C Prototype
|
||||||
|
`f32 get_environment_region(u8 index);`
|
||||||
|
|
||||||
|
[:arrow_up_small:](#)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
## [get_hand_foot_pos_x](#get_hand_foot_pos_x)
|
## [get_hand_foot_pos_x](#get_hand_foot_pos_x)
|
||||||
|
|
||||||
### Lua Example
|
### Lua Example
|
||||||
|
@ -13776,6 +13861,27 @@ The `reliable` field will ensure that the packet arrives, but should be used spa
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
|
## [set_environment_region](#set_environment_region)
|
||||||
|
|
||||||
|
### Lua Example
|
||||||
|
`set_environment_region(index, value)`
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
| Field | Type |
|
||||||
|
| ----- | ---- |
|
||||||
|
| index | `integer` |
|
||||||
|
| value | `integer` |
|
||||||
|
|
||||||
|
### Returns
|
||||||
|
- None
|
||||||
|
|
||||||
|
### C Prototype
|
||||||
|
`void set_environment_region(u8 index, s32 value);`
|
||||||
|
|
||||||
|
[:arrow_up_small:](#)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
## [smlua_level_util_get](#smlua_level_util_get)
|
## [smlua_level_util_get](#smlua_level_util_get)
|
||||||
|
|
||||||
### Lua Example
|
### Lua Example
|
||||||
|
|
|
@ -54,8 +54,9 @@ All of this is a holdover from when there were only two players. It was a reason
|
||||||
- [Custom Surface Collisions](examples/big-paddle)
|
- [Custom Surface Collisions](examples/big-paddle)
|
||||||
- [Custom Box Model](examples/custom-box-model)
|
- [Custom Box Model](examples/custom-box-model)
|
||||||
- [Custom Player Model](examples/koopa-player-model)
|
- [Custom Player Model](examples/koopa-player-model)
|
||||||
- [Moonjump](examples/Moonjump.lua)
|
- [Moonjump](examples/moonjump.lua)
|
||||||
- [Instant Clip](examples/Instant_Clip.lua)
|
- [Instant Clip](examples/instant-clip.lua)
|
||||||
|
- [Water Height Changer](examples/water-level.lua)
|
||||||
|
|
||||||
## Example Lua mods (large)
|
## Example Lua mods (large)
|
||||||
- [Extended Moveset](../../mods/extended-moveset.lua)
|
- [Extended Moveset](../../mods/extended-moveset.lua)
|
||||||
|
|
BIN
res/icon.ico
BIN
res/icon.ico
Binary file not shown.
Before Width: | Height: | Size: 401 KiB |
|
@ -1 +0,0 @@
|
||||||
id ICON res/icon.ico
|
|
|
@ -946,9 +946,11 @@ u32 interact_star_or_key(struct MarioState *m, UNUSED u32 interactType, struct O
|
||||||
}
|
}
|
||||||
save_file_do_save(gCurrSaveFileNum - 1, TRUE);
|
save_file_do_save(gCurrSaveFileNum - 1, TRUE);
|
||||||
|
|
||||||
if (!noExit || gServerSettings.stayInLevelAfterStar != 2) {
|
if (noExit && gServerSettings.stayInLevelAfterStar == 2) {
|
||||||
return set_mario_action(m, starGrabAction, noExit + 2 * grandStar);
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return set_mario_action(m, starGrabAction, noExit + 2 * grandStar);
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
|
@ -1530,6 +1530,7 @@ void update_mario_inputs(struct MarioState *m) {
|
||||||
/* End of developer stuff */
|
/* End of developer stuff */
|
||||||
|
|
||||||
if ((m->action == ACT_END_PEACH_CUTSCENE || m->action == ACT_CREDITS_CUTSCENE) && m->controller->buttonPressed & START_BUTTON) {
|
if ((m->action == ACT_END_PEACH_CUTSCENE || m->action == ACT_CREDITS_CUTSCENE) && m->controller->buttonPressed & START_BUTTON) {
|
||||||
|
gCurrCreditsEntry = NULL;
|
||||||
gCurrActStarNum = 0;
|
gCurrActStarNum = 0;
|
||||||
gCurrActNum = 0;
|
gCurrActNum = 0;
|
||||||
gChangeLevel = 16;
|
gChangeLevel = 16;
|
||||||
|
|
|
@ -2807,6 +2807,7 @@ static s32 act_credits_cutscene(struct MarioState *m) {
|
||||||
m->actionState += 2;
|
m->actionState += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gCurrCreditsEntry != NULL) {
|
||||||
if (m->playerIndex == 0) {
|
if (m->playerIndex == 0) {
|
||||||
s32 width = m->actionState * 640 / 100;
|
s32 width = m->actionState * 640 / 100;
|
||||||
s32 height = m->actionState * 480 / 100;
|
s32 height = m->actionState * 480 / 100;
|
||||||
|
@ -2819,7 +2820,9 @@ static s32 act_credits_cutscene(struct MarioState *m) {
|
||||||
override_viewport_and_clip(&sEndCutsceneVp, 0, 0, 0, 0);
|
override_viewport_and_clip(&sEndCutsceneVp, 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gCurrCreditsEntry != NULL) {
|
||||||
if (m->actionTimer == TIMER_CREDITS_PROGRESS && m->playerIndex == 0) {
|
if (m->actionTimer == TIMER_CREDITS_PROGRESS && m->playerIndex == 0) {
|
||||||
reset_cutscene_msg_fade();
|
reset_cutscene_msg_fade();
|
||||||
}
|
}
|
||||||
|
@ -2833,7 +2836,7 @@ static s32 act_credits_cutscene(struct MarioState *m) {
|
||||||
}
|
}
|
||||||
|
|
||||||
m->marioObj->header.gfx.angle[1] += (gCurrCreditsEntry->unk02 & 0xC0) << 8;
|
m->marioObj->header.gfx.angle[1] += (gCurrCreditsEntry->unk02 & 0xC0) << 8;
|
||||||
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -41,6 +41,17 @@ int smlua_func_get_behavior_from_id(lua_State* L) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int smlua_func_get_behavior_name_from_id(lua_State* L) {
|
||||||
|
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
||||||
|
|
||||||
|
int id = smlua_to_integer(L, 1);
|
||||||
|
if (!gSmLuaConvertSuccess) { return 0; }
|
||||||
|
|
||||||
|
lua_pushstring(L, get_behavior_name_from_id(id));
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int smlua_func_get_id_from_behavior(lua_State* L) {
|
int smlua_func_get_id_from_behavior(lua_State* L) {
|
||||||
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
||||||
|
|
||||||
|
@ -52,6 +63,28 @@ int smlua_func_get_id_from_behavior(lua_State* L) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int smlua_func_get_id_from_behavior_name(lua_State* L) {
|
||||||
|
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
||||||
|
|
||||||
|
const char* name = smlua_to_string(L, 1);
|
||||||
|
if (!gSmLuaConvertSuccess) { return 0; }
|
||||||
|
|
||||||
|
lua_pushinteger(L, get_id_from_behavior_name(name));
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int smlua_func_get_id_from_vanilla_behavior(lua_State* L) {
|
||||||
|
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
||||||
|
|
||||||
|
const BehaviorScript* behavior = (const BehaviorScript*)smlua_to_cpointer(L, 1, LVT_BEHAVIORSCRIPT_P);
|
||||||
|
if (!gSmLuaConvertSuccess) { return 0; }
|
||||||
|
|
||||||
|
lua_pushinteger(L, get_id_from_vanilla_behavior(behavior));
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
//////////////
|
//////////////
|
||||||
// camera.h //
|
// camera.h //
|
||||||
//////////////
|
//////////////
|
||||||
|
@ -9200,6 +9233,17 @@ int smlua_func_allocate_mario_action(lua_State* L) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int smlua_func_get_environment_region(lua_State* L) {
|
||||||
|
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
||||||
|
|
||||||
|
u8 index = smlua_to_integer(L, 1);
|
||||||
|
if (!gSmLuaConvertSuccess) { return 0; }
|
||||||
|
|
||||||
|
lua_pushnumber(L, get_environment_region(index));
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int smlua_func_get_hand_foot_pos_x(lua_State* L) {
|
int smlua_func_get_hand_foot_pos_x(lua_State* L) {
|
||||||
if(!smlua_functions_valid_param_count(L, 2)) { return 0; }
|
if(!smlua_functions_valid_param_count(L, 2)) { return 0; }
|
||||||
|
|
||||||
|
@ -9266,6 +9310,19 @@ int smlua_func_hud_show(UNUSED lua_State* L) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int smlua_func_set_environment_region(lua_State* L) {
|
||||||
|
if(!smlua_functions_valid_param_count(L, 2)) { return 0; }
|
||||||
|
|
||||||
|
u8 index = smlua_to_integer(L, 1);
|
||||||
|
if (!gSmLuaConvertSuccess) { return 0; }
|
||||||
|
s32 value = smlua_to_integer(L, 2);
|
||||||
|
if (!gSmLuaConvertSuccess) { return 0; }
|
||||||
|
|
||||||
|
set_environment_region(index, value);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int smlua_func_smlua_level_util_get(lua_State* L) {
|
int smlua_func_smlua_level_util_get(lua_State* L) {
|
||||||
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
||||||
|
|
||||||
|
@ -10031,7 +10088,10 @@ void smlua_bind_functions_autogen(void) {
|
||||||
|
|
||||||
// behavior_table.h
|
// behavior_table.h
|
||||||
smlua_bind_function(L, "get_behavior_from_id", smlua_func_get_behavior_from_id);
|
smlua_bind_function(L, "get_behavior_from_id", smlua_func_get_behavior_from_id);
|
||||||
|
smlua_bind_function(L, "get_behavior_name_from_id", smlua_func_get_behavior_name_from_id);
|
||||||
smlua_bind_function(L, "get_id_from_behavior", smlua_func_get_id_from_behavior);
|
smlua_bind_function(L, "get_id_from_behavior", smlua_func_get_id_from_behavior);
|
||||||
|
smlua_bind_function(L, "get_id_from_behavior_name", smlua_func_get_id_from_behavior_name);
|
||||||
|
smlua_bind_function(L, "get_id_from_vanilla_behavior", smlua_func_get_id_from_vanilla_behavior);
|
||||||
|
|
||||||
// camera.h
|
// camera.h
|
||||||
smlua_bind_function(L, "approach_camera_height", smlua_func_approach_camera_height);
|
smlua_bind_function(L, "approach_camera_height", smlua_func_approach_camera_height);
|
||||||
|
@ -10714,12 +10774,14 @@ void smlua_bind_functions_autogen(void) {
|
||||||
|
|
||||||
// smlua_misc_utils.h
|
// smlua_misc_utils.h
|
||||||
smlua_bind_function(L, "allocate_mario_action", smlua_func_allocate_mario_action);
|
smlua_bind_function(L, "allocate_mario_action", smlua_func_allocate_mario_action);
|
||||||
|
smlua_bind_function(L, "get_environment_region", smlua_func_get_environment_region);
|
||||||
smlua_bind_function(L, "get_hand_foot_pos_x", smlua_func_get_hand_foot_pos_x);
|
smlua_bind_function(L, "get_hand_foot_pos_x", smlua_func_get_hand_foot_pos_x);
|
||||||
smlua_bind_function(L, "get_hand_foot_pos_y", smlua_func_get_hand_foot_pos_y);
|
smlua_bind_function(L, "get_hand_foot_pos_y", smlua_func_get_hand_foot_pos_y);
|
||||||
smlua_bind_function(L, "get_hand_foot_pos_z", smlua_func_get_hand_foot_pos_z);
|
smlua_bind_function(L, "get_hand_foot_pos_z", smlua_func_get_hand_foot_pos_z);
|
||||||
smlua_bind_function(L, "get_network_area_timer", smlua_func_get_network_area_timer);
|
smlua_bind_function(L, "get_network_area_timer", smlua_func_get_network_area_timer);
|
||||||
smlua_bind_function(L, "hud_hide", smlua_func_hud_hide);
|
smlua_bind_function(L, "hud_hide", smlua_func_hud_hide);
|
||||||
smlua_bind_function(L, "hud_show", smlua_func_hud_show);
|
smlua_bind_function(L, "hud_show", smlua_func_hud_show);
|
||||||
|
smlua_bind_function(L, "set_environment_region", smlua_func_set_environment_region);
|
||||||
smlua_bind_function(L, "smlua_level_util_get", smlua_func_smlua_level_util_get);
|
smlua_bind_function(L, "smlua_level_util_get", smlua_func_smlua_level_util_get);
|
||||||
smlua_bind_function(L, "warp_exit_level", smlua_func_warp_exit_level);
|
smlua_bind_function(L, "warp_exit_level", smlua_func_warp_exit_level);
|
||||||
smlua_bind_function(L, "warp_restart_level", smlua_func_warp_restart_level);
|
smlua_bind_function(L, "warp_restart_level", smlua_func_warp_restart_level);
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#include "smlua_misc_utils.h"
|
#include "smlua_misc_utils.h"
|
||||||
#include "pc/debuglog.h"
|
#include "pc/debuglog.h"
|
||||||
|
|
||||||
|
#include "game/object_list_processor.h"
|
||||||
|
|
||||||
u32 get_network_area_timer(void) {
|
u32 get_network_area_timer(void) {
|
||||||
return gNetworkAreaTimer;
|
return gNetworkAreaTimer;
|
||||||
}
|
}
|
||||||
|
@ -58,3 +60,16 @@ f32 get_hand_foot_pos_z(struct MarioState* m, u8 index) {
|
||||||
LevelScript* smlua_level_util_get(const char* name) {
|
LevelScript* smlua_level_util_get(const char* name) {
|
||||||
return dynos_level_get(name);
|
return dynos_level_get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
f32 get_environment_region(u8 index) {
|
||||||
|
if (gEnvironmentRegions != NULL && index <= gEnvironmentRegions[0]) {
|
||||||
|
return gEnvironmentRegions[6 * (int)index];
|
||||||
|
}
|
||||||
|
return -11000;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_environment_region(u8 index, s32 value) {
|
||||||
|
if (gEnvironmentRegions != NULL && index <= gEnvironmentRegions[0]) {
|
||||||
|
gEnvironmentRegions[6 * (int)index] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -18,5 +18,7 @@ f32 get_hand_foot_pos_y(struct MarioState* m, u8 index);
|
||||||
f32 get_hand_foot_pos_z(struct MarioState* m, u8 index);
|
f32 get_hand_foot_pos_z(struct MarioState* m, u8 index);
|
||||||
|
|
||||||
LevelScript* smlua_level_util_get(const char* name);
|
LevelScript* smlua_level_util_get(const char* name);
|
||||||
|
f32 get_environment_region(u8 index);
|
||||||
|
void set_environment_region(u8 index, s32 value);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -298,6 +298,26 @@ static bool mod_load_files(struct Mod* mod, char* modName, char* fullPath) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mod_set_loading_order(struct Mod* mod) {
|
||||||
|
if (mod->fileCount <= 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: add a way to specify the loading order of a mod's files?
|
||||||
|
|
||||||
|
// By default, this is the alphabetical order on relative path
|
||||||
|
for (s32 i = 1; i < mod->fileCount; ++i) {
|
||||||
|
struct ModFile file = mod->files[i];
|
||||||
|
for (s32 j = 0; j < i; ++j) {
|
||||||
|
if (strcmp(file.relativePath, mod->files[j].relativePath) < 0) {
|
||||||
|
memmove(mod->files + j + 1, mod->files + j, sizeof(struct ModFile) * (i - j));
|
||||||
|
memcpy(mod->files + j, &file, sizeof(struct ModFile));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void mod_extract_fields(struct Mod* mod) {
|
static void mod_extract_fields(struct Mod* mod) {
|
||||||
// get full path
|
// get full path
|
||||||
char path[SYS_MAX_PATH] = { 0 };
|
char path[SYS_MAX_PATH] = { 0 };
|
||||||
|
@ -439,6 +459,9 @@ bool mod_load(struct Mods* mods, char* basePath, char* modName) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set loading order
|
||||||
|
mod_set_loading_order(mod);
|
||||||
|
|
||||||
// extract fields
|
// extract fields
|
||||||
mod_extract_fields(mod);
|
mod_extract_fields(mod);
|
||||||
|
|
||||||
|
|
|
@ -170,6 +170,11 @@ void network_receive_mod_list(struct Packet* p) {
|
||||||
packet_read(p, &relativePathLength, sizeof(u16));
|
packet_read(p, &relativePathLength, sizeof(u16));
|
||||||
packet_read(p, file->relativePath, relativePathLength * sizeof(u8));
|
packet_read(p, file->relativePath, relativePathLength * sizeof(u8));
|
||||||
packet_read(p, &file->size, sizeof(u64));
|
packet_read(p, &file->size, sizeof(u64));
|
||||||
|
if (mod->isDirectory && !strstr(file->relativePath, "actors")) {
|
||||||
|
char tmp[SYS_MAX_PATH];
|
||||||
|
snprintf(tmp, SYS_MAX_PATH, "%s-%s", mod->relativePath, file->relativePath);
|
||||||
|
memcpy(file->relativePath, tmp, strlen(tmp) + 1);
|
||||||
|
}
|
||||||
normalize_path(file->relativePath);
|
normalize_path(file->relativePath);
|
||||||
LOG_INFO(" '%s': %llu", file->relativePath, (u64)file->size);
|
LOG_INFO(" '%s': %llu", file->relativePath, (u64)file->size);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue