You've already forked HackerSM64
mirror of
https://github.com/HackerN64/HackerSM64.git
synced 2026-01-21 10:35:32 -08:00
Compare commits
2 Commits
develop/2.
...
develop/2.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e113978834 | ||
|
|
37632f3954 |
@@ -29,7 +29,6 @@ This is a fork of the ultrasm64 repo by CrashOveride which includes the followin
|
||||
- **CrashOveride**: creating the [ultrasm64](https://github.com/CrashOveride95/ultrasm64) repo
|
||||
- **falcobuster**: Original coordinate overflow fix (world scale), ASM version of extended bounds
|
||||
- **anonymous_moose**: porting falco's extended bounds to decomp
|
||||
- **tuxlovesyou**: `LOAD_MIO0_TEXTURE` macro and moral support
|
||||
|
||||
Thanks to Frame#5375 and AloXado320 for also helping with silhouette stuff
|
||||
|
||||
|
||||
@@ -57,6 +57,11 @@
|
||||
// Use 64x64 quarter shadow textures (Vanilla are 16x16).
|
||||
#define HD_SHADOWS
|
||||
|
||||
// Stretches shadows to fit the terrain instead of rotating them to align with it.
|
||||
// This makes them maintain a constant horizontal size.
|
||||
// Performs better than regular shadows.
|
||||
// #define SHEAR_SHADOWS
|
||||
|
||||
// Makes certain objects (mainly trees) transparent when the camera gets close.
|
||||
// #define OBJ_OPACITY_BY_CAM_DIST
|
||||
|
||||
|
||||
@@ -310,9 +310,6 @@ enum GoddardScene {
|
||||
CMD_PTR(romEnd)
|
||||
#endif
|
||||
|
||||
#undef LOAD_MIO0_TEXTURE
|
||||
#define LOAD_MIO0_TEXTURE(a,b,c) LOAD_YAY0_TEXTURE(a,b,c)
|
||||
|
||||
#define CHANGE_AREA_SKYBOX(area, segStart, segEnd) \
|
||||
CMD_BBH(LEVEL_CMD_CHANGE_AREA_SKYBOX, 0x0C, area), \
|
||||
CMD_PTR(segStart), \
|
||||
|
||||
@@ -592,6 +592,31 @@ void mtxf_billboard(Mat4 dest, Mat4 mtx, Vec3f position, Vec3f scale, s32 angle)
|
||||
* 'scale' is the scale of the shadow
|
||||
* 'yaw' is the angle which it should face
|
||||
*/
|
||||
#ifdef SHEAR_SHADOWS
|
||||
void mtxf_shadow(Mat4 dest, Mat4 src, Vec3f upDir, Vec3f pos, Vec3f scale, s32 yaw) {
|
||||
float hxy = -upDir[0]/upDir[1];
|
||||
float hzy = -upDir[2]/upDir[1];
|
||||
float cosyaw = coss(yaw);
|
||||
float sinyaw = sins(yaw);
|
||||
|
||||
Vec3f entry;
|
||||
entry[0] = scale[0] * cosyaw;
|
||||
entry[1] = scale[0] * cosyaw * hxy - scale[0] * sinyaw * hzy;
|
||||
entry[2] = -scale[0] * sinyaw;
|
||||
linear_mtxf_mul_vec3f(src, dest[0], entry);
|
||||
entry[0] = 0;
|
||||
entry[1] = scale[1];
|
||||
entry[2] = 0;
|
||||
linear_mtxf_mul_vec3f(src, dest[1], entry);
|
||||
entry[0] = scale[2] * sinyaw;
|
||||
entry[1] = scale[2] * sinyaw * hxy + scale[2] * cosyaw * hzy;
|
||||
entry[2] = scale[2] * cosyaw;
|
||||
linear_mtxf_mul_vec3f(src, dest[2], entry);
|
||||
linear_mtxf_mul_vec3f(src, dest[3], pos);
|
||||
vec3f_add(dest[3], src[3]);
|
||||
MTXF_END(dest);
|
||||
}
|
||||
#else
|
||||
void mtxf_shadow(Mat4 dest, Mat4 src, Vec3f upDir, Vec3f pos, Vec3f scale, s32 yaw) {
|
||||
Vec3f lateralDir;
|
||||
Vec3f leftDir;
|
||||
@@ -613,6 +638,7 @@ void mtxf_shadow(Mat4 dest, Mat4 src, Vec3f upDir, Vec3f pos, Vec3f scale, s32 y
|
||||
vec3f_add(dest[3], src[3]);
|
||||
MTXF_END(dest);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Set 'dest' to a transformation matrix that aligns an object with the terrain
|
||||
@@ -1530,40 +1556,63 @@ static ALWAYS_INLINE float construct_float(const float f)
|
||||
return f_out;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE float mul_without_nop(float a, float b)
|
||||
{
|
||||
float ret;
|
||||
__asm__ ("mul.s %0, %1, %2"
|
||||
: "=f"(ret)
|
||||
: "f"(a), "f"(b));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE void swl(void* addr, s32 val, const int offset)
|
||||
{
|
||||
__asm__ ("swl %1, %2(%0)"
|
||||
:
|
||||
: "g"(addr), "g"(val), "I"(offset));
|
||||
}
|
||||
|
||||
// Converts a floating point matrix to a fixed point matrix
|
||||
// Makes some assumptions about certain fields in the matrix, which will always be true for valid matrices.
|
||||
__attribute__((optimize("Os")))
|
||||
__attribute__((optimize("Os"))) __attribute__((aligned(32)))
|
||||
void mtxf_to_mtx_fast(s16* dst, float* src)
|
||||
{
|
||||
int i;
|
||||
float scale = construct_float(65536.0f / WORLD_SCALE);
|
||||
// Iterate over pairs of values in the input matrix
|
||||
for (int i = 0; i < 8; i++)
|
||||
// Iterate over rows of values in the input matrix
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
// Read the first input in the current pair
|
||||
float a = src[2 * i + 0];
|
||||
// Read the three input in the current row (assume the fourth is zero)
|
||||
float a = src[4 * i + 0];
|
||||
float b = src[4 * i + 1];
|
||||
float c = src[4 * i + 2];
|
||||
float a_scaled = mul_without_nop(a,scale);
|
||||
float b_scaled = mul_without_nop(b,scale);
|
||||
float c_scaled = mul_without_nop(c,scale);
|
||||
|
||||
// Convert the first input to fixed
|
||||
s32 a_int = (s32)(a * scale);
|
||||
dst[2 * i + 0] = (s16)(a_int >> 16);
|
||||
dst[2 * i + 16] = (s16)(a_int >> 0);
|
||||
// Convert the three inputs to fixed
|
||||
s32 a_int = (s32)a_scaled;
|
||||
s32 b_int = (s32)b_scaled;
|
||||
s32 c_int = (s32)c_scaled;
|
||||
s32 c_high = c_int & 0xFFFF0000;
|
||||
s32 c_low = c_int << 16;
|
||||
|
||||
// Write the integer part of a, as well as garbage into the next two bytes.
|
||||
// Those two bytes will get overwritten by the integer part of b.
|
||||
// This prevents needing to shift or mask the integer value of a.
|
||||
*(s32*)(&dst[4 * i + 0]) = a_int;
|
||||
// Write the fractional part of a
|
||||
dst[4 * i + 16] = (s16)a_int;
|
||||
|
||||
// If this is the left half of the matrix, convert the second input to fixed
|
||||
if ((i & 1) == 0)
|
||||
{
|
||||
// Read the second input in the current pair
|
||||
float b = src[2 * i + 1];
|
||||
s32 b_int = (s32)(b * scale);
|
||||
dst[2 * i + 1] = (s16)(b_int >> 16);
|
||||
dst[2 * i + 17] = (s16)(b_int >> 0);
|
||||
}
|
||||
// Otherwise, skip the second input because column 4 will always be zero
|
||||
// Row 4 column 4 is handled after the loop.
|
||||
else
|
||||
{
|
||||
dst[2 * i + 1] = 0;
|
||||
dst[2 * i + 17] = 0;
|
||||
}
|
||||
// Write the integer part of b using swl to avoid needing to shift.
|
||||
swl(dst + 4 * i, b_int, 2);
|
||||
// Write the fractional part of b.
|
||||
dst[4 * i + 17] = (s16)b_int;
|
||||
|
||||
// Write the integer part of c and two zeroes for the 4th column.
|
||||
*(s32*)(&dst[4 * i + 2]) = c_high;
|
||||
// Write the fractional part of c and two zeroes for the 4th column
|
||||
*(s32*)(&dst[4 * i + 18]) = c_low;
|
||||
}
|
||||
// Write 1.0 to the bottom right entry in the output matrix
|
||||
// The low half was already set to zero in the loop, so we only need
|
||||
|
||||
@@ -1448,7 +1448,7 @@ void render_hud_cannon_reticle(void) {
|
||||
gSPDisplayList(gDisplayListHead++, dl_draw_triangle);
|
||||
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
||||
|
||||
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
||||
// gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
||||
}
|
||||
|
||||
void reset_red_coins_collected(void) {
|
||||
|
||||
@@ -1180,32 +1180,6 @@ void geo_try_process_children(struct GraphNode *node) {
|
||||
}
|
||||
}
|
||||
|
||||
void (*geoFunctionTable[])() = {
|
||||
geo_process_ortho_projection, // GRAPH_NODE_TYPE_ORTHO_PROJECTION,
|
||||
geo_process_perspective, // GRAPH_NODE_TYPE_PERSPECTIVE,
|
||||
geo_process_master_list, // GRAPH_NODE_TYPE_MASTER_LIST,
|
||||
geo_process_level_of_detail, // GRAPH_NODE_TYPE_LEVEL_OF_DETAIL,
|
||||
geo_process_switch, // GRAPH_NODE_TYPE_SWITCH_CASE,
|
||||
geo_process_camera, // GRAPH_NODE_TYPE_CAMERA,
|
||||
geo_process_translation_rotation, // GRAPH_NODE_TYPE_TRANSLATION_ROTATION,
|
||||
geo_process_translation, // GRAPH_NODE_TYPE_TRANSLATION,
|
||||
geo_process_rotation, // GRAPH_NODE_TYPE_ROTATION,
|
||||
geo_process_object, // GRAPH_NODE_TYPE_OBJECT,
|
||||
geo_process_animated_part, // GRAPH_NODE_TYPE_ANIMATED_PART,
|
||||
geo_process_bone, // GRAPH_NODE_TYPE_BONE,
|
||||
geo_process_billboard, // GRAPH_NODE_TYPE_BILLBOARD,
|
||||
geo_process_display_list, // GRAPH_NODE_TYPE_DISPLAY_LIST,
|
||||
geo_process_scale, // GRAPH_NODE_TYPE_SCALE,
|
||||
geo_process_shadow, // GRAPH_NODE_TYPE_SHADOW,
|
||||
geo_process_object_parent, // GRAPH_NODE_TYPE_OBJECT_PARENT,
|
||||
geo_process_generated_list, // GRAPH_NODE_TYPE_GENERATED_LIST,
|
||||
geo_process_background, // GRAPH_NODE_TYPE_BACKGROUND,
|
||||
geo_process_held_object, // GRAPH_NODE_TYPE_HELD_OBJ,
|
||||
geo_try_process_children, // GRAPH_NODE_TYPE_CULLING_RADIUS,
|
||||
geo_try_process_children, // GRAPH_NODE_TYPE_ROOT,
|
||||
geo_try_process_children // GRAPH_NODE_TYPE_START,
|
||||
};
|
||||
|
||||
/**
|
||||
* Process a generic geo node and its siblings.
|
||||
* The first argument is the start node, and all its siblings will
|
||||
@@ -1227,14 +1201,6 @@ void geo_process_node_and_siblings(struct GraphNode *firstNode) {
|
||||
if (curGraphNode->flags & GRAPH_RENDER_CHILDREN_FIRST) {
|
||||
geo_try_process_children(curGraphNode);
|
||||
} else {
|
||||
#ifdef DISABLE_GRAPH_NODE_TYPE_FUNCTIONAL
|
||||
u32 curGraphNodeType = curGraphNode->type;
|
||||
if (curGraphNodeType < ARRAY_COUNT(geoFunctionTable)) {
|
||||
geoFunctionTable[curGraphNodeType](curGraphNode);
|
||||
} else {
|
||||
geo_try_process_children(curGraphNode);
|
||||
}
|
||||
#else
|
||||
switch (curGraphNode->type) {
|
||||
case GRAPH_NODE_TYPE_ORTHO_PROJECTION: geo_process_ortho_projection ((struct GraphNodeOrthoProjection *) curGraphNode); break;
|
||||
case GRAPH_NODE_TYPE_PERSPECTIVE: geo_process_perspective ((struct GraphNodePerspective *) curGraphNode); break;
|
||||
@@ -1258,7 +1224,6 @@ void geo_process_node_and_siblings(struct GraphNode *firstNode) {
|
||||
case GRAPH_NODE_TYPE_BONE: geo_process_bone ((struct GraphNodeBone *) curGraphNode); break;
|
||||
default: geo_try_process_children ((struct GraphNode *) curGraphNode); break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
if (curGraphNode->type == GRAPH_NODE_TYPE_OBJECT) {
|
||||
|
||||
@@ -361,6 +361,16 @@ void save_file_load_all(void) {
|
||||
}
|
||||
|
||||
#ifdef PUPPYCAM
|
||||
void puppycam_check_save(void) {
|
||||
if (gSaveBuffer.menuData.firstBoot != 4
|
||||
|| gSaveBuffer.menuData.saveOptions.sensitivityX < 5
|
||||
|| gSaveBuffer.menuData.saveOptions.sensitivityY < 5) {
|
||||
wipe_main_menu_data();
|
||||
gSaveBuffer.menuData.firstBoot = 4;
|
||||
puppycam_default_config();
|
||||
}
|
||||
}
|
||||
|
||||
void puppycam_get_save(void) {
|
||||
gPuppyCam.options = gSaveBuffer.menuData.saveOptions;
|
||||
|
||||
@@ -384,15 +394,6 @@ void puppycam_set_save(void) {
|
||||
gMainMenuDataModified = TRUE;
|
||||
save_main_menu_data();
|
||||
}
|
||||
|
||||
void puppycam_check_save(void) {
|
||||
if (gSaveBuffer.menuData.firstBoot != 4) {
|
||||
wipe_main_menu_data();
|
||||
gSaveBuffer.menuData.firstBoot = 4;
|
||||
puppycam_default_config();
|
||||
puppycam_set_save();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user