sm64pc/src/game/skybox.c

195 lines
5.7 KiB
C

#include <ultra64.h>
#include "sm64.h"
#include "engine/math_util.h"
#include "memory.h"
#include "area.h"
#include "save_file.h"
#include "segment2.h"
#include "level_update.h"
#include "geo_misc.h"
struct Struct8035FF50 {
u16 unk0;
s16 unk2;
s32 unk4;
s32 unk8;
s32 unkC;
};
struct Struct8032FFC8 {
u8 unk0;
u8 unk1;
u8 unk2;
u8 filler3[1];
};
struct SkyboxList {
struct Gfx *ptr[50];
};
extern struct SkyboxList water_skybox_ptrlist_0A020000;
extern struct SkyboxList bitfs_skybox_ptrlist_0A018800;
extern struct SkyboxList wdw_skybox_ptrlist_0A020000;
extern struct SkyboxList cloud_floor_skybox_ptrlist_0A020000;
extern struct SkyboxList ccm_skybox_ptrlist_0A020000;
extern struct SkyboxList ssl_skybox_ptrlist_0A020000;
extern struct SkyboxList bbh_skybox_ptrlist_0A014800;
extern struct SkyboxList bidw_skybox_ptrlist_0A020000;
extern struct SkyboxList clouds_skybox_ptrlist_0A014800;
extern struct SkyboxList bits_skybox_ptrlist_0A020000;
// TODO: These should be defined here
struct Struct8035FF50 D_8035FF50[2];
struct SkyboxList *gSkyboxLists[10] = {
&water_skybox_ptrlist_0A020000, // water_skybox
&bitfs_skybox_ptrlist_0A018800, // bitfs_skybox
&wdw_skybox_ptrlist_0A020000, // wdw_skybox
&cloud_floor_skybox_ptrlist_0A020000, // cloud_floor_skybox
&ccm_skybox_ptrlist_0A020000, // ccm_skybox
&ssl_skybox_ptrlist_0A020000, // ssl_skybox
&bbh_skybox_ptrlist_0A014800, // bbh_skybox
&bidw_skybox_ptrlist_0A020000, // bidw_skybox
&clouds_skybox_ptrlist_0A014800, // clouds_skybox
&bits_skybox_ptrlist_0A020000, // bits_skybox
};
u8 gSkyboxColors[][3] = {
{ 0x50, 0x64, 0x5A },
{ 0xFF, 0xFF, 0xFF },
};
//! double literals are used instead of floats
int func_802CEAD0(s8 a, f32 b) {
f32 spC = D_8035FF50[a].unk0;
f32 sp8 = (115200.0 * spC) / (b * 65536.0);
s32 sp4 = sp8 + 0.5;
if (sp4 > 1280) {
sp4 -= sp4 / 1280 * 1280;
}
return 1280 - sp4;
}
int func_802CEBBC(s8 a, UNUSED f32 b) {
f32 sp24 = (f32) D_8035FF50[a].unk2 * 360.0 / 65535.0;
f32 sp20 = 360.0f * sp24 / 90.0;
s32 sp1C = round_float(sp20);
s32 sp18 = sp1C + 0x258;
if (sp18 > 960) {
sp18 = 960;
}
if (sp18 < 240) {
sp18 = 240;
}
return sp18;
}
int func_802CEC9C(s8 a) {
s32 sp4 = D_8035FF50[a].unk4 / 160;
s32 sp0 = (960 - D_8035FF50[a].unk8) / 120;
return sp0 * 10 + sp4;
}
// generates vertices for some rectangle
Vtx *make_skybox_rect(s32 a, s8 b) {
Vtx *verts = alloc_display_list(4 * sizeof(*verts));
s16 x = a % 10 * 160;
s16 y = 960 - a / 10 * 120;
if (verts != NULL) {
make_vertex(verts, 0, x, y, -1, 0, 0, gSkyboxColors[b][0], gSkyboxColors[b][1],
gSkyboxColors[b][2], 255);
make_vertex(verts, 1, x, y - 0x78, -1, 0, 992, gSkyboxColors[b][0], gSkyboxColors[b][1],
gSkyboxColors[b][2], 255);
make_vertex(verts, 2, x + 160, y - 0x78, -1, 992, 992, gSkyboxColors[b][0], gSkyboxColors[b][1],
gSkyboxColors[b][2], 255);
make_vertex(verts, 3, x + 160, y, -1, 992, 0, gSkyboxColors[b][0], gSkyboxColors[b][1],
gSkyboxColors[b][2], 255);
} else {
}
return verts;
}
void func_802CEF4C(Gfx **dlist, s8 b, s8 c, s8 d) {
s32 sp54;
s32 sp50;
for (sp54 = 0; sp54 < 3; sp54++) {
for (sp50 = 0; sp50 < 3; sp50++) {
s32 sp4C = D_8035FF50[c].unkC + sp54 * 10 + sp50;
struct Gfx *sp48 =
((struct SkyboxList *) segmented_to_virtual((void *) gSkyboxLists[b]))->ptr[sp4C];
Vtx *vertices = make_skybox_rect(sp4C, d);
// Why is the width 1 here?
gDPSetTextureImage((*dlist)++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, sp48);
gDPTileSync((*dlist)++);
gDPSetTile((*dlist)++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, 0, 7, 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);
gDPLoadSync((*dlist)++);
gDPLoadBlock((*dlist)++, 7, 0, 0, 1023, 256);
gSPVertex((*dlist)++, VIRTUAL_TO_PHYSICAL(vertices), 4, 0);
gSPDisplayList((*dlist)++, dl_draw_quad_verts_0123);
}
}
}
void *func_802CF188(s8 a) {
f32 left = D_8035FF50[a].unk4;
f32 right = D_8035FF50[a].unk4 + 0x140;
f32 bottom = D_8035FF50[a].unk8 - 0xF0;
f32 top = D_8035FF50[a].unk8;
Mtx *mtx = alloc_display_list(sizeof(*mtx));
if (mtx != NULL) {
guOrtho(mtx, left, right, bottom, top, 0.0f, 3.0f, 1.0f);
} else {
}
return mtx;
}
Gfx *func_802CF2A8(s8 a, s8 b, s8 c) {
s32 sp3C = 68;
void *sp38 = alloc_display_list(sp3C * 8);
Gfx *dlist = sp38;
if (sp38 == NULL) {
return NULL;
} else {
Mtx *mtx = func_802CF188(a);
gSPDisplayList(dlist++, dl_skybox_begin);
gSPMatrix(dlist++, VIRTUAL_TO_PHYSICAL(mtx), G_MTX_PROJECTION | G_MTX_MUL);
gSPDisplayList(dlist++, dl_skybox_tex_settings);
func_802CEF4C(&dlist, b, a, c);
gSPDisplayList(dlist++, dl_skybox_end);
gSPEndDisplayList(dlist);
}
return sp38;
}
Gfx *func_802CF414(s8 a, s8 b, f32 c, f32 d, f32 e, f32 f, f32 g, f32 h, f32 i) {
f32 sp34 = g - d;
f32 sp30 = h - e;
f32 sp2C = i - f;
s8 sp2B = 1;
if (b == 8 && !(save_file_get_star_flags(gCurrSaveFileNum - 1, 2) & 1)) {
sp2B = 0;
}
c = 90.0f;
D_8035FF50[a].unk0 = atan2s(sp2C, sp34);
D_8035FF50[a].unk2 = atan2s(sqrtf(sp34 * sp34 + sp2C * sp2C), sp30);
D_8035FF50[a].unk4 = func_802CEAD0(a, c);
D_8035FF50[a].unk8 = func_802CEBBC(a, c);
D_8035FF50[a].unkC = func_802CEC9C(a);
return func_802CF2A8(a, b, sp2B);
}