work on next test chamber

This commit is contained in:
James Lambert 2022-08-26 21:20:14 -06:00
parent 70b2585a1c
commit b59695f2a4
26 changed files with 336 additions and 11 deletions

View file

@ -170,6 +170,8 @@ MODEL_LIST = assets/models/cube/cube.blend \
assets/models/props/round_elevator_interior.blend \ assets/models/props/round_elevator_interior.blend \
assets/models/props/round_elevator_collision.blend \ assets/models/props/round_elevator_collision.blend \
assets/models/props/signage.blend \ assets/models/props/signage.blend \
assets/models/props/box_dropper.blend \
assets/models/props/box_dropper_glass.blend \
assets/models/portal/portal_blue.blend \ assets/models/portal/portal_blue.blend \
assets/models/portal/portal_blue_filled.blend \ assets/models/portal/portal_blue_filled.blend \
assets/models/portal/portal_blue_face.blend \ assets/models/portal/portal_blue_face.blend \
@ -178,7 +180,7 @@ MODEL_LIST = assets/models/cube/cube.blend \
assets/models/portal/portal_orange_face.blend \ assets/models/portal/portal_orange_face.blend \
assets/models/pedestal.blend assets/models/pedestal.blend
ANIM_LIST = build/assets/models/pedestal_anim.o ANIM_LIST = build/assets/models/pedestal_anim.o build/assets/models/props/box_dropper_anim.o
MODEL_HEADERS = $(MODEL_LIST:%.blend=build/%.h) MODEL_HEADERS = $(MODEL_LIST:%.blend=build/%.h)
MODEL_OBJECTS = $(MODEL_LIST:%.blend=build/%_geo.o) MODEL_OBJECTS = $(MODEL_LIST:%.blend=build/%_geo.o)
@ -194,6 +196,8 @@ build/src/scene/portal.o: $(MODEL_HEADERS)
build/src/scene/signage.o: $(MODEL_HEADERS) build/src/scene/signage.o: $(MODEL_HEADERS)
build/src/scene/box_dropper.o: $(MODEL_HEADERS)
build/anims.ld: $(ANIM_LIST) tools/generate_animation_ld.js build/anims.ld: $(ANIM_LIST) tools/generate_animation_ld.js
@mkdir -p $(@D) @mkdir -p $(@D)
node tools/generate_animation_ld.js $@ $(ANIM_LIST) node tools/generate_animation_ld.js $@ $(ANIM_LIST)
@ -203,7 +207,8 @@ build/anims.ld: $(ANIM_LIST) tools/generate_animation_ld.js
#################### ####################
TEST_CHAMBERS = assets/test_chambers/test_chamber_00/test_chamber_00.blend \ TEST_CHAMBERS = assets/test_chambers/test_chamber_00/test_chamber_00.blend \
assets/test_chambers/test_chamber_01/test_chamber_01.blend assets/test_chambers/test_chamber_01/test_chamber_01.blend \
assets/test_chambers/test_chamber_02/test_chamber_02.blend
TEST_CHAMBER_HEADERS = $(TEST_CHAMBERS:%.blend=build/%.h) TEST_CHAMBER_HEADERS = $(TEST_CHAMBERS:%.blend=build/%.h)
TEST_CHAMBER_OBJECTS = $(TEST_CHAMBERS:%.blend=build/%_geo.o) TEST_CHAMBER_OBJECTS = $(TEST_CHAMBERS:%.blend=build/%_geo.o)

View file

@ -0,0 +1 @@
-crop 128x128+128+0 -resize 32x32

View file

@ -49,6 +49,19 @@ materials:
tileSizeS: 0.5 tileSizeS: 0.5
tileSizeT: 0.5 tileSizeT: 0.5
metal_modular_floor001:
gDPSetTile:
filename: ../../portal_pak_modified/materials/metal/metal_modular_floor001.png
siz: G_IM_SIZ_16b
gDPSetCombineMode: G_CC_DECALRGB
gDPSetCycleType: G_CYC_1CYCLE
properties:
tileSizeS: 0.5
tileSizeT: 0.5
metalwall_bts_006a: metalwall_bts_006a:
gDPSetTile: gDPSetTile:
filename: ../../portal_pak_modified/materials/metal/metalwall_bts_006a.png filename: ../../portal_pak_modified/materials/metal/metalwall_bts_006a.png

Binary file not shown.

View file

@ -0,0 +1 @@
-r 0,0,0 -m assets/materials/static.skm.yaml -m assets/materials/objects.skm.yaml --default-material default

