You've already forked Microtransactions64
mirror of
https://github.com/Print-and-Panic/Microtransactions64.git
synced 2026-01-21 10:17:19 -08:00
Puppylights
This commit is contained in:
@@ -1,37 +1,37 @@
|
|||||||
// Mario
|
// Mario
|
||||||
|
|
||||||
// 0x04000000 # solid color blue - butt, left thigh, right thigh - all poly types
|
// 0x04000000 # solid color blue - butt, left thigh, right thigh - all poly types
|
||||||
static const Lights1 mario_blue_lights_group = gdSPDefLights1(
|
const Lights1 mario_blue_lights_group = gdSPDefLights1(
|
||||||
0x00, 0x00, 0x7f,
|
0x00, 0x00, 0x7f,
|
||||||
0x00, 0x00, 0xff, 0x28, 0x28, 0x28
|
0x00, 0x00, 0xff, 0x28, 0x28, 0x28
|
||||||
);
|
);
|
||||||
|
|
||||||
// 0x04000018 # solid color red - left & right arm, torso (tshirt part), caps - all poly types
|
// 0x04000018 # solid color red - left & right arm, torso (tshirt part), caps - all poly types
|
||||||
static const Lights1 mario_red_lights_group = gdSPDefLights1(
|
const Lights1 mario_red_lights_group = gdSPDefLights1(
|
||||||
0x7f, 0x00, 0x00,
|
0x7f, 0x00, 0x00,
|
||||||
0xff, 0x00, 0x00, 0x28, 0x28, 0x28
|
0xff, 0x00, 0x00, 0x28, 0x28, 0x28
|
||||||
);
|
);
|
||||||
|
|
||||||
// 0x04000030 # solid color white - metal butt & left thigh - normal left & right hand closed & open (with cap too) and all wings - all poly types
|
// 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(
|
const Lights1 mario_white_lights_group = gdSPDefLights1(
|
||||||
0x7f, 0x7f, 0x7f,
|
0x7f, 0x7f, 0x7f,
|
||||||
0xff, 0xff, 0xff, 0x28, 0x28, 0x28
|
0xff, 0xff, 0xff, 0x28, 0x28, 0x28
|
||||||
);
|
);
|
||||||
|
|
||||||
// 0x04000048 # solid color brown 1 - foot - all poly types
|
// 0x04000048 # solid color brown 1 - foot - all poly types
|
||||||
static const Lights1 mario_brown1_lights_group = gdSPDefLights1(
|
const Lights1 mario_brown1_lights_group = gdSPDefLights1(
|
||||||
0x39, 0x0e, 0x07,
|
0x39, 0x0e, 0x07,
|
||||||
0x72, 0x1c, 0x0e, 0x28, 0x28, 0x28
|
0x72, 0x1c, 0x0e, 0x28, 0x28, 0x28
|
||||||
);
|
);
|
||||||
|
|
||||||
// 0x04000060 # solid color beige skin - face (cap on and off dls) - all poly types
|
// 0x04000060 # solid color beige skin - face (cap on and off dls) - all poly types
|
||||||
static const Lights1 mario_beige_lights_group = gdSPDefLights1(
|
const Lights1 mario_beige_lights_group = gdSPDefLights1(
|
||||||
0x7f, 0x60, 0x3c,
|
0x7f, 0x60, 0x3c,
|
||||||
0xfe, 0xc1, 0x79, 0x28, 0x28, 0x28
|
0xfe, 0xc1, 0x79, 0x28, 0x28, 0x28
|
||||||
);
|
);
|
||||||
|
|
||||||
// 0x04000078 # solid color brown 2 - hair - all poly types
|
// 0x04000078 # solid color brown 2 - hair - all poly types
|
||||||
static const Lights1 mario_brown2_lights_group = gdSPDefLights1(
|
const Lights1 mario_brown2_lights_group = gdSPDefLights1(
|
||||||
0x39, 0x03, 0x00,
|
0x39, 0x03, 0x00,
|
||||||
0x73, 0x06, 0x00, 0x28, 0x28, 0x28
|
0x73, 0x06, 0x00, 0x28, 0x28, 0x28
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -127,6 +127,8 @@
|
|||||||
//#define VISUAL_DEBUG
|
//#define VISUAL_DEBUG
|
||||||
// Number of supported areas per level.
|
// Number of supported areas per level.
|
||||||
#define AREA_COUNT 8
|
#define AREA_COUNT 8
|
||||||
|
// Lightweight directional lighting engine by Fazana. Intended for giving proximity and positional pointlights to small objects.
|
||||||
|
#define PUPPYLIGHTS
|
||||||
|
|
||||||
// BUG/GAME QOL FIXES
|
// BUG/GAME QOL FIXES
|
||||||
// Fix instant warp offset not working when warping across different areas
|
// Fix instant warp offset not working when warping across different areas
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "level_table.h"
|
#include "level_table.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "game/puppylights.h"
|
||||||
|
|
||||||
#define OP_AND 0
|
#define OP_AND 0
|
||||||
#define OP_NAND 1
|
#define OP_NAND 1
|
||||||
|
|||||||
@@ -47,6 +47,7 @@
|
|||||||
#ifdef AUTO_COLLISION_DISTANCE
|
#ifdef AUTO_COLLISION_DISTANCE
|
||||||
#define OBJ_FLAG_DONT_CALC_COLL_DIST (1 << 16) // 0x00010000
|
#define OBJ_FLAG_DONT_CALC_COLL_DIST (1 << 16) // 0x00010000
|
||||||
#endif
|
#endif
|
||||||
|
#define OBJ_FLAG_EMIT_LIGHT (1 << 17) // 0x00020000
|
||||||
#define OBJ_FLAG_HITBOX_WAS_SET (1 << 30) // 0x40000000
|
#define OBJ_FLAG_HITBOX_WAS_SET (1 << 30) // 0x40000000
|
||||||
|
|
||||||
/* oHeldState */
|
/* oHeldState */
|
||||||
@@ -283,7 +284,7 @@
|
|||||||
#define BOWSER_SUB_ACT_HIT_MINE_START 0
|
#define BOWSER_SUB_ACT_HIT_MINE_START 0
|
||||||
#define BOWSER_SUB_ACT_HIT_MINE_FALL 1
|
#define BOWSER_SUB_ACT_HIT_MINE_FALL 1
|
||||||
#define BOWSER_SUB_ACT_HIT_MINE_STOP 2
|
#define BOWSER_SUB_ACT_HIT_MINE_STOP 2
|
||||||
|
|
||||||
#define BOWSER_SUB_ACT_JUMP_ON_STAGE_IDLE 0
|
#define BOWSER_SUB_ACT_JUMP_ON_STAGE_IDLE 0
|
||||||
#define BOWSER_SUB_ACT_JUMP_ON_STAGE_START 1
|
#define BOWSER_SUB_ACT_JUMP_ON_STAGE_START 1
|
||||||
#define BOWSER_SUB_ACT_JUMP_ON_STAGE_LAND 2
|
#define BOWSER_SUB_ACT_JUMP_ON_STAGE_LAND 2
|
||||||
@@ -299,7 +300,7 @@
|
|||||||
/* oAction */
|
/* oAction */
|
||||||
#define FISH_SPAWNER_ACT_SPAWN 0
|
#define FISH_SPAWNER_ACT_SPAWN 0
|
||||||
#define FISH_SPAWNER_ACT_IDLE 1
|
#define FISH_SPAWNER_ACT_IDLE 1
|
||||||
#define FISH_SPAWNER_ACT_RESPAWN 2
|
#define FISH_SPAWNER_ACT_RESPAWN 2
|
||||||
/* oBehParams2ndByte */
|
/* oBehParams2ndByte */
|
||||||
#define FISH_SPAWNER_BP_MANY_BLUE 0
|
#define FISH_SPAWNER_BP_MANY_BLUE 0
|
||||||
#define FISH_SPAWNER_BP_FEW_BLUE 1
|
#define FISH_SPAWNER_BP_FEW_BLUE 1
|
||||||
|
|||||||
@@ -134,6 +134,9 @@
|
|||||||
#define /*0x1BC*/ oAngleToHome OBJECT_FIELD_S32(0x4D)
|
#define /*0x1BC*/ oAngleToHome OBJECT_FIELD_S32(0x4D)
|
||||||
#define /*0x1C0*/ oFloor OBJECT_FIELD_SURFACE(0x4E)
|
#define /*0x1C0*/ oFloor OBJECT_FIELD_SURFACE(0x4E)
|
||||||
#define /*0x1C4*/ oDeathSound OBJECT_FIELD_S32(0x4F)
|
#define /*0x1C4*/ oDeathSound OBJECT_FIELD_S32(0x4F)
|
||||||
|
#ifdef PUPPYLIGHTS
|
||||||
|
#define /*0x1C4*/ oLightID OBJECT_FIELD_S32(0x50)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Pathed (see obj_follow_path) */
|
/* Pathed (see obj_follow_path) */
|
||||||
#define /*0x0FC*/ oPathedStartWaypoint OBJECT_FIELD_WAYPOINT(0x1D)
|
#define /*0x0FC*/ oPathedStartWaypoint OBJECT_FIELD_WAYPOINT(0x1D)
|
||||||
|
|||||||
@@ -147,9 +147,22 @@ struct ObjectNode
|
|||||||
struct ObjectNode *prev;
|
struct ObjectNode *prev;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef PUPPYLIGHTS
|
||||||
|
struct PuppyLight {
|
||||||
|
Vec3t pos[2]; //The location of the light. First index is the absolute position, second index are offsets.
|
||||||
|
s16 yaw; //Used by cubes. Allows epic rotating of the volume.
|
||||||
|
s8 epicentre; //What percentage inside the volume you'll be before maximum light strength is applied. (E.g: 100 will be full strength always, and 0 will be full strength at the centre.)
|
||||||
|
u8 flags; //Some stuff to define how the volume is used. Mostly just shape stuff, but can potentially have other uses.
|
||||||
|
u8 rgba[4]; //Colour. Go on, take even the tiniest guess as to what this entails.
|
||||||
|
u8 active:1; //Whether the light will actually work. Mostly intended to be used for objects.
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
// NOTE: Since ObjectNode is the first member of Object, it is difficult to determine
|
// NOTE: Since ObjectNode is the first member of Object, it is difficult to determine
|
||||||
// whether some of these pointers point to ObjectNode or Object.
|
// whether some of these pointers point to ObjectNode or Object.
|
||||||
|
|
||||||
|
#define MAX_OBJECT_FIELDS 0x51
|
||||||
|
|
||||||
struct Object
|
struct Object
|
||||||
{
|
{
|
||||||
/*0x000*/ struct ObjectNode header;
|
/*0x000*/ struct ObjectNode header;
|
||||||
@@ -163,33 +176,33 @@ struct Object
|
|||||||
union
|
union
|
||||||
{
|
{
|
||||||
// Object fields. See object_fields.h.
|
// Object fields. See object_fields.h.
|
||||||
u32 asU32[0x50];
|
u32 asU32[MAX_OBJECT_FIELDS];
|
||||||
s32 asS32[0x50];
|
s32 asS32[MAX_OBJECT_FIELDS];
|
||||||
s16 asS16[0x50][2];
|
s16 asS16[MAX_OBJECT_FIELDS][2];
|
||||||
f32 asF32[0x50];
|
f32 asF32[MAX_OBJECT_FIELDS];
|
||||||
#if !IS_64_BIT
|
#if !IS_64_BIT
|
||||||
s16 *asS16P[0x50];
|
s16 *asS16P[MAX_OBJECT_FIELDS];
|
||||||
s32 *asS32P[0x50];
|
s32 *asS32P[MAX_OBJECT_FIELDS];
|
||||||
struct Animation **asAnims[0x50];
|
struct Animation **asAnims[MAX_OBJECT_FIELDS];
|
||||||
struct Waypoint *asWaypoint[0x50];
|
struct Waypoint *asWaypoint[MAX_OBJECT_FIELDS];
|
||||||
struct ChainSegment *asChainSegment[0x50];
|
struct ChainSegment *asChainSegment[MAX_OBJECT_FIELDS];
|
||||||
struct Object *asObject[0x50];
|
struct Object *asObject[MAX_OBJECT_FIELDS];
|
||||||
struct Surface *asSurface[0x50];
|
struct Surface *asSurface[MAX_OBJECT_FIELDS];
|
||||||
void *asVoidPtr[0x50];
|
void *asVoidPtr[MAX_OBJECT_FIELDS];
|
||||||
const void *asConstVoidPtr[0x50];
|
const void *asConstVoidPtr[MAX_OBJECT_FIELDS];
|
||||||
#endif
|
#endif
|
||||||
} rawData;
|
} rawData;
|
||||||
#if IS_64_BIT
|
#if IS_64_BIT
|
||||||
union {
|
union {
|
||||||
s16 *asS16P[0x50];
|
s16 *asS16P[MAX_OBJECT_FIELDS];
|
||||||
s32 *asS32P[0x50];
|
s32 *asS32P[MAX_OBJECT_FIELDS];
|
||||||
struct Animation **asAnims[0x50];
|
struct Animation **asAnims[MAX_OBJECT_FIELDS];
|
||||||
struct Waypoint *asWaypoint[0x50];
|
struct Waypoint *asWaypoint[MAX_OBJECT_FIELDS];
|
||||||
struct ChainSegment *asChainSegment[0x50];
|
struct ChainSegment *asChainSegment[MAX_OBJECT_FIELDS];
|
||||||
struct Object *asObject[0x50];
|
struct Object *asObject[MAX_OBJECT_FIELDS];
|
||||||
struct Surface *asSurface[0x50];
|
struct Surface *asSurface[MAX_OBJECT_FIELDS];
|
||||||
void *asVoidPtr[0x50];
|
void *asVoidPtr[MAX_OBJECT_FIELDS];
|
||||||
const void *asConstVoidPtr[0x50];
|
const void *asConstVoidPtr[MAX_OBJECT_FIELDS];
|
||||||
} ptrData;
|
} ptrData;
|
||||||
#endif
|
#endif
|
||||||
/*0x1C8*/ u32 unused1;
|
/*0x1C8*/ u32 unused1;
|
||||||
@@ -209,6 +222,9 @@ struct Object
|
|||||||
/*0x218*/ void *collisionData;
|
/*0x218*/ void *collisionData;
|
||||||
/*0x21C*/ Mat4 transform;
|
/*0x21C*/ Mat4 transform;
|
||||||
/*0x25C*/ void *respawnInfo;
|
/*0x25C*/ void *respawnInfo;
|
||||||
|
#ifdef PUPPYLIGHTS
|
||||||
|
struct PuppyLight puppylight;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ObjectHitbox
|
struct ObjectHitbox
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include "usb/debug.h"
|
#include "usb/debug.h"
|
||||||
#endif
|
#endif
|
||||||
#include "game/puppyprint.h"
|
#include "game/puppyprint.h"
|
||||||
|
#include "game/puppylights.h"
|
||||||
|
|
||||||
// Message IDs
|
// Message IDs
|
||||||
#define MESG_SP_COMPLETE 100
|
#define MESG_SP_COMPLETE 100
|
||||||
@@ -115,6 +116,9 @@ void alloc_pool(void) {
|
|||||||
|
|
||||||
main_pool_init(start, end);
|
main_pool_init(start, end);
|
||||||
gEffectsMemoryPool = mem_pool_init(0x4000, MEMORY_POOL_LEFT);
|
gEffectsMemoryPool = mem_pool_init(0x4000, MEMORY_POOL_LEFT);
|
||||||
|
#ifdef PUPPYLIGHTS
|
||||||
|
gLightsPool = mem_pool_init(PUPPYLIGHTS_POOL, MEMORY_POOL_LEFT);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void create_thread(OSThread *thread, OSId id, void (*entry)(void *), void *arg, void *sp, OSPri pri) {
|
void create_thread(OSThread *thread, OSId id, void (*entry)(void *), void *arg, void *sp, OSPri pri) {
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "game/object_list_processor.h"
|
#include "game/object_list_processor.h"
|
||||||
#include "graph_node.h"
|
#include "graph_node.h"
|
||||||
#include "surface_collision.h"
|
#include "surface_collision.h"
|
||||||
|
#include "game/puppylights.h"
|
||||||
|
|
||||||
// Macros for retrieving arguments from behavior scripts.
|
// Macros for retrieving arguments from behavior scripts.
|
||||||
#define BHV_CMD_GET_1ST_U8(index) (u8)((gCurBhvCommand[index] >> 24) & 0xFF) // unused
|
#define BHV_CMD_GET_1ST_U8(index) (u8)((gCurBhvCommand[index] >> 24) & 0xFF) // unused
|
||||||
@@ -982,6 +983,10 @@ void cur_obj_update(void) {
|
|||||||
obj_update_gfx_pos_and_angle(gCurrentObject);
|
obj_update_gfx_pos_and_angle(gCurrentObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef PUPPYLIGHTS
|
||||||
|
puppylights_object_emit(gCurrentObject);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Handle visibility of object
|
// Handle visibility of object
|
||||||
if (gCurrentObject->oRoom != -1) {
|
if (gCurrentObject->oRoom != -1) {
|
||||||
// If the object is in a room, only show it when Mario is in the room.
|
// If the object is in a room, only show it when Mario is in the room.
|
||||||
|
|||||||
@@ -24,7 +24,10 @@
|
|||||||
#include "math_util.h"
|
#include "math_util.h"
|
||||||
#include "surface_collision.h"
|
#include "surface_collision.h"
|
||||||
#include "surface_load.h"
|
#include "surface_load.h"
|
||||||
|
#include "string.h"
|
||||||
#include "game/puppycam2.h"
|
#include "game/puppycam2.h"
|
||||||
|
#include "game/puppyprint.h"
|
||||||
|
#include "game/puppylights.h"
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
@@ -801,6 +804,9 @@ static void level_cmd_puppyvolume(void)
|
|||||||
{
|
{
|
||||||
sCurrentCmd = CMD_NEXT;
|
sCurrentCmd = CMD_NEXT;
|
||||||
gPuppyError |= PUPPY_ERROR_POOL_FULL;
|
gPuppyError |= PUPPY_ERROR_POOL_FULL;
|
||||||
|
#if PUPPYPRINT_DEBUG
|
||||||
|
append_puppyprint_log("Puppycamera volume allocation failed.");
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -830,6 +836,52 @@ static void level_cmd_puppyvolume(void)
|
|||||||
sCurrentCmd = CMD_NEXT;
|
sCurrentCmd = CMD_NEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void level_cmd_puppylight_environment(void)
|
||||||
|
{
|
||||||
|
#ifdef PUPPYLIGHTS
|
||||||
|
Lights1 temp = gdSPDefLights1(CMD_GET(u8, 2), CMD_GET(u8, 3), CMD_GET(u8, 4), CMD_GET(u8, 5), CMD_GET(u8, 6), CMD_GET(u8, 7), CMD_GET(u8, 8), CMD_GET(u8, 9), CMD_GET(u8, 10));
|
||||||
|
|
||||||
|
memcpy(&gLevelLight, &temp, sizeof(Lights1));
|
||||||
|
levelAmbient = TRUE;
|
||||||
|
#endif
|
||||||
|
sCurrentCmd = CMD_NEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void level_cmd_puppylight_node(void)
|
||||||
|
{
|
||||||
|
#ifdef PUPPYLIGHTS
|
||||||
|
if ((gPuppyLights[gNumLights] = mem_pool_alloc(gLightsPool, sizeof(struct PuppyLight))) == NULL)
|
||||||
|
{
|
||||||
|
#if PUPPYPRINT_DEBUG
|
||||||
|
append_puppyprint_log("Puppylight allocation failed.");
|
||||||
|
#endif
|
||||||
|
sCurrentCmd = CMD_NEXT;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gPuppyLights[gNumLights]->rgba[0] = CMD_GET(u8, 2);
|
||||||
|
gPuppyLights[gNumLights]->rgba[1] = CMD_GET(u8, 3);
|
||||||
|
gPuppyLights[gNumLights]->rgba[2] = CMD_GET(u8, 4);
|
||||||
|
gPuppyLights[gNumLights]->rgba[3] = CMD_GET(u8, 5);
|
||||||
|
|
||||||
|
gPuppyLights[gNumLights]->pos[0][0] = CMD_GET(s16, 6);
|
||||||
|
gPuppyLights[gNumLights]->pos[0][1] = CMD_GET(s16, 8);
|
||||||
|
gPuppyLights[gNumLights]->pos[0][2] = CMD_GET(s16, 10);
|
||||||
|
|
||||||
|
gPuppyLights[gNumLights]->pos[1][0] = CMD_GET(s16, 12);
|
||||||
|
gPuppyLights[gNumLights]->pos[1][1] = CMD_GET(s16, 14);
|
||||||
|
gPuppyLights[gNumLights]->pos[1][2] = CMD_GET(s16, 16);
|
||||||
|
gPuppyLights[gNumLights]->yaw = CMD_GET(s16, 18);
|
||||||
|
|
||||||
|
gPuppyLights[gNumLights]->epicentre = CMD_GET(u8, 20);
|
||||||
|
gPuppyLights[gNumLights]->flags |= CMD_GET(u8, 21);
|
||||||
|
gPuppyLights[gNumLights]->active = TRUE;
|
||||||
|
|
||||||
|
gNumLights++;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
sCurrentCmd = CMD_NEXT;
|
||||||
|
}
|
||||||
|
|
||||||
static void (*LevelScriptJumpTable[])(void) = {
|
static void (*LevelScriptJumpTable[])(void) = {
|
||||||
/*00*/ level_cmd_load_and_execute,
|
/*00*/ level_cmd_load_and_execute,
|
||||||
@@ -894,7 +946,9 @@ static void (*LevelScriptJumpTable[])(void) = {
|
|||||||
/*3B*/ level_cmd_create_whirlpool,
|
/*3B*/ level_cmd_create_whirlpool,
|
||||||
/*3C*/ level_cmd_get_or_set_var,
|
/*3C*/ level_cmd_get_or_set_var,
|
||||||
/*3D*/ level_cmd_puppyvolume,
|
/*3D*/ level_cmd_puppyvolume,
|
||||||
/*3E*/ level_cmd_change_area_skybox,
|
/*3E*/ level_cmd_change_area_skybox,
|
||||||
|
/*3F*/ level_cmd_puppylight_environment,
|
||||||
|
/*40*/ level_cmd_puppylight_node,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LevelCommand *level_script_execute(struct LevelCommand *cmd) {
|
struct LevelCommand *level_script_execute(struct LevelCommand *cmd) {
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
#include "spawn_object.h"
|
#include "spawn_object.h"
|
||||||
#include "spawn_sound.h"
|
#include "spawn_sound.h"
|
||||||
#include "rumble_init.h"
|
#include "rumble_init.h"
|
||||||
|
#include "puppylights.h"
|
||||||
|
|
||||||
#define o gCurrentObject
|
#define o gCurrentObject
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#include "rumble_init.h"
|
#include "rumble_init.h"
|
||||||
#include "puppycam2.h"
|
#include "puppycam2.h"
|
||||||
#include "puppyprint.h"
|
#include "puppyprint.h"
|
||||||
|
#include "puppylights.h"
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
@@ -642,9 +643,11 @@ void initiate_warp(s16 destLevel, s16 destArea, s16 destWarpNode, s32 arg3) {
|
|||||||
sWarpDest.areaIdx = destArea;
|
sWarpDest.areaIdx = destArea;
|
||||||
sWarpDest.nodeId = destWarpNode;
|
sWarpDest.nodeId = destWarpNode;
|
||||||
sWarpDest.arg = arg3;
|
sWarpDest.arg = arg3;
|
||||||
|
//lol
|
||||||
#ifdef PUPPYCAM
|
#if defined(PUPPYCAM) || defined(PUPPYLIGHTS)
|
||||||
s32 i = 0;
|
s32 i = 0;
|
||||||
|
#endif
|
||||||
|
#ifdef PUPPYCAM
|
||||||
if (sWarpDest.type != WARP_TYPE_SAME_AREA)
|
if (sWarpDest.type != WARP_TYPE_SAME_AREA)
|
||||||
{
|
{
|
||||||
for (i = 0; i < gPuppyVolumeCount; i++)
|
for (i = 0; i < gPuppyVolumeCount; i++)
|
||||||
@@ -653,7 +656,18 @@ void initiate_warp(s16 destLevel, s16 destArea, s16 destWarpNode, s32 arg3) {
|
|||||||
}
|
}
|
||||||
gPuppyVolumeCount = 0;
|
gPuppyVolumeCount = 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef PUPPYLIGHTS
|
||||||
|
if (sWarpDest.type != WARP_TYPE_SAME_AREA)
|
||||||
|
{
|
||||||
|
for (i = 0; i < gNumLights; i++)
|
||||||
|
{
|
||||||
|
mem_pool_free(gLightsPool, gPuppyLights[i]);
|
||||||
|
}
|
||||||
|
gNumLights = 0;
|
||||||
|
levelAmbient = FALSE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// From Surface 0xD3 to 0xFC
|
// From Surface 0xD3 to 0xFC
|
||||||
@@ -1265,10 +1279,14 @@ s32 init_level(void) {
|
|||||||
sound_banks_disable(SEQ_PLAYER_SFX, SOUND_BANKS_DISABLED_DURING_INTRO_CUTSCENE);
|
sound_banks_disable(SEQ_PLAYER_SFX, SOUND_BANKS_DISABLED_DURING_INTRO_CUTSCENE);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PUPPYPRINT_DEBUG
|
#ifdef PUPPYLIGHTS
|
||||||
|
puppylights_allocate();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if PUPPYPRINT_DEBUG
|
||||||
sprintf(textBytes, "Level loaded in %dus", (s32)(OS_CYCLES_TO_USEC(osGetTime() - first)));
|
sprintf(textBytes, "Level loaded in %dus", (s32)(OS_CYCLES_TO_USEC(osGetTime() - first)));
|
||||||
append_puppyprint_log(textBytes);
|
append_puppyprint_log(textBytes);
|
||||||
#endif
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
#include "spawn_object.h"
|
#include "spawn_object.h"
|
||||||
#include "spawn_sound.h"
|
#include "spawn_sound.h"
|
||||||
#include "rumble_init.h"
|
#include "rumble_init.h"
|
||||||
|
#include "puppylights.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file obj_behaviors.c
|
* @file obj_behaviors.c
|
||||||
|
|||||||
@@ -45,6 +45,7 @@
|
|||||||
#include "save_file.h"
|
#include "save_file.h"
|
||||||
#include "seq_ids.h"
|
#include "seq_ids.h"
|
||||||
#include "spawn_sound.h"
|
#include "spawn_sound.h"
|
||||||
|
#include "puppylights.h"
|
||||||
|
|
||||||
#define POS_OP_SAVE_POSITION 0
|
#define POS_OP_SAVE_POSITION 0
|
||||||
#define POS_OP_COMPUTE_VELOCITY 1
|
#define POS_OP_COMPUTE_VELOCITY 1
|
||||||
|
|||||||
311
src/game/puppylights.c
Normal file
311
src/game/puppylights.c
Normal file
@@ -0,0 +1,311 @@
|
|||||||
|
///Puppylights 2.0 by Fazana. What happened to 1.0? Tragic accident.
|
||||||
|
/**
|
||||||
|
Intended for use with manipulating existing Lights1 structs for objects in real time.
|
||||||
|
Can support static lights that are loaded with the level, or lights created by objects.
|
||||||
|
|
||||||
|
Puppylights is generally intended to be used with things that don't directly use lights to colour
|
||||||
|
themselves. Inside the main function, you can pass through a colour to override the default light
|
||||||
|
but it will not be affected by environmental tinting. If you wish for an object to emit a light,
|
||||||
|
simply set the object flag OBJ_FLAG_EMIT_LIGHT and set some values to o->puppylight.
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include <ultra64.h>
|
||||||
|
#include "types.h"
|
||||||
|
#include "puppylights.h"
|
||||||
|
#include "area.h"
|
||||||
|
#include "engine/math_util.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "object_fields.h"
|
||||||
|
#include "object_constants.h"
|
||||||
|
#include "camera.h"
|
||||||
|
#include "memory.h"
|
||||||
|
#include "print.h"
|
||||||
|
#include "debug_box.h"
|
||||||
|
#include "object_list_processor.h"
|
||||||
|
#include "level_update.h"
|
||||||
|
|
||||||
|
Lights1 gLevelLight; //Existing ambient light in the area. Will be set by the level script, though can always be changed afterwards if desired.
|
||||||
|
u8 levelAmbient = FALSE;
|
||||||
|
Lights1 *sLightBase; //The base value where lights are written to when worked with.
|
||||||
|
Lights1 sDefaultLights = gdSPDefLights1(0x7F, 0x7F, 0x7F, 0xFE, 0xFE, 0xFE, 0x28, 0x28, 0x28); //Default lights default lights
|
||||||
|
u16 gNumLights = 0; //How many lights are loaded.
|
||||||
|
u16 gDynLightStart = 0; //Where the dynamic lights will start.
|
||||||
|
struct PuppyLight *gPuppyLights[MAX_LIGHTS]; //This contains all the loaded data.
|
||||||
|
struct MemoryPool *gLightsPool; //The memory pool where the above is stored.
|
||||||
|
|
||||||
|
//Runs after an area load, allocates the dynamic light slots.
|
||||||
|
void puppylights_allocate(void)
|
||||||
|
{
|
||||||
|
s32 numAllocate = MIN(MAX_LIGHTS - gNumLights, MAX_LIGHTS_DYNAMIC);
|
||||||
|
s32 i;
|
||||||
|
|
||||||
|
gDynLightStart = gNumLights;
|
||||||
|
|
||||||
|
if (numAllocate <= 0) //If this happens you've allocated too many static lights and therefore cucked dynamic.
|
||||||
|
return;
|
||||||
|
//Now it has the number it wants, it will allocate this many extra lights, intended for dynamic lights.
|
||||||
|
for (i = 0; i < numAllocate; i++)
|
||||||
|
{
|
||||||
|
gPuppyLights[gNumLights] = mem_pool_alloc(gLightsPool, sizeof(struct PuppyLight));
|
||||||
|
if (gPuppyLights[gNumLights] == NULL)
|
||||||
|
return;
|
||||||
|
gPuppyLights[gNumLights]->flags = PUPPYLIGHT_DYNAMIC;
|
||||||
|
gPuppyLights[gNumLights]->active = FALSE;
|
||||||
|
gNumLights++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern Mat4 gMatStack[32];
|
||||||
|
|
||||||
|
//Function that iterates through each light.
|
||||||
|
void puppylights_iterate(struct PuppyLight *light, Lights1 *src, struct Object *obj)
|
||||||
|
{
|
||||||
|
Lights1 *tempLight;
|
||||||
|
s32 lightPos[2];
|
||||||
|
Vec3i lightRelative;
|
||||||
|
Vec3i lightDir;
|
||||||
|
s32 lightIntensity = 0;
|
||||||
|
s32 i;
|
||||||
|
s32 colour;
|
||||||
|
s32 ambient;
|
||||||
|
f64 scale = 1.0f;
|
||||||
|
f32 scale2;
|
||||||
|
f64 scaleVal = 1.0f;
|
||||||
|
f64 preScale;
|
||||||
|
|
||||||
|
//Relative positions of the object vs the centre of the node.
|
||||||
|
lightRelative[0] = light->pos[0][0] - obj->oPosX;
|
||||||
|
lightRelative[1] = light->pos[0][1] - obj->oPosY;
|
||||||
|
lightRelative[2] = light->pos[0][2] - obj->oPosZ;
|
||||||
|
|
||||||
|
//If the node is a cube, then calculate the distance a bit differently.
|
||||||
|
if (light->flags & PUPPYLIGHT_SHAPE_CUBE)
|
||||||
|
{
|
||||||
|
//Get the position based off the rotation of the cube.
|
||||||
|
lightPos[0] = lightRelative[2] * sins(light->yaw) + lightRelative[0] * coss(light->yaw);
|
||||||
|
lightPos[1] = lightRelative[2] * coss(light->yaw) - lightRelative[0] * sins(light->yaw);
|
||||||
|
|
||||||
|
#ifdef VISUAL_DEBUG
|
||||||
|
Vec3f debugPos[2];
|
||||||
|
vec3f_set(debugPos[0], light->pos[0][0], light->pos[0][1], light->pos[0][2]);
|
||||||
|
vec3f_set(debugPos[1], light->pos[1][0], light->pos[1][1], light->pos[1][2]);
|
||||||
|
debug_box_color(0x00FFFF00);
|
||||||
|
debug_box_rot(debugPos[0], debugPos[1], light->yaw, DEBUG_SHAPE_BOX);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (-light->pos[1][0] < lightPos[0] && lightPos[0] < light->pos[1][0] &&
|
||||||
|
-light->pos[1][1] < lightRelative[1] && lightRelative[1] < light->pos[1][1] &&
|
||||||
|
-light->pos[1][2] < lightPos[1] && lightPos[1] < light->pos[1][2])
|
||||||
|
{
|
||||||
|
scale = (lightPos[0] * lightPos[0]) + (lightRelative[1] * lightRelative[1]) + (lightPos[1] * lightPos[1]);
|
||||||
|
scaleVal = (light->pos[1][0] + light->pos[1][1] + light->pos[1][2])/3;
|
||||||
|
scaleVal *= scaleVal;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (light->flags & PUPPYLIGHT_SHAPE_CYLINDER)
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef VISUAL_DEBUG
|
||||||
|
Vec3f debugPos[2];
|
||||||
|
vec3f_set(debugPos[0], light->pos[0][0], light->pos[0][1], light->pos[0][2]);
|
||||||
|
vec3f_set(debugPos[1], light->pos[1][0], light->pos[1][1], light->pos[1][2]);
|
||||||
|
debug_box_color(0x00FFFF00);
|
||||||
|
debug_box_rot(debugPos[0], debugPos[1], 0, DEBUG_SHAPE_CYLINDER);
|
||||||
|
#endif
|
||||||
|
//First do an AABB check, since it's a fair bit faster than doing just a distance check.
|
||||||
|
if (-light->pos[1][0] < lightRelative[0] && lightRelative[0] < light->pos[1][0] &&
|
||||||
|
-light->pos[1][1] < lightRelative[1] && lightRelative[1] < light->pos[1][1] &&
|
||||||
|
-light->pos[1][2] < lightRelative[2] && lightRelative[2] < light->pos[1][2])
|
||||||
|
{
|
||||||
|
//Okay now we can do a distance check
|
||||||
|
scale = (lightRelative[0] * lightRelative[0]) + (lightRelative[1] * lightRelative[1]) + (lightRelative[2] * lightRelative[2]);
|
||||||
|
scaleVal = (light->pos[1][0] + light->pos[1][1] + light->pos[1][2])/3;
|
||||||
|
scaleVal *= scaleVal;
|
||||||
|
if (scale > scaleVal)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
|
||||||
|
tempLight = segmented_to_virtual(src);
|
||||||
|
//Now we have a scale value and a scale factor, we can start lighting things up.
|
||||||
|
//Convert to a percentage.
|
||||||
|
preScale = scale;
|
||||||
|
scale /= scaleVal;
|
||||||
|
scale = CLAMP(scale, 0.0f, 1.0f);
|
||||||
|
//Reduce scale2 by the epicentre.
|
||||||
|
scale2 = (scale - (f32)(light->epicentre/100.0f)) * (1+(f32)(light->epicentre/100.0f));
|
||||||
|
scale2 = CLAMP(scale2, 0.0f, 1.0f);
|
||||||
|
//Normalise the light brightness.
|
||||||
|
lightIntensity = (tempLight->a.l.col[0]+tempLight->a.l.col[1]+tempLight->a.l.col[2])/3.0f;
|
||||||
|
//Get the direction numbers we want by applying some maths to the relative positions. We use 64 because light directions range from -64 to 63.
|
||||||
|
//Note: can this be optimised further? Simply squaring lightRelative and then dividing it by preScale doesn't work.
|
||||||
|
if (light->flags & PUPPYLIGHT_DIRECTIONAL)
|
||||||
|
{
|
||||||
|
lightDir[0] = ((lightRelative[0]) * 64.0f) / sqrtf(preScale);
|
||||||
|
lightDir[1] = ((lightRelative[1]) * 64.0f) / sqrtf(preScale);
|
||||||
|
lightDir[2] = ((lightRelative[2]) * 64.0f) / sqrtf(preScale);
|
||||||
|
}
|
||||||
|
//Get direction if applicable.
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
//So it works by starting from the final colour, and then lerping to the original colour, by a factor of the epicentre corrected scale. Light opacity affects this further.
|
||||||
|
colour = approach_f32_asymptotic(light->rgba[i], sLightBase->l[0].l.col[i], scale2*((f32)light->rgba[3]/255.0f));
|
||||||
|
//If it's a directional light, then increase the current ambient by 50%, to give the effect better.
|
||||||
|
//Otherwise, just normalise the brightness to keep it in line with the current ambient.
|
||||||
|
if (light->flags & PUPPYLIGHT_DIRECTIONAL)
|
||||||
|
ambient = approach_f32_asymptotic(MIN(tempLight->a.l.col[i]*1.5f, 0xFF), tempLight->a.l.col[i], scale*((f32)light->rgba[3]/255.0f));
|
||||||
|
else
|
||||||
|
ambient = approach_f32_asymptotic(lightIntensity, tempLight->a.l.col[i], scale*((f32)light->rgba[3]/255.0f));
|
||||||
|
//And now to apply the values.
|
||||||
|
tempLight->l[0].l.col[i] = colour;
|
||||||
|
tempLight->l[0].l.colc[i] = colour;
|
||||||
|
//Ambient, too.
|
||||||
|
tempLight->a.l.col[i] = ambient;
|
||||||
|
tempLight->a.l.colc[i] = ambient;
|
||||||
|
//Apply direction. It takes the relative positions, and then multiplies them with the perspective matrix to get a correct direction.
|
||||||
|
//Index 1 of the first dimension of gMatStack is perspective. Note that if you ever decide to cheat your way into rendering things after the game does :^)
|
||||||
|
if (light->flags & PUPPYLIGHT_DIRECTIONAL)
|
||||||
|
tempLight->l->l.dir[i] = approach_f32_asymptotic((s8)(lightDir[0] * gMatStack[1][0][i] + lightDir[1] * gMatStack[1][1][i] + lightDir[2] * gMatStack[1][2][i]), tempLight->l->l.dir[i], scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Main function. Run this in the object you wish to illuminate, and just give it its light, object pointer and any potential flags if you want to use them.
|
||||||
|
//If the object has multiple lights, then you run this for each light.
|
||||||
|
void puppylights_run(Lights1 *src, struct Object *obj, s32 flags, s32 baseColour)
|
||||||
|
{
|
||||||
|
s32 i;
|
||||||
|
|
||||||
|
if (gCurrLevelNum < 4)
|
||||||
|
return;
|
||||||
|
//Checks if there's a hardset colour. Colours are only the first 3 bytes, so you can really put whatever you want in the last.
|
||||||
|
//If there isn't a colour, then it decides whether to apply the ambient lighting, or the default lighting as the baseline.
|
||||||
|
//Otherwise, it hardsets a colour to begin with. I don't recommend you use this, simply because it's intended to be used
|
||||||
|
//As a hacky quick-fix for models coloured by lights. Lightcoloured models don't blend nearly as nicely as ones coloured
|
||||||
|
//By other means.
|
||||||
|
if (baseColour < 0x100)
|
||||||
|
{
|
||||||
|
if (levelAmbient)
|
||||||
|
sLightBase = &gLevelLight;
|
||||||
|
else
|
||||||
|
sLightBase = &sDefaultLights;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s32 colour;
|
||||||
|
Lights1 tempLight;
|
||||||
|
sLightBase = &tempLight;
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
colour = (((baseColour >> (24-(i*8)))) & 0xFF);
|
||||||
|
sLightBase->l[0].l.col[i] = colour;
|
||||||
|
sLightBase->l[0].l.colc[i] = colour;
|
||||||
|
sLightBase->a.l.col[i] = colour/2;
|
||||||
|
sLightBase->a.l.colc[i] = colour/2;
|
||||||
|
sLightBase->l->l.dir[i] = 0x28;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
memcpy(segmented_to_virtual(src), &sLightBase[0], sizeof(Lights1));
|
||||||
|
|
||||||
|
for (i = 0; i < gNumLights; i++)
|
||||||
|
{
|
||||||
|
if (gPuppyLights[i]->rgba[3] > 0 && gPuppyLights[i]->active == TRUE)
|
||||||
|
puppylights_iterate(gPuppyLights[i], src, obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Sets and updates dynamic lights from objects.
|
||||||
|
//0xFFFF is essentially the null ID. If the display flag is met, it will find and set an ID, otherwise it frees up the spot.
|
||||||
|
void puppylights_object_emit(struct Object *obj)
|
||||||
|
{
|
||||||
|
s32 i;
|
||||||
|
if (gCurrLevelNum < 4)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (obj->oFlags & OBJ_FLAG_EMIT_LIGHT)
|
||||||
|
{
|
||||||
|
f64 dist = ((obj->oPosX - gMarioState->pos[0]) * (obj->oPosX - gMarioState->pos[0])) +
|
||||||
|
((obj->oPosY - gMarioState->pos[1]) * (obj->oPosY - gMarioState->pos[1])) +
|
||||||
|
((obj->oPosZ - gMarioState->pos[2]) * (obj->oPosZ - gMarioState->pos[2]));
|
||||||
|
f64 lightSize = ((obj->puppylight.pos[1][0]) * (obj->puppylight.pos[1][0])) +
|
||||||
|
((obj->puppylight.pos[1][1]) * (obj->puppylight.pos[1][1])) +
|
||||||
|
((obj->puppylight.pos[1][2]) * (obj->puppylight.pos[1][2]));
|
||||||
|
if (dist > lightSize)
|
||||||
|
goto deallocate; //That's right. I used a goto. Eat your heart out xkcd.
|
||||||
|
if (obj->oLightID == 0xFFFF)
|
||||||
|
{
|
||||||
|
if (ABS(gNumLights - gDynLightStart) < MAX_LIGHTS_DYNAMIC)
|
||||||
|
goto deallocate;
|
||||||
|
for (i = gDynLightStart; i < MAX_LIGHTS; i++)
|
||||||
|
{
|
||||||
|
if (gPuppyLights[i]->active == TRUE)
|
||||||
|
continue;
|
||||||
|
memcpy(gPuppyLights[i], &obj->puppylight, sizeof(struct PuppyLight));
|
||||||
|
gPuppyLights[i]->active = TRUE;
|
||||||
|
obj->oLightID = i;
|
||||||
|
goto updatepos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
updatepos:
|
||||||
|
gPuppyLights[obj->oLightID]->pos[0][0] = obj->oPosX;
|
||||||
|
gPuppyLights[obj->oLightID]->pos[0][1] = obj->oPosY;
|
||||||
|
gPuppyLights[obj->oLightID]->pos[0][2] = obj->oPosZ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
deallocate:
|
||||||
|
if (obj->oLightID != 0xFFFF)
|
||||||
|
gPuppyLights[obj->oLightID]->active = FALSE;
|
||||||
|
obj->oLightID = 0xFFFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//A bit unorthodox, but anything to avoid having to set up data to pass through in the original function.
|
||||||
|
//Objects will completely ignore X, Y, Z and active though.
|
||||||
|
void set_light_properties(struct PuppyLight *light, s32 x, s32 y, s32 z, s32 offsetX, s32 offsetY, s32 offsetZ, s32 yaw, s32 epicentre, s32 colour, s32 flags, s32 active)
|
||||||
|
{
|
||||||
|
light->active = active;
|
||||||
|
light->pos[0][0] = x;
|
||||||
|
light->pos[0][1] = y;
|
||||||
|
light->pos[0][2] = z;
|
||||||
|
light->pos[1][0] = offsetX;
|
||||||
|
light->pos[1][1] = offsetY;
|
||||||
|
light->pos[1][2] = offsetZ;
|
||||||
|
light->rgba[0] = (colour >> 24) & 0xFF;
|
||||||
|
light->rgba[1] = (colour >> 16) & 0xFF;
|
||||||
|
light->rgba[2] = (colour >> 8) & 0xFF;
|
||||||
|
light->rgba[3] = colour & 0xFF;
|
||||||
|
light->yaw = yaw;
|
||||||
|
light->epicentre = epicentre;
|
||||||
|
light->flags |= flags | PUPPYLIGHT_DYNAMIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
//You can run these in objects to enable or disable their light properties.
|
||||||
|
void cur_obj_enable_light(void)
|
||||||
|
{
|
||||||
|
gCurrentObject->oFlags |= OBJ_FLAG_EMIT_LIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cur_obj_disable_light(void)
|
||||||
|
{
|
||||||
|
gCurrentObject->oFlags &= ~OBJ_FLAG_EMIT_LIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void obj_enable_light(struct Object *obj)
|
||||||
|
{
|
||||||
|
obj->oFlags |= OBJ_FLAG_EMIT_LIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void obj_disable_light(struct Object *obj)
|
||||||
|
{
|
||||||
|
obj->oFlags &= ~OBJ_FLAG_EMIT_LIGHT;
|
||||||
|
}
|
||||||
50
src/game/puppylights.h
Normal file
50
src/game/puppylights.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
#ifndef PUPPYLIGHTS_H
|
||||||
|
#define PUPPYLIGHTS_H
|
||||||
|
#include "types.h"
|
||||||
|
#include "command_macros_base.h"
|
||||||
|
|
||||||
|
//The maximum number of lights that can be loaded at once. Any further lights that attempt to be created past this will simply not spawn.
|
||||||
|
#define MAX_LIGHTS 32
|
||||||
|
//The maximum number of dynamic lights available at one time.
|
||||||
|
#define MAX_LIGHTS_DYNAMIC 8
|
||||||
|
|
||||||
|
//Two shapes. Choose your destiny.
|
||||||
|
#define PUPPYLIGHT_SHAPE_CUBE 0x1
|
||||||
|
#define PUPPYLIGHT_SHAPE_CYLINDER 0x2
|
||||||
|
#define PUPPYLIGHT_DYNAMIC 0x4
|
||||||
|
#define PUPPYLIGHT_DIRECTIONAL 0x8
|
||||||
|
|
||||||
|
#define PUPPYLIGHT_FLAG_SHADOW 0x1
|
||||||
|
#define PUPPYLIGHT_FLAG_WET 0x2
|
||||||
|
|
||||||
|
#define PUPPYLIGHT_ENVIRONMENT(ambientR, ambientG, ambientB, diffuseR, diffuseG, diffuseB, diffuseX, diffuseY, diffuseZ) \
|
||||||
|
CMD_BBBB(0x3F, 0x0C, ambientR, ambientG), \
|
||||||
|
CMD_BBBB(ambientB, diffuseR, diffuseG, diffuseB), \
|
||||||
|
CMD_BBBB(diffuseX, diffuseY, diffuseZ, 0x0)
|
||||||
|
|
||||||
|
#define PUPPYLIGHT_NODE(r, g, b, a, x, y, z, offsetX, offsetY, offsetZ, yaw, epicentre, flags) \
|
||||||
|
CMD_BBBB(0x40, 0x18, r, g), \
|
||||||
|
CMD_BBH(b, a, x), \
|
||||||
|
CMD_HH(y, z), \
|
||||||
|
CMD_HH(offsetX, offsetY), \
|
||||||
|
CMD_HH(offsetZ, yaw), \
|
||||||
|
CMD_BBH(epicentre, flags, 0x0)
|
||||||
|
|
||||||
|
//How much RAM is allocated to puppylights
|
||||||
|
#define PUPPYLIGHTS_POOL sizeof(struct PuppyLight) * MAX_LIGHTS
|
||||||
|
|
||||||
|
extern Lights1 gLevelLight;
|
||||||
|
extern u16 gNumLights;
|
||||||
|
extern u8 levelAmbient;
|
||||||
|
extern struct PuppyLight *gPuppyLights[MAX_LIGHTS];
|
||||||
|
extern struct MemoryPool *gLightsPool;
|
||||||
|
extern void puppylights_run(Lights1 *src, struct Object *obj, s32 flags, s32 baseColour);
|
||||||
|
extern void puppylights_object_emit(struct Object *obj);
|
||||||
|
extern void cur_obj_enable_light(void);
|
||||||
|
extern void cur_obj_disable_light(void);
|
||||||
|
extern void obj_enable_light(struct Object *obj);
|
||||||
|
extern void obj_disable_light(struct Object *obj);
|
||||||
|
extern void set_light_properties(struct PuppyLight *light, s32 x, s32 y, s32 z, s32 offsetX, s32 offsetY, s32 offsetZ, s32 yaw, s32 epicentre, s32 colour, s32 flags, s32 active);
|
||||||
|
extern void puppylights_allocate(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -289,6 +289,7 @@ struct Object *allocate_object(struct ObjectNode *objList) {
|
|||||||
obj->header.gfx.pos[1] = -10000.0f;
|
obj->header.gfx.pos[1] = -10000.0f;
|
||||||
obj->header.gfx.pos[2] = -10000.0f;
|
obj->header.gfx.pos[2] = -10000.0f;
|
||||||
obj->header.gfx.throwMatrix = NULL;
|
obj->header.gfx.throwMatrix = NULL;
|
||||||
|
obj->oLightID = 0xFFFF;
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user