mirror of https://github.com/sm64pc/sm64pc.git
Add base editor, with improved UI and support for color codes
This commit is contained in:
parent
d1f5da5ca5
commit
37e47e6451
10
Makefile
10
Makefile
|
@ -123,7 +123,7 @@ endif
|
|||
# Release (version) flag defs
|
||||
VERSION_DEF := VERSION_US
|
||||
|
||||
TARGET := moon64.$(VERSION)
|
||||
TARGET := saturn.$(VERSION)
|
||||
VERSION_CFLAGS := -D$(VERSION_DEF) -D_LANGUAGE_C
|
||||
VERSION_ASFLAGS := --defsym $(VERSION_DEF)=1
|
||||
|
||||
|
@ -672,8 +672,10 @@ ifeq ($(TARGET_SWITCH),1)
|
|||
all: $(EXE).nro
|
||||
endif
|
||||
|
||||
ADDONS := addons
|
||||
ADDONS_PATH := $(BUILD_DIR)/$(ADDONS)/
|
||||
ADDONS := addons
|
||||
ADDONS_PATH := $(BUILD_DIR)/$(ADDONS)/
|
||||
MACHINIMA := machinima
|
||||
MACHINIMA_PATH := $(BUILD_DIR)/$(MACHINIMA)/
|
||||
BASEPACK_LST := $(BUILD_DIR)/basepack.lst
|
||||
|
||||
# depend on resources as well
|
||||
|
@ -721,7 +723,7 @@ $(BUILD_DIR)/src/game/crash_screen.o: $(CRASH_TEXTURE_C_FILES)
|
|||
$(BUILD_DIR)/lib/rsp.o: $(BUILD_DIR)/rsp/rspboot.bin $(BUILD_DIR)/rsp/fast3d.bin $(BUILD_DIR)/rsp/audio.bin
|
||||
|
||||
RSP_DIRS := $(BUILD_DIR)/rsp
|
||||
ALL_DIRS := $(BUILD_DIR) $(addprefix $(BUILD_DIR)/,$(SRC_DIRS) $(ASM_DIRS) $(GODDARD_SRC_DIRS) $(ULTRA_SRC_DIRS) $(ULTRA_ASM_DIRS) $(ULTRA_BIN_DIRS) $(BIN_DIRS) $(TEXTURE_DIRS) $(SOUND_SAMPLE_DIRS) $(addprefix levels/,$(LEVEL_DIRS)) include) $(MIO0_DIR) $(addprefix $(MIO0_DIR)/,$(VERSION)) $(SOUND_BIN_DIR) $(SOUND_BIN_DIR)/sequences/$(VERSION) $(RSP_DIRS) $(ADDONS_PATH)
|
||||
ALL_DIRS := $(BUILD_DIR) $(addprefix $(BUILD_DIR)/,$(SRC_DIRS) $(ASM_DIRS) $(GODDARD_SRC_DIRS) $(ULTRA_SRC_DIRS) $(ULTRA_ASM_DIRS) $(ULTRA_BIN_DIRS) $(BIN_DIRS) $(TEXTURE_DIRS) $(SOUND_SAMPLE_DIRS) $(addprefix levels/,$(LEVEL_DIRS)) include) $(MIO0_DIR) $(addprefix $(MIO0_DIR)/,$(VERSION)) $(SOUND_BIN_DIR) $(SOUND_BIN_DIR)/sequences/$(VERSION) $(RSP_DIRS) $(ADDONS_PATH) $(MACHINIMA_PATH)
|
||||
|
||||
# Make sure build directory exists before compiling anything
|
||||
DUMMY != mkdir -p $(ALL_DIRS)
|
||||
|
|
|
@ -14,8 +14,8 @@ static const Lights1 mario_red_lights_group = gdSPDefLights1(
|
|||
|
||||
// 0x04000030 # solid color white - metal butt & left thigh - normal left & right hand closed & open (with cap too) and all wings - all poly types
|
||||
static const Lights1 mario_white_lights_group = gdSPDefLights1(
|
||||
0x7f, 0x7f, 0x7f,
|
||||
0xff, 0xff, 0xff, 0x28, 0x28, 0x28
|
||||
0x00, 0x7f, 0x00,
|
||||
0x00, 0xff, 0x00, 0x28, 0x28, 0x28
|
||||
);
|
||||
|
||||
// 0x04000048 # solid color brown 1 - foot - all poly types
|
||||
|
|
|
@ -118,6 +118,10 @@ struct GraphNodeObject_sub
|
|||
/*0x0A 0x42*/ u16 animTimer;
|
||||
/*0x0C 0x44*/ s32 animFrameAccelAssist;
|
||||
/*0x10 0x48*/ s32 animAccel;
|
||||
s16 prevAnimFrame;
|
||||
s16 prevAnimID;
|
||||
u32 prevAnimFrameTimestamp;
|
||||
struct Animation *prevAnimPtr;
|
||||
};
|
||||
|
||||
struct GraphNodeObject
|
||||
|
@ -128,11 +132,22 @@ struct GraphNodeObject
|
|||
/*0x19*/ s8 unk19;
|
||||
/*0x1A*/ Vec3s angle;
|
||||
/*0x20*/ Vec3f pos;
|
||||
Vec3s prevAngle;
|
||||
Vec3f prevPos;
|
||||
u32 prevTimestamp;
|
||||
Vec3f prevShadowPos;
|
||||
u32 prevShadowPosTimestamp;
|
||||
/*0x2C*/ Vec3f scale;
|
||||
Vec3f prevScale;
|
||||
u32 prevScaleTimestamp;
|
||||
/*0x38*/ struct GraphNodeObject_sub unk38;
|
||||
/*0x4C*/ struct SpawnInfo *unk4C;
|
||||
/*0x50*/ Mat4 *throwMatrix; // matrix ptr
|
||||
Mat4 prevThrowMatrix;
|
||||
u32 prevThrowMatrixTimestamp;
|
||||
Mat4 *throwMatrixInterpolated;
|
||||
/*0x54*/ Vec3f cameraToObject;
|
||||
u32 skipInterpolationTimestamp;
|
||||
};
|
||||
|
||||
struct ObjectNode
|
||||
|
@ -243,6 +258,10 @@ struct Surface
|
|||
} normal;
|
||||
/*0x28*/ f32 originOffset;
|
||||
/*0x2C*/ struct Object *object;
|
||||
Vec3s prevVertex1;
|
||||
Vec3s prevVertex2;
|
||||
Vec3s prevVertex3;
|
||||
u32 modifiedTimestamp;
|
||||
};
|
||||
|
||||
struct MarioBodyState
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 35 KiB |
|
@ -0,0 +1,18 @@
|
|||
IDI_ICON1 ICON DISCARDABLE "icon.ico"
|
||||
1 VERSIONINFO
|
||||
FILEVERSION 1,0,0,0
|
||||
PRODUCTVERSION 1,0,0,0
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904E4"
|
||||
BEGIN
|
||||
VALUE "InternalName", "v64saturn"
|
||||
VALUE "ProductName", "Saturn"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 0
|
||||
END
|
||||
END
|
|
@ -0,0 +1,72 @@
|
|||
{
|
||||
"files.associations": {
|
||||
"random": "c",
|
||||
"saturn.h": "c",
|
||||
"achievements.h": "c",
|
||||
"cheats.h": "c",
|
||||
"save_file.h": "c",
|
||||
"saturn_types.h": "c",
|
||||
"object_list_processor.h": "c",
|
||||
"typeinfo": "c",
|
||||
"vector": "cpp",
|
||||
"array": "cpp",
|
||||
"atomic": "cpp",
|
||||
"bit": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"bitset": "cpp",
|
||||
"cctype": "cpp",
|
||||
"chrono": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"codecvt": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"deque": "cpp",
|
||||
"forward_list": "cpp",
|
||||
"list": "cpp",
|
||||
"map": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"exception": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"functional": "cpp",
|
||||
"iterator": "cpp",
|
||||
"memory": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"numeric": "cpp",
|
||||
"optional": "cpp",
|
||||
"ratio": "cpp",
|
||||
"regex": "cpp",
|
||||
"string": "cpp",
|
||||
"string_view": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"fstream": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"iostream": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"new": "cpp",
|
||||
"ostream": "cpp",
|
||||
"shared_mutex": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"valarray": "cpp",
|
||||
"compare": "cpp",
|
||||
"concepts": "cpp",
|
||||
"ranges": "cpp"
|
||||
}
|
||||
}
|
|
@ -110,6 +110,8 @@ struct GraphNodePerspective
|
|||
/*0x1C*/ f32 fov; // horizontal field of view in degrees
|
||||
/*0x20*/ s16 near; // near clipping plane
|
||||
/*0x22*/ s16 far; // far clipping plane
|
||||
f32 prevFov;
|
||||
f32 prevTimestamp;
|
||||
};
|
||||
|
||||
/** An entry in the master list. It is a linked list of display lists
|
||||
|
@ -118,7 +120,9 @@ struct GraphNodePerspective
|
|||
struct DisplayListNode
|
||||
{
|
||||
Mtx *transform;
|
||||
void *transformInterpolated;
|
||||
void *displayList;
|
||||
void *displayListInterpolated;
|
||||
struct DisplayListNode *next;
|
||||
};
|
||||
|
||||
|
@ -185,7 +189,11 @@ struct GraphNodeCamera
|
|||
} config;
|
||||
/*0x1C*/ Vec3f pos;
|
||||
/*0x28*/ Vec3f focus;
|
||||
Vec3f prevPos;
|
||||
Vec3f prevFocus;
|
||||
u32 prevTimestamp;
|
||||
/*0x34*/ Mat4 *matrixPtr; // pointer to look-at matrix of this camera as a Mat4
|
||||
Mat4 *matrixPtrInterpolated;
|
||||
/*0x38*/ s16 roll; // roll in look at matrix. Doesn't account for light direction unlike rollScreen.
|
||||
/*0x3A*/ s16 rollScreen; // rolls screen while keeping the light direction consistent
|
||||
};
|
||||
|
@ -226,7 +234,8 @@ struct GraphNodeRotation
|
|||
/*0x00*/ struct GraphNode node;
|
||||
/*0x14*/ void *displayList;
|
||||
/*0x18*/ Vec3s rotation;
|
||||
u8 pad1E[2];
|
||||
Vec3s prevRotation;
|
||||
u32 prevTimestamp;
|
||||
};
|
||||
|
||||
/** GraphNode part that transforms itself and its children based on animation
|
||||
|
@ -323,6 +332,9 @@ struct GraphNodeBackground
|
|||
/*0x00*/ struct FnGraphNode fnNode;
|
||||
/*0x18*/ s32 unused;
|
||||
/*0x1C*/ s32 background; // background ID, or rgba5551 color if fnNode.func is null
|
||||
Vec3f prevCameraPos;
|
||||
Vec3f prevCameraFocus;
|
||||
u32 prevCameraTimestamp;
|
||||
};
|
||||
|
||||
/** Renders the object that Mario is holding.
|
||||
|
@ -333,6 +345,8 @@ struct GraphNodeHeldObject
|
|||
/*0x18*/ s32 playerIndex;
|
||||
/*0x1C*/ struct Object *objNode;
|
||||
/*0x20*/ Vec3s translation;
|
||||
Vec3f prevShadowPos;
|
||||
u32 prevShadowPosTimestamp;
|
||||
};
|
||||
|
||||
/** A node that allows an object to specify a different culling radius than the
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "surface_collision.h"
|
||||
#include "surface_load.h"
|
||||
#include "math_util.h"
|
||||
#include "game/game_init.h"
|
||||
|
||||
/**************************************************
|
||||
* WALLS *
|
||||
|
@ -394,26 +395,44 @@ f32 find_floor_height_and_data(f32 xPos, f32 yPos, f32 zPos, struct FloorGeometr
|
|||
return floorHeight;
|
||||
}
|
||||
|
||||
u8 gInterpolatingSurfaces;
|
||||
|
||||
/**
|
||||
* Iterate through the list of floors and find the first floor under a given point.
|
||||
*/
|
||||
static struct Surface *find_floor_from_list(struct SurfaceNode *surfaceNode, s32 x, s32 y, s32 z, f32 *pheight) {
|
||||
register struct Surface *surf;
|
||||
register s32 x1, z1, x2, z2, x3, z3;
|
||||
register f32 x1, z1, x2, z2, x3, z3;
|
||||
f32 nx, ny, nz;
|
||||
f32 oo;
|
||||
f32 height;
|
||||
struct Surface *floor = NULL;
|
||||
s32 interpolate;
|
||||
|
||||
// Iterate through the list of floors until there are no more floors.
|
||||
while (surfaceNode != NULL) {
|
||||
surf = surfaceNode->surface;
|
||||
surfaceNode = surfaceNode->next;
|
||||
interpolate = gInterpolatingSurfaces && surf->modifiedTimestamp == gGlobalTimer;
|
||||
|
||||
x1 = surf->vertex1[0];
|
||||
z1 = surf->vertex1[2];
|
||||
x2 = surf->vertex2[0];
|
||||
z2 = surf->vertex2[2];
|
||||
if (interpolate) {
|
||||
f32 diff = (surf->prevVertex1[0] - x1) * (surf->prevVertex1[0] - x1);
|
||||
diff += (surf->prevVertex1[1] - surf->vertex1[1]) * (surf->prevVertex1[1] - surf->vertex1[1]);
|
||||
diff += (surf->prevVertex1[2] - z1) * (surf->prevVertex1[2] - z1);
|
||||
//printf("%f\n", sqrtf(diff));
|
||||
if (diff > 10000) {
|
||||
interpolate = FALSE;
|
||||
} else {
|
||||
x1 = (surf->prevVertex1[0] + x1) / 2;
|
||||
z1 = (surf->prevVertex1[2] + z1) / 2;
|
||||
x2 = (surf->prevVertex2[0] + x2) / 2;
|
||||
z2 = (surf->prevVertex2[2] + z2) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the point is within the triangle bounds.
|
||||
if ((z1 - z) * (x2 - x1) - (x1 - x) * (z2 - z1) < 0) {
|
||||
|
@ -423,6 +442,10 @@ static struct Surface *find_floor_from_list(struct SurfaceNode *surfaceNode, s32
|
|||
// To slightly save on computation time, set this later.
|
||||
x3 = surf->vertex3[0];
|
||||
z3 = surf->vertex3[2];
|
||||
if (interpolate) {
|
||||
x3 = (surf->prevVertex3[0] + x3) / 2;
|
||||
z3 = (surf->prevVertex3[2] + z3) / 2;
|
||||
}
|
||||
|
||||
if ((z2 - z) * (x3 - x2) - (x2 - x) * (z3 - z2) < 0) {
|
||||
continue;
|
||||
|
@ -442,10 +465,30 @@ static struct Surface *find_floor_from_list(struct SurfaceNode *surfaceNode, s32
|
|||
continue;
|
||||
}
|
||||
|
||||
nx = surf->normal.x;
|
||||
ny = surf->normal.y;
|
||||
nz = surf->normal.z;
|
||||
oo = surf->originOffset;
|
||||
if (interpolate) {
|
||||
f32 y1, y2, y3;
|
||||
f32 mag;
|
||||
y1 = (surf->prevVertex1[1] + surf->vertex1[1]) / 2;
|
||||
y2 = (surf->prevVertex2[1] + surf->vertex2[1]) / 2;
|
||||
y3 = (surf->prevVertex3[1] + surf->vertex3[1]) / 2;
|
||||
nx = (y2 - y1) * (z3 - z2) - (z2 - z1) * (y3 - y2);
|
||||
ny = (z2 - z1) * (x3 - x2) - (x2 - x1) * (z3 - z2);
|
||||
nz = (x2 - x1) * (y3 - y2) - (y2 - y1) * (x3 - x2);
|
||||
mag = sqrtf(nx * nx + ny * ny + nz * nz);
|
||||
if (mag < 0.0001) {
|
||||
continue;
|
||||
}
|
||||
mag = (f32)(1.0 / mag);
|
||||
nx *= mag;
|
||||
ny *= mag;
|
||||
nz *= mag;
|
||||
oo = -(nx * x1 + ny * y1 + nz * z1);
|
||||
} else {
|
||||
nx = surf->normal.x;
|
||||
ny = surf->normal.y;
|
||||
nz = surf->normal.z;
|
||||
oo = surf->originOffset;
|
||||
}
|
||||
|
||||
// If a wall, ignore it. Likely a remnant, should never occur.
|
||||
if (ny == 0.0f) {
|
||||
|
@ -460,6 +503,15 @@ static struct Surface *find_floor_from_list(struct SurfaceNode *surfaceNode, s32
|
|||
}
|
||||
|
||||
*pheight = height;
|
||||
if (interpolate) {
|
||||
static struct Surface s;
|
||||
s.type = surf->type;
|
||||
s.normal.x = nx;
|
||||
s.normal.y = ny;
|
||||
s.normal.z = nz;
|
||||
s.originOffset = oo;
|
||||
return &s;
|
||||
}
|
||||
floor = surf;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "game/mario.h"
|
||||
#include "game/object_list_processor.h"
|
||||
#include "surface_load.h"
|
||||
#include "game/game_init.h"
|
||||
|
||||
s32 unused8038BE90;
|
||||
|
||||
|
@ -354,6 +355,11 @@ static struct Surface *read_surface_data(s16 *vertexData, s16 **vertexIndices) {
|
|||
|
||||
surface = alloc_surface();
|
||||
|
||||
vec3s_copy(surface->prevVertex1, surface->vertex1);
|
||||
vec3s_copy(surface->prevVertex2, surface->vertex2);
|
||||
vec3s_copy(surface->prevVertex3, surface->vertex3);
|
||||
surface->modifiedTimestamp = gGlobalTimer;
|
||||
|
||||
surface->vertex1[0] = x1;
|
||||
surface->vertex2[0] = x2;
|
||||
surface->vertex3[0] = x3;
|
||||
|
|
|
@ -11617,4 +11617,4 @@ void obj_rotate_towards_point(struct Object *o, Vec3f point, s16 pitchOff, s16 y
|
|||
#include "behaviors/intro_lakitu.inc.c"
|
||||
#include "behaviors/end_birds_1.inc.c"
|
||||
#include "behaviors/end_birds_2.inc.c"
|
||||
#include "behaviors/intro_scene.inc.c"
|
||||
#include "behaviors/intro_scene.inc.c"
|
|
@ -657,6 +657,8 @@ struct LakituState
|
|||
/// Mario's action from the previous frame. Only used to determine if Mario just finished a dive.
|
||||
/*0xB8*/ u32 lastFrameAction;
|
||||
/*0xBC*/ s16 unused;
|
||||
|
||||
u32 skipCameraInterpolationTimestamp;
|
||||
};
|
||||
|
||||
// bss order hack to not affect BSS order. if possible, remove me, but it will be hard to match otherwise
|
||||
|
@ -773,4 +775,7 @@ void obj_rotate_towards_point(struct Object *o, Vec3f point, s16 pitchOff, s16 y
|
|||
|
||||
Gfx *geo_camera_fov(s32 callContext, struct GraphNode *g, UNUSED void *context);
|
||||
|
||||
extern u8 machinimaMode;
|
||||
extern f32 camVelSpeed;
|
||||
|
||||
#endif // CAMERA_H
|
||||
|
|
|
@ -35,6 +35,20 @@ Vtx_t gBubbleTempVtx[3] = {
|
|||
{ { 0, 0, 0 }, 0, { -498, 964 }, { 0xFF, 0xFF, 0xFF, 0xFF } },
|
||||
};
|
||||
|
||||
static Gfx sGfxSaved[60 / 5];
|
||||
static Gfx *sBubbleInterpolatedDisplayListPos[60 / 5];
|
||||
static Vec3s sPrevBubblePositions[60];
|
||||
|
||||
void patch_interpolated_bubble_particles(void) {
|
||||
s32 i;
|
||||
for (i = 0; i < 60 / 5; i++) {
|
||||
if (sBubbleInterpolatedDisplayListPos[i] != NULL) {
|
||||
*sBubbleInterpolatedDisplayListPos[i] = sGfxSaved[i];
|
||||
sBubbleInterpolatedDisplayListPos[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the particle with the given index is
|
||||
* laterally within distance of point (x, z). Used to
|
||||
|
@ -241,6 +255,7 @@ void envfx_update_whirlpool(void) {
|
|||
(gEnvFxBuffer + i)->yPos = (i + gEnvFxBuffer)->bubbleY;
|
||||
(gEnvFxBuffer + i)->unusedBubbleVar = 0;
|
||||
(gEnvFxBuffer + i)->isAlive = 1;
|
||||
(gEnvFxBuffer + i)->spawnTimestamp = gGlobalTimer;
|
||||
|
||||
envfx_rotate_around_whirlpool(&(gEnvFxBuffer + i)->xPos, &(gEnvFxBuffer + i)->yPos,
|
||||
&(gEnvFxBuffer + i)->zPos);
|
||||
|
@ -299,6 +314,7 @@ void envfx_update_jetstream(void) {
|
|||
+ coss((gEnvFxBuffer + i)->angleAndDist[0]) * (gEnvFxBuffer + i)->angleAndDist[1];
|
||||
(gEnvFxBuffer + i)->yPos =
|
||||
gEnvFxBubbleConfig[ENVFX_STATE_SRC_Y] + (random_float() * 400.0f - 200.0f);
|
||||
(gEnvFxBuffer + i)->spawnTimestamp = gGlobalTimer;
|
||||
} else {
|
||||
(gEnvFxBuffer + i)->angleAndDist[1] += 10;
|
||||
(gEnvFxBuffer + i)->xPos += sins((gEnvFxBuffer + i)->angleAndDist[0]) * 10.0f;
|
||||
|
@ -506,6 +522,12 @@ Gfx *envfx_update_bubble_particles(s32 mode, UNUSED Vec3s marioPos, Vec3s camFro
|
|||
Vec3s vertex1;
|
||||
Vec3s vertex2;
|
||||
Vec3s vertex3;
|
||||
Vec3s interpolatedVertices[3];
|
||||
|
||||
static Vec3s prevVertex1;
|
||||
static Vec3s prevVertex2;
|
||||
static Vec3s prevVertex3;
|
||||
static u32 prevTimestamp;
|
||||
|
||||
Gfx *gfxStart;
|
||||
|
||||
|
@ -521,18 +543,52 @@ Gfx *envfx_update_bubble_particles(s32 mode, UNUSED Vec3s marioPos, Vec3s camFro
|
|||
envfx_bubbles_update_switch(mode, camTo, vertex1, vertex2, vertex3);
|
||||
rotate_triangle_vertices(vertex1, vertex2, vertex3, pitch, yaw);
|
||||
|
||||
if (gGlobalTimer == prevTimestamp + 1) {
|
||||
interpolate_vectors_s16(interpolatedVertices[0], prevVertex1, vertex1);
|
||||
interpolate_vectors_s16(interpolatedVertices[1], prevVertex2, vertex2);
|
||||
interpolate_vectors_s16(interpolatedVertices[2], prevVertex3, vertex3);
|
||||
}
|
||||
vec3s_copy(prevVertex1, vertex1);
|
||||
vec3s_copy(prevVertex2, vertex2);
|
||||
vec3s_copy(prevVertex3, vertex3);
|
||||
prevTimestamp = gGlobalTimer;
|
||||
|
||||
gSPDisplayList(sGfxCursor++, &tiny_bubble_dl_0B006D38);
|
||||
|
||||
for (i = 0; i < sBubbleParticleMaxCount; i += 5) {
|
||||
Vtx *interpolatedVertBuf = alloc_display_list(15 * sizeof(Vtx));
|
||||
s32 j, k;
|
||||
gDPPipeSync(sGfxCursor++);
|
||||
envfx_set_bubble_texture(mode, i);
|
||||
append_bubble_vertex_buffer(sGfxCursor++, i, vertex1, vertex2, vertex3, (Vtx *) gBubbleTempVtx);
|
||||
sBubbleInterpolatedDisplayListPos[i / 5] = sGfxCursor;
|
||||
for (j = 0; j < 5; j++) {
|
||||
for (k = 0; k < 3; k++) {
|
||||
Vtx *v = &interpolatedVertBuf[j * 3 + k];
|
||||
v->v = gBubbleTempVtx[k];
|
||||
if (gGlobalTimer != gEnvFxBuffer[i + j].spawnTimestamp && mode != ENVFX_LAVA_BUBBLES) {
|
||||
v->v.ob[0] = (sPrevBubblePositions[i + j][0] + gEnvFxBuffer[i + j].xPos) / 2.0f + interpolatedVertices[k][0];
|
||||
v->v.ob[1] = (sPrevBubblePositions[i + j][1] + gEnvFxBuffer[i + j].yPos) / 2.0f + interpolatedVertices[k][1];
|
||||
v->v.ob[2] = (sPrevBubblePositions[i + j][2] + gEnvFxBuffer[i + j].zPos) / 2.0f + interpolatedVertices[k][2];
|
||||
} else {
|
||||
v->v.ob[0] = gEnvFxBuffer[i + j].xPos + interpolatedVertices[k][0];
|
||||
v->v.ob[1] = gEnvFxBuffer[i + j].yPos + interpolatedVertices[k][1];
|
||||
v->v.ob[2] = gEnvFxBuffer[i + j].zPos + interpolatedVertices[k][2];
|
||||
}
|
||||
}
|
||||
}
|
||||
gSPVertex(sGfxCursor++, VIRTUAL_TO_PHYSICAL(interpolatedVertBuf), 15, 0);
|
||||
append_bubble_vertex_buffer(&sGfxSaved[i / 5], i, vertex1, vertex2, vertex3, (Vtx *) gBubbleTempVtx);
|
||||
gSP1Triangle(sGfxCursor++, 0, 1, 2, 0);
|
||||
gSP1Triangle(sGfxCursor++, 3, 4, 5, 0);
|
||||
gSP1Triangle(sGfxCursor++, 6, 7, 8, 0);
|
||||
gSP1Triangle(sGfxCursor++, 9, 10, 11, 0);
|
||||
gSP1Triangle(sGfxCursor++, 12, 13, 14, 0);
|
||||
}
|
||||
for (i = 0; i < sBubbleParticleMaxCount; i++) {
|
||||
sPrevBubblePositions[i][0] = gEnvFxBuffer[i].xPos;
|
||||
sPrevBubblePositions[i][1] = gEnvFxBuffer[i].yPos;
|
||||
sPrevBubblePositions[i][2] = gEnvFxBuffer[i].zPos;
|
||||
}
|
||||
|
||||
gSPDisplayList(sGfxCursor++, &tiny_bubble_dl_0B006AB0);
|
||||
gSPEndDisplayList(sGfxCursor++);
|
||||
|
|
|
@ -54,6 +54,26 @@ extern void *tiny_bubble_dl_0B006AB0;
|
|||
extern void *tiny_bubble_dl_0B006A50;
|
||||
extern void *tiny_bubble_dl_0B006CD8;
|
||||
|
||||
static struct {
|
||||
Gfx *pos;
|
||||
Vtx vertices[15];
|
||||
} sPrevSnowVertices[140 / 5];
|
||||
static s16 sPrevSnowParticleCount;
|
||||
static u32 sPrevSnowTimestamp;
|
||||
|
||||
void patch_interpolated_snow_particles(void) {
|
||||
int i;
|
||||
|
||||
if (gGlobalTimer != sPrevSnowTimestamp + 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < sPrevSnowParticleCount; i += 5) {
|
||||
gSPVertex(sPrevSnowVertices[i / 5].pos,
|
||||
VIRTUAL_TO_PHYSICAL(sPrevSnowVertices[i / 5].vertices), 15, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize snow particles by allocating a buffer for storing their state
|
||||
* and setting a start amount.
|
||||
|
@ -217,6 +237,7 @@ void envfx_update_snow_normal(s32 snowCylinderX, s32 snowCylinderY, s32 snowCyli
|
|||
400.0f * random_float() - 200.0f + snowCylinderZ + (s16)(deltaZ * 2);
|
||||
(gEnvFxBuffer + i)->yPos = 200.0f * random_float() + snowCylinderY;
|
||||
(gEnvFxBuffer + i)->isAlive = 1;
|
||||
(gEnvFxBuffer + i)->spawnTimestamp = gGlobalTimer;
|
||||
} else {
|
||||
(gEnvFxBuffer + i)->xPos += random_float() * 2 - 1.0f + (s16)(deltaX / 1.2);
|
||||
(gEnvFxBuffer + i)->yPos -= 2 -(s16)(deltaY * 0.8);
|
||||
|
@ -251,6 +272,7 @@ void envfx_update_snow_blizzard(s32 snowCylinderX, s32 snowCylinderY, s32 snowCy
|
|||
400.0f * random_float() - 200.0f + snowCylinderZ + (s16)(deltaZ * 2);
|
||||
(gEnvFxBuffer + i)->yPos = 400.0f * random_float() - 200.0f + snowCylinderY;
|
||||
(gEnvFxBuffer + i)->isAlive = 1;
|
||||
(gEnvFxBuffer + i)->spawnTimestamp = gGlobalTimer;
|
||||
} else {
|
||||
(gEnvFxBuffer + i)->xPos += random_float() * 2 - 1.0f + (s16)(deltaX / 1.2) + 20.0f;
|
||||
(gEnvFxBuffer + i)->yPos -= 5 -(s16)(deltaY * 0.8);
|
||||
|
@ -294,6 +316,7 @@ void envfx_update_snow_water(s32 snowCylinderX, s32 snowCylinderY, s32 snowCylin
|
|||
(gEnvFxBuffer + i)->zPos = 400.0f * random_float() - 200.0f + snowCylinderZ;
|
||||
(gEnvFxBuffer + i)->yPos = 400.0f * random_float() - 200.0f + snowCylinderY;
|
||||
(gEnvFxBuffer + i)->isAlive = 1;
|
||||
(gEnvFxBuffer + i)->spawnTimestamp = gGlobalTimer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -346,6 +369,8 @@ void rotate_triangle_vertices(Vec3s vertex1, Vec3s vertex2, Vec3s vertex3, s16 p
|
|||
void append_snowflake_vertex_buffer(Gfx *gfx, s32 index, Vec3s vertex1, Vec3s vertex2, Vec3s vertex3) {
|
||||
s32 i = 0;
|
||||
Vtx *vertBuf = (Vtx *) alloc_display_list(15 * sizeof(Vtx));
|
||||
Vtx *vertBufInterpolated = (Vtx *) alloc_display_list(15 * sizeof(Vtx));
|
||||
Vtx *v;
|
||||
#ifdef VERSION_EU
|
||||
Vtx *p;
|
||||
#endif
|
||||
|
@ -395,7 +420,23 @@ void append_snowflake_vertex_buffer(Gfx *gfx, s32 index, Vec3s vertex1, Vec3s ve
|
|||
#endif
|
||||
}
|
||||
|
||||
gSPVertex(gfx, VIRTUAL_TO_PHYSICAL(vertBuf), 15, 0);
|
||||
for (i = 0; i < 15; i++) {
|
||||
v = &sPrevSnowVertices[index / 5].vertices[i];
|
||||
vertBufInterpolated[i] = gSnowTempVtx[i % 3];
|
||||
if (index < sPrevSnowParticleCount && gGlobalTimer == sPrevSnowTimestamp + 1 &&
|
||||
gGlobalTimer != gEnvFxBuffer[index + i / 3].spawnTimestamp) {
|
||||
vertBufInterpolated[i].v.ob[0] = (v->v.ob[0] + vertBuf[i].v.ob[0]) / 2;
|
||||
vertBufInterpolated[i].v.ob[1] = (v->v.ob[1] + vertBuf[i].v.ob[1]) / 2;
|
||||
vertBufInterpolated[i].v.ob[2] = (v->v.ob[2] + vertBuf[i].v.ob[2]) / 2;
|
||||
} else {
|
||||
vertBufInterpolated[i].v.ob[0] = vertBuf[i].v.ob[0];
|
||||
vertBufInterpolated[i].v.ob[1] = vertBuf[i].v.ob[1];
|
||||
vertBufInterpolated[i].v.ob[2] = vertBuf[i].v.ob[2];
|
||||
}
|
||||
*v = vertBuf[i];
|
||||
}
|
||||
sPrevSnowVertices[index / 5].pos = gfx;
|
||||
gSPVertex(gfx, VIRTUAL_TO_PHYSICAL(vertBufInterpolated), 15, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -479,6 +520,8 @@ Gfx *envfx_update_snow(s32 snowMode, Vec3s marioPos, Vec3s camFrom, Vec3s camTo)
|
|||
gSP1Triangle(gfx++, 9, 10, 11, 0);
|
||||
gSP1Triangle(gfx++, 12, 13, 14, 0);
|
||||
}
|
||||
sPrevSnowParticleCount = gSnowParticleCount;
|
||||
sPrevSnowTimestamp = gGlobalTimer;
|
||||
|
||||
gSPDisplayList(gfx++, &tiny_bubble_dl_0B006AB0) gSPEndDisplayList(gfx++);
|
||||
|
||||
|
|
|
@ -25,7 +25,8 @@ struct EnvFxParticle {
|
|||
s32 angleAndDist[2]; // for whirpools, [0] = angle from center, [1] = distance from center
|
||||
s32 unusedBubbleVar; // set to zero for bubbles when respawning, never used elsewhere
|
||||
s32 bubbleY; // for Bubbles, yPos is always set to this
|
||||
s8 filler20[56 - 0x20];
|
||||
//s8 filler20[56 - 0x20];
|
||||
u32 spawnTimestamp;
|
||||
};
|
||||
|
||||
extern s8 gEnvFxMode;
|
||||
|
|
|
@ -82,6 +82,20 @@ void render_hud_texture(s32 x, s32 y, u32 w, u32 h, u8 *texture) {
|
|||
gSPDisplayList(gDisplayListHead++, dl_hud_img_end);
|
||||
}
|
||||
|
||||
static u32 sPowerMeterLastRenderTimestamp;
|
||||
static s16 sPowerMeterLastY;
|
||||
static Gfx *sPowerMeterDisplayListPos;
|
||||
|
||||
void patch_interpolated_hud(void) {
|
||||
if (sPowerMeterDisplayListPos != NULL) {
|
||||
Mtx *mtx = alloc_display_list(sizeof(Mtx));
|
||||
guTranslate(mtx, (f32) sPowerMeterHUD.x, (f32) sPowerMeterHUD.y, 0);
|
||||
gSPMatrix(sPowerMeterDisplayListPos, VIRTUAL_TO_PHYSICAL(mtx),
|
||||
G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_PUSH);
|
||||
sPowerMeterDisplayListPos = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a rgba16 16x16 glyph texture from a table list.
|
||||
*/
|
||||
|
@ -134,6 +148,7 @@ void render_power_meter_health_segment(s16 numHealthWedges) {
|
|||
*/
|
||||
void render_dl_power_meter(s16 numHealthWedges) {
|
||||
Mtx *mtx;
|
||||
f32 interpolatedY;
|
||||
|
||||
mtx = alloc_display_list(sizeof(Mtx));
|
||||
|
||||
|
@ -141,7 +156,15 @@ void render_dl_power_meter(s16 numHealthWedges) {
|
|||
return;
|
||||
}
|
||||
|
||||
guTranslate(mtx, (f32) sPowerMeterHUD.x, (f32) sPowerMeterHUD.y, 0);
|
||||
if (gGlobalTimer == sPowerMeterLastRenderTimestamp + 1) {
|
||||
interpolatedY = (sPowerMeterLastY + sPowerMeterHUD.y) / 2.0f;
|
||||
} else {
|
||||
interpolatedY = sPowerMeterHUD.y;
|
||||
}
|
||||
guTranslate(mtx, (f32) sPowerMeterHUD.x, interpolatedY, 0);
|
||||
sPowerMeterLastY = sPowerMeterHUD.y;
|
||||
sPowerMeterLastRenderTimestamp = gGlobalTimer;
|
||||
sPowerMeterDisplayListPos = gDisplayListHead;
|
||||
|
||||
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(mtx++),
|
||||
G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_PUSH);
|
||||
|
|
|
@ -78,6 +78,47 @@ s8 gLastDialogResponse = 0;
|
|||
u8 gMenuHoldKeyIndex = 0;
|
||||
u8 gMenuHoldKeyTimer = 0;
|
||||
s32 gDialogResponse = 0;
|
||||
static Gfx *sInterpolatedDialogOffsetPos;
|
||||
static f32 sInterpolatedDialogOffset;
|
||||
static Gfx *sInterpolatedDialogRotationPos;
|
||||
static f32 sInterpolatedDialogScale;
|
||||
static f32 sInterpolatedDialogRotation;
|
||||
static Gfx *sInterpolatedDialogZoomPos;
|
||||
|
||||
void patch_interpolated_dialog(void) {
|
||||
Mtx *matrix;
|
||||
|
||||
if (sInterpolatedDialogOffsetPos != NULL) {
|
||||
matrix = (Mtx *) alloc_display_list(sizeof(Mtx));
|
||||
guTranslate(matrix, 0, sInterpolatedDialogOffset, 0);
|
||||
gSPMatrix(sInterpolatedDialogOffsetPos, VIRTUAL_TO_PHYSICAL(matrix),
|
||||
G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH);
|
||||
sInterpolatedDialogOffsetPos = NULL;
|
||||
}
|
||||
if (sInterpolatedDialogRotationPos != NULL) {
|
||||
matrix = (Mtx *) alloc_display_list(sizeof(Mtx));
|
||||
guScale(matrix, 1.0 / sInterpolatedDialogScale, 1.0 / sInterpolatedDialogScale, 1.0f);
|
||||
gSPMatrix(sInterpolatedDialogRotationPos++, VIRTUAL_TO_PHYSICAL(matrix),
|
||||
G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH);
|
||||
matrix = (Mtx *) alloc_display_list(sizeof(Mtx));
|
||||
guRotate(matrix, sInterpolatedDialogRotation * 4.0f, 0, 0, 1.0f);
|
||||
gSPMatrix(sInterpolatedDialogRotationPos, VIRTUAL_TO_PHYSICAL(matrix),
|
||||
G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH);
|
||||
sInterpolatedDialogRotationPos = NULL;
|
||||
}
|
||||
if (sInterpolatedDialogZoomPos != NULL) {
|
||||
matrix = (Mtx *) alloc_display_list(sizeof(Mtx));
|
||||
guTranslate(matrix, 65.0 - (65.0 / sInterpolatedDialogScale),
|
||||
(40.0 / sInterpolatedDialogScale) - 40, 0);
|
||||
gSPMatrix(sInterpolatedDialogZoomPos++, VIRTUAL_TO_PHYSICAL(matrix),
|
||||
G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH);
|
||||
matrix = (Mtx *) alloc_display_list(sizeof(Mtx));
|
||||
guScale(matrix, 1.0 / sInterpolatedDialogScale, 1.0 / sInterpolatedDialogScale, 1.0f);
|
||||
gSPMatrix(sInterpolatedDialogZoomPos, VIRTUAL_TO_PHYSICAL(matrix),
|
||||
G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH);
|
||||
sInterpolatedDialogZoomPos = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void create_dl_identity_matrix(void) {
|
||||
Mtx *matrix = (Mtx *) alloc_display_list(sizeof(Mtx));
|
||||
|
@ -541,6 +582,14 @@ void render_dialog_box_type(struct DialogEntry *dialog, s8 linesPerBox) {
|
|||
switch (gDialogBoxType) {
|
||||
case DIALOG_TYPE_ROTATE: // Renders a dialog black box with zoom and rotation
|
||||
if (gDialogBoxState == DIALOG_STATE_OPENING || gDialogBoxState == DIALOG_STATE_CLOSING) {
|
||||
sInterpolatedDialogRotationPos = gDisplayListHead;
|
||||
if (gDialogBoxState == DIALOG_STATE_OPENING) {
|
||||
sInterpolatedDialogScale = gDialogBoxScale - 2 / 2;
|
||||
sInterpolatedDialogRotation = gDialogBoxOpenTimer - 7.5f / 2;
|
||||
} else {
|
||||
sInterpolatedDialogScale = gDialogBoxScale + 2 / 2;
|
||||
sInterpolatedDialogRotation = gDialogBoxOpenTimer + 7.5f / 2;
|
||||
}
|
||||
create_dl_scale_matrix(MENU_MTX_NOPUSH, 1.0 / gDialogBoxScale, 1.0 / gDialogBoxScale, 1.0f);
|
||||
// convert the speed into angle
|
||||
create_dl_rotation_matrix(MENU_MTX_NOPUSH, gDialogBoxOpenTimer * 4.0f, 0, 0, 1.0f);
|
||||
|
@ -549,6 +598,12 @@ void render_dialog_box_type(struct DialogEntry *dialog, s8 linesPerBox) {
|
|||
break;
|
||||
case DIALOG_TYPE_ZOOM: // Renders a dialog white box with zoom
|
||||
if (gDialogBoxState == DIALOG_STATE_OPENING || gDialogBoxState == DIALOG_STATE_CLOSING) {
|
||||
sInterpolatedDialogZoomPos = gDisplayListHead;
|
||||
if (gDialogBoxState == DIALOG_STATE_OPENING) {
|
||||
sInterpolatedDialogScale = gDialogBoxScale - 2 / 2;
|
||||
} else {
|
||||
sInterpolatedDialogScale = gDialogBoxScale + 2 / 2;
|
||||
}
|
||||
create_dl_translation_matrix(MENU_MTX_NOPUSH, 65.0 - (65.0 / gDialogBoxScale),
|
||||
(40.0 / gDialogBoxScale) - 40, 0);
|
||||
create_dl_scale_matrix(MENU_MTX_NOPUSH, 1.0 / gDialogBoxScale, 1.0 / gDialogBoxScale, 1.0f);
|
||||
|
@ -659,7 +714,8 @@ u32 ensure_nonnegative(s16 value) {
|
|||
return value;
|
||||
}
|
||||
|
||||
void handle_dialog_text_and_pages(s8 colorMode, struct DialogEntry *dialog, s8 lowerBound) {
|
||||
void handle_dialog_text_and_pages(s8 colorMode, struct DialogEntry *dialog, s8 lowerBound)
|
||||
{
|
||||
UNUSED s32 pad[2];
|
||||
|
||||
u8 strChar;
|
||||
|
@ -689,9 +745,11 @@ void handle_dialog_text_and_pages(s8 colorMode, struct DialogEntry *dialog, s8 l
|
|||
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
|
||||
strIdx = gDialogTextPos;
|
||||
|
||||
if (gDialogBoxState == DIALOG_STATE_HORIZONTAL)
|
||||
if (gDialogBoxState == DIALOG_STATE_HORIZONTAL) {
|
||||
sInterpolatedDialogOffset = gDialogScrollOffsetY + dialog->linesPerBox;
|
||||
sInterpolatedDialogOffsetPos = gDisplayListHead;
|
||||
create_dl_translation_matrix(MENU_MTX_NOPUSH, 0, (f32) gDialogScrollOffsetY, 0);
|
||||
|
||||
}
|
||||
create_dl_translation_matrix(MENU_MTX_PUSH, X_VAL3, 2 - lineNum * Y_VAL3, 0);
|
||||
|
||||
while (pageState == DIALOG_PAGE_STATE_NONE) {
|
||||
|
@ -716,7 +774,6 @@ void handle_dialog_text_and_pages(s8 colorMode, struct DialogEntry *dialog, s8 l
|
|||
case DIALOG_CHAR_SPACE:
|
||||
xMatrix++;
|
||||
linePos++;
|
||||
|
||||
break;
|
||||
case DIALOG_CHAR_SLASH:
|
||||
xMatrix += 2;
|
||||
|
@ -748,7 +805,6 @@ void handle_dialog_text_and_pages(s8 colorMode, struct DialogEntry *dialog, s8 l
|
|||
}
|
||||
strIdx++;
|
||||
}
|
||||
|
||||
gSPDisplayList(gDisplayListHead++, dl_ia_text_end);
|
||||
|
||||
if (gDialogBoxState == DIALOG_STATE_VERTICAL) {
|
||||
|
|
|
@ -34,12 +34,16 @@ Gfx *geo_envfx_main(s32 callContext, struct GraphNode *node, Mat4 mtxf) {
|
|||
vec3f_to_vec3s(marioPos, gPlayerCameraState->pos);
|
||||
particleList = envfx_update_particles(snowMode, marioPos, camTo, camFrom);
|
||||
if (particleList != NULL) {
|
||||
#if 0
|
||||
Mtx *mtx = alloc_display_list(sizeof(*mtx));
|
||||
|
||||
gfx = alloc_display_list(2 * sizeof(*gfx));
|
||||
mtxf_to_mtx(mtx, mtxf);
|
||||
gSPMatrix(&gfx[0], VIRTUAL_TO_PHYSICAL(mtx), G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH);
|
||||
gSPBranchList(&gfx[1], VIRTUAL_TO_PHYSICAL(particleList));
|
||||
#else
|
||||
gfx = particleList;
|
||||
#endif
|
||||
execNode->fnNode.node.flags = (execNode->fnNode.node.flags & 0xFF) | 0x400;
|
||||
}
|
||||
SET_HIGH_U16_OF_32(*params, gAreaUpdateCounter);
|
||||
|
|
|
@ -1560,15 +1560,19 @@ void update_mario_info_for_cam(struct MarioState *m) {
|
|||
}
|
||||
}
|
||||
|
||||
int current_cap_state = MARIO_HAS_DEFAULT_CAP_ON;
|
||||
int current_eye_state = MARIO_EYES_BLINK;
|
||||
int current_hand_state = MARIO_HAND_FISTS;
|
||||
|
||||
/**
|
||||
* Resets Mario's model, done every time an action is executed.
|
||||
*/
|
||||
void mario_reset_bodystate(struct MarioState *m) {
|
||||
struct MarioBodyState *bodyState = m->marioBodyState;
|
||||
|
||||
bodyState->capState = MARIO_HAS_DEFAULT_CAP_OFF;
|
||||
bodyState->eyeState = MARIO_EYES_BLINK;
|
||||
bodyState->handState = MARIO_HAND_FISTS;
|
||||
bodyState->capState = current_cap_state;
|
||||
bodyState->eyeState = current_eye_state;
|
||||
bodyState->handState = current_hand_state;
|
||||
bodyState->modelState = 0;
|
||||
bodyState->wingFlutter = FALSE;
|
||||
|
||||
|
@ -1669,6 +1673,8 @@ void mario_update_hitbox_and_cap_model(struct MarioState *m) {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
if (flags & MARIO_CAP_IN_HAND) {
|
||||
if (flags & MARIO_WING_CAP) {
|
||||
bodyState->handState = MARIO_HAND_HOLDING_WING_CAP;
|
||||
|
@ -1685,6 +1691,8 @@ void mario_update_hitbox_and_cap_model(struct MarioState *m) {
|
|||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
// Short hitbox for crouching/crawling/etc.
|
||||
if (m->action & ACT_FLAG_SHORT_HITBOX) {
|
||||
m->marioObj->hitboxHeight = 100.0f;
|
||||
|
|
|
@ -51,4 +51,8 @@ s32 execute_mario_action(UNUSED struct Object *o);
|
|||
void init_mario(void);
|
||||
void init_mario_from_save_file(void);
|
||||
|
||||
extern int current_cap_state;
|
||||
extern int current_eye_state;
|
||||
extern int current_hand_state;
|
||||
|
||||
#endif // MARIO_H
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#ifdef BETTERCAMERA
|
||||
#include "bettercamera.h"
|
||||
#endif
|
||||
#include "moon/saturn/saturn_types.h"
|
||||
|
||||
void play_flip_sounds(struct MarioState *m, s16 frame1, s16 frame2, s16 frame3) {
|
||||
s32 animFrame = m->marioObj->header.gfx.unk38.animFrame;
|
||||
|
@ -1707,7 +1708,8 @@ s32 act_shot_from_cannon(struct MarioState *m) {
|
|||
}
|
||||
|
||||
if (m->vel[1] > 0.0f) {
|
||||
m->particleFlags |= PARTICLE_DUST;
|
||||
if (enable_dust_particles)
|
||||
m->particleFlags |= PARTICLE_DUST;
|
||||
}
|
||||
|
||||
reset_rumble_timers();
|
||||
|
@ -1867,7 +1869,8 @@ s32 act_flying(struct MarioState *m) {
|
|||
}
|
||||
|
||||
if (m->faceAngle[0] > 0x800 && m->forwardVel >= 48.0f) {
|
||||
m->particleFlags |= PARTICLE_DUST;
|
||||
if (enable_dust_particles)
|
||||
m->particleFlags |= PARTICLE_DUST;
|
||||
}
|
||||
|
||||
if (startPitch <= 0 && m->faceAngle[0] > 0 && m->forwardVel >= 48.0f) {
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "../../include/libc/stdlib.h"
|
||||
#include "pc/pc_main.h"
|
||||
#include "moon/achievements/achievements.h"
|
||||
#include "moon/saturn/saturn_types.h"
|
||||
|
||||
// TODO: put this elsewhere
|
||||
enum SaveOption { SAVE_OPT_SAVE_AND_CONTINUE = 1, SAVE_OPT_SAVE_AND_QUIT, SAVE_OPT_SAVE_EXIT_GAME, SAVE_OPT_CONTINUE_DONT_SAVE };
|
||||
|
@ -2152,7 +2153,8 @@ static void end_peach_cutscene_run_to_peach(struct MarioState *m) {
|
|||
play_step_sound(m, 9, 45);
|
||||
|
||||
vec3f_copy(m->marioObj->header.gfx.pos, m->pos);
|
||||
m->particleFlags |= PARTICLE_DUST;
|
||||
if (enable_dust_particles)
|
||||
m->particleFlags |= PARTICLE_DUST;
|
||||
}
|
||||
|
||||
// dialog 1
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "pc/configfile.h"
|
||||
#include "pc/cheats.h"
|
||||
#include "moon/achievements/achievements.h"
|
||||
#include "moon/saturn/saturn_types.h"
|
||||
|
||||
struct LandingAction {
|
||||
s16 numFrames;
|
||||
|
@ -709,7 +710,8 @@ void push_or_sidle_wall(struct MarioState *m, Vec3f startPos) {
|
|||
|
||||
if (m->marioObj->header.gfx.unk38.animFrame < 20) {
|
||||
play_sound(SOUND_MOVING_TERRAIN_SLIDE + m->terrainSoundAddend, m->marioObj->header.gfx.cameraToObject);
|
||||
m->particleFlags |= PARTICLE_DUST;
|
||||
if (enable_dust_particles)
|
||||
m->particleFlags |= PARTICLE_DUST;
|
||||
}
|
||||
|
||||
m->actionState = 1;
|
||||
|
@ -837,7 +839,8 @@ s32 act_walking(struct MarioState *m) {
|
|||
case GROUND_STEP_NONE:
|
||||
anim_and_audio_for_walk(m);
|
||||
if (m->intendedMag - m->forwardVel > 16.0f) {
|
||||
m->particleFlags |= PARTICLE_DUST;
|
||||
if (enable_dust_particles)
|
||||
m->particleFlags |= PARTICLE_DUST;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -880,7 +883,8 @@ s32 act_move_punching(struct MarioState *m) {
|
|||
break;
|
||||
|
||||
case GROUND_STEP_NONE:
|
||||
m->particleFlags |= PARTICLE_DUST;
|
||||
if (enable_dust_particles)
|
||||
m->particleFlags |= PARTICLE_DUST;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -935,7 +939,8 @@ s32 act_hold_walking(struct MarioState *m) {
|
|||
anim_and_audio_for_hold_walk(m);
|
||||
|
||||
if (0.4f * m->intendedMag - m->forwardVel > 10.0f) {
|
||||
m->particleFlags |= PARTICLE_DUST;
|
||||
if (enable_dust_particles)
|
||||
m->particleFlags |= PARTICLE_DUST;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
@ -1005,7 +1010,8 @@ s32 act_turning_around(struct MarioState *m) {
|
|||
break;
|
||||
|
||||
case GROUND_STEP_NONE:
|
||||
m->particleFlags |= PARTICLE_DUST;
|
||||
if (enable_dust_particles)
|
||||
m->particleFlags |= PARTICLE_DUST;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1070,7 +1076,8 @@ s32 act_braking(struct MarioState *m) {
|
|||
break;
|
||||
|
||||
case GROUND_STEP_NONE:
|
||||
m->particleFlags |= PARTICLE_DUST;
|
||||
if (enable_dust_particles)
|
||||
m->particleFlags |= PARTICLE_DUST;
|
||||
break;
|
||||
|
||||
case GROUND_STEP_HIT_WALL:
|
||||
|
@ -1132,7 +1139,8 @@ s32 act_decelerating(struct MarioState *m) {
|
|||
set_mario_animation(m, MARIO_ANIM_IDLE_HEAD_LEFT);
|
||||
play_sound(SOUND_MOVING_TERRAIN_SLIDE + m->terrainSoundAddend, m->marioObj->header.gfx.cameraToObject);
|
||||
adjust_sound_for_speed(m);
|
||||
m->particleFlags |= PARTICLE_DUST;
|
||||
if (enable_dust_particles)
|
||||
m->particleFlags |= PARTICLE_DUST;
|
||||
} else {
|
||||
// (Speed Crash) Crashes if speed exceeds 2^17.
|
||||
if ((val0C = (s32)(m->forwardVel / 4.0f * 0x10000)) < 0x1000) {
|
||||
|
@ -1198,7 +1206,8 @@ s32 act_hold_decelerating(struct MarioState *m) {
|
|||
set_mario_animation(m, MARIO_ANIM_IDLE_WITH_LIGHT_OBJ);
|
||||
play_sound(SOUND_MOVING_TERRAIN_SLIDE + m->terrainSoundAddend, m->marioObj->header.gfx.cameraToObject);
|
||||
adjust_sound_for_speed(m);
|
||||
m->particleFlags |= PARTICLE_DUST;
|
||||
if (enable_dust_particles)
|
||||
m->particleFlags |= PARTICLE_DUST;
|
||||
} else {
|
||||
//! (Speed Crash) This crashes if Mario has more speed than 2^15 speed.
|
||||
if ((val0C = (s32)(m->forwardVel * 0x10000)) < 0x1000) {
|
||||
|
@ -1391,7 +1400,8 @@ void common_slide_action(struct MarioState *m, u32 endAction, u32 airAction, s32
|
|||
case GROUND_STEP_NONE:
|
||||
set_mario_animation(m, animation);
|
||||
align_with_floor(m);
|
||||
m->particleFlags |= PARTICLE_DUST;
|
||||
if (enable_dust_particles)
|
||||
m->particleFlags |= PARTICLE_DUST;
|
||||
break;
|
||||
|
||||
case GROUND_STEP_HIT_WALL:
|
||||
|
@ -1523,7 +1533,8 @@ s32 act_slide_kick_slide(struct MarioState *m) {
|
|||
}
|
||||
|
||||
play_sound(SOUND_MOVING_TERRAIN_SLIDE + m->terrainSoundAddend, m->marioObj->header.gfx.cameraToObject);
|
||||
m->particleFlags |= PARTICLE_DUST;
|
||||
if (enable_dust_particles)
|
||||
m->particleFlags |= PARTICLE_DUST;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -1746,7 +1757,8 @@ u32 common_landing_action(struct MarioState *m, s16 animation, u32 airAction) {
|
|||
}
|
||||
|
||||
if (m->forwardVel > 16.0f) {
|
||||
m->particleFlags |= PARTICLE_DUST;
|
||||
if (enable_dust_particles)
|
||||
m->particleFlags |= PARTICLE_DUST;
|
||||
}
|
||||
|
||||
set_mario_animation(m, animation);
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "sound_init.h"
|
||||
#include "surface_terrains.h"
|
||||
#include "thread6.h"
|
||||
#include "moon/saturn/saturn_types.h"
|
||||
|
||||
s32 check_common_idle_cancels(struct MarioState *m) {
|
||||
mario_drop_held_object(m);
|
||||
|
@ -133,15 +134,27 @@ s32 act_idle(struct MarioState *m) {
|
|||
} else {
|
||||
switch (m->actionState) {
|
||||
case 0:
|
||||
set_mario_animation(m, MARIO_ANIM_IDLE_HEAD_LEFT);
|
||||
if (enable_head_rotations) {
|
||||
set_mario_animation(m, MARIO_ANIM_IDLE_HEAD_LEFT);
|
||||
} else {
|
||||
set_mario_animation(m, MARIO_ANIM_FIRST_PERSON);
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
set_mario_animation(m, MARIO_ANIM_IDLE_HEAD_RIGHT);
|
||||
if (enable_head_rotations) {
|
||||
set_mario_animation(m, MARIO_ANIM_IDLE_HEAD_RIGHT);
|
||||
} else {
|
||||
set_mario_animation(m, MARIO_ANIM_FIRST_PERSON);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
set_mario_animation(m, MARIO_ANIM_IDLE_HEAD_CENTER);
|
||||
if (enable_head_rotations) {
|
||||
set_mario_animation(m, MARIO_ANIM_IDLE_HEAD_CENTER);
|
||||
} else {
|
||||
set_mario_animation(m, MARIO_ANIM_FIRST_PERSON);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "behavior_data.h"
|
||||
#include "level_table.h"
|
||||
#include "thread6.h"
|
||||
#include "moon/saturn/saturn_types.h"
|
||||
|
||||
#define MIN_SWIM_STRENGTH 160
|
||||
#define MIN_SWIM_SPEED 16.0f
|
||||
|
@ -1099,7 +1100,8 @@ static void play_metal_water_jumping_sound(struct MarioState *m, u32 landing) {
|
|||
static void play_metal_water_walking_sound(struct MarioState *m) {
|
||||
if (is_anim_past_frame(m, 10) || is_anim_past_frame(m, 49)) {
|
||||
play_sound(SOUND_ACTION_METAL_STEP_WATER, m->marioObj->header.gfx.cameraToObject);
|
||||
m->particleFlags |= PARTICLE_DUST;
|
||||
if (enable_dust_particles)
|
||||
m->particleFlags |= PARTICLE_DUST;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1550,6 +1550,7 @@ void cur_obj_set_pos_to_home(void) {
|
|||
o->oPosX = o->oHomeX;
|
||||
o->oPosY = o->oHomeY;
|
||||
o->oPosZ = o->oHomeZ;
|
||||
o->header.gfx.skipInterpolationTimestamp = gGlobalTimer;
|
||||
}
|
||||
|
||||
void cur_obj_set_pos_to_home_and_stop(void) {
|
||||
|
|
|
@ -189,6 +189,32 @@ struct Painting **sPaintingGroups[] = {
|
|||
s16 gPaintingUpdateCounter = 1;
|
||||
s16 gLastPaintingUpdateCounter = 0;
|
||||
|
||||
static Vtx sLastVertices[2 * 264 * 3];
|
||||
static u32 sLastVerticesTimestamp;
|
||||
static Vtx *sVerticesPtr[2];
|
||||
static s32 sVerticesCount;
|
||||
|
||||
void patch_interpolated_paintings(void) {
|
||||
if (sVerticesPtr[0] != NULL) {
|
||||
s32 i;
|
||||
if (sVerticesPtr[1] != NULL) {
|
||||
for (i = 0; i < sVerticesCount / 2; i++) {
|
||||
sVerticesPtr[0][i] = sLastVertices[i];
|
||||
}
|
||||
for (; i < sVerticesCount; i++) {
|
||||
sVerticesPtr[1][i - sVerticesCount / 2] = sLastVertices[i];
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < sVerticesCount; i++) {
|
||||
sVerticesPtr[0][i] = sLastVertices[i];
|
||||
}
|
||||
}
|
||||
sVerticesPtr[0] = NULL;
|
||||
sVerticesPtr[1] = NULL;
|
||||
sVerticesCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop paintings in paintingGroup from rippling if their id is different from *idptr.
|
||||
*/
|
||||
|
@ -890,6 +916,23 @@ Gfx *render_painting(u8 *img, s16 tWidth, s16 tHeight, s16 *textureMap, s16 mapV
|
|||
gSP1Triangle(gfx++, group * 3, group * 3 + 1, group * 3 + 2, 0);
|
||||
}
|
||||
|
||||
if (sVerticesCount >= numVtx * 2) {
|
||||
sVerticesCount = 0;
|
||||
}
|
||||
for (map = 0; map < numVtx; map++) {
|
||||
Vtx v = verts[map];
|
||||
if (gGlobalTimer == sLastVerticesTimestamp + 1) {
|
||||
s32 i;
|
||||
for (i = 0; i < 3; i++) {
|
||||
verts[map].n.ob[i] = (v.n.ob[i] + sLastVertices[sVerticesCount + map].n.ob[i]) / 2;
|
||||
verts[map].n.n[i] = (v.n.n[i] + sLastVertices[sVerticesCount + map].n.n[i]) / 2;
|
||||
}
|
||||
}
|
||||
sLastVertices[sVerticesCount + map] = v;
|
||||
}
|
||||
sVerticesPtr[sVerticesCount / numVtx] = verts;
|
||||
sVerticesCount += numVtx;
|
||||
|
||||
gSPEndDisplayList(gfx);
|
||||
return dlist;
|
||||
}
|
||||
|
@ -954,6 +997,7 @@ Gfx *painting_ripple_image(struct Painting *painting) {
|
|||
meshTris = textureMap[meshVerts * 3 + 1];
|
||||
gSPDisplayList(gfx++, render_painting(textures[i], tWidth, tHeight, textureMap, meshVerts, meshTris, painting->alpha));
|
||||
}
|
||||
sLastVerticesTimestamp = gGlobalTimer;
|
||||
|
||||
// Update the ripple, may automatically reset the painting's state.
|
||||
painting_update_ripple_state(painting);
|
||||
|
@ -991,6 +1035,7 @@ Gfx *painting_ripple_env_mapped(struct Painting *painting) {
|
|||
meshVerts = textureMap[0];
|
||||
meshTris = textureMap[meshVerts * 3 + 1];
|
||||
gSPDisplayList(gfx++, render_painting(tArray[0], tWidth, tHeight, textureMap, meshVerts, meshTris, painting->alpha));
|
||||
sLastVerticesTimestamp = gGlobalTimer;
|
||||
|
||||
// Update the ripple, may automatically reset the painting's state.
|
||||
painting_update_ripple_state(painting);
|
||||
|
|
|
@ -40,6 +40,8 @@
|
|||
s16 gMatStackIndex;
|
||||
Mat4 gMatStack[32];
|
||||
Mtx *gMatStackFixed[32];
|
||||
Mat4 gMatStackInterpolated[32];
|
||||
Mtx *gMatStackInterpolatedFixed[32];
|
||||
|
||||
/**
|
||||
* Animation nodes have state in global variables, so this struct captures
|
||||
|
@ -53,6 +55,7 @@ struct GeoAnimState {
|
|||
/*0x04*/ f32 translationMultiplier;
|
||||
/*0x08*/ u16 *attribute;
|
||||
/*0x0C*/ s16 *data;
|
||||
s16 prevFrame;
|
||||
};
|
||||
|
||||
// For some reason, this is a GeoAnimState struct, but the current state consists
|
||||
|
@ -62,6 +65,7 @@ struct GeoAnimState gGeoTempState;
|
|||
u8 gCurAnimType;
|
||||
u8 gCurAnimEnabled;
|
||||
s16 gCurrAnimFrame;
|
||||
s16 gPrevAnimFrame;
|
||||
f32 gCurAnimTranslationMultiplier;
|
||||
u16 *gCurrAnimAttribute;
|
||||
s16 *gCurAnimData;
|
||||
|
@ -130,6 +134,46 @@ u16 gAreaUpdateCounter = 0;
|
|||
LookAt lookAt;
|
||||
#endif
|
||||
|
||||
static Gfx *sPerspectivePos;
|
||||
static Mtx *sPerspectiveMtx;
|
||||
|
||||
struct {
|
||||
Gfx *pos;
|
||||
void *mtx;
|
||||
void *displayList;
|
||||
} gMtxTbl[6400];
|
||||
s32 gMtxTblSize;
|
||||
|
||||
static Gfx *sViewportPos;
|
||||
static Vp sPrevViewport;
|
||||
|
||||
void mtx_patch_interpolated(void) {
|
||||
s32 i;
|
||||
|
||||
if (sPerspectivePos != NULL) {
|
||||
gSPMatrix(sPerspectivePos, VIRTUAL_TO_PHYSICAL(sPerspectiveMtx), G_MTX_PROJECTION | G_MTX_LOAD | G_MTX_NOPUSH);
|
||||
}
|
||||
|
||||
for (i = 0; i < gMtxTblSize; i++) {
|
||||
Gfx *pos = gMtxTbl[i].pos;
|
||||
gSPMatrix(pos++, VIRTUAL_TO_PHYSICAL(gMtxTbl[i].mtx),
|
||||
G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH);
|
||||
gSPDisplayList(pos++, gMtxTbl[i].displayList);
|
||||
}
|
||||
|
||||
if (sViewportPos != NULL) {
|
||||
Gfx *saved = gDisplayListHead;
|
||||
gDisplayListHead = sViewportPos;
|
||||
make_viewport_clip_rect(&sPrevViewport);
|
||||
gSPViewport(gDisplayListHead, VIRTUAL_TO_PHYSICAL(&sPrevViewport));
|
||||
gDisplayListHead = saved;
|
||||
}
|
||||
|
||||
gMtxTblSize = 0;
|
||||
sPerspectivePos = NULL;
|
||||
sViewportPos = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a master list node.
|
||||
*/
|
||||
|
@ -157,9 +201,14 @@ static void geo_process_master_list_sub(struct GraphNodeMasterList *node) {
|
|||
if ((currList = node->listHeads[i]) != NULL) {
|
||||
gDPSetRenderMode(gDisplayListHead++, modeList->modes[i], mode2List->modes[i]);
|
||||
while (currList != NULL) {
|
||||
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(currList->transform),
|
||||
if ((u32) gMtxTblSize < sizeof(gMtxTbl) / sizeof(gMtxTbl[0])) {
|
||||
gMtxTbl[gMtxTblSize].pos = gDisplayListHead;
|
||||
gMtxTbl[gMtxTblSize].mtx = currList->transform;
|
||||
gMtxTbl[gMtxTblSize++].displayList = currList->displayList;
|
||||
}
|
||||
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(currList->transformInterpolated),
|
||||
G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH);
|
||||
gSPDisplayList(gDisplayListHead++, currList->displayList);
|
||||
gSPDisplayList(gDisplayListHead++, currList->displayListInterpolated);
|
||||
currList = currList->next;
|
||||
}
|
||||
}
|
||||
|
@ -175,7 +224,7 @@ static void geo_process_master_list_sub(struct GraphNodeMasterList *node) {
|
|||
* parameter. Look at the RenderModeContainer struct to see the corresponding
|
||||
* render modes of layers.
|
||||
*/
|
||||
static void geo_append_display_list(void *displayList, s16 layer) {
|
||||
static void geo_append_display_list2(void *displayList, void *displayListInterpolated, s16 layer) {
|
||||
|
||||
#ifdef F3DEX_GBI_2
|
||||
gSPLookAt(gDisplayListHead++, &lookAt);
|
||||
|
@ -185,7 +234,9 @@ static void geo_append_display_list(void *displayList, s16 layer) {
|
|||
alloc_only_pool_alloc(gDisplayListHeap, sizeof(struct DisplayListNode));
|
||||
|
||||
listNode->transform = gMatStackFixed[gMatStackIndex];
|
||||
listNode->transformInterpolated = gMatStackInterpolatedFixed[gMatStackIndex];
|
||||
listNode->displayList = displayList;
|
||||
listNode->displayListInterpolated = displayListInterpolated;
|
||||
listNode->next = 0;
|
||||
if (gCurGraphNodeMasterList->listHeads[layer] == 0) {
|
||||
gCurGraphNodeMasterList->listHeads[layer] = listNode;
|
||||
|
@ -196,6 +247,10 @@ static void geo_append_display_list(void *displayList, s16 layer) {
|
|||
}
|
||||
}
|
||||
|
||||
static void geo_append_display_list(void *displayList, s16 layer) {
|
||||
geo_append_display_list2(displayList, displayList, layer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the master list node.
|
||||
*/
|
||||
|
@ -242,7 +297,9 @@ static void geo_process_perspective(struct GraphNodePerspective *node) {
|
|||
}
|
||||
if (node->fnNode.node.children != NULL) {
|
||||
u16 perspNorm;
|
||||
Mtx *mtxInterpolated = alloc_display_list(sizeof(*mtxInterpolated));
|
||||
Mtx *mtx = alloc_display_list(sizeof(*mtx));
|
||||
f32 fovInterpolated;
|
||||
|
||||
#ifdef VERSION_EU
|
||||
f32 aspect = ((f32) gCurGraphNodeRoot->width / (f32) gCurGraphNodeRoot->height) * 1.1f;
|
||||
|
@ -251,9 +308,23 @@ static void geo_process_perspective(struct GraphNodePerspective *node) {
|
|||
#endif
|
||||
|
||||
guPerspective(mtx, &perspNorm, node->fov, aspect, node->near, node->far, 1.0f);
|
||||
gSPPerspNormalize(gDisplayListHead++, perspNorm);
|
||||
|
||||
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(mtx), G_MTX_PROJECTION | G_MTX_LOAD | G_MTX_NOPUSH);
|
||||
if (gGlobalTimer == node->prevTimestamp + 1 && gGlobalTimer != gLakituState.skipCameraInterpolationTimestamp) {
|
||||
|
||||
fovInterpolated = (node->prevFov + node->fov) / 2.0f;
|
||||
guPerspective(mtxInterpolated, &perspNorm, fovInterpolated, aspect, node->near, node->far, 1.0f);
|
||||
gSPPerspNormalize(gDisplayListHead++, perspNorm);
|
||||
|
||||
sPerspectivePos = gDisplayListHead;
|
||||
sPerspectiveMtx = mtx;
|
||||
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(mtxInterpolated),
|
||||
G_MTX_PROJECTION | G_MTX_LOAD | G_MTX_NOPUSH);
|
||||
} else {
|
||||
gSPPerspNormalize(gDisplayListHead++, perspNorm);
|
||||
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(mtx), G_MTX_PROJECTION | G_MTX_LOAD | G_MTX_NOPUSH);
|
||||
}
|
||||
node->prevFov = node->fov;
|
||||
node->prevTimestamp = gGlobalTimer;
|
||||
|
||||
gCurGraphNodeCamFrustum = node;
|
||||
geo_process_node_and_siblings(node->fnNode.node.children);
|
||||
|
@ -305,6 +376,39 @@ static void geo_process_switch(struct GraphNodeSwitchCase *node) {
|
|||
}
|
||||
}
|
||||
|
||||
void interpolate_vectors(Vec3f res, Vec3f a, Vec3f b) {
|
||||
res[0] = (a[0] + b[0]) / 2.0f;
|
||||
res[1] = (a[1] + b[1]) / 2.0f;
|
||||
res[2] = (a[2] + b[2]) / 2.0f;
|
||||
}
|
||||
|
||||
void interpolate_vectors_s16(Vec3s res, Vec3s a, Vec3s b) {
|
||||
res[0] = (a[0] + b[0]) / 2;
|
||||
res[1] = (a[1] + b[1]) / 2;
|
||||
res[2] = (a[2] + b[2]) / 2;
|
||||
}
|
||||
|
||||
static s16 interpolate_angle(s16 a, s16 b) {
|
||||
s32 absDiff = b - a;
|
||||
if (absDiff < 0) {
|
||||
absDiff = -absDiff;
|
||||
}
|
||||
if (absDiff >= 0x4000 && absDiff <= 0xC000) {
|
||||
return b;
|
||||
}
|
||||
if (absDiff <= 0x8000) {
|
||||
return (a + b) / 2;
|
||||
} else {
|
||||
return (a + b) / 2 + 0x8000;
|
||||
}
|
||||
}
|
||||
|
||||
static void interpolate_angles(Vec3s res, Vec3s a, Vec3s b) {
|
||||
res[0] = interpolate_angle(a[0], b[0]);
|
||||
res[1] = interpolate_angle(a[1], b[1]);
|
||||
res[2] = interpolate_angle(a[2], b[2]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a camera node.
|
||||
*/
|
||||
|
@ -312,6 +416,9 @@ static void geo_process_camera(struct GraphNodeCamera *node) {
|
|||
Mat4 cameraTransform;
|
||||
Mtx *rollMtx = alloc_display_list(sizeof(*rollMtx));
|
||||
Mtx *mtx = alloc_display_list(sizeof(*mtx));
|
||||
Mtx *mtxInterpolated = alloc_display_list(sizeof(*mtxInterpolated));
|
||||
Vec3f posInterpolated;
|
||||
Vec3f focusInterpolated;
|
||||
|
||||
if (node->fnNode.func != NULL) {
|
||||
node->fnNode.func(GEO_CONTEXT_RENDER, &node->fnNode.node, gMatStack[gMatStackIndex]);
|
||||
|
@ -322,12 +429,40 @@ static void geo_process_camera(struct GraphNodeCamera *node) {
|
|||
|
||||
mtxf_lookat(cameraTransform, node->pos, node->focus, node->roll);
|
||||
mtxf_mul(gMatStack[gMatStackIndex + 1], cameraTransform, gMatStack[gMatStackIndex]);
|
||||
|
||||
if (gGlobalTimer == node->prevTimestamp + 1 && gGlobalTimer != gLakituState.skipCameraInterpolationTimestamp) {
|
||||
interpolate_vectors(posInterpolated, node->prevPos, node->pos);
|
||||
interpolate_vectors(focusInterpolated, node->prevFocus, node->focus);
|
||||
float magnitude = 0;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
float diff = node->pos[i] - node->prevPos[i];
|
||||
magnitude += diff * diff;
|
||||
}
|
||||
if (magnitude > 500000) {
|
||||
// Observed ~479000 in BBH when toggling R camera
|
||||
// Can get over 3 million in VCUTM though...
|
||||
vec3f_copy(posInterpolated, node->pos);
|
||||
vec3f_copy(focusInterpolated, node->focus);
|
||||
}
|
||||
} else {
|
||||
vec3f_copy(posInterpolated, node->pos);
|
||||
vec3f_copy(focusInterpolated, node->focus);
|
||||
}
|
||||
vec3f_copy(node->prevPos, node->pos);
|
||||
vec3f_copy(node->prevFocus, node->focus);
|
||||
node->prevTimestamp = gGlobalTimer;
|
||||
mtxf_lookat(cameraTransform, posInterpolated, focusInterpolated, node->roll);
|
||||
mtxf_mul(gMatStackInterpolated[gMatStackIndex + 1], cameraTransform, gMatStackInterpolated[gMatStackIndex]);
|
||||
|
||||
gMatStackIndex++;
|
||||
mtxf_to_mtx(mtx, gMatStack[gMatStackIndex]);
|
||||
gMatStackFixed[gMatStackIndex] = mtx;
|
||||
mtxf_to_mtx(mtxInterpolated, gMatStackInterpolated[gMatStackIndex]);
|
||||
gMatStackInterpolatedFixed[gMatStackIndex] = mtxInterpolated;
|
||||
if (node->fnNode.node.children != 0) {
|
||||
gCurGraphNodeCamera = node;
|
||||
node->matrixPtr = &gMatStack[gMatStackIndex];
|
||||
node->matrixPtrInterpolated = &gMatStackInterpolated[gMatStackIndex];
|
||||
geo_process_node_and_siblings(node->fnNode.node.children);
|
||||
gCurGraphNodeCamera = NULL;
|
||||
}
|
||||
|
@ -344,13 +479,17 @@ static void geo_process_translation_rotation(struct GraphNodeTranslationRotation
|
|||
Mat4 mtxf;
|
||||
Vec3f translation;
|
||||
Mtx *mtx = alloc_display_list(sizeof(*mtx));
|
||||
Mtx *mtxInterpolated = alloc_display_list(sizeof(*mtxInterpolated));
|
||||
|
||||
vec3s_to_vec3f(translation, node->translation);
|
||||
mtxf_rotate_zxy_and_translate(mtxf, translation, node->rotation);
|
||||
mtxf_mul(gMatStack[gMatStackIndex + 1], mtxf, gMatStack[gMatStackIndex]);
|
||||
mtxf_mul(gMatStackInterpolated[gMatStackIndex + 1], mtxf, gMatStackInterpolated[gMatStackIndex]);
|
||||
gMatStackIndex++;
|
||||
mtxf_to_mtx(mtx, gMatStack[gMatStackIndex]);
|
||||
gMatStackFixed[gMatStackIndex] = mtx;
|
||||
mtxf_to_mtx(mtxInterpolated, gMatStackInterpolated[gMatStackIndex]);
|
||||
gMatStackInterpolatedFixed[gMatStackIndex] = mtxInterpolated;
|
||||
if (node->displayList != NULL) {
|
||||
geo_append_display_list(node->displayList, node->node.flags >> 8);
|
||||
}
|
||||
|
@ -369,13 +508,17 @@ static void geo_process_translation(struct GraphNodeTranslation *node) {
|
|||
Mat4 mtxf;
|
||||
Vec3f translation;
|
||||
Mtx *mtx = alloc_display_list(sizeof(*mtx));
|
||||
Mtx *mtxInterpolated = alloc_display_list(sizeof(*mtxInterpolated));
|
||||
|
||||
vec3s_to_vec3f(translation, node->translation);
|
||||
mtxf_rotate_zxy_and_translate(mtxf, translation, gVec3sZero);
|
||||
mtxf_mul(gMatStack[gMatStackIndex + 1], mtxf, gMatStack[gMatStackIndex]);
|
||||
mtxf_mul(gMatStackInterpolated[gMatStackIndex + 1], mtxf, gMatStackInterpolated[gMatStackIndex]);
|
||||
gMatStackIndex++;
|
||||
mtxf_to_mtx(mtx, gMatStack[gMatStackIndex]);
|
||||
gMatStackFixed[gMatStackIndex] = mtx;
|
||||
mtxf_to_mtx(mtxInterpolated, gMatStackInterpolated[gMatStackIndex]);
|
||||
gMatStackInterpolatedFixed[gMatStackIndex] = mtxInterpolated;
|
||||
if (node->displayList != NULL) {
|
||||
geo_append_display_list(node->displayList, node->node.flags >> 8);
|
||||
}
|
||||
|
@ -393,12 +536,23 @@ static void geo_process_translation(struct GraphNodeTranslation *node) {
|
|||
static void geo_process_rotation(struct GraphNodeRotation *node) {
|
||||
Mat4 mtxf;
|
||||
Mtx *mtx = alloc_display_list(sizeof(*mtx));
|
||||
Mtx *mtxInterpolated = alloc_display_list(sizeof(*mtxInterpolated));
|
||||
Vec3s rotationInterpolated;
|
||||
|
||||
mtxf_rotate_zxy_and_translate(mtxf, gVec3fZero, node->rotation);
|
||||
mtxf_mul(gMatStack[gMatStackIndex + 1], mtxf, gMatStack[gMatStackIndex]);
|
||||
if (gGlobalTimer == node->prevTimestamp + 1) {
|
||||
interpolate_angles(rotationInterpolated, node->prevRotation, node->rotation);
|
||||
mtxf_rotate_zxy_and_translate(mtxf, gVec3fZero, rotationInterpolated);
|
||||
}
|
||||
vec3s_copy(node->prevRotation, node->rotation);
|
||||
node->prevTimestamp = gGlobalTimer;
|
||||
mtxf_mul(gMatStackInterpolated[gMatStackIndex + 1], mtxf, gMatStackInterpolated[gMatStackIndex]);
|
||||
gMatStackIndex++;
|
||||
mtxf_to_mtx(mtx, gMatStack[gMatStackIndex]);
|
||||
gMatStackFixed[gMatStackIndex] = mtx;
|
||||
mtxf_to_mtx(mtxInterpolated, gMatStackInterpolated[gMatStackIndex]);
|
||||
gMatStackInterpolatedFixed[gMatStackIndex] = mtxInterpolated;
|
||||
if (node->displayList != NULL) {
|
||||
geo_append_display_list(node->displayList, node->node.flags >> 8);
|
||||
}
|
||||
|
@ -417,12 +571,16 @@ static void geo_process_scale(struct GraphNodeScale *node) {
|
|||
UNUSED Mat4 transform;
|
||||
Vec3f scaleVec;
|
||||
Mtx *mtx = alloc_display_list(sizeof(*mtx));
|
||||
Mtx *mtxInterpolated = alloc_display_list(sizeof(*mtxInterpolated));
|
||||
|
||||
vec3f_set(scaleVec, node->scale, node->scale, node->scale);
|
||||
mtxf_scale_vec3f(gMatStack[gMatStackIndex + 1], gMatStack[gMatStackIndex], scaleVec);
|
||||
mtxf_scale_vec3f(gMatStackInterpolated[gMatStackIndex + 1], gMatStackInterpolated[gMatStackIndex], scaleVec);
|
||||
gMatStackIndex++;
|
||||
mtxf_to_mtx(mtx, gMatStack[gMatStackIndex]);
|
||||
gMatStackFixed[gMatStackIndex] = mtx;
|
||||
mtxf_to_mtx(mtxInterpolated, gMatStackInterpolated[gMatStackIndex]);
|
||||
gMatStackInterpolatedFixed[gMatStackIndex] = mtxInterpolated;
|
||||
if (node->displayList != NULL) {
|
||||
geo_append_display_list(node->displayList, node->node.flags >> 8);
|
||||
}
|
||||
|
@ -441,21 +599,30 @@ static void geo_process_scale(struct GraphNodeScale *node) {
|
|||
static void geo_process_billboard(struct GraphNodeBillboard *node) {
|
||||
Vec3f translation;
|
||||
Mtx *mtx = alloc_display_list(sizeof(*mtx));
|
||||
Mtx *mtxInterpolated = alloc_display_list(sizeof(*mtxInterpolated));
|
||||
|
||||
gMatStackIndex++;
|
||||
vec3s_to_vec3f(translation, node->translation);
|
||||
mtxf_billboard(gMatStack[gMatStackIndex], gMatStack[gMatStackIndex - 1], translation,
|
||||
gCurGraphNodeCamera->roll);
|
||||
mtxf_billboard(gMatStackInterpolated[gMatStackIndex], gMatStackInterpolated[gMatStackIndex - 1], translation,
|
||||
gCurGraphNodeCamera->roll);
|
||||
if (gCurGraphNodeHeldObject != NULL) {
|
||||
mtxf_scale_vec3f(gMatStack[gMatStackIndex], gMatStack[gMatStackIndex],
|
||||
gCurGraphNodeHeldObject->objNode->header.gfx.scale);
|
||||
mtxf_scale_vec3f(gMatStackInterpolated[gMatStackIndex], gMatStackInterpolated[gMatStackIndex],
|
||||
gCurGraphNodeHeldObject->objNode->header.gfx.scale);
|
||||
} else if (gCurGraphNodeObject != NULL) {
|
||||
mtxf_scale_vec3f(gMatStack[gMatStackIndex], gMatStack[gMatStackIndex],
|
||||
gCurGraphNodeObject->scale);
|
||||
mtxf_scale_vec3f(gMatStackInterpolated[gMatStackIndex], gMatStackInterpolated[gMatStackIndex],
|
||||
gCurGraphNodeObject->scale);
|
||||
}
|
||||
|
||||
mtxf_to_mtx(mtx, gMatStack[gMatStackIndex]);
|
||||
gMatStackFixed[gMatStackIndex] = mtx;
|
||||
mtxf_to_mtx(mtxInterpolated, gMatStackInterpolated[gMatStackIndex]);
|
||||
gMatStackInterpolatedFixed[gMatStackIndex] = mtxInterpolated;
|
||||
if (node->displayList != NULL) {
|
||||
geo_append_display_list(node->displayList, node->node.flags >> 8);
|
||||
}
|
||||
|
@ -504,13 +671,39 @@ static void geo_process_generated_list(struct GraphNodeGenerated *node) {
|
|||
*/
|
||||
static void geo_process_background(struct GraphNodeBackground *node) {
|
||||
Gfx *list = NULL;
|
||||
Gfx *listInterpolated = NULL;
|
||||
|
||||
if (node->fnNode.func != NULL) {
|
||||
Vec3f posCopy;
|
||||
Vec3f focusCopy;
|
||||
Vec3f posInterpolated;
|
||||
Vec3f focusInterpolated;
|
||||
|
||||
if (gGlobalTimer == node->prevCameraTimestamp + 1 &&
|
||||
gGlobalTimer != gLakituState.skipCameraInterpolationTimestamp) {
|
||||
interpolate_vectors(posInterpolated, node->prevCameraPos, gLakituState.pos);
|
||||
interpolate_vectors(focusInterpolated, node->prevCameraFocus, gLakituState.focus);
|
||||
} else {
|
||||
vec3f_copy(posInterpolated, gLakituState.pos);
|
||||
vec3f_copy(focusInterpolated, gLakituState.focus);
|
||||
}
|
||||
vec3f_copy(node->prevCameraPos, gLakituState.pos);
|
||||
vec3f_copy(node->prevCameraFocus, gLakituState.focus);
|
||||
node->prevCameraTimestamp = gGlobalTimer;
|
||||
|
||||
list = node->fnNode.func(GEO_CONTEXT_RENDER, &node->fnNode.node,
|
||||
(struct AllocOnlyPool *) gMatStack[gMatStackIndex]);
|
||||
vec3f_copy(posCopy, gLakituState.pos);
|
||||
vec3f_copy(focusCopy, gLakituState.focus);
|
||||
vec3f_copy(gLakituState.pos, posInterpolated);
|
||||
vec3f_copy(gLakituState.focus, focusInterpolated);
|
||||
listInterpolated = node->fnNode.func(GEO_CONTEXT_RENDER, &node->fnNode.node, NULL);
|
||||
vec3f_copy(gLakituState.pos, posCopy);
|
||||
vec3f_copy(gLakituState.focus, focusCopy);
|
||||
}
|
||||
if (list != 0) {
|
||||
geo_append_display_list((void *) VIRTUAL_TO_PHYSICAL(list), node->fnNode.node.flags >> 8);
|
||||
geo_append_display_list2((void *) VIRTUAL_TO_PHYSICAL(list),
|
||||
(void *) VIRTUAL_TO_PHYSICAL(listInterpolated), node->fnNode.node.flags >> 8);
|
||||
} else if (gCurGraphNodeMasterList != NULL) {
|
||||
#ifndef F3DEX_GBI_2E
|
||||
Gfx *gfxStart = alloc_display_list(sizeof(Gfx) * 7);
|
||||
|
@ -535,6 +728,47 @@ static void geo_process_background(struct GraphNodeBackground *node) {
|
|||
}
|
||||
}
|
||||
|
||||
static void anim_process(Vec3f translation, Vec3s rotation, u8 *animType, s16 animFrame, u16 **animAttribute) {
|
||||
if (*animType == ANIM_TYPE_TRANSLATION) {
|
||||
translation[0] += gCurAnimData[retrieve_animation_index(animFrame, animAttribute)]
|
||||
* gCurAnimTranslationMultiplier;
|
||||
translation[1] += gCurAnimData[retrieve_animation_index(animFrame, animAttribute)]
|
||||
* gCurAnimTranslationMultiplier;
|
||||
translation[2] += gCurAnimData[retrieve_animation_index(animFrame, animAttribute)]
|
||||
* gCurAnimTranslationMultiplier;
|
||||
*animType = ANIM_TYPE_ROTATION;
|
||||
} else {
|
||||
if (*animType == ANIM_TYPE_LATERAL_TRANSLATION) {
|
||||
translation[0] +=
|
||||
gCurAnimData[retrieve_animation_index(animFrame, animAttribute)]
|
||||
* gCurAnimTranslationMultiplier;
|
||||
*animAttribute += 2;
|
||||
translation[2] +=
|
||||
gCurAnimData[retrieve_animation_index(animFrame, animAttribute)]
|
||||
* gCurAnimTranslationMultiplier;
|
||||
*animType = ANIM_TYPE_ROTATION;
|
||||
} else {
|
||||
if (*animType == ANIM_TYPE_VERTICAL_TRANSLATION) {
|
||||
*animAttribute += 2;
|
||||
translation[1] +=
|
||||
gCurAnimData[retrieve_animation_index(animFrame, animAttribute)]
|
||||
* gCurAnimTranslationMultiplier;
|
||||
*animAttribute += 2;
|
||||
*animType = ANIM_TYPE_ROTATION;
|
||||
} else if (*animType == ANIM_TYPE_NO_TRANSLATION) {
|
||||
*animAttribute += 6;
|
||||
*animType = ANIM_TYPE_ROTATION;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (*animType == ANIM_TYPE_ROTATION) {
|
||||
rotation[0] = gCurAnimData[retrieve_animation_index(animFrame, animAttribute)];
|
||||
rotation[1] = gCurAnimData[retrieve_animation_index(animFrame, animAttribute)];
|
||||
rotation[2] = gCurAnimData[retrieve_animation_index(animFrame, animAttribute)];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render an animated part. The current animation state is not part of the node
|
||||
* but set in global variables. If an animated part is skipped, everything afterwards desyncs.
|
||||
|
@ -543,53 +777,32 @@ static void geo_process_animated_part(struct GraphNodeAnimatedPart *node) {
|
|||
Mat4 matrix;
|
||||
Vec3s rotation;
|
||||
Vec3f translation;
|
||||
Vec3s rotationInterpolated;
|
||||
Vec3f translationInterpolated;
|
||||
Mtx *matrixPtr = alloc_display_list(sizeof(*matrixPtr));
|
||||
Mtx *mtxInterpolated = alloc_display_list(sizeof(*mtxInterpolated));
|
||||
u16 *animAttribute = gCurrAnimAttribute;
|
||||
u8 animType = gCurAnimType;
|
||||
|
||||
vec3s_copy(rotation, gVec3sZero);
|
||||
vec3f_set(translation, node->translation[0], node->translation[1], node->translation[2]);
|
||||
if (gCurAnimType == ANIM_TYPE_TRANSLATION) {
|
||||
translation[0] += gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)]
|
||||
* gCurAnimTranslationMultiplier;
|
||||
translation[1] += gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)]
|
||||
* gCurAnimTranslationMultiplier;
|
||||
translation[2] += gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)]
|
||||
* gCurAnimTranslationMultiplier;
|
||||
gCurAnimType = ANIM_TYPE_ROTATION;
|
||||
} else {
|
||||
if (gCurAnimType == ANIM_TYPE_LATERAL_TRANSLATION) {
|
||||
translation[0] +=
|
||||
gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)]
|
||||
* gCurAnimTranslationMultiplier;
|
||||
gCurrAnimAttribute += 2;
|
||||
translation[2] +=
|
||||
gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)]
|
||||
* gCurAnimTranslationMultiplier;
|
||||
gCurAnimType = ANIM_TYPE_ROTATION;
|
||||
} else {
|
||||
if (gCurAnimType == ANIM_TYPE_VERTICAL_TRANSLATION) {
|
||||
gCurrAnimAttribute += 2;
|
||||
translation[1] +=
|
||||
gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)]
|
||||
* gCurAnimTranslationMultiplier;
|
||||
gCurrAnimAttribute += 2;
|
||||
gCurAnimType = ANIM_TYPE_ROTATION;
|
||||
} else if (gCurAnimType == ANIM_TYPE_NO_TRANSLATION) {
|
||||
gCurrAnimAttribute += 6;
|
||||
gCurAnimType = ANIM_TYPE_ROTATION;
|
||||
}
|
||||
}
|
||||
}
|
||||
vec3s_copy(rotationInterpolated, rotation);
|
||||
vec3f_copy(translationInterpolated, translation);
|
||||
|
||||
anim_process(translationInterpolated, rotationInterpolated, &animType, gPrevAnimFrame, &animAttribute);
|
||||
anim_process(translation, rotation, &gCurAnimType, gCurrAnimFrame, &gCurrAnimAttribute);
|
||||
interpolate_vectors(translationInterpolated, translationInterpolated, translation);
|
||||
interpolate_angles(rotationInterpolated, rotationInterpolated, rotation);
|
||||
|
||||
if (gCurAnimType == ANIM_TYPE_ROTATION) {
|
||||
rotation[0] = gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)];
|
||||
rotation[1] = gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)];
|
||||
rotation[2] = gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)];
|
||||
}
|
||||
mtxf_rotate_xyz_and_translate(matrix, translation, rotation);
|
||||
mtxf_mul(gMatStack[gMatStackIndex + 1], matrix, gMatStack[gMatStackIndex]);
|
||||
mtxf_rotate_xyz_and_translate(matrix, translationInterpolated, rotationInterpolated);
|
||||
mtxf_mul(gMatStackInterpolated[gMatStackIndex + 1], matrix, gMatStackInterpolated[gMatStackIndex]);
|
||||
gMatStackIndex++;
|
||||
mtxf_to_mtx(matrixPtr, gMatStack[gMatStackIndex]);
|
||||
gMatStackFixed[gMatStackIndex] = matrixPtr;
|
||||
mtxf_to_mtx(mtxInterpolated, gMatStackInterpolated[gMatStackIndex]);
|
||||
gMatStackInterpolatedFixed[gMatStackIndex] = mtxInterpolated;
|
||||
if (node->displayList != NULL) {
|
||||
geo_append_display_list(node->displayList, node->node.flags >> 8);
|
||||
}
|
||||
|
@ -621,6 +834,17 @@ void geo_set_animation_globals(struct GraphNodeObject_sub *node, s32 hasAnimatio
|
|||
}
|
||||
|
||||
gCurrAnimFrame = node->animFrame;
|
||||
if (node->prevAnimPtr == anim && node->prevAnimID == node->animID &&
|
||||
gGlobalTimer == node->prevAnimFrameTimestamp + 1) {
|
||||
gPrevAnimFrame = node->prevAnimFrame;
|
||||
} else {
|
||||
gPrevAnimFrame = node->animFrame;
|
||||
}
|
||||
node->prevAnimPtr = anim;
|
||||
node->prevAnimID = node->animID;
|
||||
node->prevAnimFrame = node->animFrame;
|
||||
node->prevAnimFrameTimestamp = gGlobalTimer;
|
||||
|
||||
gCurAnimEnabled = (anim->flags & ANIM_FLAG_5) == 0;
|
||||
gCurrAnimAttribute = segmented_to_virtual((void *) anim->index);
|
||||
gCurAnimData = segmented_to_virtual((void *) anim->values);
|
||||
|
@ -639,8 +863,10 @@ void geo_set_animation_globals(struct GraphNodeObject_sub *node, s32 hasAnimatio
|
|||
*/
|
||||
static void geo_process_shadow(struct GraphNodeShadow *node) {
|
||||
Gfx *shadowList;
|
||||
Gfx *shadowListInterpolated;
|
||||
Mat4 mtxf;
|
||||
Vec3f shadowPos;
|
||||
Vec3f shadowPosInterpolated;
|
||||
Vec3f animOffset;
|
||||
f32 objScale;
|
||||
f32 shadowScale;
|
||||
|
@ -648,6 +874,7 @@ static void geo_process_shadow(struct GraphNodeShadow *node) {
|
|||
f32 cosAng;
|
||||
struct GraphNode *geo;
|
||||
Mtx *mtx;
|
||||
Mtx *mtxInterpolated;
|
||||
|
||||
if (gCurGraphNodeCamera != NULL && gCurGraphNodeObject != NULL) {
|
||||
if (gCurGraphNodeHeldObject != NULL) {
|
||||
|
@ -686,21 +913,57 @@ static void geo_process_shadow(struct GraphNodeShadow *node) {
|
|||
}
|
||||
}
|
||||
|
||||
if (gCurGraphNodeHeldObject != NULL) {
|
||||
if (gGlobalTimer == gCurGraphNodeHeldObject->prevShadowPosTimestamp + 1) {
|
||||
interpolate_vectors(shadowPosInterpolated, gCurGraphNodeHeldObject->prevShadowPos, shadowPos);
|
||||
} else {
|
||||
vec3f_copy(shadowPosInterpolated, shadowPos);
|
||||
}
|
||||
vec3f_copy(gCurGraphNodeHeldObject->prevShadowPos, shadowPos);
|
||||
gCurGraphNodeHeldObject->prevShadowPosTimestamp = gGlobalTimer;
|
||||
} else {
|
||||
if (gGlobalTimer == gCurGraphNodeObject->prevShadowPosTimestamp + 1 &&
|
||||
gGlobalTimer != gCurGraphNodeObject->skipInterpolationTimestamp) {
|
||||
interpolate_vectors(shadowPosInterpolated, gCurGraphNodeObject->prevShadowPos, shadowPos);
|
||||
} else {
|
||||
vec3f_copy(shadowPosInterpolated, shadowPos);
|
||||
}
|
||||
vec3f_copy(gCurGraphNodeObject->prevShadowPos, shadowPos);
|
||||
gCurGraphNodeObject->prevShadowPosTimestamp = gGlobalTimer;
|
||||
}
|
||||
|
||||
extern u8 gInterpolatingSurfaces;
|
||||
gInterpolatingSurfaces = TRUE;
|
||||
shadowListInterpolated = create_shadow_below_xyz(shadowPosInterpolated[0], shadowPosInterpolated[1],
|
||||
shadowPosInterpolated[2], shadowScale,
|
||||
node->shadowSolidity, node->shadowType);
|
||||
gInterpolatingSurfaces = FALSE;
|
||||
shadowList = create_shadow_below_xyz(shadowPos[0], shadowPos[1], shadowPos[2], shadowScale,
|
||||
node->shadowSolidity, node->shadowType);
|
||||
if (shadowList != NULL) {
|
||||
if (shadowListInterpolated != NULL && shadowList != NULL) {
|
||||
mtx = alloc_display_list(sizeof(*mtx));
|
||||
mtxInterpolated = alloc_display_list(sizeof(*mtxInterpolated));
|
||||
gMatStackIndex++;
|
||||
|
||||
mtxf_translate(mtxf, shadowPos);
|
||||
mtxf_mul(gMatStack[gMatStackIndex], mtxf, *gCurGraphNodeCamera->matrixPtr);
|
||||
mtxf_to_mtx(mtx, gMatStack[gMatStackIndex]);
|
||||
gMatStackFixed[gMatStackIndex] = mtx;
|
||||
|
||||
mtxf_translate(mtxf, shadowPosInterpolated);
|
||||
mtxf_mul(gMatStackInterpolated[gMatStackIndex], mtxf, *gCurGraphNodeCamera->matrixPtrInterpolated);
|
||||
mtxf_to_mtx(mtxInterpolated, gMatStackInterpolated[gMatStackIndex]);
|
||||
gMatStackInterpolatedFixed[gMatStackIndex] = mtxInterpolated;
|
||||
|
||||
if (gShadowAboveWaterOrLava == 1) {
|
||||
geo_append_display_list((void *) VIRTUAL_TO_PHYSICAL(shadowList), 4);
|
||||
geo_append_display_list2((void *) VIRTUAL_TO_PHYSICAL(shadowList),
|
||||
(void *) VIRTUAL_TO_PHYSICAL(shadowListInterpolated), 4);
|
||||
} else if (gMarioOnIceOrCarpet == 1) {
|
||||
geo_append_display_list((void *) VIRTUAL_TO_PHYSICAL(shadowList), 5);
|
||||
geo_append_display_list2((void *) VIRTUAL_TO_PHYSICAL(shadowList),
|
||||
(void *) VIRTUAL_TO_PHYSICAL(shadowListInterpolated), 5);
|
||||
} else {
|
||||
geo_append_display_list((void *) VIRTUAL_TO_PHYSICAL(shadowList), 6);
|
||||
geo_append_display_list2((void *) VIRTUAL_TO_PHYSICAL(shadowList),
|
||||
(void *) VIRTUAL_TO_PHYSICAL(shadowListInterpolated), 6);
|
||||
}
|
||||
gMatStackIndex--;
|
||||
}
|
||||
|
@ -797,31 +1060,101 @@ static int obj_is_in_view(struct GraphNodeObject *node, Mat4 matrix) {
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void interpolate_matrix(Mat4 result, Mat4 a, Mat4 b) {
|
||||
s32 i, j;
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
result[i][j] = (a[i][j] + b[i][j]) / 2.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process an object node.
|
||||
*/
|
||||
static void geo_process_object(struct Object *node) {
|
||||
Mat4 mtxf;
|
||||
s32 hasAnimation = (node->header.gfx.node.flags & GRAPH_RENDER_HAS_ANIMATION) != 0;
|
||||
Vec3f scaleInterpolated;
|
||||
|
||||
if (node->header.gfx.unk18 == gCurGraphNodeRoot->areaIndex) {
|
||||
if (node->header.gfx.throwMatrix != NULL) {
|
||||
mtxf_mul(gMatStack[gMatStackIndex + 1], *node->header.gfx.throwMatrix,
|
||||
gMatStack[gMatStackIndex]);
|
||||
if (gGlobalTimer == node->header.gfx.prevThrowMatrixTimestamp + 1 &&
|
||||
gGlobalTimer != node->header.gfx.skipInterpolationTimestamp) {
|
||||
interpolate_matrix(mtxf, *node->header.gfx.throwMatrix, node->header.gfx.prevThrowMatrix);
|
||||
mtxf_mul(gMatStackInterpolated[gMatStackIndex + 1], mtxf,
|
||||
gMatStackInterpolated[gMatStackIndex]);
|
||||
} else {
|
||||
mtxf_mul(gMatStackInterpolated[gMatStackIndex + 1], (void *) node->header.gfx.throwMatrix,
|
||||
gMatStackInterpolated[gMatStackIndex]);
|
||||
}
|
||||
mtxf_copy(node->header.gfx.prevThrowMatrix, *node->header.gfx.throwMatrix);
|
||||
node->header.gfx.prevThrowMatrixTimestamp = gGlobalTimer;
|
||||
} else if (node->header.gfx.node.flags & GRAPH_RENDER_CYLBOARD) {
|
||||
Vec3f posInterpolated;
|
||||
if (gGlobalTimer == node->header.gfx.prevTimestamp + 1 &&
|
||||
gGlobalTimer != node->header.gfx.skipInterpolationTimestamp) {
|
||||
interpolate_vectors(posInterpolated, node->header.gfx.prevPos, node->header.gfx.pos);
|
||||
} else {
|
||||
vec3f_copy(posInterpolated, node->header.gfx.pos);
|
||||
}
|
||||
vec3f_copy(node->header.gfx.prevPos, node->header.gfx.pos);
|
||||
node->header.gfx.prevTimestamp = gGlobalTimer;
|
||||
mtxf_cylboard(gMatStack[gMatStackIndex + 1], gMatStack[gMatStackIndex],
|
||||
node->header.gfx.pos, gCurGraphNodeCamera->roll);
|
||||
mtxf_cylboard(gMatStackInterpolated[gMatStackIndex + 1], gMatStackInterpolated[gMatStackIndex],
|
||||
posInterpolated, gCurGraphNodeCamera->roll);
|
||||
} else if (node->header.gfx.node.flags & GRAPH_RENDER_BILLBOARD) {
|
||||
Vec3f posInterpolated;
|
||||
if (gGlobalTimer == node->header.gfx.prevTimestamp + 1 &&
|
||||
gGlobalTimer != node->header.gfx.skipInterpolationTimestamp) {
|
||||
interpolate_vectors(posInterpolated, node->header.gfx.prevPos, node->header.gfx.pos);
|
||||
} else {
|
||||
vec3f_copy(posInterpolated, node->header.gfx.pos);
|
||||
}
|
||||
vec3f_copy(node->header.gfx.prevPos, node->header.gfx.pos);
|
||||
node->header.gfx.prevTimestamp = gGlobalTimer;
|
||||
mtxf_billboard(gMatStack[gMatStackIndex + 1], gMatStack[gMatStackIndex],
|
||||
node->header.gfx.pos, gCurGraphNodeCamera->roll);
|
||||
mtxf_billboard(gMatStackInterpolated[gMatStackIndex + 1], gMatStackInterpolated[gMatStackIndex],
|
||||
posInterpolated, gCurGraphNodeCamera->roll);
|
||||
} else {
|
||||
Vec3f posInterpolated;
|
||||
Vec3s angleInterpolated;
|
||||
if (gGlobalTimer == node->header.gfx.prevTimestamp + 1 &&
|
||||
gGlobalTimer != node->header.gfx.skipInterpolationTimestamp) {
|
||||
interpolate_vectors(posInterpolated, node->header.gfx.prevPos, node->header.gfx.pos);
|
||||
interpolate_angles(angleInterpolated, node->header.gfx.prevAngle, node->header.gfx.angle);
|
||||
} else {
|
||||
vec3f_copy(posInterpolated, node->header.gfx.pos);
|
||||
vec3s_copy(angleInterpolated, node->header.gfx.angle);
|
||||
}
|
||||
vec3f_copy(node->header.gfx.prevPos, node->header.gfx.pos);
|
||||
vec3s_copy(node->header.gfx.prevAngle, node->header.gfx.angle);
|
||||
node->header.gfx.prevTimestamp = gGlobalTimer;
|
||||
mtxf_rotate_zxy_and_translate(mtxf, node->header.gfx.pos, node->header.gfx.angle);
|
||||
mtxf_mul(gMatStack[gMatStackIndex + 1], mtxf, gMatStack[gMatStackIndex]);
|
||||
mtxf_rotate_zxy_and_translate(mtxf, posInterpolated, angleInterpolated);
|
||||
mtxf_mul(gMatStackInterpolated[gMatStackIndex + 1], mtxf, gMatStackInterpolated[gMatStackIndex]);
|
||||
}
|
||||
|
||||
if (gGlobalTimer == node->header.gfx.prevScaleTimestamp + 1 &&
|
||||
gGlobalTimer != node->header.gfx.skipInterpolationTimestamp) {
|
||||
interpolate_vectors(scaleInterpolated, node->header.gfx.prevScale, node->header.gfx.scale);
|
||||
} else {
|
||||
vec3f_copy(scaleInterpolated, node->header.gfx.scale);
|
||||
}
|
||||
vec3f_copy(node->header.gfx.prevScale, node->header.gfx.scale);
|
||||
node->header.gfx.prevScaleTimestamp = gGlobalTimer;
|
||||
|
||||
mtxf_scale_vec3f(gMatStack[gMatStackIndex + 1], gMatStack[gMatStackIndex + 1],
|
||||
node->header.gfx.scale);
|
||||
mtxf_scale_vec3f(gMatStackInterpolated[gMatStackIndex + 1], gMatStackInterpolated[gMatStackIndex + 1],
|
||||
scaleInterpolated);
|
||||
node->header.gfx.throwMatrix = &gMatStack[++gMatStackIndex];
|
||||
node->header.gfx.throwMatrixInterpolated = &gMatStackInterpolated[gMatStackIndex];
|
||||
node->header.gfx.cameraToObject[0] = gMatStack[gMatStackIndex][3][0];
|
||||
node->header.gfx.cameraToObject[1] = gMatStack[gMatStackIndex][3][1];
|
||||
node->header.gfx.cameraToObject[2] = gMatStack[gMatStackIndex][3][2];
|
||||
|
@ -832,9 +1165,12 @@ static void geo_process_object(struct Object *node) {
|
|||
}
|
||||
if (obj_is_in_view(&node->header.gfx, gMatStack[gMatStackIndex])) {
|
||||
Mtx *mtx = alloc_display_list(sizeof(*mtx));
|
||||
Mtx *mtxInterpolated = alloc_display_list(sizeof(*mtxInterpolated));
|
||||
|
||||
mtxf_to_mtx(mtx, gMatStack[gMatStackIndex]);
|
||||
gMatStackFixed[gMatStackIndex] = mtx;
|
||||
mtxf_to_mtx(mtxInterpolated, gMatStackInterpolated[gMatStackIndex]);
|
||||
gMatStackInterpolatedFixed[gMatStackIndex] = mtxInterpolated;
|
||||
if (node->header.gfx.sharedChild != NULL) {
|
||||
gCurGraphNodeObject = (struct GraphNodeObject *) node;
|
||||
node->header.gfx.sharedChild->parent = &node->header.gfx.node;
|
||||
|
@ -845,11 +1181,16 @@ static void geo_process_object(struct Object *node) {
|
|||
if (node->header.gfx.node.children != NULL) {
|
||||
geo_process_node_and_siblings(node->header.gfx.node.children);
|
||||
}
|
||||
} else {
|
||||
node->header.gfx.prevThrowMatrixTimestamp = 0;
|
||||
node->header.gfx.prevTimestamp = 0;
|
||||
node->header.gfx.prevScaleTimestamp = 0;
|
||||
}
|
||||
|
||||
gMatStackIndex--;
|
||||
gCurAnimType = ANIM_TYPE_NONE;
|
||||
node->header.gfx.throwMatrix = NULL;
|
||||
node->header.gfx.throwMatrixInterpolated = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -876,6 +1217,8 @@ void geo_process_held_object(struct GraphNodeHeldObject *node) {
|
|||
Mat4 mat;
|
||||
Vec3f translation;
|
||||
Mtx *mtx = alloc_display_list(sizeof(*mtx));
|
||||
Mtx *mtxInterpolated = alloc_display_list(sizeof(*mtxInterpolated));
|
||||
Vec3f scaleInterpolated;
|
||||
|
||||
#ifdef F3DEX_GBI_2
|
||||
gSPLookAt(gDisplayListHead++, &lookAt);
|
||||
|
@ -891,6 +1234,14 @@ void geo_process_held_object(struct GraphNodeHeldObject *node) {
|
|||
translation[1] = node->translation[1] / 4.0f;
|
||||
translation[2] = node->translation[2] / 4.0f;
|
||||
|
||||
if (gGlobalTimer == node->objNode->header.gfx.prevScaleTimestamp + 1) {
|
||||
interpolate_vectors(scaleInterpolated, node->objNode->header.gfx.prevScale, node->objNode->header.gfx.scale);
|
||||
} else {
|
||||
vec3f_copy(scaleInterpolated, node->objNode->header.gfx.scale);
|
||||
}
|
||||
vec3f_copy(node->objNode->header.gfx.prevScale, node->objNode->header.gfx.scale);
|
||||
node->objNode->header.gfx.prevScaleTimestamp = gGlobalTimer;
|
||||
|
||||
mtxf_translate(mat, translation);
|
||||
mtxf_copy(gMatStack[gMatStackIndex + 1], *gCurGraphNodeObject->throwMatrix);
|
||||
gMatStack[gMatStackIndex + 1][3][0] = gMatStack[gMatStackIndex][3][0];
|
||||
|
@ -899,6 +1250,13 @@ void geo_process_held_object(struct GraphNodeHeldObject *node) {
|
|||
mtxf_mul(gMatStack[gMatStackIndex + 1], mat, gMatStack[gMatStackIndex + 1]);
|
||||
mtxf_scale_vec3f(gMatStack[gMatStackIndex + 1], gMatStack[gMatStackIndex + 1],
|
||||
node->objNode->header.gfx.scale);
|
||||
mtxf_copy(gMatStackInterpolated[gMatStackIndex + 1], (void *) gCurGraphNodeObject->throwMatrixInterpolated);
|
||||
gMatStackInterpolated[gMatStackIndex + 1][3][0] = gMatStackInterpolated[gMatStackIndex][3][0];
|
||||
gMatStackInterpolated[gMatStackIndex + 1][3][1] = gMatStackInterpolated[gMatStackIndex][3][1];
|
||||
gMatStackInterpolated[gMatStackIndex + 1][3][2] = gMatStackInterpolated[gMatStackIndex][3][2];
|
||||
mtxf_mul(gMatStackInterpolated[gMatStackIndex + 1], mat, gMatStackInterpolated[gMatStackIndex + 1]);
|
||||
mtxf_scale_vec3f(gMatStackInterpolated[gMatStackIndex + 1], gMatStackInterpolated[gMatStackIndex + 1],
|
||||
scaleInterpolated);
|
||||
if (node->fnNode.func != NULL) {
|
||||
node->fnNode.func(GEO_CONTEXT_HELD_OBJ, &node->fnNode.node,
|
||||
(struct AllocOnlyPool *) gMatStack[gMatStackIndex + 1]);
|
||||
|
@ -906,12 +1264,15 @@ void geo_process_held_object(struct GraphNodeHeldObject *node) {
|
|||
gMatStackIndex++;
|
||||
mtxf_to_mtx(mtx, gMatStack[gMatStackIndex]);
|
||||
gMatStackFixed[gMatStackIndex] = mtx;
|
||||
mtxf_to_mtx(mtxInterpolated, gMatStackInterpolated[gMatStackIndex]);
|
||||
gMatStackInterpolatedFixed[gMatStackIndex] = mtxInterpolated;
|
||||
gGeoTempState.type = gCurAnimType;
|
||||
gGeoTempState.enabled = gCurAnimEnabled;
|
||||
gGeoTempState.frame = gCurrAnimFrame;
|
||||
gGeoTempState.translationMultiplier = gCurAnimTranslationMultiplier;
|
||||
gGeoTempState.attribute = gCurrAnimAttribute;
|
||||
gGeoTempState.data = gCurAnimData;
|
||||
gGeoTempState.prevFrame = gPrevAnimFrame;
|
||||
gCurAnimType = 0;
|
||||
gCurGraphNodeHeldObject = (void *) node;
|
||||
if (node->objNode->header.gfx.unk38.curAnim != NULL) {
|
||||
|
@ -926,6 +1287,7 @@ void geo_process_held_object(struct GraphNodeHeldObject *node) {
|
|||
gCurAnimTranslationMultiplier = gGeoTempState.translationMultiplier;
|
||||
gCurrAnimAttribute = gGeoTempState.attribute;
|
||||
gCurAnimData = gGeoTempState.data;
|
||||
gPrevAnimFrame = gGeoTempState.prevFrame;
|
||||
gMatStackIndex--;
|
||||
}
|
||||
|
||||
|
@ -1047,6 +1409,7 @@ void geo_process_root(struct GraphNodeRoot *node, Vp *b, Vp *c, s32 clearColor)
|
|||
if (node->node.flags & GRAPH_RENDER_ACTIVE) {
|
||||
Mtx *initialMatrix;
|
||||
Vp *viewport = alloc_display_list(sizeof(*viewport));
|
||||
Vp *viewportInterpolated = viewport;
|
||||
|
||||
gDisplayListHeap = alloc_only_pool_init();
|
||||
initialMatrix = alloc_display_list(sizeof(*initialMatrix));
|
||||
|
@ -1056,7 +1419,12 @@ void geo_process_root(struct GraphNodeRoot *node, Vp *b, Vp *c, s32 clearColor)
|
|||
vec3s_set(viewport->vp.vscale, node->width * 4, node->height * 4, 511);
|
||||
if (b != NULL) {
|
||||
clear_frame_buffer(clearColor);
|
||||
make_viewport_clip_rect(b);
|
||||
viewportInterpolated = alloc_display_list(sizeof(*viewportInterpolated));
|
||||
interpolate_vectors_s16(viewportInterpolated->vp.vtrans, sPrevViewport.vp.vtrans, b->vp.vtrans);
|
||||
interpolate_vectors_s16(viewportInterpolated->vp.vscale, sPrevViewport.vp.vscale, b->vp.vscale);
|
||||
|
||||
sViewportPos = gDisplayListHead;
|
||||
make_viewport_clip_rect(viewportInterpolated);
|
||||
*viewport = *b;
|
||||
}
|
||||
|
||||
|
@ -1064,11 +1432,16 @@ void geo_process_root(struct GraphNodeRoot *node, Vp *b, Vp *c, s32 clearColor)
|
|||
clear_frame_buffer(clearColor);
|
||||
make_viewport_clip_rect(c);
|
||||
}
|
||||
sPrevViewport = *viewport;
|
||||
|
||||
mtxf_identity(gMatStack[gMatStackIndex]);
|
||||
mtxf_to_mtx(initialMatrix, gMatStack[gMatStackIndex]);
|
||||
gMatStackFixed[gMatStackIndex] = initialMatrix;
|
||||
gSPViewport(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(viewport));
|
||||
|
||||
mtxf_identity(gMatStackInterpolated[gMatStackIndex]);
|
||||
gMatStackInterpolatedFixed[gMatStackIndex] = initialMatrix;
|
||||
|
||||
gSPViewport(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(viewportInterpolated));
|
||||
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(gMatStackFixed[gMatStackIndex]),
|
||||
G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH);
|
||||
gCurGraphNodeRoot = node;
|
||||
|
|
|
@ -16,6 +16,19 @@
|
|||
u8 sTransitionColorFadeCount[4] = { 0 };
|
||||
u16 sTransitionTextureFadeCount[2] = { 0 };
|
||||
|
||||
static Gfx *sScreenTransitionVerticesPos[2];
|
||||
static Vtx *sScreenTransitionVertices;
|
||||
|
||||
void patch_screen_transition_interpolated(void) {
|
||||
if (sScreenTransitionVerticesPos[0] != NULL) {
|
||||
gSPVertex(sScreenTransitionVerticesPos[0], VIRTUAL_TO_PHYSICAL(sScreenTransitionVertices), 8, 0);
|
||||
gSPVertex(sScreenTransitionVerticesPos[1], VIRTUAL_TO_PHYSICAL(sScreenTransitionVertices), 4, 0);
|
||||
sScreenTransitionVerticesPos[0] = NULL;
|
||||
sScreenTransitionVerticesPos[1] = NULL;
|
||||
sScreenTransitionVertices = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
s32 set_and_reset_transition_fade_timer(s8 fadeTimer, u8 transTime) {
|
||||
s32 reset = FALSE;
|
||||
|
||||
|
@ -85,14 +98,29 @@ s32 render_fade_transition_into_color(s8 fadeTimer, u8 transTime, struct WarpTra
|
|||
return dl_transition_color(fadeTimer, transTime, transData, alpha);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
s16 calc_tex_transition_radius(s8 fadeTimer, s8 transTime, struct WarpTransitionData *transData) {
|
||||
f32 texRadius = transData->endTexRadius - transData->startTexRadius;
|
||||
f32 radiusTime = sTransitionColorFadeCount[fadeTimer] * texRadius / (f32)(transTime - 1);
|
||||
f32 result = transData->startTexRadius + radiusTime;
|
||||
|
||||
return (s16)(result + 0.5);;
|
||||
return (s16)(result + 0.5);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
s16 calc_tex_transition_radius(s8 fadeTimer, f32 interpolationFraction, s8 transTime, struct WarpTransitionData *transData) {
|
||||
f32 texRadius = transData->endTexRadius - transData->startTexRadius;
|
||||
f32 radiusTime = (sTransitionColorFadeCount[fadeTimer] == 0 ? 0 :
|
||||
sTransitionColorFadeCount[fadeTimer] - 1 + interpolationFraction) * texRadius / (f32)(transTime - 1);
|
||||
f32 result = transData->startTexRadius + radiusTime;
|
||||
|
||||
return (s16)(result + 0.5);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
f32 calc_tex_transition_time(s8 fadeTimer, s8 transTime, struct WarpTransitionData *transData) {
|
||||
f32 startX = transData->startTexX;
|
||||
f32 startY = transData->startTexY;
|
||||
|
@ -166,6 +194,8 @@ void *sTextureTransitionID[] = {
|
|||
texture_transition_bowser_half,
|
||||
};
|
||||
|
||||
#if 0
|
||||
|
||||
s32 render_textured_transition(s8 fadeTimer, s8 transTime, struct WarpTransitionData *transData, s8 texID, s8 transTexType) {
|
||||
f32 texTransTime = calc_tex_transition_time(fadeTimer, transTime, transData);
|
||||
u16 texTransPos = convert_tex_transition_angle_to_pos(transData);
|
||||
|
@ -206,6 +236,56 @@ s32 render_textured_transition(s8 fadeTimer, s8 transTime, struct WarpTransition
|
|||
return set_and_reset_transition_fade_timer(fadeTimer, transTime);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
s32 render_textured_transition(s8 fadeTimer, s8 transTime, struct WarpTransitionData *transData, s8 texID, s8 transTexType) {
|
||||
f32 texTransTime = calc_tex_transition_time(fadeTimer, transTime, transData);
|
||||
u16 texTransPos = convert_tex_transition_angle_to_pos(transData);
|
||||
s16 centerTransX = center_tex_transition_x(transData, texTransTime, texTransPos);
|
||||
s16 centerTransY = center_tex_transition_y(transData, texTransTime, texTransPos);
|
||||
s16 texTransRadius = calc_tex_transition_radius(fadeTimer, 1.0f, transTime, transData);
|
||||
s16 texTransRadiusInterpolated = calc_tex_transition_radius(fadeTimer, 0.5f, transTime, transData);
|
||||
Vtx *verts = alloc_display_list(8 * sizeof(*verts));
|
||||
Vtx *vertsInterpolated = alloc_display_list(8 * sizeof(*vertsInterpolated));
|
||||
|
||||
if (verts != NULL && vertsInterpolated != NULL) {
|
||||
load_tex_transition_vertex(verts, fadeTimer, transData, centerTransX, centerTransY, texTransRadius, transTexType);
|
||||
load_tex_transition_vertex(vertsInterpolated, fadeTimer, transData, centerTransX, centerTransY, texTransRadiusInterpolated, transTexType);
|
||||
sScreenTransitionVertices = verts;
|
||||
gSPDisplayList(gDisplayListHead++, dl_proj_mtx_fullscreen)
|
||||
gDPSetCombineMode(gDisplayListHead++, G_CC_SHADE, G_CC_SHADE);
|
||||
gDPSetRenderMode(gDisplayListHead++, G_RM_AA_OPA_SURF, G_RM_AA_OPA_SURF2);
|
||||
sScreenTransitionVerticesPos[0] = gDisplayListHead;
|
||||
gSPVertex(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(vertsInterpolated), 8, 0);
|
||||
gSPDisplayList(gDisplayListHead++, dl_transition_draw_filled_region);
|
||||
gDPPipeSync(gDisplayListHead++);
|
||||
gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA);
|
||||
gDPSetRenderMode(gDisplayListHead++, G_RM_AA_XLU_SURF, G_RM_AA_XLU_SURF2);
|
||||
gDPSetTextureFilter(gDisplayListHead++, G_TF_BILERP);
|
||||
switch (transTexType) {
|
||||
case TRANS_TYPE_MIRROR:
|
||||
gDPLoadTextureBlock(gDisplayListHead++, sTextureTransitionID[texID], G_IM_FMT_IA, G_IM_SIZ_8b, 32, 64, 0,
|
||||
G_TX_WRAP | G_TX_MIRROR, G_TX_WRAP | G_TX_MIRROR, 5, 6, G_TX_NOLOD, G_TX_NOLOD);
|
||||
break;
|
||||
case TRANS_TYPE_CLAMP:
|
||||
gDPLoadTextureBlock(gDisplayListHead++, sTextureTransitionID[texID], G_IM_FMT_IA, G_IM_SIZ_8b, 64, 64, 0,
|
||||
G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD);
|
||||
break;
|
||||
}
|
||||
gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON);
|
||||
sScreenTransitionVerticesPos[1] = gDisplayListHead;
|
||||
gSPVertex(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(vertsInterpolated), 4, 0);
|
||||
gSPDisplayList(gDisplayListHead++, dl_draw_quad_verts_0123);
|
||||
gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF);
|
||||
gSPDisplayList(gDisplayListHead++, dl_screen_transition_end);
|
||||
sTransitionTextureFadeCount[fadeTimer] += transData->texTimer;
|
||||
} else {
|
||||
}
|
||||
return set_and_reset_transition_fade_timer(fadeTimer, transTime);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int render_screen_transition(s8 fadeTimer, s8 transType, u8 transTime, struct WarpTransitionData *transData) {
|
||||
switch (transType) {
|
||||
case WARP_TRANSITION_FADE_FROM_COLOR:
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "segment2.h"
|
||||
#include "shadow.h"
|
||||
#include "sm64.h"
|
||||
#include "moon/saturn/saturn_types.h"
|
||||
|
||||
// Avoid Z-fighting
|
||||
#define find_floor_height_and_data 0.4 + find_floor_height_and_data
|
||||
|
@ -851,6 +852,11 @@ Gfx *create_shadow_hardcoded_rectangle(f32 xPos, f32 yPos, f32 zPos, UNUSED s16
|
|||
*/
|
||||
Gfx *create_shadow_below_xyz(f32 xPos, f32 yPos, f32 zPos, s16 shadowScale, u8 shadowSolidity,
|
||||
s8 shadowType) {
|
||||
|
||||
if (!enable_shadows) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Gfx *displayList = NULL;
|
||||
struct Surface *pfloor;
|
||||
find_floor(xPos, yPos, zPos, &pfloor);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <PR/ultratypes.h>
|
||||
|
||||
#include "engine/math_util.h"
|
||||
#include "game/memory.h"
|
||||
#include "game/segment2.h"
|
||||
#include "game/segment7.h"
|
||||
|
@ -146,6 +147,18 @@ Gfx *geo_n64_screen(s32 sp50, struct GraphNode *sp54, UNUSED void *context) {
|
|||
}
|
||||
|
||||
|
||||
static Gfx *sIntroScalePos;
|
||||
static Vec3f sIntroScale;
|
||||
|
||||
void patch_title_screen_scales(void) {
|
||||
if (sIntroScalePos != NULL) {
|
||||
Mtx *scaleMat = alloc_display_list(sizeof(*scaleMat));
|
||||
guScale(scaleMat, sIntroScale[0], sIntroScale[1], sIntroScale[2]);
|
||||
gSPMatrix(sIntroScalePos, scaleMat, G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_PUSH);
|
||||
sIntroScalePos = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Gfx *geo_title_screen(s32 sp50, struct GraphNode *sp54, UNUSED void *context) {
|
||||
struct GraphNode *graphNode; // sp4c
|
||||
Gfx *displayList; // sp48
|
||||
|
@ -156,6 +169,8 @@ Gfx *geo_title_screen(s32 sp50, struct GraphNode *sp54, UNUSED void *context) {
|
|||
f32 scaleX; // sp34
|
||||
f32 scaleY; // sp30
|
||||
f32 scaleZ; // sp2c
|
||||
Vec3f scale;
|
||||
Vec3f scaleInterpolated;
|
||||
graphNode = sp54;
|
||||
displayList = NULL;
|
||||
displayListIter = NULL;
|
||||
|
@ -187,6 +202,11 @@ Gfx *geo_title_screen(s32 sp50, struct GraphNode *sp54, UNUSED void *context) {
|
|||
scaleZ = 0.0f;
|
||||
}
|
||||
guScale(scaleMat, scaleX, scaleY, scaleZ);
|
||||
vec3f_set(scale, scaleX, scaleY, scaleZ);
|
||||
interpolate_vectors(scaleInterpolated, sIntroScale, scale);
|
||||
vec3f_set(sIntroScale, scaleX, scaleY, scaleZ);
|
||||
guScale(scaleMat, scaleInterpolated[0], scaleInterpolated[1], scaleInterpolated[2]);
|
||||
sIntroScalePos = displayListIter;
|
||||
gSPMatrix(displayListIter++, scaleMat, G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_PUSH);
|
||||
gSPDisplayList(displayListIter++, &intro_seg7_dl_0700B3A0);
|
||||
gSPPopMatrix(displayListIter++, G_MTX_MODELVIEW);
|
||||
|
|
|
@ -30,7 +30,7 @@ using namespace std;
|
|||
|
||||
map<string, Achievement*> registeredAchievements;
|
||||
map<int, vector<AchievementEntry*>> entries;
|
||||
bool cheatsGotEnabled = false;
|
||||
bool cheatsGotEnabled = true;
|
||||
|
||||
namespace AchievementList {
|
||||
/* Star achievements */
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
#include "moon/mod-engine/hooks/hook.h"
|
||||
#include "moon/mod-engine/textures/mod-texture.h"
|
||||
#include "moon/mod-engine/engine.h"
|
||||
#include "moon/saturn/saturn.h"
|
||||
#include "moon/saturn/saturn_colors.h"
|
||||
#include "moon/saturn/saturn_types.h"
|
||||
#include "icons/IconsForkAwesome.h"
|
||||
#include "icons/IconsMaterialDesign.h"
|
||||
#include "moon/utils/moon-env.h"
|
||||
|
@ -63,6 +66,8 @@ extern "C" {
|
|||
extern "C" {
|
||||
#include "pc/gfx/gfx_pc.h"
|
||||
#include "pc/pc_main.h"
|
||||
#include "game/camera.h"
|
||||
#include "game/mario.h"
|
||||
}
|
||||
|
||||
#include "pc/configfile.h"
|
||||
|
@ -133,6 +138,26 @@ namespace MoonInternal {
|
|||
|
||||
map<string, ImFont*> fontMap;
|
||||
|
||||
// Colors
|
||||
static ImVec4 uiHatColor = ImVec4(255.0f / 255.0f, 0.0f / 255.0f, 0.0f / 255.0f, 255.0f / 255.0f);
|
||||
static ImVec4 uiHatShadeColor = ImVec4(127.0f / 255.0f, 0.0f / 255.0f, 0.0f / 255.0f, 255.0f / 255.0f);
|
||||
static ImVec4 uiOverallsColor = ImVec4(0.0f / 255.0f, 0.0f / 255.0f, 255.0f / 255.0f, 255.0f / 255.0f);
|
||||
static ImVec4 uiOverallsShadeColor = ImVec4(0.0f / 255.0f, 0.0f / 255.0f, 127.0f / 255.0f, 255.0f / 255.0f);
|
||||
static ImVec4 uiGlovesColor = ImVec4(255.0f / 255.0f, 255.0f / 255.0f, 255.0f / 255.0f, 255.0f / 255.0f);
|
||||
static ImVec4 uiGlovesShadeColor = ImVec4(127.0f / 255.0f, 127.0f / 255.0f, 127.0f / 255.0f, 255.0f / 255.0f);
|
||||
static ImVec4 uiShoesColor = ImVec4(114.0f / 255.0f, 28.0f / 255.0f, 14.0f / 255.0f, 255.0f / 255.0f);
|
||||
static ImVec4 uiShoesShadeColor = ImVec4(57.0f / 255.0f, 14.0f / 255.0f, 7.0f / 255.0f, 255.0f / 255.0f);
|
||||
static ImVec4 uiSkinColor = ImVec4(254.0f / 255.0f, 193.0f / 255.0f, 121.0f / 255.0f, 255.0f / 255.0f);
|
||||
static ImVec4 uiSkinShadeColor = ImVec4(127.0f / 255.0f, 96.0f / 255.0f, 60.0f / 255.0f, 255.0f / 255.0f);
|
||||
static ImVec4 uiHairColor = ImVec4(115.0f / 255.0f, 6.0f / 255.0f, 0.0f / 255.0f, 255.0f / 255.0f);
|
||||
static ImVec4 uiHairShadeColor = ImVec4(57.0f / 255.0f, 3.0f / 255.0f, 0.0f / 255.0f, 255.0f / 255.0f);
|
||||
|
||||
static char bufname[128] = "Sample";
|
||||
|
||||
bool hasChangedFullscreen;
|
||||
int tempXRes;
|
||||
int tempYRes;
|
||||
|
||||
void setupFonts() {
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
// for (auto entry = Moon::fonts.begin(); entry != Moon::fonts.end(); entry++){
|
||||
|
@ -156,6 +181,45 @@ namespace MoonInternal {
|
|||
io.Fonts->Build();
|
||||
}
|
||||
|
||||
void apply_cc_from_editor() {
|
||||
defaultColorHatRLight = (int)(uiHatColor.x * 255);
|
||||
defaultColorHatGLight = (int)(uiHatColor.y * 255);
|
||||
defaultColorHatBLight = (int)(uiHatColor.z * 255);
|
||||
defaultColorHatRDark = (int)(uiHatShadeColor.x * 255);
|
||||
defaultColorHatGDark = (int)(uiHatShadeColor.y * 255);
|
||||
defaultColorHatBDark = (int)(uiHatShadeColor.z * 255);
|
||||
defaultColorOverallsRLight = (int)(uiOverallsColor.x * 255);
|
||||
defaultColorOverallsGLight = (int)(uiOverallsColor.y * 255);
|
||||
defaultColorOverallsBLight = (int)(uiOverallsColor.z * 255);
|
||||
defaultColorOverallsRDark = (int)(uiOverallsShadeColor.x * 255);
|
||||
defaultColorOverallsGDark = (int)(uiOverallsShadeColor.y * 255);
|
||||
defaultColorOverallsBDark = (int)(uiOverallsShadeColor.z * 255);
|
||||
defaultColorGlovesRLight = (int)(uiGlovesColor.x * 255);
|
||||
defaultColorGlovesGLight = (int)(uiGlovesColor.y * 255);
|
||||
defaultColorGlovesBLight = (int)(uiGlovesColor.z * 255);
|
||||
defaultColorGlovesRDark = (int)(uiGlovesShadeColor.x * 255);
|
||||
defaultColorGlovesGDark = (int)(uiGlovesShadeColor.y * 255);
|
||||
defaultColorGlovesBDark = (int)(uiGlovesShadeColor.z * 255);
|
||||
defaultColorShoesRLight = (int)(uiShoesColor.x * 255);
|
||||
defaultColorShoesGLight = (int)(uiShoesColor.y * 255);
|
||||
defaultColorShoesBLight = (int)(uiShoesColor.z * 255);
|
||||
defaultColorShoesRDark = (int)(uiShoesShadeColor.x * 255);
|
||||
defaultColorShoesGDark = (int)(uiShoesShadeColor.y * 255);
|
||||
defaultColorShoesBDark = (int)(uiShoesShadeColor.z * 255);
|
||||
defaultColorSkinRLight = (int)(uiSkinColor.x * 255);
|
||||
defaultColorSkinGLight = (int)(uiSkinColor.y * 255);
|
||||
defaultColorSkinBLight = (int)(uiSkinColor.z * 255);
|
||||
defaultColorSkinRDark = (int)(uiSkinShadeColor.x * 255);
|
||||
defaultColorSkinGDark = (int)(uiSkinShadeColor.y * 255);
|
||||
defaultColorSkinBDark = (int)(uiSkinShadeColor.z * 255);
|
||||
defaultColorHairRLight = (int)(uiHairColor.x * 255);
|
||||
defaultColorHairGLight = (int)(uiHairColor.y * 255);
|
||||
defaultColorHairBLight = (int)(uiHairColor.z * 255);
|
||||
defaultColorHairRDark = (int)(uiHairShadeColor.x * 255);
|
||||
defaultColorHairGDark = (int)(uiHairShadeColor.y * 255);
|
||||
defaultColorHairBDark = (int)(uiHairShadeColor.z * 255);
|
||||
}
|
||||
|
||||
void setupImGuiModule(string status) {
|
||||
MoonInternal::setupWindowHook(status);
|
||||
if(status == "PreStartup"){
|
||||
|
@ -182,6 +246,9 @@ namespace MoonInternal {
|
|||
ImGui_ImplSDL2_InitForOpenGL(window, call.baseArgs["context"]);
|
||||
ImGui_ImplOpenGL3_Init(glsl_version);
|
||||
|
||||
tempXRes = configWindow.w;
|
||||
tempYRes = configWindow.h;
|
||||
|
||||
#ifdef TARGET_SWITCH
|
||||
MoonNX::handleVirtualKeyboard("Init");
|
||||
#endif
|
||||
|
@ -227,7 +294,7 @@ namespace MoonInternal {
|
|||
|
||||
if (!ImGui::DockBuilderGetNode(dockspace_id)) {
|
||||
ImGui::DockBuilderRemoveNode(dockspace_id);
|
||||
ImGui::DockBuilderAddNode(dockspace_id, ImGuiDockNodeFlags_None);
|
||||
ImGui::DockBuilderAddNode(dockspace_id, ImGuiDockNodeFlags_NoTabBar);
|
||||
|
||||
ImGui::DockBuilderDockWindow("Game", dockspace_id);
|
||||
|
||||
|
@ -236,24 +303,39 @@ namespace MoonInternal {
|
|||
|
||||
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
|
||||
|
||||
if (ImGui::BeginMenuBar()) {
|
||||
TextureData* tmp = forceTextureLoad("mod-icons://Moon64");
|
||||
if(tmp != nullptr) {
|
||||
ImGui::SetCursorPos(ImVec2(0, 0));
|
||||
ImGui::Image((ImTextureID) tmp->texture_id, ImVec2(25.0f, 25.0f));
|
||||
//if (show_menu_bar) {
|
||||
if (ImGui::BeginMenuBar()) {
|
||||
/*
|
||||
TextureData* tmp = forceTextureLoad("mod-icons://Moon64");
|
||||
if(tmp != nullptr) {
|
||||
ImGui::SetCursorPos(ImVec2(0, 0));
|
||||
ImGui::Image((ImTextureID) tmp->texture_id, ImVec2(25.0f, 25.0f));
|
||||
ImGui::SameLine();
|
||||
}
|
||||
*/
|
||||
ImGui::Text("Saturn");
|
||||
ImGui::SameLine();
|
||||
ImGui::Separator();
|
||||
if (ImGui::BeginMenu("Tools")) {
|
||||
ImGui::MenuItem("Toggle View (F1)", NULL, &show_menu_bar);
|
||||
ImGui::MenuItem("N64 Mode", NULL, &configImGui.n64Mode);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
if (ImGui::BeginMenu("View")) {
|
||||
ImGui::MenuItem("Stats", NULL, &configImGui.moon64);
|
||||
ImGui::MenuItem("Machinima", NULL, &configImGui.s_machinima);
|
||||
ImGui::MenuItem("Quick Toggles", NULL, &configImGui.s_toggles);
|
||||
ImGui::MenuItem("CC Editor", NULL, &configImGui.s_cceditor);
|
||||
//ImGui::MenuItem("Debug Textures", NULL, &configImGui.texture_debug);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
if (ImGui::BeginMenu("Misc")) {
|
||||
ImGui::MenuItem("Settings", NULL, &configImGui.s_options);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
ImGui::Text("Moon64");
|
||||
ImGui::SameLine();
|
||||
ImGui::Separator();
|
||||
if (ImGui::BeginMenu("View")) {
|
||||
ImGui::MenuItem("Moon64", NULL, &configImGui.moon64);
|
||||
ImGui::MenuItem("Textures", NULL, &configImGui.texture_debug);
|
||||
ImGui::MenuItem("N64 Mode", NULL, &configImGui.n64Mode);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
//}
|
||||
ImGui::End();
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0,0));
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); // Set window background to red
|
||||
|
@ -264,6 +346,27 @@ namespace MoonInternal {
|
|||
ImVec2 size = ImGui::GetContentRegionAvail();
|
||||
ImVec2 pos = ImVec2(0, 0);
|
||||
|
||||
if (configWindow.fullscreen) {
|
||||
if (!hasChangedFullscreen) {
|
||||
std::cout << "fullscreen test" << std::endl;
|
||||
tempXRes = configWindow.w;
|
||||
tempYRes = configWindow.h;
|
||||
SDL_DisplayMode DM;
|
||||
SDL_GetCurrentDisplayMode(0, &DM);
|
||||
configWindow.w = DM.w;
|
||||
configWindow.h = DM.h;
|
||||
hasChangedFullscreen = true;
|
||||
}
|
||||
} else {
|
||||
if (hasChangedFullscreen) {
|
||||
std::cout << "test2 fsd" << std::endl;
|
||||
configWindow.w = tempXRes;
|
||||
configWindow.h = tempYRes;
|
||||
SDL_SetWindowSize(window, tempXRes, tempYRes);
|
||||
hasChangedFullscreen = false;
|
||||
}
|
||||
}
|
||||
|
||||
configWindow.internal_w = configImGui.n64Mode ? SM64_WIDTH : size.x;
|
||||
configWindow.internal_h = configImGui.n64Mode ? SM64_HEIGHT : size.y;
|
||||
|
||||
|
@ -278,27 +381,203 @@ namespace MoonInternal {
|
|||
ImGui::ImageRotated((ImTextureID) fbuf, pos, size, 180.0f);
|
||||
ImGui::End();
|
||||
|
||||
if (configImGui.moon64){
|
||||
if (configImGui.moon64 && show_menu_bar){
|
||||
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0));
|
||||
ImGui::Begin("Moon64 Game Stats", NULL, ImGuiWindowFlags_None);
|
||||
ImGui::Begin("Stats", NULL, ImGuiWindowFlags_None);
|
||||
|
||||
ImGui::Text("Platform: " PLATFORM " (" RAPI_NAME ")");
|
||||
ImGui::Text("Status: %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
|
||||
ImGui::Text("View: %.0fx%.0f (%.1f FPS)", configWindow.internal_w * configWindow.multiplier, configWindow.internal_h * configWindow.multiplier, ImGui::GetIO().Framerate);
|
||||
ImGui::Text("Version: " GIT_BRANCH " " GIT_HASH);
|
||||
ImGui::Text("Addons: %d\n", Moon::addons.size());
|
||||
ImGui::Text("Resolution: %.0fx%.0f\n", configWindow.internal_w * configWindow.multiplier, configWindow.internal_h * configWindow.multiplier);
|
||||
ImGui::Text("Internal Resolution:");
|
||||
|
||||
if(!configImGui.n64Mode)
|
||||
ImGui::SliderFloat("Mul", &configWindow.multiplier, 0.0f, 4.0f);
|
||||
else
|
||||
ImGui::SliderInt("Mul", &n64Mul, 1, 8);
|
||||
ImGui::End();
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
if (configImGui.s_toggles && show_menu_bar){
|
||||
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0));
|
||||
ImGui::Begin("Quick Toggles", NULL, ImGuiWindowFlags_None);
|
||||
|
||||
if (ImGui::BeginTable("quick_toggles", 1))
|
||||
{
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Checkbox("HUD", &configHUD);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Checkbox("Head Rotations", &enable_head_rotations);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Checkbox("Shadows", &enable_shadows);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Checkbox("Dust Particles", &enable_dust_particles);
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
if(configImGui.texture_debug) {
|
||||
if (configImGui.s_machinima && show_menu_bar) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0));
|
||||
ImGui::Begin("Machinima", NULL, ImGuiWindowFlags_None);
|
||||
|
||||
ImGui::Checkbox("Machinima Camera", &camera_frozen);
|
||||
if (camera_frozen == true) {
|
||||
ImGui::SliderFloat("Speed", &camera_speed, 0.0f, 0.3f);
|
||||
}
|
||||
|
||||
ImGui::Dummy(ImVec2(0, 10));
|
||||
|
||||
ImGui::Text("Body States");
|
||||
const char* eyeStates[] = { "Default", "Open", "Half", "Closed", "Left", "Right", "Up", "Down", "Dead" };
|
||||
ImGui::Combo("Eyes", ¤t_eye_state, eyeStates, IM_ARRAYSIZE(eyeStates));
|
||||
const char* handStates[] = { "Fists", "Open", "Peace", "With Cap", "With Wing Cap", "Right Open" };
|
||||
ImGui::Combo("Hands", ¤t_hand_state, handStates, IM_ARRAYSIZE(handStates));
|
||||
const char* capStates[] = { "Cap On", "Cap Off", "Wing Cap" }; // unused "wing cap off" not included
|
||||
ImGui::Combo("Cap", ¤t_cap_state, capStates, IM_ARRAYSIZE(capStates));
|
||||
|
||||
ImGui::Dummy(ImVec2(0, 10));
|
||||
|
||||
ImGui::Text("Select Color Code");
|
||||
static int current_cc_id = 0;
|
||||
string cc_name = MoonInternal::cc_array[current_cc_id].substr(0, MoonInternal::cc_array[current_cc_id].size() - 3);
|
||||
if (ImGui::BeginCombo(".gs", cc_name.c_str()))
|
||||
{
|
||||
for (int n = 0; n < MoonInternal::cc_array.size(); n++)
|
||||
{
|
||||
const bool is_selected = (current_cc_id == n);
|
||||
cc_name = MoonInternal::cc_array[n].substr(0, MoonInternal::cc_array[n].size() - 3);
|
||||
if (ImGui::Selectable(cc_name.c_str(), is_selected)) {
|
||||
current_cc_id = n;
|
||||
}
|
||||
|
||||
// Set the initial focus when opening the combo (scrolling + keyboard navigation focus)
|
||||
if (is_selected)
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
if (ImGui::Button("Load")) {
|
||||
load_cc_file(cc_array[current_cc_id]);
|
||||
|
||||
uiHatColor = ImVec4(float(defaultColorHatRLight) / 255.0f, float(defaultColorHatGLight) / 255.0f, float(defaultColorHatBLight) / 255.0f, 255.0f / 255.0f);
|
||||
uiHatShadeColor = ImVec4(float(defaultColorHatRDark) / 255.0f, float(defaultColorHatGDark) / 255.0f, float(defaultColorHatBDark) / 255.0f, 255.0f / 255.0f);
|
||||
uiOverallsColor = ImVec4(float(defaultColorOverallsRLight) / 255.0f, float(defaultColorOverallsGLight) / 255.0f, float(defaultColorOverallsBLight) / 255.0f, 255.0f / 255.0f);
|
||||
uiOverallsShadeColor = ImVec4(float(defaultColorOverallsRDark) / 255.0f, float(defaultColorOverallsGDark) / 255.0f, float(defaultColorOverallsBDark) / 255.0f, 255.0f / 255.0f);
|
||||
uiGlovesColor = ImVec4(float(defaultColorGlovesRLight) / 255.0f, float(defaultColorGlovesGLight) / 255.0f, float(defaultColorGlovesBLight) / 255.0f, 255.0f / 255.0f);
|
||||
uiGlovesShadeColor = ImVec4(float(defaultColorGlovesRDark) / 255.0f, float(defaultColorGlovesGDark) / 255.0f, float(defaultColorGlovesBDark) / 255.0f, 255.0f / 255.0f);
|
||||
uiShoesColor = ImVec4(float(defaultColorShoesRLight) / 255.0f, float(defaultColorShoesGLight) / 255.0f, float(defaultColorShoesBLight) / 255.0f, 255.0f / 255.0f);
|
||||
uiShoesShadeColor = ImVec4(float(defaultColorShoesRDark) / 255.0f, float(defaultColorShoesGDark) / 255.0f, float(defaultColorShoesBDark) / 255.0f, 255.0f / 255.0f);
|
||||
uiSkinColor = ImVec4(float(defaultColorSkinRLight) / 255.0f, float(defaultColorSkinGLight) / 255.0f, float(defaultColorSkinBLight) / 255.0f, 255.0f / 255.0f);
|
||||
uiSkinShadeColor = ImVec4(float(defaultColorSkinRDark) / 255.0f, float(defaultColorSkinGDark) / 255.0f, float(defaultColorSkinBDark) / 255.0f, 255.0f / 255.0f);
|
||||
uiHairColor = ImVec4(float(defaultColorHairRLight) / 255.0f, float(defaultColorHairGLight) / 255.0f, float(defaultColorHairBLight) / 255.0f, 255.0f / 255.0f);
|
||||
uiHairShadeColor = ImVec4(float(defaultColorHairRDark) / 255.0f, float(defaultColorHairGDark) / 255.0f, float(defaultColorHairBDark) / 255.0f, 255.0f / 255.0f);
|
||||
|
||||
// We never want to use the name "Mario" when saving/loading a CC, as it will cause file issues.
|
||||
if (cc_name == "Mario") {
|
||||
strcpy(bufname, "Sample");
|
||||
} else {
|
||||
strcpy(bufname, cc_name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
if (configImGui.s_cceditor && show_menu_bar) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0));
|
||||
ImGui::Begin("CC Editor", NULL, ImGuiWindowFlags_None);
|
||||
|
||||
ImGui::Text("Shirt/Cap");
|
||||
ImGui::ColorEdit4("Hat Main", (float*)&uiHatColor, ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_NoLabel);
|
||||
ImGui::ColorEdit4("Hat Shade", (float*)&uiHatShadeColor, ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_NoLabel);
|
||||
ImGui::Text("Overalls");
|
||||
ImGui::ColorEdit4("Overalls Main", (float*)&uiOverallsColor, ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_NoLabel);
|
||||
ImGui::ColorEdit4("Overalls Shade", (float*)&uiOverallsShadeColor, ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_NoLabel);
|
||||
ImGui::Text("Gloves");
|
||||
ImGui::ColorEdit4("Gloves Main", (float*)&uiGlovesColor, ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_NoLabel);
|
||||
ImGui::ColorEdit4("Gloves Shade", (float*)&uiGlovesShadeColor, ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_NoLabel);
|
||||
ImGui::Text("Shoes");
|
||||
ImGui::ColorEdit4("Shoes Main", (float*)&uiShoesColor, ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_NoLabel);
|
||||
ImGui::ColorEdit4("Shoes Shade", (float*)&uiShoesShadeColor, ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_NoLabel);
|
||||
ImGui::Text("Skin");
|
||||
ImGui::ColorEdit4("Skin Main", (float*)&uiSkinColor, ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_NoLabel);
|
||||
ImGui::ColorEdit4("Skin Shade", (float*)&uiSkinShadeColor, ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_NoLabel);
|
||||
ImGui::Text("Hair");
|
||||
ImGui::ColorEdit4("Hair Main", (float*)&uiHairColor, ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_NoLabel);
|
||||
ImGui::ColorEdit4("Hair Shade", (float*)&uiHairShadeColor, ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_NoLabel);
|
||||
|
||||
ImGui::Dummy(ImVec2(0, 5));
|
||||
|
||||
if (ImGui::Button("Load")) {
|
||||
apply_cc_from_editor();
|
||||
}
|
||||
|
||||
ImGui::Dummy(ImVec2(0, 5));
|
||||
|
||||
ImGui::InputText(".gs", bufname, IM_ARRAYSIZE(bufname));
|
||||
if (ImGui::Button("Save")) {
|
||||
apply_cc_from_editor();
|
||||
|
||||
std::string cc_name = bufname;
|
||||
// We don't want to save a CC named "Mario", as it may cause file issues.
|
||||
if (cc_name != "Mario") {
|
||||
save_cc_file(cc_name);
|
||||
} else {
|
||||
strcpy(bufname, "Sample");
|
||||
save_cc_file("Sample");
|
||||
}
|
||||
|
||||
load_cc_directory();
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
//ImGui::ShowDemoWindow();
|
||||
|
||||
if (configImGui.s_options && show_menu_bar) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0));
|
||||
ImGui::Begin("Settings", NULL, ImGuiWindowFlags_None);
|
||||
|
||||
if (ImGui::CollapsingHeader("Graphics")) {
|
||||
if (ImGui::Button("Toggle Fullscreen")) {
|
||||
configWindow.fullscreen = !configWindow.fullscreen;
|
||||
configWindow.settings_changed = true;
|
||||
}
|
||||
if (!configWindow.fullscreen) {
|
||||
if (ImGui::Button("Reset Window Size")) {
|
||||
configWindow.w = 1280;
|
||||
configWindow.h = 768; // 720 + 48 for the top bar
|
||||
SDL_SetWindowSize(window, 1280, 768);
|
||||
}
|
||||
}
|
||||
ImGui::Checkbox("VSync", &configWindow.vsync);
|
||||
ImGui::Text("Graphics Quality");
|
||||
const char* lod_modes[] = { "Auto", "Low", "High" };
|
||||
ImGui::Combo("###lod_modes", (int*)&configLODMode, lod_modes, IM_ARRAYSIZE(lod_modes));
|
||||
ImGui::Text("Texture Filtering");
|
||||
const char* texture_filters[] = { "Nearest", "Linear", "Three-point" };
|
||||
ImGui::Combo("###texture_filters", (int*)&configFiltering, texture_filters, IM_ARRAYSIZE(texture_filters));
|
||||
}
|
||||
if (ImGui::CollapsingHeader("Audio")) {
|
||||
ImGui::Text("Volume");
|
||||
ImGui::SliderInt("Master", (int*)&configMasterVolume, 0, MAX_VOLUME);
|
||||
ImGui::SliderInt("SFX", (int*)&configSfxVolume, 0, MAX_VOLUME);
|
||||
ImGui::SliderInt("Music", (int*)&configMusicVolume, 0, MAX_VOLUME);
|
||||
ImGui::SliderInt("Environment", (int*)&configEnvVolume, 0, MAX_VOLUME);
|
||||
}
|
||||
if (ImGui::CollapsingHeader("Gameplay")) {
|
||||
ImGui::Text("Rumble Strength");
|
||||
ImGui::SliderInt("###rumble_strength", (int*)&configRumbleStrength, 0, 50);
|
||||
ImGui::Checkbox("Skip Intro", &configSkipIntro);
|
||||
#ifdef DISCORDRPC
|
||||
ImGui::Checkbox("Discord Activity Status", &configDiscordRPC);
|
||||
#endif
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
if(configImGui.texture_debug && show_menu_bar) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0));
|
||||
ImGui::Begin("Loaded textures", NULL, ImGuiWindowFlags_None);
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "moon/utils/moon-env.h"
|
||||
#include "moon/mod-engine/engine.h"
|
||||
#include "moon/mod-engine/test.h"
|
||||
#include "moon/saturn/saturn.h"
|
||||
#include "moon/io/moon-io.h"
|
||||
|
||||
#include "moon/imgui/imgui_impl.h"
|
||||
|
@ -28,6 +29,7 @@ void moon_setup(char *state){
|
|||
MoonInternal::setupImGuiModule(string(state));
|
||||
// MoonRenderer::setupSkyboxRenderer(string(state));
|
||||
// MoonInternal::setupSoundModule(string(state));
|
||||
MoonInternal::setupSaturnModule(string(state));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
#include "saturn.h"
|
||||
#include "moon/mod-engine/hooks/hook.h"
|
||||
|
||||
#include "moon/utils/moon-env.h"
|
||||
#include "moon/fs/moonfs.h"
|
||||
#include "pc/configfile.h"
|
||||
|
||||
#include "saturn_colors.h"
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
#include <dirent.h>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
extern "C" {
|
||||
#include "game/camera.h"
|
||||
#include "game/level_update.h"
|
||||
#include "game/mario.h"
|
||||
#include "sm64.h"
|
||||
}
|
||||
|
||||
bool camera_frozen;
|
||||
bool enable_head_rotations;
|
||||
bool enable_shadows;
|
||||
bool enable_dust_particles;
|
||||
|
||||
bool show_menu_bar;
|
||||
|
||||
float camera_speed = 0.0f;
|
||||
|
||||
namespace MoonInternal {
|
||||
|
||||
// Machinima
|
||||
|
||||
void freeze_camera() {
|
||||
camera_frozen = !camera_frozen;
|
||||
//camVelSpeed = 1.0f;
|
||||
}
|
||||
void cycle_eye_state(int cycle) {
|
||||
current_eye_state += cycle;
|
||||
}
|
||||
|
||||
// Setup Module
|
||||
|
||||
void setupSaturnModule(string status){
|
||||
if(status == "PreStartup"){
|
||||
|
||||
Moon::registerHookListener({.hookName = WINDOW_API_INIT, .callback = [&](HookCall call){
|
||||
camera_frozen = false;
|
||||
enable_shadows = true;
|
||||
current_eye_state = 0;
|
||||
|
||||
show_menu_bar = false;
|
||||
|
||||
MoonInternal::load_cc_directory();
|
||||
}});
|
||||
|
||||
Moon::registerHookListener({.hookName = WINDOW_API_HANDLE_EVENTS, .callback = [&](HookCall call){
|
||||
SDL_Event* ev = (SDL_Event*) call.baseArgs["event"];
|
||||
switch (ev->type){
|
||||
case SDL_KEYDOWN:
|
||||
if(ev->key.keysym.sym == SDLK_f){
|
||||
freeze_camera();
|
||||
}
|
||||
if(ev->key.keysym.sym == SDLK_x){
|
||||
cycle_eye_state(1);
|
||||
}
|
||||
if(ev->key.keysym.sym == SDLK_z){
|
||||
cycle_eye_state(-1);
|
||||
}
|
||||
if(ev->key.keysym.sym == SDLK_F1){
|
||||
show_menu_bar = !show_menu_bar;
|
||||
}
|
||||
case SDL_CONTROLLERBUTTONDOWN:
|
||||
if (ev->cbutton.button == SDL_CONTROLLER_BUTTON_DPAD_UP) {
|
||||
freeze_camera();
|
||||
}
|
||||
if (ev->cbutton.button == SDL_CONTROLLER_BUTTON_DPAD_RIGHT) {
|
||||
cycle_eye_state(1);
|
||||
}
|
||||
if (ev->cbutton.button == SDL_CONTROLLER_BUTTON_DPAD_LEFT) {
|
||||
cycle_eye_state(-1);
|
||||
}
|
||||
if(ev->cbutton.button == SDL_CONTROLLER_BUTTON_BACK){
|
||||
show_menu_bar = !show_menu_bar;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}});
|
||||
|
||||
Moon::registerHookListener({.hookName = GFX_PRE_START_FRAME, .callback = [&](HookCall call){
|
||||
// Machinima Camera
|
||||
|
||||
if (camera_frozen == true) {
|
||||
if (set_cam_angle(0) != CAM_ANGLE_MARIO) {
|
||||
gLakituState.focVSpeed = camera_speed;
|
||||
gLakituState.focHSpeed = camera_speed;
|
||||
}
|
||||
gLakituState.posVSpeed = camera_speed;
|
||||
gLakituState.posHSpeed = camera_speed;
|
||||
gCamera->nextYaw = calculate_yaw(gLakituState.focus, gLakituState.pos);
|
||||
gCamera->yaw = gCamera->nextYaw;
|
||||
gCameraMovementFlags &= ~CAM_MOVE_FIX_IN_PLACE;
|
||||
}
|
||||
|
||||
// Body States
|
||||
|
||||
if (current_cap_state >= 3) {
|
||||
current_cap_state = 0;
|
||||
}
|
||||
|
||||
if (current_eye_state >= 9) {
|
||||
current_eye_state = 0;
|
||||
} else if (current_eye_state <= -1) {
|
||||
current_eye_state = 8;
|
||||
}
|
||||
|
||||
if (current_hand_state >= 6) {
|
||||
current_hand_state = 0;
|
||||
}
|
||||
}});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef MoonSaturnEngine
|
||||
#define MoonSaturnEngine
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace MoonInternal {
|
||||
void setupSaturnModule(std::string status);
|
||||
void freeze_camera();
|
||||
}
|
||||
|
||||
extern bool camera_frozen;
|
||||
#include "saturn_types.h"
|
||||
|
||||
extern bool show_menu_bar;
|
||||
|
||||
extern float camera_speed;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,343 @@
|
|||
#include "saturn_colors.h"
|
||||
#include "saturn.h"
|
||||
#include "moon/mod-engine/hooks/hook.h"
|
||||
|
||||
#include "moon/utils/moon-env.h"
|
||||
#include "moon/fs/moonfs.h"
|
||||
#include "pc/configfile.h"
|
||||
#include "moon/imgui/imgui_impl.h"
|
||||
#include "moon/libs/imgui/imgui.h"
|
||||
#include "moon/libs/imgui/imgui_internal.h"
|
||||
#include "moon/libs/imgui/imgui_impl_sdl.h"
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
#include <dirent.h>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
extern "C" {
|
||||
#include "game/camera.h"
|
||||
#include "game/level_update.h"
|
||||
#include "sm64.h"
|
||||
}
|
||||
|
||||
unsigned int defaultColorHatRLight = 255;
|
||||
unsigned int defaultColorHatRDark = 127;
|
||||
unsigned int defaultColorHatGLight = 0;
|
||||
unsigned int defaultColorHatGDark = 0;
|
||||
unsigned int defaultColorHatBLight = 0;
|
||||
unsigned int defaultColorHatBDark = 0;
|
||||
|
||||
unsigned int defaultColorOverallsRLight = 0;
|
||||
unsigned int defaultColorOverallsRDark = 0;
|
||||
unsigned int defaultColorOverallsGLight = 0;
|
||||
unsigned int defaultColorOverallsGDark = 0;
|
||||
unsigned int defaultColorOverallsBLight = 255;
|
||||
unsigned int defaultColorOverallsBDark = 127;
|
||||
|
||||
unsigned int defaultColorGlovesRLight = 255;
|
||||
unsigned int defaultColorGlovesRDark = 127;
|
||||
unsigned int defaultColorGlovesGLight = 255;
|
||||
unsigned int defaultColorGlovesGDark = 127;
|
||||
unsigned int defaultColorGlovesBLight = 255;
|
||||
unsigned int defaultColorGlovesBDark = 127;
|
||||
|
||||
unsigned int defaultColorShoesRLight = 114;
|
||||
unsigned int defaultColorShoesRDark = 57;
|
||||
unsigned int defaultColorShoesGLight = 28;
|
||||
unsigned int defaultColorShoesGDark = 14;
|
||||
unsigned int defaultColorShoesBLight = 14;
|
||||
unsigned int defaultColorShoesBDark = 7;
|
||||
|
||||
unsigned int defaultColorSkinRLight = 254;
|
||||
unsigned int defaultColorSkinRDark = 127;
|
||||
unsigned int defaultColorSkinGLight = 193;
|
||||
unsigned int defaultColorSkinGDark = 96;
|
||||
unsigned int defaultColorSkinBLight = 121;
|
||||
unsigned int defaultColorSkinBDark = 60;
|
||||
|
||||
unsigned int defaultColorHairRLight = 115;
|
||||
unsigned int defaultColorHairRDark = 57;
|
||||
unsigned int defaultColorHairGLight = 6;
|
||||
unsigned int defaultColorHairGDark = 3;
|
||||
unsigned int defaultColorHairBLight = 0;
|
||||
unsigned int defaultColorHairBDark = 0;
|
||||
|
||||
// Color Codes
|
||||
|
||||
namespace MoonInternal {
|
||||
|
||||
std::vector<string> cc_array;
|
||||
string colorCodeDir;
|
||||
|
||||
void load_cc_directory() {
|
||||
cc_array.clear();
|
||||
cc_array.push_back("Mario.gs");
|
||||
|
||||
string cwd = MoonInternal::getEnvironmentVar("MOON_CWD");
|
||||
#ifdef __MINGW32__
|
||||
// Windows moment
|
||||
colorCodeDir = cwd.substr(0, cwd.find_last_of("/\\")) + "\\machinima\\colorcodes\\";
|
||||
#else
|
||||
colorCodeDir = cwd.substr(0, cwd.find_last_of("/\\")) + "/machinima/colorcodes/";
|
||||
#endif
|
||||
|
||||
for (const auto & entry : fs::directory_iterator(colorCodeDir))
|
||||
cc_array.push_back(entry.path().filename().u8string());
|
||||
|
||||
//std::cout << cc_array[0] << std::endl;
|
||||
}
|
||||
|
||||
void reset_cc_colors() {
|
||||
defaultColorHatRLight = 255;
|
||||
defaultColorHatRDark = 127;
|
||||
defaultColorHatGLight = 0;
|
||||
defaultColorHatGDark = 0;
|
||||
defaultColorHatBLight = 0;
|
||||
defaultColorHatBDark = 0;
|
||||
|
||||
defaultColorOverallsRLight = 0;
|
||||
defaultColorOverallsRDark = 0;
|
||||
defaultColorOverallsGLight = 0;
|
||||
defaultColorOverallsGDark = 0;
|
||||
defaultColorOverallsBLight = 255;
|
||||
defaultColorOverallsBDark = 127;
|
||||
|
||||
defaultColorGlovesRLight = 255;
|
||||
defaultColorGlovesRDark = 127;
|
||||
defaultColorGlovesGLight = 255;
|
||||
defaultColorGlovesGDark = 127;
|
||||
defaultColorGlovesBLight = 255;
|
||||
defaultColorGlovesBDark = 127;
|
||||
|
||||
defaultColorShoesRLight = 114;
|
||||
defaultColorShoesRDark = 57;
|
||||
defaultColorShoesGLight = 28;
|
||||
defaultColorShoesGDark = 14;
|
||||
defaultColorShoesBLight = 14;
|
||||
defaultColorShoesBDark = 7;
|
||||
|
||||
defaultColorSkinRLight = 254;
|
||||
defaultColorSkinRDark = 127;
|
||||
defaultColorSkinGLight = 193;
|
||||
defaultColorSkinGDark = 96;
|
||||
defaultColorSkinBLight = 121;
|
||||
defaultColorSkinBDark = 60;
|
||||
|
||||
defaultColorHairRLight = 115;
|
||||
defaultColorHairRDark = 57;
|
||||
defaultColorHairGLight = 6;
|
||||
defaultColorHairGDark = 3;
|
||||
defaultColorHairBLight = 0;
|
||||
defaultColorHairBDark = 0;
|
||||
}
|
||||
|
||||
void load_cc_file(string cc_filename) {
|
||||
if (cc_filename == "Mario.gs") {
|
||||
reset_cc_colors();
|
||||
return;
|
||||
}
|
||||
|
||||
std::ifstream file(colorCodeDir + cc_filename, std::ios::in | std::ios::binary);
|
||||
|
||||
// If the color code was previously deleted, reload the list and cancel.
|
||||
if (!file.good()) {
|
||||
load_cc_directory();
|
||||
return;
|
||||
}
|
||||
|
||||
const std::size_t& size = std::filesystem::file_size(colorCodeDir + cc_filename);
|
||||
std::string content(size, '\0');
|
||||
file.read(content.data(), size);
|
||||
|
||||
file.close();
|
||||
|
||||
std::istringstream f(content);
|
||||
std::string line;
|
||||
|
||||
while (std::getline(f, line)) {
|
||||
std::string address = line.substr(2, 6);
|
||||
int value1 = std::stoi(line.substr(9, 2), 0, 16);
|
||||
int value2 = std::stoi(line.substr(11, 2), 0, 16);
|
||||
|
||||
// Hat
|
||||
if (address == "07EC40") {
|
||||
defaultColorHatRLight = value1;
|
||||
defaultColorHatGLight = value2;
|
||||
}
|
||||
if (address == "07EC42") {
|
||||
defaultColorHatBLight = value1;
|
||||
}
|
||||
if (address == "07EC38") {
|
||||
defaultColorHatRDark = value1;
|
||||
defaultColorHatGDark = value2;
|
||||
}
|
||||
if (address == "07EC3A") {
|
||||
defaultColorHatBDark = value1;
|
||||
}
|
||||
|
||||
// Overalls
|
||||
if (address == "07EC28") {
|
||||
defaultColorOverallsRLight = value1;
|
||||
defaultColorOverallsGLight = value2;
|
||||
}
|
||||
if (address == "07EC2A") {
|
||||
defaultColorOverallsBLight = value1;
|
||||
}
|
||||
if (address == "07EC20") {
|
||||
defaultColorOverallsRDark = value1;
|
||||
defaultColorOverallsGDark = value2;
|
||||
}
|
||||
if (address == "07EC22") {
|
||||
defaultColorOverallsBDark = value1;
|
||||
}
|
||||
|
||||
// Gloves
|
||||
if (address == "07EC58") {
|
||||
defaultColorGlovesRLight = value1;
|
||||
defaultColorGlovesGLight = value2;
|
||||
}
|
||||
if (address == "07EC5A") {
|
||||
defaultColorGlovesBLight = value1;
|
||||
}
|
||||
if (address == "07EC50") {
|
||||
defaultColorGlovesRDark = value1;
|
||||
defaultColorGlovesGDark = value2;
|
||||
}
|
||||
if (address == "07EC52") {
|
||||
defaultColorGlovesBDark = value1;
|
||||
}
|
||||
|
||||
// Shoes
|
||||
if (address == "07EC70") {
|
||||
defaultColorShoesRLight = value1;
|
||||
defaultColorShoesGLight = value2;
|
||||
}
|
||||
if (address == "07EC72") {
|
||||
defaultColorShoesBLight = value1;
|
||||
}
|
||||
if (address == "07EC68") {
|
||||
defaultColorShoesRDark = value1;
|
||||
defaultColorShoesGDark = value2;
|
||||
}
|
||||
if (address == "07EC6A") {
|
||||
defaultColorShoesBDark = value1;
|
||||
}
|
||||
|
||||
// Skin
|
||||
if (address == "07EC88") {
|
||||
defaultColorSkinRLight = value1;
|
||||
defaultColorSkinGLight = value2;
|
||||
}
|
||||
if (address == "07EC8A") {
|
||||
defaultColorSkinBLight = value1;
|
||||
}
|
||||
if (address == "07EC80") {
|
||||
defaultColorSkinRDark = value1;
|
||||
defaultColorSkinGDark = value2;
|
||||
}
|
||||
if (address == "07EC82") {
|
||||
defaultColorSkinBDark = value1;
|
||||
}
|
||||
|
||||
// Hair
|
||||
if (address == "07ECA0") {
|
||||
defaultColorHairRLight = value1;
|
||||
defaultColorHairGLight = value2;
|
||||
}
|
||||
if (address == "07ECA2") {
|
||||
defaultColorHairBLight = value1;
|
||||
}
|
||||
if (address == "07EC98") {
|
||||
defaultColorHairRDark = value1;
|
||||
defaultColorHairGDark = value2;
|
||||
}
|
||||
if (address == "07EC9A") {
|
||||
defaultColorHairBDark = value1;
|
||||
}
|
||||
|
||||
//std::cout << address << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void save_cc_file(std::string name) {
|
||||
std::string gameshark;
|
||||
|
||||
char col1char[64];
|
||||
ImFormatString(col1char, IM_ARRAYSIZE(col1char), "%02X%02X%02X", ImClamp((int)defaultColorHatRLight, 0, 255), ImClamp((int)defaultColorHatGLight, 0, 255), ImClamp((int)defaultColorHatBLight, 0, 255));
|
||||
std::string col1 = col1char;
|
||||
char col2char[64];
|
||||
ImFormatString(col2char, IM_ARRAYSIZE(col2char), "%02X%02X%02X", ImClamp((int)defaultColorHatRDark, 0, 255), ImClamp((int)defaultColorHatGDark, 0, 255), ImClamp((int)defaultColorHatBDark, 0, 255));
|
||||
std::string col2 = col2char;
|
||||
char col3char[64];
|
||||
ImFormatString(col3char, IM_ARRAYSIZE(col3char), "%02X%02X%02X", ImClamp((int)defaultColorOverallsRLight, 0, 255), ImClamp((int)defaultColorOverallsGLight, 0, 255), ImClamp((int)defaultColorOverallsBLight, 0, 255));
|
||||
std::string col3 = col3char;
|
||||
char col4char[64];
|
||||
ImFormatString(col4char, IM_ARRAYSIZE(col4char), "%02X%02X%02X", ImClamp((int)defaultColorOverallsRDark, 0, 255), ImClamp((int)defaultColorOverallsGDark, 0, 255), ImClamp((int)defaultColorOverallsBDark, 0, 255));
|
||||
std::string col4 = col4char;
|
||||
char col5char[64];
|
||||
ImFormatString(col5char, IM_ARRAYSIZE(col5char), "%02X%02X%02X", ImClamp((int)defaultColorGlovesRLight, 0, 255), ImClamp((int)defaultColorGlovesGLight, 0, 255), ImClamp((int)defaultColorGlovesBLight, 0, 255));
|
||||
std::string col5 = col5char;
|
||||
char col6char[64];
|
||||
ImFormatString(col6char, IM_ARRAYSIZE(col6char), "%02X%02X%02X", ImClamp((int)defaultColorGlovesRDark, 0, 255), ImClamp((int)defaultColorGlovesGDark, 0, 255), ImClamp((int)defaultColorGlovesBDark, 0, 255));
|
||||
std::string col6 = col6char;
|
||||
char col7char[64];
|
||||
ImFormatString(col7char, IM_ARRAYSIZE(col7char), "%02X%02X%02X", ImClamp((int)defaultColorShoesRLight, 0, 255), ImClamp((int)defaultColorShoesGLight, 0, 255), ImClamp((int)defaultColorShoesBLight, 0, 255));
|
||||
std::string col7 = col7char;
|
||||
char col8char[64];
|
||||
ImFormatString(col8char, IM_ARRAYSIZE(col8char), "%02X%02X%02X", ImClamp((int)defaultColorShoesRDark, 0, 255), ImClamp((int)defaultColorShoesGDark, 0, 255), ImClamp((int)defaultColorShoesBDark, 0, 255));
|
||||
std::string col8 = col8char;
|
||||
char col9char[64];
|
||||
ImFormatString(col9char, IM_ARRAYSIZE(col9char), "%02X%02X%02X", ImClamp((int)defaultColorSkinRLight, 0, 255), ImClamp((int)defaultColorSkinGLight, 0, 255), ImClamp((int)defaultColorSkinBLight, 0, 255));
|
||||
std::string col9 = col9char;
|
||||
char col10char[64];
|
||||
ImFormatString(col10char, IM_ARRAYSIZE(col10char), "%02X%02X%02X", ImClamp((int)defaultColorSkinRDark, 0, 255), ImClamp((int)defaultColorSkinGDark, 0, 255), ImClamp((int)defaultColorSkinBDark, 0, 255));
|
||||
std::string col10 = col10char;
|
||||
char col11char[64];
|
||||
ImFormatString(col11char, IM_ARRAYSIZE(col11char), "%02X%02X%02X", ImClamp((int)defaultColorHairRLight, 0, 255), ImClamp((int)defaultColorHairGLight, 0, 255), ImClamp((int)defaultColorHairBLight, 0, 255));
|
||||
std::string col11 = col11char;
|
||||
char col12char[64];
|
||||
ImFormatString(col12char, IM_ARRAYSIZE(col12char), "%02X%02X%02X", ImClamp((int)defaultColorHairRDark, 0, 255), ImClamp((int)defaultColorHairGDark, 0, 255), ImClamp((int)defaultColorHairBDark, 0, 255));
|
||||
std::string col12 = col12char;
|
||||
|
||||
gameshark += "8107EC40 " + col1.substr(0, 2) + col1.substr(2, 2) + "\n";
|
||||
gameshark += "8107EC42 " + col1.substr(4, 2) + "00\n";
|
||||
gameshark += "8107EC38 " + col2.substr(0, 2) + col2.substr(2, 2) + "\n";
|
||||
gameshark += "8107EC3A " + col2.substr(4, 2) + "00\n";
|
||||
gameshark += "8107EC28 " + col3.substr(0, 2) + col3.substr(2, 2) + "\n";
|
||||
gameshark += "8107EC2A " + col3.substr(4, 2) + "00\n";
|
||||
gameshark += "8107EC20 " + col4.substr(0, 2) + col4.substr(2, 2) + "\n";
|
||||
gameshark += "8107EC22 " + col4.substr(4, 2) + "00\n";
|
||||
gameshark += "8107EC58 " + col5.substr(0, 2) + col5.substr(2, 2) + "\n";
|
||||
gameshark += "8107EC5A " + col5.substr(4, 2) + "00\n";
|
||||
gameshark += "8107EC50 " + col6.substr(0, 2) + col6.substr(2, 2) + "\n";
|
||||
gameshark += "8107EC52 " + col6.substr(4, 2) + "00\n";
|
||||
gameshark += "8107EC70 " + col7.substr(0, 2) + col7.substr(2, 2) + "\n";
|
||||
gameshark += "8107EC72 " + col7.substr(4, 2) + "00\n";
|
||||
gameshark += "8107EC68 " + col8.substr(0, 2) + col8.substr(2, 2) + "\n";
|
||||
gameshark += "8107EC6A " + col8.substr(4, 2) + "00\n";
|
||||
gameshark += "8107EC88 " + col9.substr(0, 2) + col9.substr(2, 2) + "\n";
|
||||
gameshark += "8107EC8A " + col9.substr(4, 2) + "00\n";
|
||||
gameshark += "8107EC80 " + col10.substr(0, 2) + col10.substr(2, 2) + "\n";
|
||||
gameshark += "8107EC82 " + col10.substr(4, 2) + "00\n";
|
||||
gameshark += "8107ECA0 " + col11.substr(0, 2) + col11.substr(2, 2) + "\n";
|
||||
gameshark += "8107ECA2 " + col11.substr(4, 2) + "00\n";
|
||||
gameshark += "8107EC98 " + col12.substr(0, 2) + col12.substr(2, 2) + "\n";
|
||||
gameshark += "8107EC9A " + col12.substr(4, 2) + "00";
|
||||
|
||||
//std::cout << gameshark << std::endl;
|
||||
|
||||
#ifdef __MINGW32__
|
||||
std::ofstream file("machinima\\colorcodes\\" + name + ".gs");
|
||||
#else
|
||||
std::ofstream file("machinima/colorcodes/" + name + ".gs");
|
||||
#endif
|
||||
file << gameshark;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef SaturnColors
|
||||
#define SaturnColors
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace MoonInternal {
|
||||
extern std::vector<std::string> cc_array;
|
||||
void load_cc_directory(void);
|
||||
void load_cc_file(std::string cc_path);
|
||||
void save_cc_file(std::string name);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,54 @@
|
|||
#ifndef MoonSaturnTypes
|
||||
#define MoonSaturnTypes
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
extern bool enable_head_rotations;
|
||||
extern bool enable_shadows;
|
||||
extern bool enable_dust_particles;
|
||||
|
||||
// Color Codes
|
||||
|
||||
extern unsigned int defaultColorHatRLight;
|
||||
extern unsigned int defaultColorHatRDark;
|
||||
extern unsigned int defaultColorHatGLight;
|
||||
extern unsigned int defaultColorHatGDark;
|
||||
extern unsigned int defaultColorHatBLight;
|
||||
extern unsigned int defaultColorHatBDark;
|
||||
|
||||
extern unsigned int defaultColorOverallsRLight;
|
||||
extern unsigned int defaultColorOverallsRDark;
|
||||
extern unsigned int defaultColorOverallsGLight;
|
||||
extern unsigned int defaultColorOverallsGDark;
|
||||
extern unsigned int defaultColorOverallsBLight;
|
||||
extern unsigned int defaultColorOverallsBDark;
|
||||
|
||||
extern unsigned int defaultColorGlovesRLight;
|
||||
extern unsigned int defaultColorGlovesRDark;
|
||||
extern unsigned int defaultColorGlovesGLight;
|
||||
extern unsigned int defaultColorGlovesGDark;
|
||||
extern unsigned int defaultColorGlovesBLight;
|
||||
extern unsigned int defaultColorGlovesBDark;
|
||||
|
||||
extern unsigned int defaultColorShoesRLight;
|
||||
extern unsigned int defaultColorShoesRDark;
|
||||
extern unsigned int defaultColorShoesGLight;
|
||||
extern unsigned int defaultColorShoesGDark;
|
||||
extern unsigned int defaultColorShoesBLight;
|
||||
extern unsigned int defaultColorShoesBDark;
|
||||
|
||||
extern unsigned int defaultColorSkinRLight;
|
||||
extern unsigned int defaultColorSkinRDark;
|
||||
extern unsigned int defaultColorSkinGLight;
|
||||
extern unsigned int defaultColorSkinGDark;
|
||||
extern unsigned int defaultColorSkinBLight;
|
||||
extern unsigned int defaultColorSkinBDark;
|
||||
|
||||
extern unsigned int defaultColorHairRLight;
|
||||
extern unsigned int defaultColorHairRDark;
|
||||
extern unsigned int defaultColorHairGLight;
|
||||
extern unsigned int defaultColorHairGDark;
|
||||
extern unsigned int defaultColorHairBLight;
|
||||
extern unsigned int defaultColorHairBDark;
|
||||
|
||||
#endif
|
|
@ -54,11 +54,13 @@ void MoonChangeUI(int index){
|
|||
}
|
||||
|
||||
void MoonHandleToggle(){
|
||||
/*
|
||||
if(gPlayer1Controller->buttonPressed & toggle){
|
||||
currentScreen = 0;
|
||||
isOpen = !isOpen;
|
||||
MoonUpdateStatus();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void MoonUpdateStatus() {
|
||||
|
|
|
@ -153,7 +153,7 @@ extern "C" {
|
|||
basePath.append(stickAnim ? "stick-down.rgba16" : "stick-up.rgba16");
|
||||
MoonDrawButton(5, GetScreenHeight() - 24, "Move", basePath, 16, 0, false, false);
|
||||
|
||||
MoonDrawButton(7, GetScreenHeight() - 24, "Open settings", "textures/moon/controller/r-btn.rgba16", 10, 4, true, false);
|
||||
//MoonDrawButton(7, GetScreenHeight() - 24, "Open settings", "textures/moon/controller/r-btn.rgba16", 10, 4, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -58,6 +58,10 @@ ConfigWindow configWindow = {
|
|||
ImGuiConfig configImGui = {
|
||||
.moon64 = false,
|
||||
.texture_debug = false,
|
||||
.s_toggles = false,
|
||||
.s_machinima = false,
|
||||
.s_cceditor = false,
|
||||
.s_options = false,
|
||||
.n64Mode = false
|
||||
};
|
||||
|
||||
|
@ -71,7 +75,7 @@ bool configPrecacheRes = true;
|
|||
|
||||
unsigned int configFiltering = 1; // 0=force nearest, 1=linear, (TODO) 2=three-point
|
||||
unsigned int configMasterVolume = MAX_VOLUME; // 0 - MAX_VOLUME
|
||||
unsigned int configMusicVolume = MAX_VOLUME;
|
||||
unsigned int configMusicVolume = 0;
|
||||
unsigned int configSfxVolume = MAX_VOLUME;
|
||||
unsigned int configEnvVolume = MAX_VOLUME;
|
||||
|
||||
|
@ -105,8 +109,8 @@ bool configEnableCamera = false;
|
|||
bool configCameraAnalog = true;
|
||||
bool configCameraMouse = false;
|
||||
#endif
|
||||
bool configSkipIntro = 0;
|
||||
bool configHUD = true;
|
||||
bool configSkipIntro = 1;
|
||||
bool configHUD = false;
|
||||
#ifdef DISCORDRPC
|
||||
bool configDiscordRPC = true;
|
||||
#endif
|
||||
|
@ -117,7 +121,7 @@ bool configDiscordRPC = true;
|
|||
################################
|
||||
*/
|
||||
|
||||
unsigned int configLODMode = 0;
|
||||
unsigned int configLODMode = 2;
|
||||
|
||||
static const struct ConfigOption options[] = {
|
||||
{.name = "fullscreen", .type = CONFIG_TYPE_BOOL, .boolValue = &configWindow.fullscreen},
|
||||
|
@ -177,6 +181,10 @@ static const struct ConfigOption options[] = {
|
|||
|
||||
{.name = "moon64_win", .type = CONFIG_TYPE_BOOL, .boolValue = &configImGui.moon64},
|
||||
{.name = "texture_debug_win", .type = CONFIG_TYPE_BOOL, .boolValue = &configImGui.texture_debug},
|
||||
{.name = "s_toggles_win", .type = CONFIG_TYPE_BOOL, .boolValue = &configImGui.s_toggles},
|
||||
{.name = "s_machinima", .type = CONFIG_TYPE_BOOL, .boolValue = &configImGui.s_machinima},
|
||||
{.name = "s_cceditor_win", .type = CONFIG_TYPE_BOOL, .boolValue = &configImGui.s_cceditor},
|
||||
{.name = "s_options_win", .type = CONFIG_TYPE_BOOL, .boolValue = &configImGui.s_options},
|
||||
{.name = "n64Mode", .type = CONFIG_TYPE_BOOL, .boolValue = &configImGui.n64Mode}
|
||||
};
|
||||
|
||||
|
|
|
@ -23,6 +23,10 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
bool moon64;
|
||||
bool s_toggles;
|
||||
bool s_machinima;
|
||||
bool s_cceditor;
|
||||
bool s_options;
|
||||
bool texture_debug;
|
||||
bool n64Mode;
|
||||
} ImGuiConfig;
|
||||
|
|
|
@ -42,7 +42,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#define DISCORDLIB DISCORDLIBFILE DISCORDLIBEXT
|
||||
#define DISCORD_APP_ID "856717153431453716"
|
||||
#define DISCORD_APP_ID "895788060518793226"
|
||||
#define DISCORD_UPDATE_RATE 3
|
||||
|
||||
using namespace std;
|
||||
|
@ -228,35 +228,22 @@ string getLevelLogo(){
|
|||
}
|
||||
|
||||
void set_logo(void) {
|
||||
discordRichPresence.largeImageKey = sys_strdup(getLevelLogo().data());
|
||||
discordRichPresence.largeImageKey = "saturn-logo-star-bg";
|
||||
discordRichPresence.largeImageText = "https://github.com/Llennpie/Saturn";
|
||||
}
|
||||
|
||||
void DiscordReloadPresence() {
|
||||
reloadRPC = true;
|
||||
}
|
||||
|
||||
void set_health(){
|
||||
if(gCurrCourseNum == 0) return;
|
||||
if(lastHealth != gHudDisplay.wedges){
|
||||
lastHealth = gHudDisplay.wedges;
|
||||
string new_health_icon = "health-"+to_string(lastHealth);
|
||||
string new_health_text = to_string(gHudDisplay.lives) + " Lives";
|
||||
discordRichPresence.smallImageKey = sys_strdup(new_health_icon.data());
|
||||
discordRichPresence.smallImageText = sys_strdup(new_health_text.data());
|
||||
}
|
||||
}
|
||||
|
||||
void set_image_key(){
|
||||
if(gCurrCourseNum == 0) return;
|
||||
int size = entries[gCurrSaveFileNum - 1].size();
|
||||
if(lastAchievements != size || lastStarAmount != gHudDisplay.stars){
|
||||
lastAchievements = size;
|
||||
lastStarAmount = gHudDisplay.stars;
|
||||
|
||||
string new_text = to_string(lastStarAmount) + "/120 Stars - " + to_string(lastAchievements) + "/" + to_string(registeredAchievements.size()) + " Achievements";
|
||||
|
||||
discordRichPresence.largeImageText = sys_strdup(new_text.data());
|
||||
}
|
||||
void set_platform(){
|
||||
#ifdef __MINGW32__
|
||||
discordRichPresence.smallImageKey = "windows";
|
||||
discordRichPresence.smallImageText = "Windows";
|
||||
#else
|
||||
discordRichPresence.smallImageKey = "linux";
|
||||
discordRichPresence.smallImageText = "Linux";
|
||||
#endif
|
||||
}
|
||||
|
||||
void DiscordUpdatePresence(){
|
||||
|
@ -268,8 +255,7 @@ void DiscordUpdatePresence(){
|
|||
set_state();
|
||||
set_details();
|
||||
set_logo();
|
||||
set_health();
|
||||
set_image_key();
|
||||
set_platform();
|
||||
discordUpdatePresence(&discordRichPresence);
|
||||
reloadRPC = false;
|
||||
}
|
||||
|
@ -306,8 +292,8 @@ void discord_init(void) {
|
|||
discordUpdatePresence = (Discord_UpdatePresence) dlsym(handle, "Discord_UpdatePresence");
|
||||
init_discord();
|
||||
|
||||
discordRichPresence.details = stage;
|
||||
discordRichPresence.state = act;
|
||||
discordRichPresence.details = "Making Machinima";
|
||||
discordRichPresence.state = stage;
|
||||
|
||||
lastUpdatedTime = 0;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "../fs/fs.h"
|
||||
#include "moon/moon64.h"
|
||||
#include "moon/mod-engine/hooks/hook.h"
|
||||
#include "moon/saturn/saturn_types.h"
|
||||
|
||||
#define SUPPORT_CHECK(x) assert(x)
|
||||
|
||||
|
@ -447,6 +448,48 @@ static void gfx_sp_vertex(size_t n_vertices, size_t dest_index, const Vtx *verti
|
|||
int g = rsp.current_lights[rsp.current_num_lights - 1].col[1];
|
||||
int b = rsp.current_lights[rsp.current_num_lights - 1].col[2];
|
||||
|
||||
// sm64plus saves the day...
|
||||
|
||||
// Detect if these are one of Mario's colors
|
||||
bool mario_hat = (r == 0x7f && g == 0x00 && b == 0x00);
|
||||
bool mario_overalls = (r == 0x00 && g == 0x00 && b == 0x7f);
|
||||
bool mario_gloves = (r == 0x00 && g == 0x7f && b == 0x00);
|
||||
bool mario_shoes = (r == 0x39 && g == 0x0e && b == 0x07);
|
||||
bool mario_skin = (r == 0x7f && g == 0x60 && b == 0x3c);
|
||||
bool mario_hair = (r == 0x39 && g == 0x03 && b == 0x00);
|
||||
|
||||
// Override them lazily
|
||||
if (mario_hat) {
|
||||
r = defaultColorHatRDark;
|
||||
g = defaultColorHatGDark;
|
||||
b = defaultColorHatBDark;
|
||||
}
|
||||
if (mario_overalls) {
|
||||
r = defaultColorOverallsRDark;
|
||||
g = defaultColorOverallsGDark;
|
||||
b = defaultColorOverallsBDark;
|
||||
}
|
||||
if (mario_gloves) {
|
||||
r = defaultColorGlovesRDark;
|
||||
g = defaultColorGlovesGDark;
|
||||
b = defaultColorGlovesBDark;
|
||||
}
|
||||
if (mario_shoes) {
|
||||
r = defaultColorShoesRDark;
|
||||
g = defaultColorShoesGDark;
|
||||
b = defaultColorShoesBDark;
|
||||
}
|
||||
if (mario_skin) {
|
||||
r = defaultColorSkinRDark;
|
||||
g = defaultColorSkinGDark;
|
||||
b = defaultColorSkinBDark;
|
||||
}
|
||||
if (mario_hair) {
|
||||
r = defaultColorHairRDark;
|
||||
g = defaultColorHairGDark;
|
||||
b = defaultColorHairBDark;
|
||||
}
|
||||
|
||||
for (int i = 0; i < rsp.current_num_lights - 1; i++) {
|
||||
float intensity = 0;
|
||||
intensity += vn->n[0] * rsp.current_lights_coeffs[i][0];
|
||||
|
@ -454,9 +497,47 @@ static void gfx_sp_vertex(size_t n_vertices, size_t dest_index, const Vtx *verti
|
|||
intensity += vn->n[2] * rsp.current_lights_coeffs[i][2];
|
||||
intensity /= 127.0f;
|
||||
if (intensity > 0.0f) {
|
||||
r += intensity * rsp.current_lights[i].col[0];
|
||||
g += intensity * rsp.current_lights[i].col[1];
|
||||
b += intensity * rsp.current_lights[i].col[2];
|
||||
// Light colors
|
||||
int lightr = rsp.current_lights[i].col[0];
|
||||
int lightg = rsp.current_lights[i].col[1];
|
||||
int lightb = rsp.current_lights[i].col[2];
|
||||
|
||||
// Override these too
|
||||
if (mario_hat) {
|
||||
r += intensity * defaultColorHatRLight;
|
||||
g += intensity * defaultColorHatGLight;
|
||||
b += intensity * defaultColorHatBLight;
|
||||
}
|
||||
else if (mario_overalls) {
|
||||
r += intensity * defaultColorOverallsRLight;
|
||||
g += intensity * defaultColorOverallsGLight;
|
||||
b += intensity * defaultColorOverallsBLight;
|
||||
}
|
||||
else if (mario_gloves) {
|
||||
r += intensity * defaultColorGlovesRLight;
|
||||
g += intensity * defaultColorGlovesGLight;
|
||||
b += intensity * defaultColorGlovesBLight;
|
||||
}
|
||||
else if (mario_shoes) {
|
||||
r += intensity * defaultColorShoesRLight;
|
||||
g += intensity * defaultColorShoesGLight;
|
||||
b += intensity * defaultColorShoesBLight;
|
||||
}
|
||||
else if (mario_skin) {
|
||||
r += intensity * defaultColorSkinRLight;
|
||||
g += intensity * defaultColorSkinGLight;
|
||||
b += intensity * defaultColorSkinBLight;
|
||||
}
|
||||
else if (mario_hair) {
|
||||
r += intensity * defaultColorHairRLight;
|
||||
g += intensity * defaultColorHairGLight;
|
||||
b += intensity * defaultColorHairBLight;
|
||||
}
|
||||
else {
|
||||
r += intensity * lightr;
|
||||
g += intensity * lightg;
|
||||
b += intensity * lightb;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef GFX_SCREEN_CONFIG_H
|
||||
#define GFX_SCREEN_CONFIG_H
|
||||
|
||||
#define DESIRED_SCREEN_WIDTH 640
|
||||
#define DESIRED_SCREEN_HEIGHT 480
|
||||
#define DESIRED_SCREEN_WIDTH 1280
|
||||
#define DESIRED_SCREEN_HEIGHT 768
|
||||
|
||||
#endif
|
||||
|
|
|
@ -62,7 +62,7 @@ static void (*kb_all_keys_up)(void) = NULL;
|
|||
// whether to use timer for frame control
|
||||
static bool use_timer = true;
|
||||
// time between consequtive game frames
|
||||
static const int frame_time = 1000 / FRAMERATE;
|
||||
static const int frame_time = 1000 / (2 * FRAMERATE);
|
||||
|
||||
const SDL_Scancode windows_scancode_table[] = {
|
||||
/* 0 1 2 3 4 5 6 7 */
|
||||
|
@ -149,13 +149,17 @@ int test_vsync(void) {
|
|||
|
||||
static inline void gfx_sdl_set_vsync(const bool enabled) {
|
||||
#ifdef TARGET_SWITCH
|
||||
SDL_GL_SetSwapInterval(2);
|
||||
SDL_GL_SetSwapInterval(1);
|
||||
use_timer = false;
|
||||
#else
|
||||
if (enabled) {
|
||||
// try to detect refresh rate
|
||||
SDL_GL_SetSwapInterval(1);
|
||||
const int vblanks = test_vsync();
|
||||
int vblanks = test_vsync();
|
||||
if (vblanks & 1)
|
||||
vblanks = 0; // not divisible by 60, fuck that
|
||||
else
|
||||
vblanks /= 2;
|
||||
if (vblanks) {
|
||||
printf("determined swap interval: %d\n", vblanks);
|
||||
SDL_GL_SetSwapInterval(vblanks);
|
||||
|
|
|
@ -86,6 +86,25 @@ void send_display_list(struct SPTask *spTask) {
|
|||
#define SAMPLES_LOW 528
|
||||
#endif
|
||||
|
||||
static inline void patch_interpolations(void) {
|
||||
extern void mtx_patch_interpolated(void);
|
||||
extern void patch_screen_transition_interpolated(void);
|
||||
extern void patch_title_screen_scales(void);
|
||||
extern void patch_interpolated_dialog(void);
|
||||
extern void patch_interpolated_hud(void);
|
||||
extern void patch_interpolated_paintings(void);
|
||||
extern void patch_interpolated_bubble_particles(void);
|
||||
extern void patch_interpolated_snow_particles(void);
|
||||
mtx_patch_interpolated();
|
||||
patch_screen_transition_interpolated();
|
||||
patch_title_screen_scales();
|
||||
patch_interpolated_dialog();
|
||||
patch_interpolated_hud();
|
||||
patch_interpolated_paintings();
|
||||
patch_interpolated_bubble_particles();
|
||||
patch_interpolated_snow_particles();
|
||||
}
|
||||
|
||||
void produce_one_frame(void) {
|
||||
moon_setup("Update");
|
||||
gfx_start_frame();
|
||||
|
@ -114,6 +133,11 @@ void produce_one_frame(void) {
|
|||
}
|
||||
//printf("Audio samples before submitting: %d\n", audio_api->buffered());
|
||||
|
||||
gfx_start_frame();
|
||||
patch_interpolations();
|
||||
send_display_list(gGfxSPTask);
|
||||
gfx_end_frame();
|
||||
|
||||
audio_api->play((u8 *)audio_buffer, 2 * num_audio_samples * 4);
|
||||
|
||||
gfx_end_frame();
|
||||
|
@ -211,8 +235,7 @@ void main_func(char *argv[]) {
|
|||
# define RAPI_NAME "OpenGL"
|
||||
# endif
|
||||
|
||||
char window_title[96] =
|
||||
"Super Mario 64 - Moon64 (" RAPI_NAME ")";
|
||||
char window_title[96] = "Saturn";
|
||||
|
||||
gfx_init(wm_api, rendering_api, window_title);
|
||||
wm_api->set_keyboard_callbacks(keyboard_on_key_down, keyboard_on_key_up, keyboard_on_all_keys_up);
|
||||
|
|
Loading…
Reference in New Issue