Binary file not shown.

View file

@ -0,0 +1 @@
-r 0,0,0 -m assets/materials/static.skm.yaml -m assets/materials/objects.skm.yaml --default-material glasswindow_frosted_002

Binary file not shown.

View file

@ -0,0 +1 @@
-c 1 -r 22050

View file

@ -0,0 +1 @@
-c 1 -r 22050

View file

@ -0,0 +1 @@
-c 1 -r 22050

View file

@ -0,0 +1 @@
-c 1 -r 22050

View file

@ -747,6 +747,51 @@ void generateSignageDefinitions(
levelDef.AddPrimitive("signageCount", signageCount); levelDef.AddPrimitive("signageCount", signageCount);
} }
void generateBoxDropperDefinitions(
const aiScene* scene,
CFileDefinition& fileDefinition,
StructureDataChunk& levelDef,
const RoomGeneratorOutput& roomOutput,
const DisplayListSettings& settings,
NodeGroups& nodeGroups,
Signals& signals) {
int boxDropperCount = 0;
std::unique_ptr<StructureDataChunk> signage(new StructureDataChunk());
aiMatrix4x4 baseTransform = settings.CreateCollisionTransform();
for (auto& nodeInfo : nodeGroups.NodesForType("@box_dropper")) {
if (nodeInfo.arguments.size() == 0) {
continue;
}
std::unique_ptr<StructureDataChunk> boxDropperData(new StructureDataChunk());
aiVector3D pos;
aiQuaternion rot;
aiVector3D scale;
(baseTransform * nodeInfo.node->mTransformation).Decompose(scale, rot, pos);
boxDropperData->Add(std::unique_ptr<StructureDataChunk>(new StructureDataChunk(pos)));
boxDropperData->AddPrimitive(roomOutput.RoomForNode(nodeInfo.node));
boxDropperData->AddPrimitive(signals.SignalIndexForName(nodeInfo.arguments[0]));
signage->Add(std::move(boxDropperData));
++boxDropperCount;
}
std::string boxDropperDef = fileDefinition.AddDataDefinition(
"box_dropper",
"struct BoxDropperDefinition",
true,
"_geo",
std::move(signage)
);
levelDef.AddPrimitive("boxDroppers", boxDropperDef);
levelDef.AddPrimitive("boxDropperCount", boxDropperCount);
}
void generateLevel( void generateLevel(
const aiScene* scene, const aiScene* scene,
CFileDefinition& fileDefinition, CFileDefinition& fileDefinition,
@ -794,5 +839,7 @@ void generateLevel(
generateSignageDefinitions(scene, fileDefinition, *levelDef, roomOutput, settings, nodeGroups); generateSignageDefinitions(scene, fileDefinition, *levelDef, roomOutput, settings, nodeGroups);
generateBoxDropperDefinitions(scene, fileDefinition, *levelDef, roomOutput, settings, nodeGroups, signals);
fileDefinition.AddDefinition(std::unique_ptr<FileDefinition>(new DataFileDefinition("struct LevelDefinition", fileDefinition.GetUniqueName("level"), false, "_geo", std::move(levelDef)))); fileDefinition.AddDefinition(std::unique_ptr<FileDefinition>(new DataFileDefinition("struct LevelDefinition", fileDefinition.GetUniqueName("level"), false, "_geo", std::move(levelDef))));
} }

View file

@ -71,13 +71,17 @@ void decorObjectInit(struct DecorObject* object, struct DecorObjectDefinition* d
} }
} }
void decorObjectDelete(struct DecorObject* decorObject) { void decorObjectClenaup(struct DecorObject* decorObject) {
dynamicSceneRemove(decorObject->dynamicId); dynamicSceneRemove(decorObject->dynamicId);
collisionSceneRemoveDynamicObject(&decorObject->collisionObject); collisionSceneRemoveDynamicObject(&decorObject->collisionObject);
}
void decorObjectDelete(struct DecorObject* decorObject) {
decorObjectClenaup(decorObject);
free(decorObject); free(decorObject);
} }
void decorObjectUpdate(struct DecorObject* decorObject) { int decorObjectUpdate(struct DecorObject* decorObject) {
if (decorObject->playingSound != SOUND_ID_NONE) { if (decorObject->playingSound != SOUND_ID_NONE) {
soundPlayerUpdatePosition(decorObject->playingSound, &decorObject->rigidBody.transform.position); soundPlayerUpdatePosition(decorObject->playingSound, &decorObject->rigidBody.transform.position);
} }
@ -97,5 +101,11 @@ void decorObjectUpdate(struct DecorObject* decorObject) {
decorObject->fizzleTime += FIZZLE_TIME_STEP; decorObject->fizzleTime += FIZZLE_TIME_STEP;
decorObject->collisionObject.body->flags &= ~RigidBodyFlagsGrabbable; decorObject->collisionObject.body->flags &= ~RigidBodyFlagsGrabbable;
decorObject->collisionObject.body->flags |= RigidBodyDisableGravity; decorObject->collisionObject.body->flags |= RigidBodyDisableGravity;
if (decorObject->fizzleTime > 1.0f) {
return 0;
} }
}
return 1;
} }

