Document artifacts
This commit is contained in:
parent
ce8ff8822b
commit
62e9f4d1a6
|
@ -17,10 +17,71 @@
|
|||
#include "data.h"
|
||||
#include "types.h"
|
||||
|
||||
/**
|
||||
* Artifacts are points of interest in the z-buffer.
|
||||
*
|
||||
* They correspond to:
|
||||
* - Individual circles in the lens flare effect from the sun.
|
||||
* - Individual corners of each light fixture's box.
|
||||
*
|
||||
* The game needs to do line of sight checks to these points. The collision
|
||||
* system would normally be used for line of sight checks, but it only works
|
||||
* with basic geometric volumes and also doesn't take into account the player's
|
||||
* gun. Instead, the checks are done by reading from the previous frame's
|
||||
* z-buffer.
|
||||
*
|
||||
* Typically, the z-buffer would be read by the scheduler after a graphics frame
|
||||
* is rendered, but this only works if the z-buffer is a complete image.
|
||||
* PD draws the scene, then clears the z-buffer before drawing the player's gun,
|
||||
* so the z-buffer at the end only contains the player's gun. To work around
|
||||
* this, the GPU is given commands to read the z-buffer as a texture and copy
|
||||
* depth values to a safe place before clearing it. Then once the frame is
|
||||
* rendered, the scheduler compares the saved depths with the current z-buffer
|
||||
* and updates the artifact, applying the minimum of the two depths.
|
||||
*
|
||||
* The scheduler maintains 3 arrays of artifacts, each referenced by indexes
|
||||
* which rotate between them.
|
||||
* - Artifacts are written by the main thread using the write index.
|
||||
* The write and front indexes are then incremented.
|
||||
* - The same artifacts are updated by the scheduler using the pending index.
|
||||
* The pending index is then updated.
|
||||
* - The artifacts are then rendered on a later frame using the front index.
|
||||
*
|
||||
* In each artifacts array, the first several slots are reserved for the sun
|
||||
* flare artifacts. The quantity depends on the number of suns in the stage
|
||||
* (Skedar Ruins has 3) and there are 8 artifacts per sun. The remaining slots
|
||||
* are used for light fixture corners. The array is big enough to handle at
|
||||
* least 90 lights on screen at a time.
|
||||
*
|
||||
* The initial state of the indexes are write=0, front=1, pending=0.
|
||||
* These are set in sched_reset_artifacts.
|
||||
*
|
||||
* The detailed workflow is:
|
||||
* - CPU: Light artifacts are determined and added to write artifacts (0) array
|
||||
* - CPU: Constructs the gdl in this order:
|
||||
* - Render scene
|
||||
* - Copy relevant parts of z-buffer to write depths (0) array
|
||||
* - Clear z-buffer and render gun
|
||||
* - Render artifacts by reading from front artifacts (1) array
|
||||
* - CPU: increments write (0 -> 1) and front (1 -> 2) indexes
|
||||
* - GPU: Executes above task. g_ArtifactDepths0 now contains depths, and is
|
||||
* pointed to by pending.
|
||||
* - Scheduler: Reads the z-buffer, which at this point only contains the gun
|
||||
* depth information, and updates the artifact with the minimum of the two
|
||||
* - Scheduler: Increments pending (0 -> 1)
|
||||
*
|
||||
* It appears that the front index should be initialised to 2 instead, so that
|
||||
* it's one frame behind the others rather than two frames behind.
|
||||
*
|
||||
* There's no doubt this went through several iterations before landing on this
|
||||
* implementation. It's likely that this was implemented using a single and full
|
||||
* z-buffer and it worked well until they decided to clear the z-buffer before
|
||||
* rendering the gun. There is evidence in zbuf.c that they allocated a second
|
||||
* z-buffer and swapped it. But when memory got too tight they had to change it
|
||||
* to this texture read method.
|
||||
*/
|
||||
|
||||
u8 *var800a41a0;
|
||||
u32 var800a41a4;
|
||||
u32 var800a41a8;
|
||||
u32 var800a41ac;
|
||||
|
||||
void artifacts_clear(void)
|
||||
{
|
||||
|
@ -38,11 +99,11 @@ void artifacts_tick(void)
|
|||
sched_increment_front_artifacts();
|
||||
}
|
||||
|
||||
u16 func0f13c574(f32 arg0)
|
||||
u16 artifacts_calculate_unk04(f32 arg0)
|
||||
{
|
||||
u32 value = arg0 * 8.0f;
|
||||
u32 left;
|
||||
u32 right = value;
|
||||
u32 right;
|
||||
|
||||
if (value > 0x3f800) {
|
||||
right = value & 0x7ff;
|
||||
|
@ -78,10 +139,10 @@ u16 func0f13c574(f32 arg0)
|
|||
left = 0;
|
||||
}
|
||||
|
||||
return left << 13 | (right << 2);
|
||||
return left << 13 | right << 2;
|
||||
}
|
||||
|
||||
s32 func0f13c710(f32 arg0)
|
||||
s32 artifacts_float_to_int(f32 arg0)
|
||||
{
|
||||
if (arg0 > 0.0f) {
|
||||
if (arg0 > 2147483520.0f) {
|
||||
|
@ -198,8 +259,8 @@ void artifacts_calculate_glares_for_room(s32 roomnum)
|
|||
|
||||
if (spdc[3] > 0.0001f) {
|
||||
f20 = 1.0f / spdc[3];
|
||||
x = func0f13c710(viewleft + (1.0f + spdc[0] * f20) * (viewwidth * 0.5f));
|
||||
y = func0f13c710(viewtop + (1.0f - spdc[1] * f20) * (viewheight * 0.5f));
|
||||
x = artifacts_float_to_int(viewleft + (1.0f + spdc[0] * f20) * (viewwidth * 0.5f));
|
||||
y = artifacts_float_to_int(viewtop + (1.0f - spdc[1] * f20) * (viewheight * 0.5f));
|
||||
f0 = (spdc[2] * f20 * 511.0f + 511.0f) * 32.0f;
|
||||
|
||||
if (f0 < 32576.0f) {
|
||||
|
@ -301,8 +362,8 @@ void artifacts_calculate_glares_for_room(s32 roomnum)
|
|||
f20 = -9999.0f;
|
||||
}
|
||||
|
||||
xi = func0f13c710(viewleft + (1.0f + spdc[0] * f20) * (viewwidth * 0.5f));
|
||||
yi = func0f13c710(viewtop + (1.0f - spdc[1] * f20) * (viewheight * 0.5f));
|
||||
xi = artifacts_float_to_int(viewleft + (1.0f + spdc[0] * f20) * (viewwidth * 0.5f));
|
||||
yi = artifacts_float_to_int(viewtop + (1.0f - spdc[1] * f20) * (viewheight * 0.5f));
|
||||
f0 = (spdc[2] * f20 * 511.0f + 511.0f) * 32.0f;
|
||||
|
||||
if (g_ZbufPtr1
|
||||
|
@ -322,12 +383,12 @@ void artifacts_calculate_glares_for_room(s32 roomnum)
|
|||
}
|
||||
|
||||
if (index < MAX_ARTIFACTS) {
|
||||
artifact->unk04 = func0f13c574(f0) >> 2;
|
||||
artifact->unk08 = &g_ZbufPtr1[vi_get_width() * yi + xi];
|
||||
artifact->expecteddepth = artifacts_calculate_unk04(f0) >> 2;
|
||||
artifact->zbufptr = &g_ZbufPtr1[vi_get_width() * yi + xi];
|
||||
artifact->light = &roomlights[i];
|
||||
artifact->type = ARTIFACTTYPE_GLARE;
|
||||
artifact->unk0c.u16_2 = xi;
|
||||
artifact->unk0c.u16_1 = yi;
|
||||
artifact->screenx = xi;
|
||||
artifact->screeny = yi;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -338,17 +399,20 @@ void artifacts_calculate_glares_for_room(s32 roomnum)
|
|||
}
|
||||
}
|
||||
|
||||
u8 func0f13d3c4(u8 arg0, u8 arg1)
|
||||
/**
|
||||
* Clamp the given value to with 7 units of base.
|
||||
*/
|
||||
u8 artifacts_clamp(u8 base, u8 value)
|
||||
{
|
||||
if (arg1 >= arg0 + 7) {
|
||||
return arg0 + 7;
|
||||
if (value >= base + 7) {
|
||||
return base + 7;
|
||||
}
|
||||
|
||||
if (arg1 <= arg0 - 7) {
|
||||
return arg0 - 7;
|
||||
if (value <= base - 7) {
|
||||
return base - 7;
|
||||
}
|
||||
|
||||
return arg1;
|
||||
return value;
|
||||
}
|
||||
|
||||
Gfx *artifacts_configure_for_glares(Gfx *gdl)
|
||||
|
@ -386,18 +450,18 @@ Gfx *artifacts_render_glares_for_room(Gfx *gdl, s32 roomnum)
|
|||
u16 min;
|
||||
u16 max;
|
||||
f32 lightop_cur_frac;
|
||||
s32 t2;
|
||||
s32 numgood;
|
||||
struct light *light;
|
||||
u8 *s3;
|
||||
s32 k;
|
||||
s32 count;
|
||||
u16 t4;
|
||||
u16 actualdepth;
|
||||
f32 add;
|
||||
s32 l;
|
||||
f32 brightness;
|
||||
s32 avg;
|
||||
s32 tolerance;
|
||||
f32 f0;
|
||||
s32 v1;
|
||||
s32 difference;
|
||||
s32 r;
|
||||
s32 g;
|
||||
s32 b;
|
||||
|
@ -405,8 +469,8 @@ Gfx *artifacts_render_glares_for_room(Gfx *gdl, s32 roomnum)
|
|||
u8 colour[4];
|
||||
s16 lightroompos[3];
|
||||
struct coord lightworldpos;
|
||||
struct coord lightscreenpos;
|
||||
f32 spdc[2];
|
||||
struct coord lightworlddiff;
|
||||
f32 screenpos[2];
|
||||
f32 spd4[2];
|
||||
f32 f24;
|
||||
bool extra;
|
||||
|
@ -433,48 +497,48 @@ Gfx *artifacts_render_glares_for_room(Gfx *gdl, s32 roomnum)
|
|||
if (roomnum == light->roomnum) {
|
||||
lightindex = ((uintptr_t)light - (uintptr_t)g_BgLightsFileData) / sizeof(struct light);
|
||||
s3 = &var800a41a0[lightindex * 3];
|
||||
t2 = 0;
|
||||
numgood = 0;
|
||||
min = 0xffff;
|
||||
max = 0;
|
||||
|
||||
for (k = i; k < i + count; k++) {
|
||||
if (artifacts[k].unk04 > max) {
|
||||
max = artifacts[k].unk04;
|
||||
if (artifacts[k].expecteddepth > max) {
|
||||
max = artifacts[k].expecteddepth;
|
||||
}
|
||||
|
||||
if (artifacts[k].unk04 < min) {
|
||||
min = artifacts[k].unk04;
|
||||
if (artifacts[k].expecteddepth < min) {
|
||||
min = artifacts[k].expecteddepth;
|
||||
}
|
||||
}
|
||||
|
||||
avg = (max - min) >> 1;
|
||||
tolerance = (max - min) >> 1;
|
||||
|
||||
if (avg < 25) {
|
||||
avg = 25;
|
||||
if (tolerance < 25) {
|
||||
tolerance = 25;
|
||||
}
|
||||
|
||||
for (k = i; k < i + count; k++) {
|
||||
u16 tmp;
|
||||
t4 = (artifacts[k].unk02 & 0xfffc) >> 2;
|
||||
tmp = artifacts[k].unk04;
|
||||
u16 expecteddepth;
|
||||
actualdepth = (artifacts[k].actualdepth & 0xfffc) >> 2;
|
||||
expecteddepth = artifacts[k].expecteddepth;
|
||||
|
||||
if (tmp < t4) {
|
||||
v1 = t4 - tmp;
|
||||
if (actualdepth > expecteddepth) {
|
||||
difference = actualdepth - expecteddepth;
|
||||
} else {
|
||||
v1 = tmp - t4;
|
||||
difference = expecteddepth - actualdepth;
|
||||
}
|
||||
|
||||
if (avg >= v1) {
|
||||
t2++;
|
||||
if (difference <= tolerance) {
|
||||
numgood++;
|
||||
}
|
||||
|
||||
artifacts[k].type = ARTIFACTTYPE_FREE;
|
||||
}
|
||||
|
||||
s3[0] = func0f13d3c4(s3[0], t2 * 2);
|
||||
s3[0] = artifacts_clamp(s3[0], numgood * 2);
|
||||
|
||||
if (t2 > 0) {
|
||||
brightness = vi_get_fov_y() * 0.017453292f;
|
||||
if (numgood > 0) {
|
||||
brightness = vi_get_fov_y() * DTOR(1.0f);
|
||||
add = cosf(brightness) / sinf(brightness) * 14.6f;
|
||||
|
||||
if (light_is_healthy(roomnum, lightindex - g_Rooms[roomnum].gfxdata->lightsindex)) {
|
||||
|
@ -510,14 +574,14 @@ Gfx *artifacts_render_glares_for_room(Gfx *gdl, s32 roomnum)
|
|||
for (l = 0; l < 3; l++) {
|
||||
lightroompos[l] = (light->bbox[0].s[l] + light->bbox[1].s[l] + light->bbox[2].s[l] + light->bbox[3].s[l]) / 4;
|
||||
lightworldpos.f[l] = lightroompos[l] + g_BgRooms[roomnum].pos.f[l];
|
||||
lightscreenpos.f[l] = lightworldpos.f[l] - g_Vars.currentplayer->cam_pos.f[l];
|
||||
lightworlddiff.f[l] = lightworldpos.f[l] - g_Vars.currentplayer->cam_pos.f[l];
|
||||
}
|
||||
|
||||
mtx4_rotate_vec_in_place(cam_get_world_to_screen_mtxf(), &lightscreenpos);
|
||||
mtx4_rotate_vec_in_place(cam_get_world_to_screen_mtxf(), &lightworlddiff);
|
||||
|
||||
cam0f0b4d04(&lightscreenpos, spdc);
|
||||
cam0f0b4d04(&lightworlddiff, screenpos);
|
||||
|
||||
brightness *= 27500.0f / (-lightscreenpos.z < 1.0f ? 1.0f : -lightscreenpos.z);
|
||||
brightness *= 27500.0f / (-lightworlddiff.z < 1.0f ? 1.0f : -lightworlddiff.z);
|
||||
|
||||
if (light->brightnessmult != 0) {
|
||||
brightness *= light->brightnessmult * (1.0f / 32.0f);
|
||||
|
@ -568,7 +632,7 @@ Gfx *artifacts_render_glares_for_room(Gfx *gdl, s32 roomnum)
|
|||
spd4[0] = f24;
|
||||
spd4[1] = f26;
|
||||
|
||||
func0f0b2740(&gdl, spdc, spd4, 64, 64, false, false, false, 1);
|
||||
func0f0b2740(&gdl, screenpos, spd4, 64, 64, false, false, false, 1);
|
||||
|
||||
if (extra) {
|
||||
colour[0] = 0xff;
|
||||
|
@ -582,7 +646,7 @@ Gfx *artifacts_render_glares_for_room(Gfx *gdl, s32 roomnum)
|
|||
spd4[0] = f24 * 0.4f;
|
||||
spd4[1] = f26 * 0.4f;
|
||||
|
||||
func0f0b2740(&gdl, spdc, spd4, 64, 64, false, false, false, 1);
|
||||
func0f0b2740(&gdl, screenpos, spd4, 64, 64, false, false, false, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8195,7 +8195,7 @@ void bgun_render(Gfx **gdlptr)
|
|||
return;
|
||||
}
|
||||
|
||||
gdl = zbuf_draw_artifacts_offscreen(gdl);
|
||||
gdl = zbuf_save_artifact_depths(gdl);
|
||||
gdl = vi_prepare_zbuf(gdl);
|
||||
gdl = vi0000b1d0(gdl);
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* With this function stubbed, light glares do not render,
|
||||
* nor do suns or their lens flares.
|
||||
*/
|
||||
void func0f0b2150(Gfx **gdlptr, f32 *arg1, f32 *arg2, s32 width, s32 height, s32 arg5, s32 arg6, s32 arg7, s32 arg8, s32 tile, s32 arg10)
|
||||
void func0f0b2150(Gfx **gdlptr, f32 *arg1, f32 *arg2, s32 width, s32 height, bool flip, bool arg6, bool arg7, bool arg8, s32 tile, bool arg10)
|
||||
{
|
||||
if (arg2[0] > 0.0f && arg2[1] > 0.0f) {
|
||||
Gfx *gdl = *gdlptr;
|
||||
|
@ -50,7 +50,7 @@ void func0f0b2150(Gfx **gdlptr, f32 *arg1, f32 *arg2, s32 width, s32 height, s32
|
|||
}
|
||||
|
||||
if (xl < 0) {
|
||||
if (arg5) {
|
||||
if (flip) {
|
||||
t += ((-xl * height) << 5) / (xh - xl);
|
||||
} else {
|
||||
s += ((-xl * width) << 5) / (xh - xl);
|
||||
|
@ -60,7 +60,7 @@ void func0f0b2150(Gfx **gdlptr, f32 *arg1, f32 *arg2, s32 width, s32 height, s32
|
|||
}
|
||||
|
||||
if (yl < 0) {
|
||||
if (arg5) {
|
||||
if (flip) {
|
||||
s += ((-yl * width) << 5) / (yh - yl);
|
||||
} else {
|
||||
t += ((-yl * height) << 5) / (yh - yl);
|
||||
|
@ -80,7 +80,7 @@ void func0f0b2150(Gfx **gdlptr, f32 *arg1, f32 *arg2, s32 width, s32 height, s32
|
|||
yh = heightx4;
|
||||
}
|
||||
|
||||
if (arg5) {
|
||||
if (flip) {
|
||||
dsdx = width / (2.0f * arg2[1]) * 1024.0f;
|
||||
dtdy = height / (2.0f * arg2[0]) * 1024.0f;
|
||||
} else {
|
||||
|
@ -113,7 +113,7 @@ void func0f0b2150(Gfx **gdlptr, f32 *arg1, f32 *arg2, s32 width, s32 height, s32
|
|||
}
|
||||
}
|
||||
|
||||
if (arg5) {
|
||||
if (flip) {
|
||||
gSPTextureRectangleFlip(gdl++, xl, yl, xh, yh, tile, s, t, dsdx, dtdy);
|
||||
} else {
|
||||
gSPTextureRectangle(gdl++, xl, yl, xh, yh, tile, s, t, dsdx, dtdy);
|
||||
|
@ -126,17 +126,17 @@ void func0f0b2150(Gfx **gdlptr, f32 *arg1, f32 *arg2, s32 width, s32 height, s32
|
|||
}
|
||||
}
|
||||
|
||||
void func0f0b26f0(Gfx **gdl, f32 *arg1, f32 *arg2, s32 width, s32 height, bool arg5, bool arg6, bool arg7, bool arg8, s32 tile)
|
||||
void func0f0b26f0(Gfx **gdl, f32 *arg1, f32 *arg2, s32 width, s32 height, bool flip, bool arg6, bool arg7, bool arg8, s32 tile)
|
||||
{
|
||||
func0f0b2150(gdl, arg1, arg2, width, height, arg5, arg6, arg7, arg8, tile, false);
|
||||
func0f0b2150(gdl, arg1, arg2, width, height, flip, arg6, arg7, arg8, tile, false);
|
||||
}
|
||||
|
||||
void func0f0b2740(Gfx **gdl, f32 *arg1, f32 *arg2, s32 width, s32 height, bool arg5, bool arg6, bool arg7, u32 arg8)
|
||||
void func0f0b2740(Gfx **gdl, f32 *arg1, f32 *arg2, s32 width, s32 height, bool flip, bool arg6, bool arg7, bool arg8)
|
||||
{
|
||||
func0f0b2150(gdl, arg1, arg2, width, height, arg5, arg6, arg7, arg8, G_TX_RENDERTILE, false);
|
||||
func0f0b2150(gdl, arg1, arg2, width, height, flip, arg6, arg7, arg8, G_TX_RENDERTILE, false);
|
||||
}
|
||||
|
||||
void func0f0b278c(Gfx **gdlptr, f32 *arg1, f32 *arg2, s32 twidth, u32 theight, u32 arg5, u32 arg6, u32 arg7, u32 r, u32 g, u32 b, u32 alpha, u32 arg12, u32 arg13)
|
||||
void func0f0b278c(Gfx **gdlptr, f32 *arg1, f32 *arg2, s32 twidth, u32 theight, bool flip, bool arg6, bool arg7, u32 r, u32 g, u32 b, u32 alpha, bool arg12, bool arg13)
|
||||
{
|
||||
if (arg2[0] > 0.0f && arg2[1] > 0.0f) {
|
||||
Gfx *gdl = *gdlptr;
|
||||
|
@ -153,6 +153,6 @@ void func0f0b278c(Gfx **gdlptr, f32 *arg1, f32 *arg2, s32 twidth, u32 theight, u
|
|||
|
||||
*gdlptr = gdl;
|
||||
|
||||
func0f0b2150(gdlptr, arg1, arg2, twidth, theight, arg5, arg6, arg7, false, G_TX_RENDERTILE, false);
|
||||
func0f0b2150(gdlptr, arg1, arg2, twidth, theight, flip, arg6, arg7, false, G_TX_RENDERTILE, false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2427,9 +2427,9 @@ void sky_create_sun_artifact(struct artifact *artifact, s32 x, s32 y)
|
|||
s32 viewheight = vi_get_view_height();
|
||||
|
||||
if (x >= viewleft && x < viewleft + viewwidth && y >= viewtop && y < viewtop + viewheight) {
|
||||
artifact->unk08 = &g_ZbufPtr1[(s32)cam_get_screen_width() * y + x];
|
||||
artifact->unk0c.u16_2 = x;
|
||||
artifact->unk0c.u16_1 = y;
|
||||
artifact->zbufptr = &g_ZbufPtr1[(s32)cam_get_screen_width() * y + x];
|
||||
artifact->screenx = x;
|
||||
artifact->screeny = y;
|
||||
artifact->type = ARTIFACTTYPE_CIRCLE;
|
||||
}
|
||||
}
|
||||
|
@ -2440,7 +2440,7 @@ f32 sky_get_artifact_group_intensity_frac(struct artifact *artifacts)
|
|||
s32 i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (artifacts[i].type == ARTIFACTTYPE_CIRCLE && artifacts[i].unk02 == 0xfffc) {
|
||||
if (artifacts[i].type == ARTIFACTTYPE_CIRCLE && artifacts[i].actualdepth == 0xfffc) {
|
||||
sum += 0.125f;
|
||||
}
|
||||
}
|
||||
|
@ -2616,7 +2616,8 @@ Gfx *sky_render_suns(Gfx *gdl, bool xray)
|
|||
sp12c[0] = radius * 0.50f * xscale;
|
||||
sp12c[1] = radius * 0.50f;
|
||||
|
||||
func0f0b2150(&gdl, sp134, sp12c, g_TexLightGlareConfigs[TEX_LIGHT_05].width, g_TexLightGlareConfigs[TEX_LIGHT_05].height, 0, 1, 1, 1, 0, 1);
|
||||
func0f0b2150(&gdl, sp134, sp12c, g_TexLightGlareConfigs[TEX_LIGHT_05].width, g_TexLightGlareConfigs[TEX_LIGHT_05].height,
|
||||
false, true, true, true, 0, true);
|
||||
|
||||
gDPPipeSync(gdl++);
|
||||
gDPSetColorDither(gdl++, G_CD_BAYER);
|
||||
|
@ -2707,7 +2708,8 @@ Gfx *sky_render_flare(Gfx *gdl, f32 x, f32 y, f32 intensityfrac, f32 size, s32 f
|
|||
sp174[1] = f2 * 0.5f;
|
||||
sp174[0] = f2 * 0.5f * scale;
|
||||
|
||||
func0f0b2150(&gdl, sp17c, sp174, g_TexLightGlareConfigs[TEX_LIGHT_06].width, g_TexLightGlareConfigs[TEX_LIGHT_06].height, 0, 1, 1, 1, 0, 1);
|
||||
func0f0b2150(&gdl, sp17c, sp174, g_TexLightGlareConfigs[TEX_LIGHT_06].width, g_TexLightGlareConfigs[TEX_LIGHT_06].height,
|
||||
false, true, true, true, 0, true);
|
||||
|
||||
// Render the other artifacts
|
||||
tex_select(&gdl, &g_TexLightGlareConfigs[TEX_LIGHT_01], 4, 0, 2, 1, NULL);
|
||||
|
@ -2764,7 +2766,8 @@ Gfx *sky_render_flare(Gfx *gdl, f32 x, f32 y, f32 intensityfrac, f32 size, s32 f
|
|||
sp174[1] = tmp * 0.5f;
|
||||
sp174[0] = tmp * 0.5f * scale;
|
||||
|
||||
func0f0b2150(&gdl, sp17c, sp174, g_TexLightGlareConfigs[TEX_LIGHT_01].width, g_TexLightGlareConfigs[TEX_LIGHT_01].height, 0, 0, 0, 0, 0, 1);
|
||||
func0f0b2150(&gdl, sp17c, sp174, g_TexLightGlareConfigs[TEX_LIGHT_01].width, g_TexLightGlareConfigs[TEX_LIGHT_01].height,
|
||||
false, false, false, false, 0, true);
|
||||
}
|
||||
|
||||
// Check if the source is close to the center of the screen and create the bloom effect if so
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
|
||||
u32 g_ZbufWidth;
|
||||
u32 g_ZbufHeight;
|
||||
u16 g_ArtifactsCfb0[0x180];
|
||||
u16 g_ArtifactsCfb1[0x180];
|
||||
u16 g_ArtifactsCfb2[0x180];
|
||||
u16 g_ArtifactDepths0[384];
|
||||
u16 g_ArtifactDepths1[384];
|
||||
u16 g_ArtifactDepths2[384];
|
||||
|
||||
u16 *g_ZbufPtr1 = NULL;
|
||||
u16 *g_ZbufPtr2 = NULL;
|
||||
|
@ -76,12 +76,17 @@ void zbuf_allocate(void)
|
|||
}
|
||||
|
||||
/**
|
||||
* Note: There is only one z-buffer, so there is nothing to swap.
|
||||
* Both of these pointers always have the same value.
|
||||
* In an older implementation, the game almost certainly had two z-buffers.
|
||||
* It needs a fresh z-buffer after rendering the scene and before rendering the
|
||||
* player's gun, but it also needs to read values off both z-buffers for
|
||||
* lighting purposes. In this older implementation, two z-buffers would have
|
||||
* been used and swapped.
|
||||
*
|
||||
* We assume this is a swap function due to the context in which it's called.
|
||||
* Perhaps the developers implemented two buffers with swapping before realising
|
||||
* they only needed one.
|
||||
* Due to memory limitations, this method was removed and an alternative
|
||||
* solution was used to read this values.
|
||||
*
|
||||
* This function is still called but it does nothing.
|
||||
* There is only one z-buffer, and both pointers always have the same value.
|
||||
*/
|
||||
void zbuf_swap(void)
|
||||
{
|
||||
|
@ -154,20 +159,20 @@ Gfx *zbuf_clear(Gfx *gdl)
|
|||
return gdl;
|
||||
}
|
||||
|
||||
u16 *zbuf_get_artifacts_cfb(s32 index)
|
||||
u16 *zbuf_get_artifacts_depth_samples(s32 index)
|
||||
{
|
||||
u16 *addr;
|
||||
|
||||
if (index == 0) {
|
||||
addr = g_ArtifactsCfb0;
|
||||
addr = g_ArtifactDepths0;
|
||||
}
|
||||
|
||||
if (index == 1) {
|
||||
addr = g_ArtifactsCfb1;
|
||||
addr = g_ArtifactDepths1;
|
||||
}
|
||||
|
||||
if (index == 2) {
|
||||
addr = g_ArtifactsCfb2;
|
||||
addr = g_ArtifactDepths2;
|
||||
}
|
||||
|
||||
addr = (u16 *) (((uintptr_t) addr + 0x3f) & ~0x3f);
|
||||
|
@ -175,23 +180,29 @@ u16 *zbuf_get_artifacts_cfb(s32 index)
|
|||
return addr;
|
||||
}
|
||||
|
||||
Gfx *zbuf_draw_artifacts_offscreen(Gfx *gdl)
|
||||
/**
|
||||
* Append GDL commands which make the GPU read from the z-buffer as a texture
|
||||
* and write it to the scheduler's write artifacts list. Only the individual
|
||||
* pixels of interest are copied.
|
||||
*/
|
||||
Gfx *zbuf_save_artifact_depths(Gfx *gdl)
|
||||
{
|
||||
struct artifact *artifacts = sched_get_write_artifacts();
|
||||
u32 stack;
|
||||
u16 *sp4c = g_ZbufPtr1;
|
||||
u32 s4 = 0;
|
||||
u16 *sp44;
|
||||
u16 *s2;
|
||||
u16 *image;
|
||||
u16 *zbuf = g_ZbufPtr1;
|
||||
u32 numsamples = 0;
|
||||
u16 *samples;
|
||||
u16 *thissample;
|
||||
u16 *zbufrow;
|
||||
s32 i;
|
||||
|
||||
vi_get_back_buffer();
|
||||
sp44 = zbuf_get_artifacts_cfb(g_SchedWriteArtifactsIndex);
|
||||
g_SchedSpecialArtifactIndexes[g_SchedWriteArtifactsIndex] = 1;
|
||||
samples = zbuf_get_artifacts_depth_samples(g_SchedWriteArtifactsIndex);
|
||||
|
||||
g_SchedArtifactsWithDualBuffers[g_SchedWriteArtifactsIndex] = true;
|
||||
|
||||
gDPPipeSync(gdl++);
|
||||
gDPSetColorImage(gdl++, G_IM_FMT_RGBA, G_IM_SIZ_16b, vi_get_buf_width(), OS_PHYSICAL_TO_K0(sp44));
|
||||
gDPSetColorImage(gdl++, G_IM_FMT_RGBA, G_IM_SIZ_16b, vi_get_buf_width(), OS_PHYSICAL_TO_K0(samples));
|
||||
gDPSetScissor(gdl++, G_SC_NON_INTERLACE, 0, 0, SCREEN_320, SCREEN_240);
|
||||
gDPSetCycleType(gdl++, G_CYC_COPY);
|
||||
gDPSetTile(gdl++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, 0x0000, 5, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD);
|
||||
|
@ -218,24 +229,24 @@ Gfx *zbuf_draw_artifacts_offscreen(Gfx *gdl)
|
|||
if (1);
|
||||
|
||||
if (artifacts[i].type != ARTIFACTTYPE_FREE) {
|
||||
s2 = &sp44[s4];
|
||||
image = &sp4c[artifacts[i].unk0c.u16_1 * vi_get_width()];
|
||||
thissample = &samples[numsamples];
|
||||
zbufrow = &zbuf[artifacts[i].screeny * vi_get_width()];
|
||||
|
||||
gDPPipeSync(gdl++);
|
||||
gDPSetTextureImage(gdl++, G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_320, image);
|
||||
gDPSetTextureImage(gdl++, G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_320, zbufrow);
|
||||
gDPLoadSync(gdl++);
|
||||
gDPLoadBlock(gdl++, 5, 0, 0, vi_get_width() - 1, 0);
|
||||
gDPPipeSync(gdl++);
|
||||
|
||||
gSPTextureRectangle(gdl++,
|
||||
s4 << 2, 0,
|
||||
(s4 + 3) << 2, 0,
|
||||
G_TX_RENDERTILE, (artifacts[i].unk0c.u16_2 * 32) + 16, 0x0010, 0x1000, 0);
|
||||
numsamples << 2, 0,
|
||||
(numsamples + 3) << 2, 0,
|
||||
G_TX_RENDERTILE, (artifacts[i].screenx * 32) + 16, 0x0010, 0x1000, 0);
|
||||
|
||||
artifacts[i].unk0c.u16p = s2;
|
||||
s4++;
|
||||
artifacts[i].depthptr = thissample;
|
||||
numsamples++;
|
||||
|
||||
if (s2);
|
||||
if (thissample);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -249,7 +260,7 @@ Gfx *zbuf_draw_artifacts_offscreen(Gfx *gdl)
|
|||
gDPSetTexturePersp(gdl++, G_TP_PERSP);
|
||||
gDPSetColorDither(gdl++, G_CD_BAYER);
|
||||
|
||||
if (sp44);
|
||||
if (samples);
|
||||
|
||||
return gdl;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ extern OSViMode *var8008dd60[NUM_GFXTASKS];
|
|||
extern s32 var8008de08;
|
||||
extern s32 g_ViCurVStart0;
|
||||
extern s32 g_ViCurVStart1;
|
||||
extern u8 g_SchedSpecialArtifactIndexes[3];
|
||||
extern u8 g_SchedArtifactsWithDualBuffers[3];
|
||||
extern s32 g_SchedWriteArtifactsIndex;
|
||||
extern OSPiHandle CartRomHandle;
|
||||
extern OSPiHandle LeoDiskHandle;
|
||||
|
|
|
@ -4651,7 +4651,7 @@ enum weaponnum {
|
|||
#define INVAIMFLAG_AUTOAIM 0x00000002
|
||||
#define INVAIMFLAG_ACCURATESINGLESHOT 0x00000004
|
||||
|
||||
#define WEAPONFLAG_THROWABLE 0x00000001 // Entire weapon is throwable (eg. grendes, mines, knives)
|
||||
#define WEAPONFLAG_THROWABLE 0x00000001 // Entire weapon is throwable (eg. grenades, mines, knives)
|
||||
#define WEAPONFLAG_00000004 0x00000004
|
||||
#define WEAPONFLAG_ONEHANDED 0x00000008 // Makes guards carry the gun with one hand
|
||||
#define WEAPONFLAG_AICANUSE 0x00000010
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
#include "data.h"
|
||||
#include "types.h"
|
||||
|
||||
void func0f0b2150(Gfx **gdl, f32 *arg1, f32 *arg2, s32 width, s32 height, bool arg5, bool arg6, bool arg7, bool arg8, bool arg9, bool arg10);
|
||||
void func0f0b2740(Gfx **gdl, f32 *arg1, f32 *arg2, s32 width, s32 height, bool arg5, bool arg6, bool arg7, u32 arg8);
|
||||
void func0f0b278c(Gfx **gdl, f32 *arg1, f32 *arg2, s32 width, u32 height, u32 arg5, u32 arg6, u32 arg7, u32 r, u32 g, u32 b, u32 alpha, u32 arg12, u32 arg13);
|
||||
void func0f0b2150(Gfx **gdl, f32 *arg1, f32 *arg2, s32 width, s32 height, bool flip, bool arg6, bool arg7, bool arg8, bool arg9, bool arg10);
|
||||
void func0f0b2740(Gfx **gdl, f32 *arg1, f32 *arg2, s32 width, s32 height, bool flip, bool arg6, bool arg7, bool arg8);
|
||||
void func0f0b278c(Gfx **gdl, f32 *arg1, f32 *arg2, s32 width, u32 height, bool flip, bool arg6, bool arg7, u32 r, u32 g, u32 b, u32 alpha, bool arg12, bool arg13);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -9,6 +9,6 @@ void zbuf_reset(s32 stagenum);
|
|||
void zbuf_swap(void);
|
||||
Gfx *zbuf_configure_rdp(Gfx *gdl);
|
||||
Gfx *zbuf_clear(Gfx *gdl);
|
||||
Gfx *zbuf_draw_artifacts_offscreen(Gfx *gdl);
|
||||
Gfx *zbuf_save_artifact_depths(Gfx *gdl);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3447,17 +3447,16 @@ struct audioconfig {
|
|||
|
||||
struct artifact {
|
||||
u16 type;
|
||||
u16 unk02;
|
||||
u16 unk04;
|
||||
u16 unk06;
|
||||
u16 *unk08;
|
||||
u16 actualdepth;
|
||||
u16 expecteddepth;
|
||||
u16 *zbufptr;
|
||||
union {
|
||||
u16 *u16p;
|
||||
u16 *depthptr;
|
||||
struct {
|
||||
u16 u16_1;
|
||||
u16 u16_2;
|
||||
u16 screeny;
|
||||
u16 screenx;
|
||||
};
|
||||
} unk0c;
|
||||
};
|
||||
struct light *light;
|
||||
};
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ u32 var8008de14;
|
|||
OSTimer g_SchedRspTimer;
|
||||
u32 g_SchedDpCounters[4];
|
||||
struct artifact g_ArtifactLists[3][120];
|
||||
u8 g_SchedSpecialArtifactIndexes[3];
|
||||
u8 g_SchedArtifactsWithDualBuffers[3];
|
||||
s32 g_SchedWriteArtifactsIndex;
|
||||
s32 g_SchedFrontArtifactsIndex;
|
||||
s32 g_SchedPendingArtifactsIndex;
|
||||
|
@ -479,7 +479,7 @@ void sched_init_artifacts(void)
|
|||
g_ArtifactLists[i][j].type = ARTIFACTTYPE_FREE;
|
||||
}
|
||||
|
||||
g_SchedSpecialArtifactIndexes[i] = 0;
|
||||
g_SchedArtifactsWithDualBuffers[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -494,19 +494,13 @@ struct artifact *sched_get_write_artifacts(void)
|
|||
|
||||
/**
|
||||
* The front list is the artifact list that is currently being displayed on the
|
||||
* screen. Rendering logic reads this list. The list may be re-used for multiple
|
||||
* frames in a row during lag.
|
||||
* screen. Rendering logic reads this list.
|
||||
*/
|
||||
struct artifact *sched_get_front_artifacts(void)
|
||||
{
|
||||
return g_ArtifactLists[g_SchedFrontArtifactsIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* The pending list is possibly misnamed. I'm not sure how this list works.
|
||||
*
|
||||
* @TODO: Investigate.
|
||||
*/
|
||||
struct artifact *sched_get_pending_artifacts(void)
|
||||
{
|
||||
return g_ArtifactLists[g_SchedPendingArtifactsIndex];
|
||||
|
@ -543,25 +537,25 @@ void sched_update_pending_artifacts(void)
|
|||
struct artifact *artifact = &artifacts[i];
|
||||
|
||||
if (artifact->type != ARTIFACTTYPE_FREE) {
|
||||
u16 *unk08 = artifact->unk08;
|
||||
u16 value08 = unk08[0];
|
||||
u16 *currdepthptr = artifact->zbufptr;
|
||||
u16 currdepth = *currdepthptr;
|
||||
|
||||
if (g_SchedSpecialArtifactIndexes[g_SchedPendingArtifactsIndex] == 1) {
|
||||
u16 *unk0c = artifact->unk0c.u16p;
|
||||
u16 value0c = unk0c[0];
|
||||
if (g_SchedArtifactsWithDualBuffers[g_SchedPendingArtifactsIndex] == true) {
|
||||
u16 *prevdepthptr = artifact->depthptr;
|
||||
u16 prevdepth = *prevdepthptr;
|
||||
|
||||
if (value0c > value08) {
|
||||
artifact->unk02 = value08;
|
||||
if (currdepth < prevdepth) {
|
||||
artifact->actualdepth = currdepth;
|
||||
} else {
|
||||
artifact->unk02 = value0c;
|
||||
artifact->actualdepth = prevdepth;
|
||||
}
|
||||
} else {
|
||||
artifact->unk02 = value08;
|
||||
artifact->actualdepth = currdepth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_SchedSpecialArtifactIndexes[g_SchedPendingArtifactsIndex] = 0;
|
||||
g_SchedArtifactsWithDualBuffers[g_SchedPendingArtifactsIndex] = false;
|
||||
|
||||
sched_increment_pending_artifacts();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue