Document artifacts

This commit is contained in:
Ryan Dwyer 2024-10-05 22:32:13 +10:00
parent ce8ff8822b
commit 62e9f4d1a6
11 changed files with 206 additions and 135 deletions

View File

@ -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);
}
}
}

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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

View File

@ -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;
}

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
};

View File

@ -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();
}