widescreen non stretched skyboxes

This commit is contained in:
Isaac0-dev 2025-02-20 23:18:38 +10:00
parent ef3c38ddd6
commit f4b79bc7a4
3 changed files with 31 additions and 37 deletions

View file

@ -17,6 +17,7 @@
#include "game/skybox.h" #include "game/skybox.h"
#include "game/first_person_cam.h" #include "game/first_person_cam.h"
#include "course_table.h" #include "course_table.h"
#include "skybox.h"
/** /**
* This file contains the code that processes the scene graph for rendering. * This file contains the code that processes the scene graph for rendering.
@ -172,7 +173,7 @@ static Vp sViewportInterp = { 0 };
static struct GraphNodeBackground* sBackgroundNode = NULL; static struct GraphNodeBackground* sBackgroundNode = NULL;
Gfx* gBackgroundSkyboxGfx = NULL; Gfx* gBackgroundSkyboxGfx = NULL;
Vtx* gBackgroundSkyboxVerts[3][3] = { 0 }; Vtx* gBackgroundSkyboxVerts[SKYBOX_TILES_Y][SKYBOX_TILES_X] = { 0 };
Mtx* gBackgroundSkyboxMtx = NULL; Mtx* gBackgroundSkyboxMtx = NULL;
struct GraphNodeRoot* sBackgroundNodeRoot = NULL; struct GraphNodeRoot* sBackgroundNodeRoot = NULL;
@ -1628,7 +1629,7 @@ static void geo_clear_interp_variables(void) {
sBackgroundNode = NULL; sBackgroundNode = NULL;
gBackgroundSkyboxGfx = NULL; gBackgroundSkyboxGfx = NULL;
memset(gBackgroundSkyboxVerts, 0, sizeof(Vtx*) * 3 * 3); memset(gBackgroundSkyboxVerts, 0, sizeof(Vtx*) * SKYBOX_TILES_Y * SKYBOX_TILES_X);
gBackgroundSkyboxMtx = NULL; gBackgroundSkyboxMtx = NULL;
sBackgroundNodeRoot = NULL; sBackgroundNodeRoot = NULL;

View file

@ -12,6 +12,7 @@
#include "hud.h" #include "hud.h"
#include "geo_commands.h" #include "geo_commands.h"
#include "hardcoded.h" #include "hardcoded.h"
#include "skybox.h"
/** /**
* @file skybox.c * @file skybox.c
@ -55,9 +56,6 @@ struct Skybox {
f32 scaledX; f32 scaledX;
/// The skybox's Y position in world space /// The skybox's Y position in world space
f32 scaledY; f32 scaledY;
/// The index of the upper-left tile in the 3x3 grid that gets drawn
s32 upperLeftTile;
}; };
struct Skybox sSkyBoxInfo[2]; struct Skybox sSkyBoxInfo[2];
@ -182,16 +180,6 @@ f32 calculate_skybox_scaled_y(s8 player, UNUSED f32 fov) {
return scaledY; return scaledY;
} }
/**
* Converts the upper left xPos and yPos to the index of the upper left tile in the skybox.
*/
static s32 get_top_left_tile_idx(s8 player) {
s32 tileCol = sSkyBoxInfo[player].scaledX / SKYBOX_TILE_WIDTH;
s32 tileRow = (SKYBOX_HEIGHT - sSkyBoxInfo[player].scaledY) / SKYBOX_TILE_HEIGHT;
return tileRow * SKYBOX_COLS + tileCol;
}
/** /**
* Generates vertices for the skybox tile. * Generates vertices for the skybox tile.
* *
@ -199,8 +187,8 @@ static s32 get_top_left_tile_idx(s8 player) {
* into an x and y by modulus and division by SKYBOX_COLS. x and y are then scaled by * into an x and y by modulus and division by SKYBOX_COLS. x and y are then scaled by
* SKYBOX_TILE_WIDTH to get a point in world space. * SKYBOX_TILE_WIDTH to get a point in world space.
*/ */
Vtx *make_skybox_rect(s32 tileIndex, s8 colorIndex, s32 row, s32 col) { Vtx *make_skybox_rect(s32 tileRow, s32 tileCol, s8 colorIndex, s32 row, s32 col) {
extern Vtx* gBackgroundSkyboxVerts[3][3]; extern Vtx* gBackgroundSkyboxVerts[SKYBOX_TILES_Y][SKYBOX_TILES_X];
Vtx *verts; Vtx *verts;
if (gRenderingInterpolated) { if (gRenderingInterpolated) {
@ -210,22 +198,18 @@ Vtx *make_skybox_rect(s32 tileIndex, s8 colorIndex, s32 row, s32 col) {
gBackgroundSkyboxVerts[row][col] = verts; gBackgroundSkyboxVerts[row][col] = verts;
} }
f32 x = tileIndex % SKYBOX_COLS * SKYBOX_TILE_WIDTH; f32 x = tileCol * SKYBOX_TILE_WIDTH;
f32 y = SKYBOX_HEIGHT - tileIndex / SKYBOX_COLS * SKYBOX_TILE_HEIGHT; f32 y = SKYBOX_HEIGHT - tileRow / SKYBOX_COLS * SKYBOX_TILE_HEIGHT;
if (verts != NULL) { if (verts != NULL) {
f32 r = gSkyboxColor[0] / 255.0f; f32 r = gSkyboxColor[0] / 255.0f;
f32 g = gSkyboxColor[1] / 255.0f; f32 g = gSkyboxColor[1] / 255.0f;
f32 b = gSkyboxColor[2] / 255.0f; f32 b = gSkyboxColor[2] / 255.0f;
make_vertex(verts, 0, x, y, -1, 0, 0, sSkyboxColors[colorIndex][0] * r, sSkyboxColors[colorIndex][1] * g, u8 *colors = sSkyboxColors[colorIndex];
sSkyboxColors[colorIndex][2] * b, 255); make_vertex(verts, 0, x, y, -1, 0, 0, colors[0] * r, colors[1] * g, colors[2] * b, 255);
make_vertex(verts, 1, x, y - SKYBOX_TILE_HEIGHT, -1, 0, 31 << 5, sSkyboxColors[colorIndex][0] * r, sSkyboxColors[colorIndex][1] * g, make_vertex(verts, 1, x, y - SKYBOX_TILE_HEIGHT, -1, 0, 31 << 5, colors[0] * r, colors[1] * g, colors[2] * b, 255);
sSkyboxColors[colorIndex][2] * b, 255); make_vertex(verts, 2, x + SKYBOX_TILE_WIDTH, y - SKYBOX_TILE_HEIGHT, -1, 31 << 5, 31 << 5, colors[0] * r, colors[1] * g, colors[2] * b, 255);
make_vertex(verts, 2, x + SKYBOX_TILE_WIDTH, y - SKYBOX_TILE_HEIGHT, -1, 31 << 5, 31 << 5, sSkyboxColors[colorIndex][0] * r, make_vertex(verts, 3, x + SKYBOX_TILE_WIDTH, y, -1, 31 << 5, 0, colors[0] * r, colors[1] * g, colors[2] * b, 255);
sSkyboxColors[colorIndex][1] * g, sSkyboxColors[colorIndex][2] * b, 255);
make_vertex(verts, 3, x + SKYBOX_TILE_WIDTH, y, -1, 31 << 5, 0, sSkyboxColors[colorIndex][0] * r, sSkyboxColors[colorIndex][1] * g,
sSkyboxColors[colorIndex][2] * b, 255);
} else {
} }
return verts; return verts;
} }
@ -239,9 +223,15 @@ void draw_skybox_tile_grid(Gfx **dlist, s8 background, s8 player, s8 colorIndex)
s32 row; s32 row;
s32 col; s32 col;
for (row = 0; row < 3; row++) { for (row = 0; row < SKYBOX_TILES_Y; row++) {
for (col = 0; col < 3; col++) { for (col = 0; col < SKYBOX_TILES_X; col++) {
s32 tileIndex = sSkyBoxInfo[player].upperLeftTile + row * SKYBOX_COLS + col; s32 tileRow = (s32) (((SKYBOX_HEIGHT - sSkyBoxInfo[player].scaledY) / SKYBOX_TILE_HEIGHT) + row) * SKYBOX_COLS;
s32 tileColTmp = ((floor(sSkyBoxInfo[player].scaledX / SKYBOX_TILE_WIDTH) + col) - 1);
s32 tileCol = tileColTmp;
if (tileCol >= SKYBOX_ROWS) { tileCol -= SKYBOX_ROWS; }
if (tileCol < 0) { tileCol += SKYBOX_ROWS; }
s32 tileIndex = tileRow + tileCol;
// UGLY HACK: if the camera moves weird after a level transition this can go too high // UGLY HACK: if the camera moves weird after a level transition this can go too high
if (tileIndex < 0) { tileIndex = 0; } if (tileIndex < 0) { tileIndex = 0; }
if (tileIndex > 79) { tileIndex = 79; } if (tileIndex > 79) { tileIndex = 79; }
@ -252,7 +242,7 @@ void draw_skybox_tile_grid(Gfx **dlist, s8 background, s8 player, s8 colorIndex)
texture = (Texture*)(*(SkyboxTexture *) segmented_to_virtual(sSkyboxTextures[background]))[tileIndex]; texture = (Texture*)(*(SkyboxTexture *) segmented_to_virtual(sSkyboxTextures[background]))[tileIndex];
} }
Vtx *vertices = make_skybox_rect(tileIndex, colorIndex, row, col); Vtx *vertices = make_skybox_rect(tileRow, tileColTmp, colorIndex, row, col);
gLoadBlockTexture((*dlist)++, 32, 32, G_IM_FMT_RGBA, texture); gLoadBlockTexture((*dlist)++, 32, 32, G_IM_FMT_RGBA, texture);
gSPVertexNonGlobal((*dlist)++, VIRTUAL_TO_PHYSICAL(vertices), 4, 0); gSPVertexNonGlobal((*dlist)++, VIRTUAL_TO_PHYSICAL(vertices), 4, 0);
@ -276,10 +266,11 @@ void *create_skybox_ortho_matrix(s8 player) {
gBackgroundSkyboxMtx = mtx; gBackgroundSkyboxMtx = mtx;
} }
f32 half_width = (4.0f / 3.0f) / GFX_DIMENSIONS_ASPECT_RATIO * SCREEN_WIDTH / 2; // Stretch the screen to hide sides of skybox
f32 half_width = (21.0f / 9.0f) / GFX_DIMENSIONS_ASPECT_RATIO * SCREEN_WIDTH / 2;
f32 center = (sSkyBoxInfo[player].scaledX + SCREEN_WIDTH / 2); f32 center = (sSkyBoxInfo[player].scaledX + SCREEN_WIDTH / 2);
if (half_width < SCREEN_WIDTH / 2) { if (half_width < SCREEN_WIDTH / 2) {
// A wider screen than 4:3 // A wider screen than 21:9
left = center - half_width; left = center - half_width;
right = center + half_width; right = center + half_width;
} }
@ -298,7 +289,7 @@ void *create_skybox_ortho_matrix(s8 player) {
Gfx *init_skybox_display_list(s8 player, s8 background, s8 colorIndex) { Gfx *init_skybox_display_list(s8 player, s8 background, s8 colorIndex) {
extern Gfx* gBackgroundSkyboxGfx; extern Gfx* gBackgroundSkyboxGfx;
s32 dlCommandCount = 5 + (3 * 3) * 7; // 5 for the start and end, plus 9 skybox tiles s32 dlCommandCount = 5 + (SKYBOX_TILES_Y * SKYBOX_TILES_X) * 7; // 5 for the start and end, plus the amount of skybox tiles
void *skybox; void *skybox;
if (gRenderingInterpolated) { if (gRenderingInterpolated) {
@ -362,7 +353,6 @@ Gfx *create_skybox_facing_camera(s8 player, s8 background, f32 fov,
sSkyBoxInfo[player].scaledX = calculate_skybox_scaled_x(player, fov); sSkyBoxInfo[player].scaledX = calculate_skybox_scaled_x(player, fov);
sSkyBoxInfo[player].scaledY = calculate_skybox_scaled_y(player, fov); sSkyBoxInfo[player].scaledY = calculate_skybox_scaled_y(player, fov);
sSkyBoxInfo[player].upperLeftTile = get_top_left_tile_idx(player);
return init_skybox_display_list(player, background, colorIndex); return init_skybox_display_list(player, background, colorIndex);
} }

View file

@ -4,6 +4,9 @@
#include <PR/ultratypes.h> #include <PR/ultratypes.h>
#include <PR/gbi.h> #include <PR/gbi.h>
#define SKYBOX_TILES_X 5
#define SKYBOX_TILES_Y 3
extern s8 gReadOnlyBackground; extern s8 gReadOnlyBackground;
extern s8 gOverrideBackground; extern s8 gOverrideBackground;
extern Color gSkyboxColor; extern Color gSkyboxColor;