Clean up F3DEX3 support (#118)

* Basic cleanup

* Added specular light sizes

* Added camera world changes

* Forgot specular size in the unused function
This commit is contained in:
Sauraen
2024-05-28 05:33:44 -07:00
committed by GitHub
parent bbf5fadd83
commit c2892d8507
8 changed files with 95 additions and 41 deletions

View File

@@ -7,15 +7,17 @@
/**
* F3DEX3 options
* This only works on "LLE-Emulators" like ares or ParaLLEl. It will not work on standard Project64.
* ``ENABLE_F3DEX3_RECOMMENDATIONS`` will enable the recommended changes listed in F3DEX3's readme
* ``ENABLE_F3DEX3_NEW_FEATURES`` will enable the required changes to use the new features from F3DEX3
* This only works on real console or LLE emulators like ares or ParaLLEl. It
* will not work on legacy HLE emulators such as Project64.
*/
#define ENABLE_F3DEX3 true
#define ENABLE_F3DEX3_RECOMMENDATIONS true // missing matrix stuff + fast64 re-export process
#define ENABLE_F3DEX3_NOSYNCS false // not working properly currently
#define ENABLE_F3DEX3_LIGHT_RECO false // unfinished, faster but experimental (reco -> recommendations)
// #define ENABLE_F3DEX3_NEW_FEATURES true // not implemented yet
// Remove usually-unnecessary syncs from texture loading commands. Only matters
// for vanilla display lists--new ones exported from fast64 already have the
// syncs removed. This is buggy (graphical issues / crashes) as some vanilla DLs
// rely on the syncs within the texture loading commands for correctness. Some
// have already had the missing syncs manually added, but some have not been
// fixed yet.
#define ENABLE_F3DEX3_NOSYNCS false
/**
* Other graphical settings

View File

@@ -110,20 +110,8 @@
* config_game.h
*/
#if !ENABLE_F3DEX3
#if ENABLE_F3DEX3_RECOMMENDATIONS
#undef ENABLE_F3DEX3_RECOMMENDATIONS
#define ENABLE_F3DEX3_RECOMMENDATIONS false
#endif
#if ENABLE_F3DEX3_NEW_FEATURES
#undef ENABLE_F3DEX3_NEW_FEATURES
#define ENABLE_F3DEX3_NEW_FEATURES false
#endif
#if ENABLE_F3DEX3_NOSYNCS
#undef ENABLE_F3DEX3_NOSYNCS
#define ENABLE_F3DEX3_NOSYNCS false
#endif
#undef ENABLE_F3DEX3_NOSYNCS
#define ENABLE_F3DEX3_NOSYNCS false
#endif
#if FORCE_WIDESCREEN

View File

@@ -28,6 +28,9 @@ typedef struct {
/* 0x0A0 */ Mtx viewing;
/* 0x0E0 */ Mtx* projectionPtr;
/* 0x0E4 */ Mtx* viewingPtr;
#if ENABLE_F3DEX3
PlainVtx* cameraWorldPosPtr;
#endif
/* 0x0E8 */ Vec3f distortionOrientation;
/* 0x0F4 */ Vec3f distortionScale;
/* 0x100 */ f32 distortionSpeed;

View File

@@ -61,16 +61,21 @@ void Lights_Draw(Lights* lights, GraphicsContext* gfxCtx) {
OPEN_DISPS(gfxCtx, "../z_lights.c", 339);
#if ENABLE_F3DEX3
// Copy ambient to light slot after last light
lights->l.l[lights->numLights].l.col[0] = lights->l.l[lights->numLights].l.colc[0]
= lights->l.a.l.col[0];
lights->l.l[lights->numLights].l.col[1] = lights->l.l[lights->numLights].l.colc[1]
= lights->l.a.l.col[1];
lights->l.l[lights->numLights].l.col[2] = lights->l.l[lights->numLights].l.colc[2]
= lights->l.a.l.col[2];
gSPSetLights(POLY_OPA_DISP++, lights->numLights, lights->l);
gSPSetLights(POLY_XLU_DISP++, lights->numLights, lights->l);
#else
gSPNumLights(POLY_OPA_DISP++, lights->numLights);
gSPNumLights(POLY_XLU_DISP++, lights->numLights);
#if ENABLE_F3DEX3_LIGHT_RECO
gSPSetLights(POLY_OPA_DISP++, lights->numLights, *lights);
gSPSetLights(POLY_XLU_DISP++, lights->numLights, *lights);
gSPAmbient(POLY_OPA_DISP++, &lights->l.a, lights->numLights);
gSPAmbient(POLY_XLU_DISP++, &lights->l.a, lights->numLights);
#else
light = &lights->l.l[0];
i = 0;
@@ -80,16 +85,20 @@ void Lights_Draw(Lights* lights, GraphicsContext* gfxCtx) {
}
// ambient light is total number of lights + 1
gSPAmbient(POLY_OPA_DISP++, &lights->l.a, ++i);
gSPAmbient(POLY_XLU_DISP++, &lights->l.a, i);
gSPLight(POLY_OPA_DISP++, &lights->l.a, ++i);
gSPLight(POLY_XLU_DISP++, &lights->l.a, i);
#endif
CLOSE_DISPS(gfxCtx, "../z_lights.c", 352);
}
Light* Lights_FindSlot(Lights* lights) {
u8 numLights = ENABLE_F3DEX3_RECOMMENDATIONS ? 9 : 7;
if (lights->numLights >= numLights) {
#if ENABLE_F3DEX3
#define MAX_LIGHTS 9
#else
#define MAX_LIGHTS 7
#endif
if (lights->numLights >= MAX_LIGHTS) {
return NULL;
} else {
return &lights->l.l[lights->numLights++];
@@ -120,7 +129,13 @@ void Lights_BindPoint(Lights* lights, LightParams* params, Vec3f* vec) {
scale = posDiff / scale;
scale = 1 - SQ(scale);
#if ENABLE_F3DEX3
light->l.type = 0;
light->l.type = 0; // directional
// Radius doesn't really mean the same thing as specular size;
// specular size is about how large the actual light emitting
// object is, and for a point light it's just a point. Plus it
// should be dependent on how rough the specular object is.
const s16 radius = params->point.radius;
light->l.size = radius > 1000 ? 1 : radius > 500 ? 2 : radius > 250 ? 3 : 4;
#endif
light->l.col[0] = light->l.colc[0] = params->point.color[0] * scale;
light->l.col[1] = light->l.colc[1] = params->point.color[1] * scale;
@@ -141,7 +156,10 @@ void Lights_BindDirectional(Lights* lights, LightParams* params, Vec3f* vec) {
if (light != NULL) {
#if ENABLE_F3DEX3
light->l.type = 0;
light->l.type = 0; // directional
// The engine doesn't have a parameter in LightDirectional which
// represents specular size, so just make something up generally.
light->l.size = 3;
#endif
light->l.col[0] = light->l.colc[0] = params->dir.color[0];
light->l.col[1] = light->l.colc[1] = params->dir.color[1];
@@ -301,7 +319,8 @@ Lights* Lights_NewAndDraw(GraphicsContext* gfxCtx, u8 ambientR, u8 ambientG, u8
for (i = 0; i < numLights; i++) {
#if ENABLE_F3DEX3
lights->l.l[i].l.type = 0;
lights->l.l[i].l.type = 0; // directional
lights->l.l[i].l.size = 3; // some arbitrary specular size
#endif
lights->l.l[i].l.col[0] = lights->l.l[i].l.colc[0] = r;
lights->l.l[i].l.col[1] = lights->l.l[i].l.colc[1] = g;

View File

@@ -1820,9 +1820,9 @@ void Player_DrawPauseImpl(PlayState* play, void* gameplayKeep, void* linkObject,
gSPLoadGeometryMode(POLY_OPA_DISP++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH);
gDPSetScissor(POLY_OPA_DISP++, G_SC_NON_INTERLACE, 0, 0, width, height);
if (!ENABLE_F3DEX3_RECOMMENDATIONS) {
gSPClipRatio(POLY_OPA_DISP++, FRUSTRATIO_1);
}
#if !ENABLE_F3DEX3
gSPClipRatio(POLY_OPA_DISP++, FRUSTRATIO_1);
#endif
gDPSetColorImage(POLY_OPA_DISP++, G_IM_FMT_RGBA, G_IM_SIZ_16b, width, depthFrameBuffer);
gDPSetCycleType(POLY_OPA_DISP++, G_CYC_FILL);

View File

@@ -818,7 +818,7 @@ Gfx sFillSetupDL[] = {
gsSPLoadGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH),
gsDPSetScissor(G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT),
gsDPSetBlendColor(0, 0, 0, 8),
#if !ENABLE_F3DEX3_RECOMMENDATIONS
#if !ENABLE_F3DEX3
gsSPClipRatio(FRUSTRATIO_2),
#endif
gsSPEndDisplayList(),

View File

@@ -14,7 +14,7 @@ Gfx D_801270B0[] = {
G_AC_NONE | G_ZS_PIXEL | G_RM_NOOP | G_RM_NOOP2),
gsSPLoadGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH),
gsDPSetScissor(G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT),
#if !ENABLE_F3DEX3_RECOMMENDATIONS
#if !ENABLE_F3DEX3
gsSPClipRatio(FRUSTRATIO_1),
#endif
gsSPEndDisplayList(),

View File

@@ -6,6 +6,19 @@ vu32 sLogOnNextViewInit = true;
s32 View_ApplyPerspective(View*);
s32 View_ApplyOrtho(View*);
#if ENABLE_F3DEX3
void View_SetCameraWorld(PlainVtx* cameraWorldPos, View* view){
cameraWorldPos->c.pos[0] = (s16)view->eye.x;
cameraWorldPos->c.pos[1] = (s16)view->eye.y;
cameraWorldPos->c.pos[2] = (s16)view->eye.z;
}
PlainVtx* View_CreateCameraWorld(View* view){
PlainVtx* cameraWorldPos = Graph_Alloc(view->gfxCtx, sizeof(PlainVtx));
View_SetCameraWorld(cameraWorldPos, view);
return cameraWorldPos;
}
#endif
void View_ViewportToVp(Vp* dest, Viewport* src) {
s32 width = src->rightX - src->leftX;
s32 height = src->bottomY - src->topY;
@@ -369,6 +382,11 @@ s32 View_ApplyPerspective(View* view) {
viewing = GRAPH_ALLOC(gfxCtx, sizeof(Mtx));
LOG_UTILS_CHECK_NULL_POINTER("viewing", viewing, "../z_view.c", 667);
view->viewingPtr = viewing;
#if ENABLE_F3DEX3
PlainVtx* cameraWorldPos = View_CreateCameraWorld(view);
view->cameraWorldPosPtr = cameraWorldPos;
#endif
if (view->eye.x == view->at.x && view->eye.y == view->at.y && view->eye.z == view->at.z) {
view->eye.x += 1.0f;
@@ -400,6 +418,10 @@ s32 View_ApplyPerspective(View* view) {
gSPMatrix(POLY_OPA_DISP++, viewing, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION);
gSPMatrix(POLY_XLU_DISP++, viewing, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION);
#if ENABLE_F3DEX3
gSPCameraWorld(POLY_OPA_DISP++, cameraWorldPos);
gSPCameraWorld(POLY_XLU_DISP++, cameraWorldPos);
#endif
CLOSE_DISPS(gfxCtx, "../z_view.c", 711);
@@ -537,6 +559,11 @@ s32 View_ApplyPerspectiveToOverlay(View* view) {
viewing = GRAPH_ALLOC(gfxCtx, sizeof(Mtx));
LOG_UTILS_CHECK_NULL_POINTER("viewing", viewing, "../z_view.c", 848);
view->viewingPtr = viewing;
#if ENABLE_F3DEX3
PlainVtx* cameraWorldPos = View_CreateCameraWorld(view);
view->cameraWorldPosPtr = cameraWorldPos;
#endif
// This check avoids a divide-by-zero in guLookAt if eye == at
if (view->eye.x == view->at.x && view->eye.y == view->at.y && view->eye.z == view->at.z) {
@@ -553,6 +580,9 @@ s32 View_ApplyPerspectiveToOverlay(View* view) {
view->viewing = *viewing;
gSPMatrix(OVERLAY_DISP++, viewing, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION);
#if ENABLE_F3DEX3
gSPCameraWorld(OVERLAY_DISP++, cameraWorldPos);
#endif
CLOSE_DISPS(gfxCtx, "../z_view.c", 871);
@@ -570,6 +600,10 @@ s32 View_UpdateViewingMatrix(View* view) {
guLookAt(view->viewingPtr, view->eye.x, view->eye.y, view->eye.z, view->at.x, view->at.y, view->at.z, view->up.x,
view->up.y, view->up.z);
#if ENABLE_F3DEX3
View_SetCameraWorld(view->cameraWorldPosPtr, view);
#endif
CLOSE_DISPS(view->gfxCtx, "../z_view.c", 886);
return 1;
@@ -637,6 +671,11 @@ s32 View_ApplyTo(View* view, s32 mask, Gfx** gfxP) {
viewing = GRAPH_ALLOC(gfxCtx, sizeof(Mtx));
LOG_UTILS_CHECK_NULL_POINTER("viewing", viewing, "../z_view.c", 948);
view->viewingPtr = viewing;
#if ENABLE_F3DEX3
PlainVtx* cameraWorldPos = View_CreateCameraWorld(view);
view->cameraWorldPosPtr = cameraWorldPos;
#endif
VIEW_ERROR_CHECK_EYE_POS(view->eye.x, view->eye.y, view->eye.z);
@@ -646,6 +685,9 @@ s32 View_ApplyTo(View* view, s32 mask, Gfx** gfxP) {
view->viewing = *viewing;
gSPMatrix(gfx++, viewing, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION);
#if ENABLE_F3DEX3
gSPCameraWorld(gfx++, cameraWorldPos);
#endif
}
view->flags = 0;