summaryrefslogtreecommitdiff
path: root/src/code
diff options
context:
space:
mode:
Diffstat (limited to 'src/code')
-rw-r--r--src/code/m_actor.c11
-rw-r--r--src/code/m_lights.c369
2 files changed, 374 insertions, 6 deletions
diff --git a/src/code/m_actor.c b/src/code/m_actor.c
index 809a754..1762c01 100644
--- a/src/code/m_actor.c
+++ b/src/code/m_actor.c
@@ -251,7 +251,7 @@ void Actor_dt(Actor* actor, struct Game_Play* game_play);
void Actor_draw(Game_Play* game_play, Actor* actor) {
FaultClient faultClient;
- Lights* light;
+ LightsN* light;
Fault_AddClient(&faultClient, func_80056380_jp, actor, "Actor_draw");
@@ -263,9 +263,8 @@ void Actor_draw(Game_Play* game_play, Actor* actor) {
OPEN_DISPS(game_play->state.gfxCtx);
- light = Global_light_read(&game_play->lightCtx, game_play->state.gfxCtx);
- LightsN_list_check(light, game_play->lightCtx.listHead,
- (actor->flags & ACTOR_FLAG_400000) ? NULL : &actor->world.pos);
+ light = Global_light_read(&game_play->glight, game_play->state.gfxCtx);
+ LightsN_list_check(light, game_play->glight.list, (actor->flags & ACTOR_FLAG_400000) ? NULL : &actor->world.pos);
LightsN_disp(light, game_play->state.gfxCtx);
Matrix_softcv3_load(actor->world.pos.x, actor->world.pos.y + actor->shape.unk_08 * actor->scale.y,
@@ -345,8 +344,8 @@ void Actor_delete_check(Actor* actor, Game_Play* game_play) {
Actor_delete(actor);
}
-void Actor_info_ct(Game_Play* play2, ActorInfo* actorInfo, ActorEntry* actorEntry) {
- Game_Play* game_play = play2;
+void Actor_info_ct(Game_Play* game_play2, ActorInfo* actorInfo, ActorEntry* actorEntry) {
+ Game_Play* game_play = game_play2;
Actor* temp_v0;
ActorOverlay* var_v0;
ActorEntry* var_s0_2;
diff --git a/src/code/m_lights.c b/src/code/m_lights.c
new file mode 100644
index 0000000..172fba0
--- /dev/null
+++ b/src/code/m_lights.c
@@ -0,0 +1,369 @@
+#include "global.h"
+#include "m_lights.h"
+#include "gfx.h"
+#include "macros.h"
+#include "sys_matrix.h"
+#include "overlays/gamestates/ovl_play/m_play.h"
+#include "6E0F50.h"
+
+extern Gfx D_400AA00[]; // point_light_init_model
+extern Gfx D_400AA40[]; // point_light_model
+
+LightBuffer light_list_buf;
+
+void point_data_set(Lights* lights, s16 x, s16 y, s16 z, u8 r, u8 g, u8 b, s16 radius, s32 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);
+}
+
+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);
+}
+
+void Light_point2_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, 2);
+}
+
+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;
+}
+
+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;
+}
+
+void LightsN_ct(LightsN* lights, u8 r, u8 g, u8 b) {
+ lights->lights.a.l.col[0] = lights->lights.a.l.colc[0] = r;
+ lights->lights.a.l.col[1] = lights->lights.a.l.colc[1] = g;
+ lights->lights.a.l.col[2] = lights->lights.a.l.colc[2] = b;
+ lights->diffuse_count = 0;
+}
+
+void LightsN_disp(LightsN* lights, GraphicsContext* gfxCtx) {
+ Light* light;
+ s32 i;
+ Gfx* opaGfx;
+ Gfx* xluGfx;
+
+ OPEN_DISPS(gfxCtx);
+
+ opaGfx = POLY_OPA_DISP;
+ xluGfx = POLY_XLU_DISP;
+
+ gSPNumLights(opaGfx++, lights->diffuse_count);
+ gSPNumLights(xluGfx++, lights->diffuse_count);
+
+ light = lights->lights.l;
+
+ for (i = 0; i < lights->diffuse_count;) {
+ i++;
+ gSPLight(opaGfx++, light, i);
+ gSPLight(xluGfx++, light, i);
+ light++;
+ }
+
+ i++;
+ gSPLight(opaGfx++, &lights->lights.a.l, i);
+ gSPLight(xluGfx++, &lights->lights.a.l, i);
+
+ POLY_OPA_DISP = opaGfx;
+ POLY_XLU_DISP = xluGfx;
+
+ CLOSE_DISPS(gfxCtx);
+}
+
+Light* LightsN_new_diffuse(LightsN* lights) {
+ if (lights->diffuse_count >= ARRAY_COUNT(lights->lights.l)) {
+ return NULL;
+ }
+
+ return &lights->lights.l[lights->diffuse_count++];
+}
+
+void LightsN__point_proc(LightsN* lights, LightParams* lightInfo, Vec3f* point) {
+ f32 xdiff;
+ f32 ydiff;
+ f32 zdiff;
+ f32 pointd;
+ f32 rad;
+ Light* 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 = SQ(xdiff) + SQ(ydiff) + SQ(zdiff);
+
+ rad = lightInfo->point.radius;
+
+ if (pointd < SQ(rad)) {
+ light = LightsN_new_diffuse(lights);
+
+ if (light != NULL) {
+ pointd = sqrtf(pointd);
+ rad = pointd / rad;
+ rad = 1 - SQ(rad);
+
+ light->l.col[0] = light->l.colc[0] = (s8)(lightInfo->point.color[0] * rad);
+ light->l.col[1] = light->l.colc[1] = (s8)(lightInfo->point.color[1] * rad);
+ light->l.col[2] = light->l.colc[2] = (s8)(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;
+ }
+ }
+ }
+}
+
+void LightsN__P_point_proc(LightsN* lights, LightParams* lightInfo, UNUSED Vec3f* pos) {
+ if (lightInfo->point.radius > 0) {
+ Light* light = LightsN_new_diffuse(lights);
+
+ if (light != NULL) {
+ f32 kq = lightInfo->point.radius;
+ kq = 4500000 / SQ(kq);
+
+ if (kq > 255) {
+ kq = 255;
+ } else if (kq < 20) {
+ kq = 20;
+ }
+
+ 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 = (s32)kq;
+ }
+ }
+}
+
+void LightsN__diffuse_proc(LightsN* lights, LightParams* lightInfo, UNUSED Vec3f* pos) {
+ 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;
+ }
+}
+
+void LightsN_list_check(LightsN* lights, LightNode* node, Vec3f* pos) {
+ static light_point_proc poslight_type_proc[] = {
+ LightsN__point_proc,
+ LightsN__diffuse_proc,
+ LightsN__point_proc,
+ };
+ static light_P_point_proc light_type_proc[] = {
+ LightsN__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;
+ }
+ }
+}
+
+LightNode* Light_list_buf_new(void) {
+ LightNode* lightNode;
+
+ if (light_list_buf.current >= ARRAY_COUNT(light_list_buf.lights)) {
+ return NULL;
+ }
+
+ lightNode = &light_list_buf.lights[light_list_buf.idx];
+
+ while (lightNode->info != NULL) {
+ light_list_buf.idx++;
+ if (light_list_buf.idx < ARRAY_COUNT(light_list_buf.lights)) {
+ lightNode++;
+ } else {
+ light_list_buf.idx = 0;
+ lightNode = &light_list_buf.lights[0];
+ }
+ }
+ light_list_buf.current++;
+ return lightNode;
+}
+
+void Light_list_buf_delete(LightNode* lightNode) {
+ if (lightNode != NULL) {
+ light_list_buf.current--;
+ lightNode->info = NULL;
+ light_list_buf.idx = (lightNode - light_list_buf.lights) / (s32)sizeof(LightNode);
+ }
+}
+
+void Global_light_ct(Global_light* glight) {
+ Global_light_list_ct(glight);
+ Global_light_ambient_set(glight, 0x50, 0x50, 0x50);
+ Global_light_fog_set(glight, 0, 0, 0, 0x3E4, 0x640);
+ bzero(&light_list_buf, sizeof(LightBuffer));
+}
+
+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;
+}
+
+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;
+}
+
+LightsN* Global_light_read(Global_light* glight, struct GraphicsContext* gfxCtx) {
+ return new_LightsN(gfxCtx, glight->ambientColor[0], glight->ambientColor[1], glight->ambientColor[2]);
+}
+
+void Global_light_list_ct(Global_light* glight) {
+ glight->list = NULL;
+}
+
+void Global_light_list_dt(Global_light* glight) {
+ while (glight->list != NULL) {
+ Global_light_list_delete(glight, glight->list);
+ glight->list = glight->list->next;
+ }
+}
+
+LightNode* Global_light_list_new(UNUSED Game_Play* play, Global_light* glight, Lights* light) {
+ LightNode* newNode = Light_list_buf_new();
+
+ if (newNode != NULL) {
+ newNode->info = light;
+ newNode->prev = NULL;
+ newNode->next = glight->list;
+ if (glight->list != NULL) {
+ glight->list->prev = newNode;
+ }
+ glight->list = newNode;
+ }
+ return newNode;
+}
+
+void Global_light_list_delete(Global_light* glight, LightNode* lightNode) {
+ if (lightNode != NULL) {
+ if (lightNode->prev != NULL) {
+ lightNode->prev->next = lightNode->next;
+ } else {
+ glight->list = lightNode->next;
+ }
+ if (lightNode->next != NULL) {
+ lightNode->next->prev = lightNode->prev;
+ }
+ Light_list_buf_delete(lightNode);
+ }
+}
+
+LightsN* new_Lights(GraphicsContext* gfxCtx, u8 ambient_r, u8 ambient_g, u8 ambient_b, u8 count, u8 light_r, u8 light_g,
+ u8 light_b, s8 dir_x, s8 dir_y, s8 dir_z) {
+ LightsN* lights = GRAPH_ALLOC(gfxCtx, sizeof(LightsN) * 1);
+ s32 i;
+
+ lights->lights.a.l.col[0] = lights->lights.a.l.colc[0] = ambient_r;
+ lights->lights.a.l.col[1] = lights->lights.a.l.colc[1] = ambient_g;
+ lights->lights.a.l.col[2] = lights->lights.a.l.colc[2] = ambient_b;
+ lights->diffuse_count = count;
+
+ for (i = 0; i < count; i++) {
+ lights->lights.l[i].l.col[0] = lights->lights.l[i].l.colc[0] = light_r;
+ lights->lights.l[i].l.col[1] = lights->lights.l[i].l.colc[1] = light_g;
+ lights->lights.l[i].l.col[2] = lights->lights.l[i].l.colc[2] = light_b;
+
+ lights->lights.l[i].l.dir[0] = dir_x;
+ lights->lights.l[i].l.dir[1] = dir_y;
+ lights->lights.l[i].l.dir[2] = dir_z;
+ }
+
+ LightsN_disp(lights, gfxCtx);
+ return lights;
+}
+
+LightsN* new_LightsN(GraphicsContext* gfxCtx, u8 r, u8 g, u8 b) {
+ LightsN* lights = GRAPH_ALLOC(gfxCtx, sizeof(LightsN) * 1);
+
+ lights->lights.a.l.col[0] = r;
+ lights->lights.a.l.colc[0] = r;
+ lights->lights.a.l.col[1] = g;
+ lights->lights.a.l.colc[1] = g;
+ lights->lights.a.l.col[2] = b;
+ lights->lights.a.l.colc[2] = b;
+ lights->diffuse_count = 0;
+ return lights;
+}
+
+void Light_list_point_draw(Game_Play* game_play) {
+ LightNode* lightNode = game_play->glight.list;
+ Gfx* gfx;
+
+ OPEN_DISPS(game_play->state.gfxCtx);
+ gfx = func_800BD7C0_jp(POLY_XLU_DISP);
+
+ gDPSetAlphaDither(gfx++, G_AD_NOISE);
+ gDPSetColorDither(gfx++, G_CD_MAGICSQ);
+ gSPDisplayList(gfx++, D_400AA00);
+
+ while (lightNode != NULL) {
+ LightParams* lightParams = &lightNode->info->lights;
+
+ if ((lightNode->info->type == 2) && lightParams->point.drawGlow) {
+ f32 rad = SQ(lightParams->point.radius) * 0.0000026f;
+
+ gDPSetPrimColor(gfx++, 0, 0, lightParams->point.color[0], lightParams->point.color[1],
+ lightParams->point.color[2], 50);
+
+ Matrix_translate(lightParams->point.x, lightParams->point.y, lightParams->point.z, 0);
+ Matrix_scale(rad, rad, rad, 1);
+
+ gSPMatrix(gfx++, _Matrix_to_Mtx_new(game_play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(gfx++, D_400AA40);
+ }
+ lightNode = lightNode->next;
+ }
+
+ POLY_XLU_DISP = gfx;
+
+ CLOSE_DISPS(game_play->state.gfxCtx);
+}