View file

@ -26,8 +26,9 @@ struct DecorObject {
struct DecorObject* decorObjectNew(struct DecorObjectDefinition* definition, struct Transform* at, int room); struct DecorObject* decorObjectNew(struct DecorObjectDefinition* definition, struct Transform* at, int room);
void decorObjectInit(struct DecorObject* object, struct DecorObjectDefinition* definition, struct Transform* at, int room); void decorObjectInit(struct DecorObject* object, struct DecorObjectDefinition* definition, struct Transform* at, int room);
void decorObjectClenaup(struct DecorObject* decorObject);
void decorObjectDelete(struct DecorObject* decorObject); void decorObjectDelete(struct DecorObject* decorObject);
void decorObjectUpdate(struct DecorObject* decorObject); int decorObjectUpdate(struct DecorObject* decorObject);
#endif #endif

View file

@ -162,6 +162,12 @@ struct SignageDefinition {
short testChamberNumber; short testChamberNumber;
}; };
struct BoxDropperDefinition {
struct Vector3 position;
short roomIndex;
short signalIndex;
};
struct LevelDefinition { struct LevelDefinition {
struct CollisionObject* collisionQuads; struct CollisionObject* collisionQuads;
struct StaticContentElement *staticContent; struct StaticContentElement *staticContent;
@ -183,6 +189,7 @@ struct LevelDefinition {
struct ElevatorDefinition* elevators; struct ElevatorDefinition* elevators;
struct PedestalDefinition* pedestals; struct PedestalDefinition* pedestals;
struct SignageDefinition* signage; struct SignageDefinition* signage;
struct BoxDropperDefinition* boxDroppers;
short collisionQuadCount; short collisionQuadCount;
short staticContentCount; short staticContentCount;
short portalSurfaceCount; short portalSurfaceCount;
@ -197,6 +204,7 @@ struct LevelDefinition {
short elevatorCount; short elevatorCount;
short pedestalCount; short pedestalCount;
short signageCount; short signageCount;
short boxDropperCount;
short startLocation; short startLocation;
}; };

View file

@ -81,6 +81,7 @@ struct LevelDefinition* levelFixPointers(struct LevelDefinition* from, int point
result->elevators = ADJUST_POINTER_POS(result->elevators, pointerOffset); result->elevators = ADJUST_POINTER_POS(result->elevators, pointerOffset);
result->pedestals = ADJUST_POINTER_POS(result->pedestals, pointerOffset); result->pedestals = ADJUST_POINTER_POS(result->pedestals, pointerOffset);
result->signage = ADJUST_POINTER_POS(result->signage, pointerOffset); result->signage = ADJUST_POINTER_POS(result->signage, pointerOffset);
result->boxDroppers = ADJUST_POINTER_POS(result->boxDroppers, pointerOffset);
return result; return result;
} }

View file

@ -154,7 +154,7 @@ static void gameProc(void* arg) {
dynamicSceneInit(); dynamicSceneInit();
contactSolverInit(&gContactSolver); contactSolverInit(&gContactSolver);
portalSurfaceCleanupQueueInit(); portalSurfaceCleanupQueueInit();
levelLoad(0); levelLoad(2);
cutsceneRunnerReset(); cutsceneRunnerReset();
controllersInit(); controllersInit();
initAudio(); initAudio();

View file

@ -8,6 +8,8 @@
#include "../../build/assets/models/props/button.h" #include "../../build/assets/models/props/button.h"
#include "../../build/assets/models/props/door_01.h" #include "../../build/assets/models/props/door_01.h"
#include "../../build/assets/models/props/cylinder_test.h" #include "../../build/assets/models/props/cylinder_test.h"
#include "../../build/assets/models/props/box_dropper.h"
#include "../../build/assets/models/props/box_dropper_glass.h"
Gfx* v_portal_gun_gfx = &portal_gun_v_portalgun_model_gfx[0]; Gfx* v_portal_gun_gfx = &portal_gun_v_portalgun_model_gfx[0];
@ -23,3 +25,8 @@ Gfx* cylinder_gfx = &props_cylinder_test_model_gfx[0];
short cylinder_material_index = PLASTIC_PLASTICWALL001A_INDEX; short cylinder_material_index = PLASTIC_PLASTICWALL001A_INDEX;
short fizzler_material_index = PORTAL_CLEANSER_INDEX; short fizzler_material_index = PORTAL_CLEANSER_INDEX;
Gfx* box_dropper_gfx = props_box_dropper_model_gfx;
Gfx* box_dropper_glass_gfx = props_box_dropper_glass_model_gfx;
short box_dropper_material_index = DEFAULT_INDEX;
short box_dropper_glass_material_index = GLASSWINDOW_FROSTED_002_INDEX;

View file

@ -19,4 +19,10 @@ extern short cylinder_material_index;
extern short fizzler_material_index; extern short fizzler_material_index;
extern Gfx* box_dropper_gfx;
extern Gfx* box_dropper_glass_gfx;
extern short box_dropper_material_index;
extern short box_dropper_glass_material_index;
#endif #endif

View file

@ -277,10 +277,18 @@ int minkowsiSumAgainstQuad(void* data, struct Vector3* direction, struct Vector3
int minkowsiSumAgainstSweptObject(void* data, struct Vector3* direction, struct Vector3* output) { int minkowsiSumAgainstSweptObject(void* data, struct Vector3* direction, struct Vector3* output) {
struct SweptCollisionObject* sweptObject = (struct SweptCollisionObject*)data; struct SweptCollisionObject* sweptObject = (struct SweptCollisionObject*)data;
int result = sweptObject->object->collider->callbacks->minkowsiSum(sweptObject->object->collider->data, &sweptObject->object->body->rotationBasis, direction, output); struct ColliderTypeData* collider = sweptObject->object->collider;
struct RigidBody* body = sweptObject->object->body;
if (vector3Dot(&sweptObject->object->body->transform.position, direction) > vector3Dot(sweptObject->prevPos, direction)) { int result = collider->callbacks->minkowsiSum(
vector3Add(output, &sweptObject->object->body->transform.position, output); collider->data,
&body->rotationBasis,
direction,
output
);
if (vector3Dot(&body->transform.position, direction) > vector3Dot(sweptObject->prevPos, direction)) {
vector3Add(output, &body->transform.position, output);
} else { } else {
vector3Add(output, sweptObject->prevPos, output); vector3Add(output, sweptObject->prevPos, output);
} }

148
src/scene/box_dropper.c Normal file
View file

@ -0,0 +1,148 @@
#include "box_dropper.h"
#include "../scene/dynamic_scene.h"
#include "../models/models.h"
#include "../defs.h"
#include "../physics/config.h"
#include "../util/time.h"
#include "signals.h"
#include "../decor/decor_object_list.h"
#include "../../build/assets/materials/static.h"
#include "../../build/assets/models/cube/cube.h"
#include "../../build/assets/models/props/box_dropper.h"
#define DROOPER_RELOAD_TIME 2.0f
#define DROPPER_DROP_TIME 0.5f
void boxDropperFakePos(struct BoxDropper* dropper, struct Transform* result) {
*result = dropper->transform;
result->position.y += 0.4f;
if (dropper->reloadTimer) {
float timeSinceDrop = (DROPPER_DROP_TIME - dropper->reloadTimer);
result->position.y -= GRAVITY_CONSTANT * DROPPER_DROP_TIME * DROPPER_DROP_TIME;
result->position.y += GRAVITY_CONSTANT * timeSinceDrop * timeSinceDrop;
}
}
void boxDropperRender(void* data, struct RenderScene* renderScene) {
struct BoxDropper* dropper = (struct BoxDropper*)data;
Mtx* matrix = renderStateRequestMatrices(renderScene->renderState, 1);
transformToMatrixL(&dropper->transform, matrix, SCENE_SCALE);
Mtx* armature = renderStateRequestMatrices(renderScene->renderState, PROPS_BOX_DROPPER_DEFAULT_BONES_COUNT);
skCalculateTransforms(&dropper->armature, armature);
renderSceneAdd(
renderScene,
props_box_dropper_model_gfx,
matrix,
box_dropper_material_index,
&dropper->transform.position,
armature
);
renderSceneAdd(
renderScene,
box_dropper_glass_gfx,
matrix,
box_dropper_glass_material_index,
&dropper->transform.position,
NULL
);
if (dropper->reloadTimer < DROPPER_DROP_TIME) {
struct Transform pendingCubePos;
boxDropperFakePos(dropper, &pendingCubePos);
Mtx* pendingBoxMatrix = renderStateRequestMatrices(renderScene->renderState, 1);
transformToMatrixL(&pendingCubePos, pendingBoxMatrix, SCENE_SCALE);
renderSceneAdd(
renderScene,
cube_cube_model_gfx,
pendingBoxMatrix,
CUBE_INDEX,
&dropper->transform.position,
NULL
);
}
}
void boxDropperInit(struct BoxDropper* dropper, struct BoxDropperDefinition* definition) {
dropper->dynamicId = dynamicSceneAdd(dropper, boxDropperRender, &dropper->transform, 1.5f);
dropper->transform.position = definition->position;
quatIdent(&dropper->transform.rotation);
dropper->transform.scale = gOneVec;
dropper->roomIndex = definition->roomIndex;
dropper->signalIndex = definition->signalIndex;
skArmatureInit(
&dropper->armature,
props_box_dropper_model_gfx,
PROPS_BOX_DROPPER_DEFAULT_BONES_COUNT,
props_box_dropper_default_bones,
props_box_dropper_bone_parent,
PROPS_BOX_DROPPER_ATTACHMENT_COUNT
);
skAnimatorInit(&dropper->animator, PROPS_BOX_DROPPER_DEFAULT_BONES_COUNT, NULL, NULL);
dropper->flags = 0;
dropper->reloadTimer = DROOPER_RELOAD_TIME;
}
void boxDropperUpdate(struct BoxDropper* dropper) {
skAnimatorUpdate(&dropper->animator, dropper->armature.boneTransforms, 1.0f);
if (dropper->reloadTimer > 0.0f) {
dropper->reloadTimer -= FIXED_DELTA_TIME;
if (dropper->reloadTimer < 0.0f) {
dropper->reloadTimer = 0.0f;
}
}
if (dropper->flags & BoxDropperFlagsCubeIsActive) {
if (!decorObjectUpdate(&dropper->activeCube)) {
decorObjectClenaup(&dropper->activeCube);
dropper->flags &= ~BoxDropperFlagsCubeIsActive;
}
}
int signalIsSet = signalsRead(dropper->signalIndex);
if (signalIsSet && !(dropper->flags & BoxDropperFlagsSignalWasSet)) {
if (dropper->flags & BoxDropperFlagsCubeIsActive) {
dropper->activeCube.rigidBody.flags |= RigidBodyFizzled;
}
dropper->flags |= BoxDropperFlagsCubeRequested;
}
if (signalIsSet && !(dropper->flags & BoxDropperFlagsCubeIsActive)) {
dropper->flags |= BoxDropperFlagsCubeRequested;
}
if (((dropper->flags & (BoxDropperFlagsCubeIsActive | BoxDropperFlagsCubeRequested)) == BoxDropperFlagsCubeRequested)) {
struct Transform pendingCubePos;
boxDropperFakePos(dropper, &pendingCubePos);
decorObjectInit(&dropper->activeCube, decorObjectDefinitionForId(DECOR_TYPE_CUBE), &pendingCubePos, dropper->roomIndex);
skAnimatorRunClip(&dropper->animator, &props_box_dropper_animations[PROPS_BOX_DROPPER_PROPS_BOX_DROPPER_ARMATURE_DROPCUBE_INDEX], 0);
dropper->flags &= ~BoxDropperFlagsCubeRequested;
dropper->flags |= BoxDropperFlagsCubeIsActive;
dropper->reloadTimer = DROOPER_RELOAD_TIME;
}
dropper->flags &= ~BoxDropperFlagsSignalWasSet;
if (signalIsSet) {
dropper->flags |= BoxDropperFlagsSignalWasSet;
}
}

36
src/scene/box_dropper.h Normal file
View file

@ -0,0 +1,36 @@
#ifndef _SCENE_BOX_DROPPER_H__
#define _SCENE_BOX_DROPPER_H__
#include "../math/transform.h"
#include "../sk64/skelatool_armature.h"
#include "../sk64/skelatool_animator.h"
#include "../levels/level_definition.h"
#include "../decor/decor_object.h"
enum BoxDropperFlags {
BoxDropperFlagsCubeRequested = (1 << 0),
BoxDropperFlagsCubeIsActive = (1 << 1),
BoxDropperFlagsSignalWasSet = (1 << 2),
};
struct BoxDropper {
struct Transform transform;
struct SKArmature armature;
struct SKAnimator animator;
struct DecorObject activeCube;
float reloadTimer;
short dynamicId;
short roomIndex;
short signalIndex;
short flags;
};
void boxDropperInit(struct BoxDropper* dropper, struct BoxDropperDefinition* definition);
void boxDropperUpdate(struct BoxDropper* dropper);
#endif

View file

@ -109,6 +109,12 @@ void sceneInit(struct Scene* scene) {
for (int i = 0; i < scene->signageCount; ++i) { for (int i = 0; i < scene->signageCount; ++i) {
signageInit(&scene->signage[i], &gCurrentLevel->signage[i]); signageInit(&scene->signage[i], &gCurrentLevel->signage[i]);
} }
scene->boxDropperCount = gCurrentLevel->boxDropperCount;
scene->boxDroppers = malloc(sizeof(struct BoxDropper) * scene->boxDropperCount);
for (int i = 0; i < scene->boxDropperCount; ++i) {
boxDropperInit(&scene->boxDroppers[i], &gCurrentLevel->boxDroppers[i]);
}
} }
void sceneRenderWithProperties(void* data, struct RenderProps* properties, struct RenderState* renderState) { void sceneRenderWithProperties(void* data, struct RenderProps* properties, struct RenderState* renderState) {
@ -283,10 +289,23 @@ void sceneUpdate(struct Scene* scene) {
doorUpdate(&scene->doors[i]); doorUpdate(&scene->doors[i]);
} }
int decorWriteIndex = 0;
for (int i = 0; i < scene->decorCount; ++i) { for (int i = 0; i < scene->decorCount; ++i) {
decorObjectUpdate(scene->decor[i]); if (!decorObjectUpdate(scene->decor[i])) {
decorObjectDelete(scene->decor[i]);
continue;;
} }
if (decorWriteIndex != i) {
scene->decor[decorWriteIndex] = scene->decor[i];
}
++decorWriteIndex;
}
scene->decorCount = decorWriteIndex;
for (int i = 0; i < scene->fizzlerCount; ++i) { for (int i = 0; i < scene->fizzlerCount; ++i) {
fizzlerUpdate(&scene->fizzlers[i]); fizzlerUpdate(&scene->fizzlers[i]);
} }
@ -299,6 +318,10 @@ void sceneUpdate(struct Scene* scene) {
pedestalUpdate(&scene->pedestals[i]); pedestalUpdate(&scene->pedestals[i]);
} }
for (int i = 0; i < scene->boxDropperCount; ++i) {
boxDropperUpdate(&scene->boxDroppers[i]);
}
collisionSceneUpdateDynamics(); collisionSceneUpdateDynamics();
levelCheckTriggers(&scene->player.lookTransform.position); levelCheckTriggers(&scene->player.lookTransform.position);

View file

@ -15,6 +15,7 @@
#include "elevator.h" #include "elevator.h"
#include "pedestal.h" #include "pedestal.h"
#include "signage.h" #include "signage.h"
#include "box_dropper.h"
struct Scene { struct Scene {
struct Camera camera; struct Camera camera;
@ -27,6 +28,7 @@ struct Scene {
struct Elevator* elevators; struct Elevator* elevators;
struct Pedestal* pedestals; struct Pedestal* pedestals;
struct Signage* signage; struct Signage* signage;
struct BoxDropper* boxDroppers;
OSTime cpuTime; OSTime cpuTime;
OSTime lastFrameStart; OSTime lastFrameStart;
OSTime lastFrameTime; OSTime lastFrameTime;
@ -37,6 +39,7 @@ struct Scene {
u8 elevatorCount; u8 elevatorCount;
u8 pedestalCount; u8 pedestalCount;
u8 signageCount; u8 signageCount;
u8 boxDropperCount;
}; };
extern struct Scene gScene; extern struct Scene gScene;

View file

@ -64,6 +64,8 @@ char gLevelWarnings[] = {
0, 0,
0, 0,
0, 0,
LevelWarningsCubeDispense | LevelWarningsCubeHit,
LevelWarningsCubeHit,
}; };
static struct Coloru8 gSignageOnColor = {0, 0, 0, 255}; static struct Coloru8 gSignageOnColor = {0, 0, 0, 255};