1
0
mirror of https://github.com/zeldaret/oot.git synced 2024-09-21 04:24:43 +00:00

Doc room drawing (#1283)

* (wip) some doc on room draw2

* doc room_draw2

* do what can be done for `func_80095AA0`

* wip

* more cleanup around Room_DrawBackground2D

* format"

* commit to naming things

* move forward declarations of draw handlers to draw handlers array

* two z_room regs

* `R_MESH2_` -> `R_ROOM_CULL_`

* offset -> quakeOffset

* kb -> kB

* Improve cull mesh type doc

* `Sphere16` MeshHeaderCullEntry.bounds

* Revert "`Sphere16` MeshHeaderCullEntry.bounds" (ZAPD...)

This reverts commit cbe55e8090.

* Mesh header type: "cull" -> "cullable"

* Reword some Cullable doc

Co-authored-by: EllipticEllipsis <elliptic.ellipsis@gmail.com>

* `boundsSphere*` for now for the can't-be-`Sphere16 bounds`

* Improve the PrerenderMulti bgCamInfo usage situation

* Comment on `overrideBgCamIndex`

* "are left" -> "remain"

* enum and defines for room draw debug regs

* drawBg -> drawBackground

* "mesh header all" -> "mesh header normal" 🤷

* array_count back to define

* Name some temps a lot less specifically

* "mesh header" -> "room shape"

* "Room shape prerender" -> "Room shape image"

* `ROOM_SHAPE_IMAGE_FORMAT_` -> `ROOM_SHAPE_IMAGE_AMOUNT_`

* `RoomShapeImageMultiBackgroundEntry` -> `RoomShapeImageMultiBgEntry`

* Remove references to "header" (old "mesh header" name)

* Axe variable names

Co-authored-by: EllipticEllipsis <elliptic.ellipsis@gmail.com>
This commit is contained in:
Dragorn421 2022-09-01 01:28:51 +02:00 committed by GitHub
parent 2e18eb334b
commit c0cf83a814
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 380 additions and 309 deletions

View File

@ -1132,9 +1132,9 @@ Gfx* Gfx_TwoTexScrollEnvColor(GraphicsContext* gfxCtx, s32 tile1, u32 x1, u32 y1
Gfx* Gfx_EnvColor(GraphicsContext* gfxCtx, s32 r, s32 g, s32 b, s32 a);
void Gfx_SetupFrame(GraphicsContext* gfxCtx, u8 r, u8 g, u8 b);
void func_80095974(GraphicsContext* gfxCtx);
void func_80095AA0(PlayState* play, Room* room, Input* arg2, UNK_TYPE arg3);
void func_8009638C(Gfx** displayList, void* source, void* tlut, u16 width, u16 height, u8 fmt, u8 siz, u16 mode0,
u16 tlutCount, f32 frameX, f32 frameY);
void func_80095AA0(PlayState* play, Room* room, Input* input, s32 arg3);
void Room_DrawBackground2D(Gfx** gfxP, void* tex, void* tlut, u16 width, u16 height, u8 fmt, u8 siz, u16 tlutMode,
u16 tlutCount, f32 offsetX, f32 offsetY);
void func_80096FD4(PlayState* play, Room* room);
u32 func_80096FE8(PlayState* play, RoomContext* roomCtx);
s32 func_8009728C(PlayState* play, RoomContext* roomCtx, s32 roomNum);

View File

@ -48,6 +48,8 @@
#define R_ENV_TIME_SPEED_OLD REG(15) // Most likely used during development. Unused in the final game.
#define R_RUN_SPEED_LIMIT REG(45)
#define R_ENABLE_ARENA_DBG SREG(0)
#define R_ROOM_IMAGE_NODRAW_FLAGS SREG(25)
#define R_ROOM_BG2D_FORCE_SCALEBG SREG(26)
#define R_UPDATE_RATE SREG(30)
#define R_ENABLE_AUDIO_DBG SREG(36)
#define R_FB_FILTER_TYPE SREG(80)
@ -131,6 +133,10 @@
#define R_TEXTBOX_TEXHEIGHT_TARGET XREG(77)
#define R_ENV_LIGHT1_DIR(i) cREG(3 + (i))
#define R_ENV_LIGHT2_DIR(i) cREG(6 + (i))
#define R_ROOM_CULL_DEBUG_MODE iREG(86)
#define R_ROOM_CULL_NUM_ENTRIES iREG(87)
#define R_ROOM_CULL_USED_ENTRIES iREG(88)
#define R_ROOM_CULL_DEBUG_TARGET iREG(89)
#define R_B_LABEL_DD WREG(0)
#define R_OW_MINIMAP_X WREG(29)
#define R_OW_MINIMAP_Y WREG(30)

View File

@ -872,7 +872,7 @@ typedef struct {
/* 0x03 */ u8 behaviorType1;
/* 0x04 */ s8 echo;
/* 0x05 */ u8 lensMode;
/* 0x08 */ MeshHeader* meshHeader; // original name: "ground_shape"
/* 0x08 */ RoomShape* roomShape; // original name: "ground_shape"
/* 0x0C */ void* segment;
/* 0x10 */ char unk_10[0x4];
} Room; // size = 0x14

View File

@ -64,7 +64,7 @@ typedef struct {
/* 0x06 */ Vec3s rot;
/* 0x0C */ s16 fov;
/* 0x0E */ union {
s16 jfifId;
s16 roomImageOverrideBgCamIndex;
s16 timer;
s16 flags;
};

View File

@ -813,7 +813,7 @@ typedef struct {
/* 0x0 */ Vec3s rot;
/* 0x6 */ s16 fov;
/* 0x8 */ s16 updDirTimer;
/* 0xA */ s16 jfifId;
/* 0xA */ s16 roomImageOverrideBgCamIndex;
} Fixed3ReadWriteData; // size = 0xC
typedef struct {

View File

@ -58,44 +58,44 @@ typedef struct {
/* 0x04 */ Vec3s* points; // Segment Address to the array of points
} Path; // size = 0x8
// Mesh headers
// Room shapes
typedef enum {
/* 0 */ MESH_HEADER_TYPE_0,
/* 1 */ MESH_HEADER_TYPE_1,
/* 2 */ MESH_HEADER_TYPE_2,
/* 3 */ MESH_HEADER_TYPE_MAX
} MeshHeaderType;
/* 0 */ ROOM_SHAPE_TYPE_NORMAL,
/* 1 */ ROOM_SHAPE_TYPE_IMAGE,
/* 2 */ ROOM_SHAPE_TYPE_CULLABLE,
/* 3 */ ROOM_SHAPE_TYPE_MAX
} RoomShapeType;
typedef struct {
/* 0x00 */ u8 type;
} MeshHeaderBase; // size = 0x01
} RoomShapeBase; // size = 0x01
typedef struct {
/* 0x00 */ Gfx* opa;
/* 0x04 */ Gfx* xlu;
} MeshHeader01Entry; // size = 0x08
} RoomShapeDListsEntry; // size = 0x08
typedef struct {
/* 0x00 */ MeshHeaderBase base;
/* 0x00 */ RoomShapeBase base;
/* 0x01 */ u8 numEntries;
/* 0x04 */ MeshHeader01Entry* entries;
/* 0x08 */ MeshHeader01Entry* entriesEnd;
} MeshHeader0; // size = 0x0C
/* 0x04 */ RoomShapeDListsEntry* entries;
/* 0x08 */ RoomShapeDListsEntry* entriesEnd;
} RoomShapeNormal; // size = 0x0C
typedef enum {
/* 1 */ MESH_HEADER1_FORMAT_SINGLE = 1,
/* 2 */ MESH_HEADER1_FORMAT_MULTI
} MeshHeader1Format;
/* 1 */ ROOM_SHAPE_IMAGE_AMOUNT_SINGLE = 1,
/* 2 */ ROOM_SHAPE_IMAGE_AMOUNT_MULTI
} RoomShapeImageAmountType;
typedef struct {
/* 0x00 */ MeshHeaderBase base;
/* 0x01 */ u8 format; // MeshHeader1Format
/* 0x04 */ MeshHeader01Entry* entry;
} MeshHeader1Base; // size = 0x08
/* 0x00 */ RoomShapeBase base;
/* 0x01 */ u8 amountType; // RoomShapeImageAmountType
/* 0x04 */ RoomShapeDListsEntry* entry;
} RoomShapeImageBase; // size = 0x08
typedef struct {
/* 0x00 */ MeshHeader1Base base;
/* 0x00 */ RoomShapeImageBase base;
/* 0x08 */ void* source;
/* 0x0C */ u32 unk_0C;
/* 0x10 */ void* tlut;
@ -103,13 +103,13 @@ typedef struct {
/* 0x16 */ u16 height;
/* 0x18 */ u8 fmt;
/* 0x19 */ u8 siz;
/* 0x1A */ u16 mode0;
/* 0x1A */ u16 tlutMode;
/* 0x1C */ u16 tlutCount;
} MeshHeader1Single; // size = 0x20
} RoomShapeImageSingle; // size = 0x20
typedef struct {
/* 0x00 */ u16 unk_00;
/* 0x02 */ u8 id;
/* 0x02 */ u8 bgCamIndex; // for which bg cam index is this entry for
/* 0x04 */ void* source;
/* 0x08 */ u32 unk_0C;
/* 0x0C */ void* tlut;
@ -117,44 +117,52 @@ typedef struct {
/* 0x12 */ u16 height;
/* 0x14 */ u8 fmt;
/* 0x15 */ u8 siz;
/* 0x16 */ u16 mode0;
/* 0x16 */ u16 tlutMode;
/* 0x18 */ u16 tlutCount;
} BgImage; // size = 0x1C
} RoomShapeImageMultiBgEntry; // size = 0x1C
typedef struct {
/* 0x00 */ MeshHeader1Base base;
/* 0x08 */ u8 count;
/* 0x0C */ BgImage* list;
} MeshHeader1Multi; // size = 0x10
/* 0x00 */ RoomShapeImageBase base;
/* 0x08 */ u8 numBackgrounds;
/* 0x0C */ RoomShapeImageMultiBgEntry* backgrounds;
} RoomShapeImageMulti; // size = 0x10
typedef struct {
/* 0x00 */ Vec3s pos;
/* 0x06 */ s16 unk_06;
/* 0x00 */ Vec3s boundsSphereCenter;
/* 0x06 */ s16 boundsSphereRadius;
/* 0x08 */ Gfx* opa;
/* 0x0C */ Gfx* xlu;
} MeshHeader2Entry; // size = 0x10
} RoomShapeCullableEntry; // size = 0x10
#define ROOM_SHAPE_CULLABLE_MAX_ENTRIES 64
typedef struct {
/* 0x00 */ MeshHeaderBase base;
/* 0x00 */ RoomShapeBase base;
/* 0x01 */ u8 numEntries;
/* 0x04 */ MeshHeader2Entry* entries;
/* 0x08 */ MeshHeader2Entry* entriesEnd;
} MeshHeader2; // size = 0x0C
/* 0x04 */ RoomShapeCullableEntry* entries;
/* 0x08 */ RoomShapeCullableEntry* entriesEnd;
} RoomShapeCullable; // size = 0x0C
typedef union {
MeshHeaderBase base;
MeshHeader0 meshHeader0;
MeshHeader1Base meshHeader1Base;
MeshHeader1Single meshHeader1Single;
MeshHeader1Multi meshHeader1Multi;
MeshHeader2 meshHeader2;
} MeshHeader; // "Ground Shape"
RoomShapeBase base;
RoomShapeNormal normal;
union {
RoomShapeImageBase base;
RoomShapeImageSingle single;
RoomShapeImageMulti multi;
} image;
RoomShapeCullable cullable;
} RoomShape; // "Ground Shape"
// TODO update ZAPD
typedef MeshHeader01Entry PolygonDlist;
typedef MeshHeader0 PolygonType0;
typedef MeshHeader2Entry PolygonDlist2;
typedef MeshHeader2 PolygonType2;
typedef RoomShapeDListsEntry PolygonDlist;
typedef RoomShapeNormal PolygonType0;
typedef RoomShapeImageSingle MeshHeader1Single;
typedef RoomShapeImageMultiBgEntry BgImage;
typedef RoomShapeImageMulti MeshHeader1Multi;
typedef RoomShapeCullableEntry PolygonDlist2;
typedef RoomShapeCullable PolygonType2;
#define SCENE_CMD_MESH SCENE_CMD_ROOM_SHAPE
#define ROOM_DRAW_OPA (1 << 0)
#define ROOM_DRAW_XLU (1 << 1)
@ -228,7 +236,7 @@ typedef struct {
typedef struct {
/* 0x00 */ u8 code;
/* 0x01 */ u8 data1;
/* 0x04 */ MeshHeaderBase* data;
/* 0x04 */ RoomShapeBase* data;
} SCmdMesh;
typedef struct {
@ -474,7 +482,7 @@ typedef enum {
/* 0x07 */ SCENE_CMD_ID_SPECIAL_FILES,
/* 0x08 */ SCENE_CMD_ID_ROOM_BEHAVIOR,
/* 0x09 */ SCENE_CMD_ID_UNDEFINED_9,
/* 0x0A */ SCENE_CMD_ID_MESH_HEADER,
/* 0x0A */ SCENE_CMD_ID_ROOM_SHAPE,
/* 0x0B */ SCENE_CMD_ID_OBJECT_LIST,
/* 0x0C */ SCENE_CMD_ID_LIGHT_LIST,
/* 0x0D */ SCENE_CMD_ID_PATH_LIST,
@ -524,8 +532,8 @@ typedef enum {
#define SCENE_CMD_UNK_09() \
{ SCENE_CMD_ID_UNDEFINED_9, 0, CMD_W(0) }
#define SCENE_CMD_MESH(meshHeader) \
{ SCENE_CMD_ID_MESH_HEADER, 0, CMD_PTR(meshHeader) }
#define SCENE_CMD_ROOM_SHAPE(roomShape) \
{ SCENE_CMD_ID_ROOM_SHAPE, 0, CMD_PTR(roomShape) }
#define SCENE_CMD_OBJECT_LIST(numObjects, objectList) \
{ SCENE_CMD_ID_OBJECT_LIST, numObjects, CMD_PTR(objectList) }

View File

@ -4059,7 +4059,7 @@ s32 Camera_Fixed3(Camera* camera) {
*eye = *eyeNext;
rwData->rot = bgCamFuncData->rot;
rwData->fov = bgCamFuncData->fov;
rwData->jfifId = bgCamFuncData->jfifId;
rwData->roomImageOverrideBgCamIndex = bgCamFuncData->roomImageOverrideBgCamIndex;
if (rwData->fov == -1) {
rwData->fov = 6000;
}
@ -4078,9 +4078,9 @@ s32 Camera_Fixed3(Camera* camera) {
camera->animState++;
}
if (bgCamFuncData->jfifId != rwData->jfifId) {
osSyncPrintf("camera: position change %d \n", rwData->jfifId);
rwData->jfifId = bgCamFuncData->jfifId;
if (bgCamFuncData->roomImageOverrideBgCamIndex != rwData->roomImageOverrideBgCamIndex) {
osSyncPrintf("camera: position change %d \n", rwData->roomImageOverrideBgCamIndex);
rwData->roomImageOverrideBgCamIndex = bgCamFuncData->roomImageOverrideBgCamIndex;
rwData->updDirTimer = 5;
}
@ -6984,7 +6984,7 @@ void func_80057FC4(Camera* camera) {
if (camera != &camera->play->mainCamera) {
camera->prevSetting = camera->setting = CAM_SET_FREE0;
camera->unk_14C &= ~0x4;
} else if (camera->play->roomCtx.curRoom.meshHeader->base.type != MESH_HEADER_TYPE_1) {
} else if (camera->play->roomCtx.curRoom.roomShape->base.type != ROOM_SHAPE_TYPE_IMAGE) {
switch (camera->play->roomCtx.curRoom.behaviorType1) {
case ROOM_BEHAVIOR_TYPE1_1:
Camera_ChangeDoorCam(camera, NULL, -99, 0, 0, 18, 10);

View File

@ -1731,8 +1731,8 @@ void Play_TriggerRespawn(PlayState* this) {
s32 Play_CamIsNotFixed(PlayState* this) {
// SCENE_CAM_TYPE_FIXED_SHOP_VIEWPOINT was probably intended to be in this condition,
// but the scene mesh header handles all shop cases regardless
return (this->roomCtx.curRoom.meshHeader->base.type != MESH_HEADER_TYPE_1) &&
// but the room shape type check handles all shop cases regardless
return (this->roomCtx.curRoom.roomShape->base.type != ROOM_SHAPE_TYPE_IMAGE) &&
(R_SCENE_CAM_TYPE != SCENE_CAM_TYPE_FIXED_TOGGLE_VIEWPOINT) && (R_SCENE_CAM_TYPE != SCENE_CAM_TYPE_FIXED) &&
(R_SCENE_CAM_TYPE != SCENE_CAM_TYPE_FIXED_MARKET) && (this->sceneId != SCENE_HAIRAL_NIWA);
}

View File

@ -1,10 +1,6 @@
#include "global.h"
#include "vt.h"
void Room_Draw0(PlayState* play, Room* room, u32 flags);
void Room_Draw2(PlayState* play, Room* room, u32 flags);
void Room_Draw1(PlayState* play, Room* room, u32 flags);
Vec3f D_801270A0 = { 0.0f, 0.0f, 0.0f };
// unused
@ -22,19 +18,23 @@ Gfx D_801270B0[] = {
gsSPEndDisplayList(),
};
void (*sRoomDrawHandlers[MESH_HEADER_TYPE_MAX])(PlayState* play, Room* room, u32 flags) = {
Room_Draw0,
Room_Draw1,
Room_Draw2,
void Room_DrawNormal(PlayState* play, Room* room, u32 flags);
void Room_DrawImage(PlayState* play, Room* room, u32 flags);
void Room_DrawCullable(PlayState* play, Room* room, u32 flags);
void (*sRoomDrawHandlers[ROOM_SHAPE_TYPE_MAX])(PlayState* play, Room* room, u32 flags) = {
Room_DrawNormal, // ROOM_SHAPE_TYPE_NORMAL
Room_DrawImage, // ROOM_SHAPE_TYPE_IMAGE
Room_DrawCullable, // ROOM_SHAPE_TYPE_CULLABLE
};
void func_80095AA0(PlayState* play, Room* room, Input* arg2, UNK_TYPE arg3) {
void func_80095AA0(PlayState* play, Room* room, Input* input, s32 arg3) {
}
void Room_Draw0(PlayState* play, Room* room, u32 flags) {
void Room_DrawNormal(PlayState* play, Room* room, u32 flags) {
s32 i;
MeshHeader0* meshHeader0;
MeshHeader01Entry* meshHeader0Entry;
RoomShapeNormal* roomShape;
RoomShapeDListsEntry* entry;
OPEN_DISPS(play->state.gfxCtx, "../z_room.c", 193);
@ -52,59 +52,75 @@ void Room_Draw0(PlayState* play, Room* room, u32 flags) {
gSPMatrix(POLY_XLU_DISP++, &gMtxClear, G_MTX_MODELVIEW | G_MTX_LOAD);
}
meshHeader0 = &room->meshHeader->meshHeader0;
meshHeader0Entry = SEGMENTED_TO_VIRTUAL(meshHeader0->entries);
for (i = 0; i < meshHeader0->numEntries; i++) {
if ((flags & ROOM_DRAW_OPA) && (meshHeader0Entry->opa != NULL)) {
gSPDisplayList(POLY_OPA_DISP++, meshHeader0Entry->opa);
roomShape = &room->roomShape->normal;
entry = SEGMENTED_TO_VIRTUAL(roomShape->entries);
for (i = 0; i < roomShape->numEntries; i++) {
if ((flags & ROOM_DRAW_OPA) && (entry->opa != NULL)) {
gSPDisplayList(POLY_OPA_DISP++, entry->opa);
}
if ((flags & ROOM_DRAW_XLU) && (meshHeader0Entry->xlu != NULL)) {
gSPDisplayList(POLY_XLU_DISP++, meshHeader0Entry->xlu);
if ((flags & ROOM_DRAW_XLU) && (entry->xlu != NULL)) {
gSPDisplayList(POLY_XLU_DISP++, entry->xlu);
}
meshHeader0Entry++;
entry++;
}
CLOSE_DISPS(play->state.gfxCtx, "../z_room.c", 239);
}
#define SHAPE_SORT_MAX 64
typedef enum {
/* 0 */ ROOM_CULL_DEBUG_MODE_OFF,
/* 1 */ ROOM_CULL_DEBUG_MODE_UP_TO_TARGET,
/* 2 */ ROOM_CULL_DEBUG_MODE_ONLY_TARGET
} RoomCullableDebugMode;
typedef struct struct_80095D04 {
/* 0x00 */ MeshHeader2Entry* unk_00;
/* 0x04 */ f32 unk_04;
/* 0x08 */ struct struct_80095D04* unk_08;
/* 0x0C */ struct struct_80095D04* unk_0C;
} struct_80095D04; // size = 0x10
typedef struct RoomShapeCullableEntryLinked {
/* 0x00 */ RoomShapeCullableEntry* entry;
/* 0x04 */ f32 boundsNearZ;
/* 0x08 */ struct RoomShapeCullableEntryLinked* prev;
/* 0x0C */ struct RoomShapeCullableEntryLinked* next;
} RoomShapeCullableEntryLinked; // size = 0x10
void Room_Draw2(PlayState* play, Room* room, u32 flags) {
MeshHeader2* meshHeader2;
MeshHeader2Entry* meshHeader2Entry;
struct_80095D04 spB8[SHAPE_SORT_MAX];
struct_80095D04* spB4 = NULL;
struct_80095D04* spB0 = NULL;
struct_80095D04* iter;
/**
* Handle room drawing for the "cullable" type of room shape.
*
* Each entry referenced by the room shape struct is attached to display lists, and a position and radius indicating the
* bounding sphere for the geometry drawn.
* The first step Z-sorts the entries, and excludes the entries with a bounding sphere that is entirely before or
* beyond the rendered depth range.
* The second step draws the entries that remain, from nearest to furthest.
*/
void Room_DrawCullable(PlayState* play, Room* room, u32 flags) {
RoomShapeCullable* roomShape;
RoomShapeCullableEntry* roomShapeCullableEntry;
RoomShapeCullableEntryLinked linkedEntriesBuffer[ROOM_SHAPE_CULLABLE_MAX_ENTRIES];
RoomShapeCullableEntryLinked* head = NULL;
RoomShapeCullableEntryLinked* tail = NULL;
RoomShapeCullableEntryLinked* iter;
s32 pad;
struct_80095D04* spA4;
RoomShapeCullableEntryLinked* insert;
s32 j;
s32 i;
Vec3f pos;
Vec3f projectedPos;
f32 projectedW;
s32 pad2;
MeshHeader2Entry* meshHeader2Entries;
MeshHeader2Entry* meshHeader2EntryIter;
f32 temp_f2;
RoomShapeCullableEntry* roomShapeCullableEntries;
RoomShapeCullableEntry* roomShapeCullableEntryIter;
f32 entryBoundsNearZ;
OPEN_DISPS(play->state.gfxCtx, "../z_room.c", 287);
if (flags & ROOM_DRAW_OPA) {
func_800342EC(&D_801270A0, play);
gSPSegment(POLY_OPA_DISP++, 0x03, room->segment);
func_80093C80(play);
gSPMatrix(POLY_OPA_DISP++, &gMtxClear, G_MTX_MODELVIEW | G_MTX_LOAD);
}
if (1) {}
if (flags & ROOM_DRAW_XLU) {
func_8003435C(&D_801270A0, play);
gSPSegment(POLY_XLU_DISP++, 0x03, room->segment);
@ -112,80 +128,103 @@ void Room_Draw2(PlayState* play, Room* room, u32 flags) {
gSPMatrix(POLY_XLU_DISP++, &gMtxClear, G_MTX_MODELVIEW | G_MTX_LOAD);
}
meshHeader2 = &room->meshHeader->meshHeader2;
meshHeader2Entry = SEGMENTED_TO_VIRTUAL(meshHeader2->entries);
spA4 = spB8;
roomShape = &room->roomShape->cullable;
roomShapeCullableEntry = SEGMENTED_TO_VIRTUAL(roomShape->entries);
insert = linkedEntriesBuffer;
ASSERT(meshHeader2->numEntries <= SHAPE_SORT_MAX, "polygon2->num <= SHAPE_SORT_MAX", "../z_room.c", 317);
meshHeader2Entries = meshHeader2Entry;
ASSERT(roomShape->numEntries <= ROOM_SHAPE_CULLABLE_MAX_ENTRIES, "polygon2->num <= SHAPE_SORT_MAX", "../z_room.c",
317);
for (i = 0; i < meshHeader2->numEntries; i++, meshHeader2Entry++) {
pos.x = meshHeader2Entry->pos.x;
pos.y = meshHeader2Entry->pos.y;
pos.z = meshHeader2Entry->pos.z;
roomShapeCullableEntries = roomShapeCullableEntry;
// Pick and sort entries by depth
for (i = 0; i < roomShape->numEntries; i++, roomShapeCullableEntry++) {
// Project the entry position, to get the depth it is at.
pos.x = roomShapeCullableEntry->boundsSphereCenter.x;
pos.y = roomShapeCullableEntry->boundsSphereCenter.y;
pos.z = roomShapeCullableEntry->boundsSphereCenter.z;
SkinMatrix_Vec3fMtxFMultXYZW(&play->viewProjectionMtxF, &pos, &projectedPos, &projectedW);
if (-(f32)meshHeader2Entry->unk_06 < projectedPos.z) {
temp_f2 = projectedPos.z - meshHeader2Entry->unk_06;
if (temp_f2 < play->lightCtx.fogFar) {
spA4->unk_00 = meshHeader2Entry;
spA4->unk_04 = temp_f2;
iter = spB4;
// If the entry bounding sphere isn't fully before the rendered depth range
if (-(f32)roomShapeCullableEntry->boundsSphereRadius < projectedPos.z) {
// Compute the depth of the nearest point in the entry's bounding sphere
entryBoundsNearZ = projectedPos.z - roomShapeCullableEntry->boundsSphereRadius;
// If the entry bounding sphere isn't fully beyond the rendered depth range
if (entryBoundsNearZ < play->lightCtx.fogFar) {
// This entry will be rendered
insert->entry = roomShapeCullableEntry;
insert->boundsNearZ = entryBoundsNearZ;
// Insert into the linked list, ordered by ascending depth of the nearest point in the bounding sphere
iter = head;
if (iter == NULL) {
spB4 = spB0 = spA4;
spA4->unk_08 = spA4->unk_0C = NULL;
head = tail = insert;
insert->prev = insert->next = NULL;
} else {
do {
if (spA4->unk_04 < iter->unk_04) {
if (insert->boundsNearZ < iter->boundsNearZ) {
break;
}
iter = iter->unk_0C;
iter = iter->next;
} while (iter != NULL);
if (iter == NULL) {
spA4->unk_08 = spB0;
spA4->unk_0C = NULL;
spB0->unk_0C = spA4;
spB0 = spA4;
insert->prev = tail;
insert->next = NULL;
tail->next = insert;
tail = insert;
} else {
spA4->unk_08 = iter->unk_08;
if (spA4->unk_08 == NULL) {
spB4 = spA4;
insert->prev = iter->prev;
if (insert->prev == NULL) {
head = insert;
} else {
spA4->unk_08->unk_0C = spA4;
insert->prev->next = insert;
}
iter->unk_08 = spA4;
spA4->unk_0C = iter;
iter->prev = insert;
insert->next = iter;
}
}
spA4++;
insert++;
}
}
}
iREG(87) = meshHeader2->numEntries & 0xFFFF & 0xFFFF & 0xFFFF; // if this is real then I might not be
// if this is real then I might not be
R_ROOM_CULL_NUM_ENTRIES = roomShape->numEntries & 0xFFFF & 0xFFFF & 0xFFFF;
for (i = 1; spB4 != NULL; spB4 = spB4->unk_0C, i++) {
// Draw entries, from nearest to furthest
for (i = 1; head != NULL; head = head->next, i++) {
Gfx* displayList;
meshHeader2Entry = spB4->unk_00;
if (iREG(86) != 0) {
meshHeader2EntryIter = meshHeader2Entries;
for (j = 0; j < meshHeader2->numEntries; j++, meshHeader2EntryIter++) {
if (meshHeader2Entry == meshHeader2EntryIter) {
break; // This loop does nothing?
roomShapeCullableEntry = head->entry;
if (R_ROOM_CULL_DEBUG_MODE != ROOM_CULL_DEBUG_MODE_OFF) {
// Debug mode drawing
// This loop does nothing
roomShapeCullableEntryIter = roomShapeCullableEntries;
for (j = 0; j < roomShape->numEntries; j++, roomShapeCullableEntryIter++) {
if (roomShapeCullableEntry == roomShapeCullableEntryIter) {
break;
}
}
if (((iREG(86) == 1) && (iREG(89) >= i)) || ((iREG(86) == 2) && (iREG(89) == i))) {
if (((R_ROOM_CULL_DEBUG_MODE == ROOM_CULL_DEBUG_MODE_UP_TO_TARGET) && (i <= R_ROOM_CULL_DEBUG_TARGET)) ||
((R_ROOM_CULL_DEBUG_MODE == ROOM_CULL_DEBUG_MODE_ONLY_TARGET) && (i == R_ROOM_CULL_DEBUG_TARGET))) {
if (flags & ROOM_DRAW_OPA) {
displayList = meshHeader2Entry->opa;
displayList = roomShapeCullableEntry->opa;
if (displayList != NULL) {
gSPDisplayList(POLY_OPA_DISP++, displayList);
}
}
if (flags & ROOM_DRAW_XLU) {
displayList = meshHeader2Entry->xlu;
displayList = roomShapeCullableEntry->xlu;
if (displayList != NULL) {
gSPDisplayList(POLY_XLU_DISP++, displayList);
}
@ -193,14 +232,14 @@ void Room_Draw2(PlayState* play, Room* room, u32 flags) {
}
} else {
if (flags & ROOM_DRAW_OPA) {
displayList = meshHeader2Entry->opa;
displayList = roomShapeCullableEntry->opa;
if (displayList != NULL) {
gSPDisplayList(POLY_OPA_DISP++, displayList);
}
}
if (flags & ROOM_DRAW_XLU) {
displayList = meshHeader2Entry->xlu;
displayList = roomShapeCullableEntry->xlu;
if (displayList != NULL) {
gSPDisplayList(POLY_XLU_DISP++, displayList);
}
@ -208,14 +247,18 @@ void Room_Draw2(PlayState* play, Room* room, u32 flags) {
}
}
iREG(88) = i - 1;
R_ROOM_CULL_USED_ENTRIES = i - 1;
CLOSE_DISPS(play->state.gfxCtx, "../z_room.c", 430);
}
#define JPEG_MARKER 0xFFD8FFE0
s32 func_80096238(void* data) {
/**
* If the data is JPEG, decode it and overwrite the initial data with the result.
* Uses the depth frame buffer as temporary storage.
*/
s32 Room_DecodeJpeg(void* data) {
OSTime time;
if (*(u32*)data == JPEG_MARKER) {
@ -232,10 +275,10 @@ s32 func_80096238(void* data) {
osSyncPrintf("成功…だと思う。 time = %6.3f ms \n", OS_CYCLES_TO_USEC(time) / 1000.0f);
// "Writing back to original address from work buffer."
osSyncPrintf("ワークバッファから元のアドレスに書き戻します。\n");
// "If the original buffer size isn't at least 150kb, it will be out of control."
// "If the original buffer size isn't at least 150kB, it will be out of control."
osSyncPrintf("元のバッファのサイズが150キロバイト無いと暴走するでしょう。\n");
bcopy(gZBuffer, data, sizeof(gZBuffer));
bcopy(gZBuffer, data, sizeof(u16[SCREEN_HEIGHT][SCREEN_WIDTH]));
} else {
osSyncPrintf("失敗!なんで〜\n"); // "Failure! Why is it 〜"
}
@ -244,72 +287,78 @@ s32 func_80096238(void* data) {
return 0;
}
void func_8009638C(Gfx** displayList, void* source, void* tlut, u16 width, u16 height, u8 fmt, u8 siz, u16 mode0,
u16 tlutCount, f32 frameX, f32 frameY) {
Gfx* displayListHead;
void Room_DrawBackground2D(Gfx** gfxP, void* tex, void* tlut, u16 width, u16 height, u8 fmt, u8 siz, u16 tlutMode,
u16 tlutCount, f32 offsetX, f32 offsetY) {
Gfx* gfx = *gfxP;
uObjBg* bg;
displayListHead = *displayList;
func_80096238(SEGMENTED_TO_VIRTUAL(source));
Room_DecodeJpeg(SEGMENTED_TO_VIRTUAL(tex));
bg = (uObjBg*)(gfx + 1);
gSPBranchList(gfx, (u32)bg + sizeof(uObjBg));
bg = (uObjBg*)(displayListHead + 1);
gSPBranchList(displayListHead, (u8*)bg + sizeof(uObjBg));
bg->b.imageX = 0;
bg->b.imageW = width * 4;
bg->b.frameX = frameX * 4;
bg->b.imageW = width * (1 << 2);
bg->b.frameX = offsetX * (1 << 2);
bg->b.imageY = 0;
bg->b.imageH = height * 4;
bg->b.frameY = frameY * 4;
bg->b.imagePtr = source;
bg->b.imageH = height * (1 << 2);
bg->b.frameY = offsetY * (1 << 2);
bg->b.imagePtr = tex;
bg->b.imageLoad = G_BGLT_LOADTILE;
bg->b.imageFmt = fmt;
bg->b.imageSiz = siz;
bg->b.imagePal = 0;
bg->b.imageFlip = 0;
displayListHead = (void*)(bg + 1);
gfx = (Gfx*)((u32)bg + sizeof(uObjBg));
if (fmt == G_IM_FMT_CI) {
gDPLoadTLUT(displayListHead++, tlutCount, 256, tlut);
gDPLoadTLUT(gfx++, tlutCount, 256, tlut);
} else {
gDPPipeSync(displayListHead++);
gDPPipeSync(gfx++);
}
if ((fmt == G_IM_FMT_RGBA) && (SREG(26) == 0)) {
bg->b.frameW = width * 4;
bg->b.frameH = height * 4;
if ((fmt == G_IM_FMT_RGBA) && !R_ROOM_BG2D_FORCE_SCALEBG) {
bg->b.frameW = width * (1 << 2);
bg->b.frameH = height * (1 << 2);
guS2DInitBg(bg);
gDPSetOtherMode(displayListHead++, mode0 | G_TL_TILE | G_TD_CLAMP | G_TP_NONE | G_CYC_COPY | G_PM_NPRIMITIVE,
gDPSetOtherMode(gfx++, tlutMode | G_TL_TILE | G_TD_CLAMP | G_TP_NONE | G_CYC_COPY | G_PM_NPRIMITIVE,
G_AC_THRESHOLD | G_ZS_PIXEL | G_RM_NOOP | G_RM_NOOP2);
gSPBgRectCopy(displayListHead++, bg);
gSPBgRectCopy(gfx++, bg);
} else {
bg->s.frameW = width * 4;
bg->s.frameH = height * 4;
bg->s.scaleW = 1024;
bg->s.scaleH = 1024;
bg->s.frameW = width * (1 << 2);
bg->s.frameH = height * (1 << 2);
bg->s.scaleW = 1 << 10;
bg->s.scaleH = 1 << 10;
bg->s.imageYorig = bg->b.imageY;
gDPSetOtherMode(displayListHead++,
mode0 | G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TT_NONE |
G_TL_TILE | G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
gDPSetOtherMode(gfx++,
tlutMode | G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TL_TILE |
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
G_AC_THRESHOLD | G_ZS_PIXEL | AA_EN | CVG_DST_CLAMP | ZMODE_OPA | CVG_X_ALPHA | ALPHA_CVG_SEL |
GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_BL, G_BL_1MA) |
GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_BL, G_BL_1MA));
gDPSetCombineLERP(displayListHead++, 0, 0, 0, TEXEL0, 0, 0, 0, 1, 0, 0, 0, TEXEL0, 0, 0, 0, 1);
gSPObjRenderMode(displayListHead++, G_OBJRM_ANTIALIAS | G_OBJRM_BILERP);
gSPBgRect1Cyc(displayListHead++, bg);
gDPSetCombineLERP(gfx++, 0, 0, 0, TEXEL0, 0, 0, 0, 1, 0, 0, 0, TEXEL0, 0, 0, 0, 1);
gSPObjRenderMode(gfx++, G_OBJRM_ANTIALIAS | G_OBJRM_BILERP);
gSPBgRect1Cyc(gfx++, bg);
}
gDPPipeSync(displayListHead++);
*displayList = displayListHead;
gDPPipeSync(gfx++);
*gfxP = gfx;
}
void Room_Draw1Single(PlayState* play, Room* room, u32 flags) {
#define ROOM_IMAGE_NODRAW_BACKGROUND (1 << 0)
#define ROOM_IMAGE_NODRAW_OPA (1 << 1)
#define ROOM_IMAGE_NODRAW_XLU (1 << 2)
void Room_DrawImageSingle(PlayState* play, Room* room, u32 flags) {
Camera* activeCam;
Gfx* spA8;
MeshHeader1Single* meshHeader1Single;
MeshHeader01Entry* meshHeader1Entry;
Gfx* gfx;
RoomShapeImageSingle* roomShape;
RoomShapeDListsEntry* entry;
u32 isFixedCamera;
u32 drawBg;
u32 drawBackground;
u32 drawOpa;
u32 drawXlu;
@ -317,123 +366,34 @@ void Room_Draw1Single(PlayState* play, Room* room, u32 flags) {
activeCam = GET_ACTIVE_CAM(play);
isFixedCamera = (activeCam->setting == CAM_SET_PREREND_FIXED);
meshHeader1Single = &room->meshHeader->meshHeader1Single;
meshHeader1Entry = SEGMENTED_TO_VIRTUAL(meshHeader1Single->base.entry);
drawBg = (flags & ROOM_DRAW_OPA) && isFixedCamera && meshHeader1Single->source && !(SREG(25) & 1);
drawOpa = (flags & ROOM_DRAW_OPA) && (meshHeader1Entry->opa != NULL) && !(SREG(25) & 2);
drawXlu = (flags & ROOM_DRAW_XLU) && (meshHeader1Entry->xlu != NULL) && !(SREG(25) & 4);
roomShape = &room->roomShape->image.single;
entry = SEGMENTED_TO_VIRTUAL(roomShape->base.entry);
drawBackground = (flags & ROOM_DRAW_OPA) && isFixedCamera && (roomShape->source != NULL) &&
!(R_ROOM_IMAGE_NODRAW_FLAGS & ROOM_IMAGE_NODRAW_BACKGROUND);
drawOpa = (flags & ROOM_DRAW_OPA) && (entry->opa != NULL) && !(R_ROOM_IMAGE_NODRAW_FLAGS & ROOM_IMAGE_NODRAW_OPA);
drawXlu = (flags & ROOM_DRAW_XLU) && (entry->xlu != NULL) && !(R_ROOM_IMAGE_NODRAW_FLAGS & ROOM_IMAGE_NODRAW_XLU);
if (drawOpa || drawBg) {
if (drawOpa || drawBackground) {
gSPSegment(POLY_OPA_DISP++, 0x03, room->segment);
if (drawOpa) {
Gfx_SetupDL_25Opa(play->state.gfxCtx);
gSPMatrix(POLY_OPA_DISP++, &gMtxClear, G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_OPA_DISP++, meshHeader1Entry->opa);
gSPDisplayList(POLY_OPA_DISP++, entry->opa);
}
if (drawBg) {
if (drawBackground) {
gSPLoadUcodeL(POLY_OPA_DISP++, gspS2DEX2d_fifo);
{
Vec3f sp60;
spA8 = POLY_OPA_DISP;
Camera_GetSkyboxOffset(&sp60, activeCam);
func_8009638C(&spA8, meshHeader1Single->source, meshHeader1Single->tlut, meshHeader1Single->width,
meshHeader1Single->height, meshHeader1Single->fmt, meshHeader1Single->siz,
meshHeader1Single->mode0, meshHeader1Single->tlutCount,
(sp60.x + sp60.z) * 1.2f + sp60.y * 0.6f, sp60.y * 2.4f + (sp60.x + sp60.z) * 0.3f);
POLY_OPA_DISP = spA8;
}
gSPLoadUcode(POLY_OPA_DISP++, SysUcode_GetUCode(), SysUcode_GetUCodeData());
}
}
if (drawXlu) {
gSPSegment(POLY_XLU_DISP++, 0x03, room->segment);
Gfx_SetupDL_25Xlu(play->state.gfxCtx);
gSPMatrix(POLY_XLU_DISP++, &gMtxClear, G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_XLU_DISP++, meshHeader1Entry->xlu);
}
CLOSE_DISPS(play->state.gfxCtx, "../z_room.c", 691);
}
BgImage* func_80096A74(MeshHeader1Multi* meshHeader1Multi, PlayState* play) {
Camera* activeCam = GET_ACTIVE_CAM(play);
s32 bgCamIndex = activeCam->bgCamIndex;
s16 jfifId;
Player* player;
BgImage* bgImage;
s32 i;
jfifId = ((BgCamFuncData*)BgCheck_GetBgCamFuncDataImpl(&play->colCtx, bgCamIndex, BGCHECK_SCENE))->jfifId;
if (jfifId >= 0) {
bgCamIndex = jfifId;
}
player = GET_PLAYER(play);
player->actor.params = (player->actor.params & 0xFF00) | bgCamIndex;
bgImage = SEGMENTED_TO_VIRTUAL(meshHeader1Multi->list);
for (i = 0; i < meshHeader1Multi->count; i++) {
if (bgImage->id == bgCamIndex) {
return bgImage;
}
bgImage++;
}
// "z_room.c: Data consistent with camera id does not exist camid=%d"
osSyncPrintf(VT_COL(RED, WHITE) "z_room.c:カメラIDに一致するデータが存在しません camid=%d\n" VT_RST, bgCamIndex);
LogUtils_HungupThread("../z_room.c", 726);
return NULL;
}
void Room_Draw1Multi(PlayState* play, Room* room, u32 flags) {
Camera* activeCam;
Gfx* gfx;
MeshHeader1Multi* meshHeader1Multi;
BgImage* bgImage;
MeshHeader01Entry* meshHeader1Entry;
u32 isFixedCamera;
u32 drawBg;
u32 drawOpa;
u32 drawXlu;
OPEN_DISPS(play->state.gfxCtx, "../z_room.c", 752);
activeCam = GET_ACTIVE_CAM(play);
isFixedCamera = (activeCam->setting == CAM_SET_PREREND_FIXED);
meshHeader1Multi = &room->meshHeader->meshHeader1Multi;
meshHeader1Entry = SEGMENTED_TO_VIRTUAL(meshHeader1Multi->base.entry);
bgImage = func_80096A74(meshHeader1Multi, play);
drawBg = (flags & ROOM_DRAW_OPA) && isFixedCamera && bgImage->source && !(SREG(25) & 1);
drawOpa = (flags & ROOM_DRAW_OPA) && (meshHeader1Entry->opa != NULL) && !(SREG(25) & 2);
drawXlu = (flags & ROOM_DRAW_XLU) && (meshHeader1Entry->xlu != NULL) && !(SREG(25) & 4);
if (drawOpa || drawBg) {
gSPSegment(POLY_OPA_DISP++, 0x03, room->segment);
if (drawOpa) {
Gfx_SetupDL_25Opa(play->state.gfxCtx);
gSPMatrix(POLY_OPA_DISP++, &gMtxClear, G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_OPA_DISP++, meshHeader1Entry->opa);
}
if (drawBg) {
gSPLoadUcodeL(POLY_OPA_DISP++, gspS2DEX2d_fifo);
{
Vec3f skyboxOffset;
Vec3f quakeOffset;
gfx = POLY_OPA_DISP;
Camera_GetSkyboxOffset(&skyboxOffset, activeCam);
func_8009638C(&gfx, bgImage->source, bgImage->tlut, bgImage->width, bgImage->height, bgImage->fmt,
bgImage->siz, bgImage->mode0, bgImage->tlutCount,
(skyboxOffset.x + skyboxOffset.z) * 1.2f + skyboxOffset.y * 0.6f,
skyboxOffset.y * 2.4f + (skyboxOffset.x + skyboxOffset.z) * 0.3f);
Camera_GetSkyboxOffset(&quakeOffset, activeCam);
Room_DrawBackground2D(&gfx, roomShape->source, roomShape->tlut, roomShape->width, roomShape->height,
roomShape->fmt, roomShape->siz, roomShape->tlutMode, roomShape->tlutCount,
(quakeOffset.x + quakeOffset.z) * 1.2f + quakeOffset.y * 0.6f,
quakeOffset.y * 2.4f + (quakeOffset.x + quakeOffset.z) * 0.3f);
POLY_OPA_DISP = gfx;
}
@ -445,19 +405,117 @@ void Room_Draw1Multi(PlayState* play, Room* room, u32 flags) {
gSPSegment(POLY_XLU_DISP++, 0x03, room->segment);
Gfx_SetupDL_25Xlu(play->state.gfxCtx);
gSPMatrix(POLY_XLU_DISP++, &gMtxClear, G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_XLU_DISP++, meshHeader1Entry->xlu);
gSPDisplayList(POLY_XLU_DISP++, entry->xlu);
}
CLOSE_DISPS(play->state.gfxCtx, "../z_room.c", 691);
}
RoomShapeImageMultiBgEntry* Room_GetImageMultiBgEntry(RoomShapeImageMulti* roomShapeImageMulti, PlayState* play) {
Camera* activeCam = GET_ACTIVE_CAM(play);
s32 bgCamIndex = activeCam->bgCamIndex;
s16 overrideBgCamIndex;
Player* player;
RoomShapeImageMultiBgEntry* bgEntry;
s32 i;
// In mq debug vanilla scenes, overrideBgCamIndex is always -1 or the same as bgCamIndex
overrideBgCamIndex = ((BgCamFuncData*)BgCheck_GetBgCamFuncDataImpl(&play->colCtx, bgCamIndex, BGCHECK_SCENE))
->roomImageOverrideBgCamIndex;
if (overrideBgCamIndex >= 0) {
bgCamIndex = overrideBgCamIndex;
}
player = GET_PLAYER(play);
player->actor.params = (player->actor.params & 0xFF00) | bgCamIndex;
bgEntry = SEGMENTED_TO_VIRTUAL(roomShapeImageMulti->backgrounds);
for (i = 0; i < roomShapeImageMulti->numBackgrounds; i++) {
if (bgEntry->bgCamIndex == bgCamIndex) {
return bgEntry;
}
bgEntry++;
}
// "z_room.c: Data consistent with camera id does not exist camid=%d"
osSyncPrintf(VT_COL(RED, WHITE) "z_room.c:カメラIDに一致するデータが存在しません camid=%d\n" VT_RST, bgCamIndex);
LogUtils_HungupThread("../z_room.c", 726);
return NULL;
}
void Room_DrawImageMulti(PlayState* play, Room* room, u32 flags) {
Camera* activeCam;
Gfx* gfx;
RoomShapeImageMulti* roomShape;
RoomShapeImageMultiBgEntry* bgEntry;
RoomShapeDListsEntry* dListsEntry;
u32 isFixedCamera;
u32 drawBackground;
u32 drawOpa;
u32 drawXlu;
OPEN_DISPS(play->state.gfxCtx, "../z_room.c", 752);
activeCam = GET_ACTIVE_CAM(play);
isFixedCamera = (activeCam->setting == CAM_SET_PREREND_FIXED);
roomShape = &room->roomShape->image.multi;
dListsEntry = SEGMENTED_TO_VIRTUAL(roomShape->base.entry);
bgEntry = Room_GetImageMultiBgEntry(roomShape, play);
drawBackground = (flags & ROOM_DRAW_OPA) && isFixedCamera && (bgEntry->source != NULL) &&
!(R_ROOM_IMAGE_NODRAW_FLAGS & ROOM_IMAGE_NODRAW_BACKGROUND);
drawOpa =
(flags & ROOM_DRAW_OPA) && (dListsEntry->opa != NULL) && !(R_ROOM_IMAGE_NODRAW_FLAGS & ROOM_IMAGE_NODRAW_OPA);
drawXlu =
(flags & ROOM_DRAW_XLU) && (dListsEntry->xlu != NULL) && !(R_ROOM_IMAGE_NODRAW_FLAGS & ROOM_IMAGE_NODRAW_XLU);
if (drawOpa || drawBackground) {
gSPSegment(POLY_OPA_DISP++, 0x03, room->segment);
if (drawOpa) {
Gfx_SetupDL_25Opa(play->state.gfxCtx);
gSPMatrix(POLY_OPA_DISP++, &gMtxClear, G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_OPA_DISP++, dListsEntry->opa);
}
if (drawBackground) {
gSPLoadUcodeL(POLY_OPA_DISP++, gspS2DEX2d_fifo);
{
Vec3f quakeOffset;
gfx = POLY_OPA_DISP;
Camera_GetSkyboxOffset(&quakeOffset, activeCam);
Room_DrawBackground2D(&gfx, bgEntry->source, bgEntry->tlut, bgEntry->width, bgEntry->height,
bgEntry->fmt, bgEntry->siz, bgEntry->tlutMode, bgEntry->tlutCount,
(quakeOffset.x + quakeOffset.z) * 1.2f + quakeOffset.y * 0.6f,
quakeOffset.y * 2.4f + (quakeOffset.x + quakeOffset.z) * 0.3f);
POLY_OPA_DISP = gfx;
}
gSPLoadUcode(POLY_OPA_DISP++, SysUcode_GetUCode(), SysUcode_GetUCodeData());
}
}
if (drawXlu) {
gSPSegment(POLY_XLU_DISP++, 0x03, room->segment);
Gfx_SetupDL_25Xlu(play->state.gfxCtx);
gSPMatrix(POLY_XLU_DISP++, &gMtxClear, G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_XLU_DISP++, dListsEntry->xlu);
}
CLOSE_DISPS(play->state.gfxCtx, "../z_room.c", 819);
}
void Room_Draw1(PlayState* play, Room* room, u32 flags) {
MeshHeader1Base* meshHeader1Base = &room->meshHeader->meshHeader1Base;
void Room_DrawImage(PlayState* play, Room* room, u32 flags) {
RoomShapeImageBase* roomShape = &room->roomShape->image.base;
if (meshHeader1Base->format == MESH_HEADER1_FORMAT_SINGLE) {
Room_Draw1Single(play, room, flags);
} else if (meshHeader1Base->format == MESH_HEADER1_FORMAT_MULTI) {
Room_Draw1Multi(play, room, flags);
if (roomShape->amountType == ROOM_SHAPE_IMAGE_AMOUNT_SINGLE) {
Room_DrawImageSingle(play, room, flags);
} else if (roomShape->amountType == ROOM_SHAPE_IMAGE_AMOUNT_MULTI) {
Room_DrawImageMulti(play, room, flags);
} else {
LogUtils_HungupThread("../z_room.c", 841);
}
@ -578,9 +636,9 @@ s32 func_800973FC(PlayState* play, RoomContext* roomCtx) {
void Room_Draw(PlayState* play, Room* room, u32 flags) {
if (room->segment != NULL) {
gSegments[3] = VIRTUAL_TO_PHYSICAL(room->segment);
ASSERT(room->meshHeader->base.type < ARRAY_COUNTU(sRoomDrawHandlers),
ASSERT(room->roomShape->base.type < ARRAY_COUNTU(sRoomDrawHandlers),
"this->ground_shape->polygon.type < number(Room_Draw_Proc)", "../z_room.c", 1125);
sRoomDrawHandlers[room->meshHeader->base.type](play, room, flags);
sRoomDrawHandlers[room->roomShape->base.type](play, room, flags);
}
}

View File

@ -243,8 +243,8 @@ void Scene_CommandRoomBehavior(PlayState* play, SceneCmd* cmd) {
play->msgCtx.disableWarpSongs = (cmd->roomBehavior.gpFlag2 >> 0xA) & 1;
}
void Scene_CommandMeshHeader(PlayState* play, SceneCmd* cmd) {
play->roomCtx.curRoom.meshHeader = SEGMENTED_TO_VIRTUAL(cmd->mesh.data);
void Scene_CommandRoomShape(PlayState* play, SceneCmd* cmd) {
play->roomCtx.curRoom.roomShape = SEGMENTED_TO_VIRTUAL(cmd->mesh.data);
}
void Scene_CommandObjectList(PlayState* play, SceneCmd* cmd) {
@ -480,7 +480,7 @@ void (*gSceneCmdHandlers[SCENE_CMD_ID_MAX])(PlayState*, SceneCmd*) = {
Scene_CommandSpecialFiles, // SCENE_CMD_ID_SPECIAL_FILES
Scene_CommandRoomBehavior, // SCENE_CMD_ID_ROOM_BEHAVIOR
Scene_CommandUndefined9, // SCENE_CMD_ID_UNDEFINED_9
Scene_CommandMeshHeader, // SCENE_CMD_ID_MESH_HEADER
Scene_CommandRoomShape, // SCENE_CMD_ID_ROOM_SHAPE
Scene_CommandObjectList, // SCENE_CMD_ID_OBJECT_LIST
Scene_CommandLightList, // SCENE_CMD_ID_LIGHT_LIST
Scene_CommandPathList, // SCENE_CMD_ID_PATH_LIST

View File

@ -526,17 +526,16 @@ void KaleidoScope_DrawWorldMap(PlayState* play, GraphicsContext* gfxCtx) {
gSP1Quadrangle(POLY_OPA_DISP++, j, j + 2, j + 3, j + 1, 0);
} else if (HREG(15) == 1) {
Gfx* sp1CC = POLY_OPA_DISP;
void* mapImage = gWorldMapImageTex;
Gfx* gfx = POLY_OPA_DISP;
gSPLoadUcodeL(sp1CC++, gspS2DEX2d_fifo);
gSPLoadUcodeL(gfx++, gspS2DEX2d_fifo);
func_8009638C(&sp1CC, mapImage, gWorldMapImageTLUT, 216, 128, G_IM_FMT_CI, G_IM_SIZ_8b, 0x8000, 256,
HREG(13) / 100.0f, HREG(14) / 100.0f);
Room_DrawBackground2D(&gfx, gWorldMapImageTex, gWorldMapImageTLUT, 216, 128, G_IM_FMT_CI, G_IM_SIZ_8b,
G_TT_RGBA16, 256, HREG(13) / 100.0f, HREG(14) / 100.0f);
gSPLoadUcode(sp1CC++, SysUcode_GetUCode(), SysUcode_GetUCodeData());
gSPLoadUcode(gfx++, SysUcode_GetUCode(), SysUcode_GetUCodeData());
POLY_OPA_DISP = sp1CC;
POLY_OPA_DISP = gfx;
}
if (HREG(15) == 2) {