mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-05-23 06:34:18 -04:00
link m_lights
This commit is contained in:
@@ -48,6 +48,10 @@ m_kabu_manager.c:
|
||||
.text: [0x803B5CC4, 0x803B6280]
|
||||
.rodata: [0x80642480, 0x806424C0]
|
||||
.data: [0x80655D48, 0x80655D78]
|
||||
m_lights.c:
|
||||
.text: [0x803BB960, 0x803BC510]
|
||||
.rodata: [0x80642680, 0x806426D8]
|
||||
.bss: [0x81297B18, 0x81297CA0]
|
||||
m_malloc.c:
|
||||
.text: [0x803BC510, 0x803BC70C]
|
||||
.bss: [0x81297CA0, 0x81297CD0]
|
||||
|
||||
@@ -336,7 +336,7 @@ typedef struct {
|
||||
unsigned char col[3];
|
||||
unsigned char kc;
|
||||
unsigned char colc[3];
|
||||
unsigned char k1;
|
||||
unsigned char kl;
|
||||
signed short pos[3]; /* position of light */
|
||||
unsigned char kq;
|
||||
} Light_pos_t;
|
||||
|
||||
+63
-7
@@ -2,25 +2,81 @@
|
||||
#define M_LIGHTS_H
|
||||
|
||||
#include "types.h"
|
||||
#include "PR/mbi.h"
|
||||
#include "libforest/gbi_extensions.h"
|
||||
#include "m_lib.h"
|
||||
#include "m_play_h.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct lightsn_s {
|
||||
u8 diffuse_count;
|
||||
Lights7 lights;
|
||||
} LightsN;
|
||||
typedef struct {
|
||||
/* 0x0 */ s16 x;
|
||||
/* 0x2 */ s16 y;
|
||||
/* 0x4 */ s16 z;
|
||||
/* 0x6 */ u8 color[3];
|
||||
/* 0x9 */ u8 drawGlow;
|
||||
/* 0xA */ s16 radius;
|
||||
} LightPoint; // size = 0xC
|
||||
|
||||
typedef struct {
|
||||
/* 0x0 */ s8 x;
|
||||
/* 0x1 */ s8 y;
|
||||
/* 0x2 */ s8 z;
|
||||
/* 0x3 */ u8 color[3];
|
||||
} LightDiffuse; // size = 0x6
|
||||
|
||||
typedef union {
|
||||
LightPoint point;
|
||||
LightDiffuse diffuse;
|
||||
} LightParams; // size = 0xC
|
||||
|
||||
typedef struct lights_s {
|
||||
u8 type;
|
||||
LightParams lights;
|
||||
} Lights;
|
||||
|
||||
|
||||
typedef struct LightNode {
|
||||
/* 0x0 */ Lights* info;
|
||||
/* 0x4 */ struct LightNode* prev;
|
||||
/* 0x8 */ struct LightNode* next;
|
||||
} LightNode; // size = 0xC
|
||||
|
||||
typedef struct light_buf_s{
|
||||
int current;
|
||||
int idx;
|
||||
LightNode lights[32];
|
||||
}Light_buffer;
|
||||
|
||||
|
||||
typedef struct lightsn_s{
|
||||
u8 diffuse_count;
|
||||
Ambient a;
|
||||
Light_new l[7];
|
||||
}LightsN;
|
||||
|
||||
typedef struct global_light_s {
|
||||
/* 0x0 */ void* list;
|
||||
/* 0x0 */ LightNode* list;
|
||||
/* 0x4 */ u8 ambientColor[3];
|
||||
/* 0x7 */ u8 fogColor[3];
|
||||
/* 0xA */ s16 fogNear;
|
||||
/* 0xC */ s16 fogFar;
|
||||
} Global_light;
|
||||
} Global_light; // size = 0x10
|
||||
|
||||
typedef void (*light_point_proc)(LightsN*, LightParams*, xyz_t*);
|
||||
typedef void (*light_P_point_proc)(LightsN*, LightParams*, xyz_t*);
|
||||
|
||||
extern void Light_point_ct(Lights* lights, s16 x, s16 y, s16 z, u8 r, u8 g, u8 b, s16 radius);
|
||||
extern void Light_diffuse_ct(Lights* lights, s8 x, s8 y, s8 z, u8 r, u8 g, u8 b);
|
||||
extern void LightsN_disp_BG(LightsN* lights, GRAPH* graph);
|
||||
extern void LightsN_disp(LightsN* lights, GRAPH* graph);
|
||||
extern void LightsN_list_check(LightsN* lights, LightNode* node, xyz_t* pos);
|
||||
extern void Global_light_ct(Global_light* glight);
|
||||
extern void Global_light_read(Global_light* glight, GRAPH* graph);
|
||||
extern void Global_light_list_new(GAME_PLAY*, Global_light* glight, Lights* light);
|
||||
extern void Global_light_list_delete(Global_light* glight, LightNode* light);
|
||||
extern void Light_list_point_draw(GAME_PLAY* play);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
+406
@@ -0,0 +1,406 @@
|
||||
#include "m_lights.h"
|
||||
|
||||
#include "m_rcp.h"
|
||||
#include "libultra/libultra.h"
|
||||
#include "m_play.h"
|
||||
#include "sys_matrix.h"
|
||||
Light_buffer light_list_buf;
|
||||
|
||||
extern Gfx point_light_init_model[];
|
||||
extern Gfx point_light_model[];
|
||||
|
||||
static void Light_point_color_set(Lights* lights, u8 r, u8 g, u8 b, s16 radius);
|
||||
static void Global_light_list_ct(Global_light* light);
|
||||
static void Global_light_ambient_set(Global_light* light, u8 r,u8 g,u8 b);
|
||||
static void Global_light_fog_set(Global_light* light ,u8 r,u8 g,u8 b,s16 near,s16 far);
|
||||
static LightsN* new_LightsN(GRAPH*, u8 r, u8 g, u8 b);
|
||||
|
||||
|
||||
static void point_data_set(Lights* lights, s16 x, s16 y, s16 z,u8 r, u8 g, u8 b, s16 radius, int type ){
|
||||
|
||||
lights->type = type;
|
||||
lights->lights.point.x = x;
|
||||
lights->lights.point.y = y;
|
||||
lights->lights.point.z = z;
|
||||
Light_point_color_set(lights,r,g,b,radius);
|
||||
}
|
||||
|
||||
extern void Light_point_ct(Lights* lights, s16 x, s16 y, s16 z, u8 r, u8 g, u8 b, s16 radius){
|
||||
|
||||
point_data_set(lights, x, y, z, r,g,b,radius,0);
|
||||
}
|
||||
|
||||
static void Light_point_color_set(Lights* lights, u8 r, u8 g, u8 b, s16 radius){
|
||||
|
||||
lights->lights.point.color[0] = r;
|
||||
lights->lights.point.color[1] = g;
|
||||
lights->lights.point.color[2] = b;
|
||||
lights->lights.point.radius = radius;
|
||||
}
|
||||
|
||||
extern void Light_diffuse_ct(Lights* lights, s8 x, s8 y, s8 z, u8 r, u8 g, u8 b){
|
||||
|
||||
lights->type = 1;
|
||||
lights->lights.diffuse.x = x;
|
||||
lights->lights.diffuse.y = y;
|
||||
lights->lights.diffuse.z = z;
|
||||
lights->lights.diffuse.color[0] = r;
|
||||
lights->lights.diffuse.color[1] = g;
|
||||
lights->lights.diffuse.color[2] = b;
|
||||
|
||||
}
|
||||
|
||||
extern void LightsN_disp_BG(LightsN* lights, GRAPH* graph){
|
||||
|
||||
Light_new* light;
|
||||
int i;
|
||||
|
||||
OPEN_DISP(graph);
|
||||
|
||||
gSPNumLights(NOW_BG_OPA_DISP++, lights->diffuse_count);
|
||||
|
||||
|
||||
light = lights->l;
|
||||
|
||||
for(i = 0; i < lights->diffuse_count; i){
|
||||
i++;
|
||||
gSPLight(NOW_BG_OPA_DISP++, light, i);
|
||||
gSPLight(NOW_BG_XLU_DISP++, light, i);
|
||||
light++;
|
||||
}
|
||||
|
||||
i++;
|
||||
gSPLight(NOW_BG_OPA_DISP++, &lights->a.l, i);
|
||||
gSPLight(NOW_BG_XLU_DISP++, &lights->a.l, i);
|
||||
|
||||
CLOSE_DISP(graph);
|
||||
}
|
||||
|
||||
extern void LightsN_disp(LightsN* lights, GRAPH* graph){
|
||||
|
||||
Light_new* light;
|
||||
int i;
|
||||
Gfx* opa_gfx;
|
||||
Gfx* xlu_gfx;
|
||||
|
||||
|
||||
OPEN_DISP(graph);
|
||||
opa_gfx = NOW_POLY_OPA_DISP;
|
||||
xlu_gfx = NOW_POLY_XLU_DISP;
|
||||
|
||||
gSPNumLights(opa_gfx++, lights->diffuse_count);
|
||||
gSPNumLights(xlu_gfx++, lights->diffuse_count);
|
||||
|
||||
light = lights->l;
|
||||
|
||||
for(i = 0; i < lights->diffuse_count;){
|
||||
i++;
|
||||
gSPLight(opa_gfx++, light, i);
|
||||
gSPLight(xlu_gfx++, light, i);
|
||||
light++;
|
||||
}
|
||||
|
||||
i++;
|
||||
gSPLight(opa_gfx++, &lights->a.l, i);
|
||||
gSPLight(xlu_gfx++, &lights->a.l, i);
|
||||
|
||||
SET_POLY_OPA_DISP(opa_gfx);
|
||||
SET_POLY_XLU_DISP(xlu_gfx);
|
||||
CLOSE_DISP(graph);
|
||||
}
|
||||
|
||||
static Light_new* LightsN_new_diffuse(LightsN* lights){
|
||||
|
||||
if(lights->diffuse_count >= 7){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &lights->l[lights->diffuse_count++];
|
||||
}
|
||||
|
||||
static void LightsN__point_proc(LightsN* lights, LightParams* lightInfo, xyz_t* point){
|
||||
f32 xdiff;
|
||||
f32 ydiff;
|
||||
f32 zdiff;
|
||||
f32 pointd;
|
||||
f32 rad;
|
||||
Light_new* light;
|
||||
|
||||
if((point != NULL) && (lightInfo->point.radius > 0)){
|
||||
xdiff = lightInfo->point.x - point->x;
|
||||
ydiff = lightInfo->point.y - point->y;
|
||||
zdiff = lightInfo->point.z - point->z;
|
||||
pointd = (xdiff * xdiff) + (ydiff * ydiff) + (zdiff * zdiff);
|
||||
|
||||
rad = lightInfo->point.radius;
|
||||
|
||||
if(pointd < (rad * rad)){
|
||||
light = LightsN_new_diffuse(lights);
|
||||
|
||||
if(light != NULL){
|
||||
pointd = sqrtf(pointd);
|
||||
rad = pointd / rad;
|
||||
rad = 1 - (rad* rad);
|
||||
|
||||
light->l.col[0] = light->l.colc[0] = lightInfo->point.color[0] * rad;
|
||||
light->l.col[1] = light->l.colc[1] = lightInfo->point.color[1] * rad;
|
||||
light->l.col[2] = light->l.colc[2] = lightInfo->point.color[2] * rad;
|
||||
|
||||
rad = (pointd < 1) ? 120.0f : 120.0f / pointd;
|
||||
|
||||
light->l.dir[0] = xdiff * rad;
|
||||
light->l.dir[1] = ydiff * rad;
|
||||
light->l.dir[2] = zdiff * rad;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void LightsN__P_point_proc(LightsN* lights, LightParams* lightInfo, xyz_t*){
|
||||
|
||||
f32 rad;
|
||||
xyz_t point;
|
||||
Light_new* light;
|
||||
f32 kq;
|
||||
|
||||
if(lightInfo->point.radius > 0){
|
||||
light = LightsN_new_diffuse(lights);
|
||||
|
||||
if(light != NULL){
|
||||
rad = lightInfo->point.radius;
|
||||
kq = 4500000.0f / (rad * rad);
|
||||
if(kq > 255.0f){
|
||||
kq = 255.0f;
|
||||
}
|
||||
else if(kq < 20.0f){
|
||||
kq = 20.0f;
|
||||
}
|
||||
light->l.col[0] = lightInfo->point.color[0];
|
||||
light->l.colc[0] = light->l.col[0];
|
||||
|
||||
light->l.col[1] = lightInfo->point.color[1];
|
||||
light->l.colc[1] = light->l.col[1];
|
||||
|
||||
light->l.col[2] = lightInfo->point.color[2];
|
||||
light->l.colc[2] = light->l.col[2];
|
||||
|
||||
light->p.pos[0] = lightInfo->point.x;
|
||||
light->p.pos[1] = lightInfo->point.y;
|
||||
light->p.pos[2] = lightInfo->point.z;
|
||||
light->p.kc = 8;
|
||||
light->p.kl = -1;
|
||||
light->p.kq = kq;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void LightsN__diffuse_proc(LightsN* lights, LightParams* lightInfo){
|
||||
|
||||
Light_new* light;
|
||||
|
||||
light = LightsN_new_diffuse(lights);
|
||||
|
||||
if(light != NULL){
|
||||
light->l.col[0] = light->l.colc[0] = lightInfo->diffuse.color[0];
|
||||
light->l.col[1] = light->l.colc[1] = lightInfo->diffuse.color[1];
|
||||
light->l.col[2] = light->l.colc[2] = lightInfo->diffuse.color[2];
|
||||
light->l.dir[0] = lightInfo->diffuse.x;
|
||||
light->l.dir[1] = lightInfo->diffuse.y;
|
||||
light->l.dir[2] = lightInfo->diffuse.z;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern void LightsN_list_check(LightsN* lights, LightNode* node, xyz_t* pos){
|
||||
|
||||
const static light_point_proc poslight_type_proc[] = {
|
||||
LightsN__point_proc,
|
||||
(light_point_proc)LightsN__diffuse_proc,
|
||||
LightsN__point_proc
|
||||
};
|
||||
|
||||
const static light_P_point_proc light_type_proc[] = {
|
||||
LightsN__P_point_proc,
|
||||
(light_P_point_proc)LightsN__diffuse_proc,
|
||||
LightsN__P_point_proc
|
||||
};
|
||||
|
||||
if(pos == NULL){
|
||||
while(node != NULL) {
|
||||
light_type_proc[node->info->type](lights, &node->info->lights, pos);
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
else{
|
||||
while(node != NULL) {
|
||||
poslight_type_proc[node->info->type](lights, &node->info->lights, pos);
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static LightNode* Light_list_buf_new(){
|
||||
|
||||
LightNode* light;
|
||||
|
||||
if(light_list_buf.current >= 32){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
light = &light_list_buf.lights[light_list_buf.idx];
|
||||
|
||||
while(light->info != NULL){
|
||||
light_list_buf.idx++;
|
||||
if(light_list_buf.idx < 32){
|
||||
light++;
|
||||
}
|
||||
else{
|
||||
light_list_buf.idx = 0;
|
||||
light = &light_list_buf.lights[0];
|
||||
}
|
||||
}
|
||||
|
||||
light_list_buf.current++;
|
||||
return light;
|
||||
}
|
||||
|
||||
static void Light_list_buf_delete(LightNode* light){
|
||||
if(light != NULL){
|
||||
light_list_buf.current--;
|
||||
light->info = NULL;
|
||||
light_list_buf.idx = (light - light_list_buf.lights) / (int)(sizeof(LightNode));
|
||||
}
|
||||
}
|
||||
|
||||
extern void Global_light_ct(Global_light* glight){
|
||||
|
||||
Global_light_list_ct(glight);
|
||||
Global_light_ambient_set(glight, 80,80,80);
|
||||
Global_light_fog_set(glight, 0,0,0, 996, 1600);
|
||||
bzero(&light_list_buf, sizeof(Light_buffer));
|
||||
}
|
||||
|
||||
static void Global_light_ambient_set(Global_light* glight, u8 r, u8 g, u8 b){
|
||||
|
||||
glight->ambientColor[0] = r;
|
||||
glight->ambientColor[1] = g;
|
||||
glight->ambientColor[2] = b;
|
||||
|
||||
}
|
||||
|
||||
static void Global_light_fog_set(Global_light* glight, u8 r, u8 g, u8 b, s16 near, s16 far){
|
||||
|
||||
glight->fogColor[0] = r;
|
||||
glight->fogColor[1] = g;
|
||||
glight->fogColor[2] = b;
|
||||
glight->fogNear = near;
|
||||
glight->fogFar = far;
|
||||
|
||||
}
|
||||
|
||||
|
||||
extern void Global_light_read(Global_light* glight, GRAPH* graph){
|
||||
|
||||
new_LightsN(graph, glight->ambientColor[0], glight->ambientColor[1], glight->ambientColor[2]);
|
||||
}
|
||||
|
||||
static void Global_light_list_ct(Global_light* glight){
|
||||
|
||||
glight->list = NULL;
|
||||
}
|
||||
|
||||
extern void Global_light_list_new(GAME_PLAY*, Global_light* glight, Lights* light){
|
||||
|
||||
LightNode* clight;
|
||||
|
||||
clight = Light_list_buf_new();
|
||||
|
||||
if(clight != NULL){
|
||||
clight->info = light;
|
||||
clight->prev = NULL;
|
||||
clight->next = glight->list;
|
||||
|
||||
if(glight->list != NULL){
|
||||
glight->list->prev = clight;
|
||||
}
|
||||
|
||||
glight->list = clight;
|
||||
}
|
||||
}
|
||||
|
||||
extern void Global_light_list_delete(Global_light* glight, LightNode* light){
|
||||
|
||||
if(light != NULL){
|
||||
if(light->prev != NULL){
|
||||
light->prev->next = light->next;
|
||||
}
|
||||
else{
|
||||
glight->list = light->next;
|
||||
}
|
||||
|
||||
if(light->next != NULL){
|
||||
light->next->prev = light->prev;
|
||||
}
|
||||
Light_list_buf_delete(light);
|
||||
}
|
||||
}
|
||||
|
||||
static LightsN* new_LightsN(GRAPH* graph, u8 r, u8 g, u8 b){
|
||||
|
||||
LightsN* light;
|
||||
|
||||
light = GRAPH_ALLOC(graph, sizeof(LightsN));
|
||||
|
||||
light->a.l.col[0] = light->a.l.colc[0] = r;
|
||||
light->a.l.col[1] = light->a.l.colc[1] = g;
|
||||
light->a.l.col[2] = light->a.l.colc[2] = b;
|
||||
|
||||
light->diffuse_count = 0;
|
||||
|
||||
return light;
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern void Light_list_point_draw(GAME_PLAY* play){
|
||||
LightPoint* lightInfo;
|
||||
LightNode* light;
|
||||
GRAPH* g = play->game.graph;
|
||||
f32 rad;
|
||||
Gfx* dl;
|
||||
|
||||
light = play->global_light.list;
|
||||
|
||||
|
||||
OPEN_DISP(g);
|
||||
dl = gfx_softsprite_prim_xlu(NOW_POLY_XLU_DISP);
|
||||
|
||||
gDPSetAlphaDither(dl++, G_AD_NOISE);
|
||||
gDPSetColorDither(dl++, G_CD_MAGICSQ);
|
||||
gSPDisplayList(dl++,point_light_init_model);
|
||||
|
||||
while(light != NULL) {
|
||||
if(light->info->type == 2){
|
||||
lightInfo = &light->info->lights.point;
|
||||
if(lightInfo->drawGlow){
|
||||
rad = (lightInfo->radius * lightInfo->radius) * 2.60000001617e-06f;
|
||||
gDPSetPrimColor(dl++, 0, 0, lightInfo->color[0], lightInfo->color[1], lightInfo->color[2], 50);
|
||||
|
||||
Matrix_translate(lightInfo->x, lightInfo->y, lightInfo->z, 0);
|
||||
Matrix_scale(rad,rad,rad, 1);
|
||||
|
||||
gSPMatrix(dl++, _Matrix_to_Mtx_new(play->game.graph),G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
|
||||
gSPDisplayList(dl++,point_light_model);
|
||||
}
|
||||
}
|
||||
light = light->next;
|
||||
}
|
||||
|
||||
SET_POLY_XLU_DISP(dl);
|
||||
CLOSE_DISP(g);
|
||||
}
|
||||
+1
-1
Submodule tools/ppcdis updated: 29c3a24832...396925fc98
Reference in New Issue
Block a user