Fix pointers after loading level from cart
This commit is contained in:
parent
0a8db5cc0e
commit
20f84f1fd4
2
Makefile
2
Makefile
|
@ -192,7 +192,7 @@ build/src/scene/portal.o: $(MODEL_HEADERS)
|
|||
## Test Chambers
|
||||
####################
|
||||
|
||||
TEST_CHAMBERS = assets/test_chambers/test_chamber_00/test_chamber_00.blend
|
||||
TEST_CHAMBERS = assets/test_chambers/test_chamber_00.blend
|
||||
|
||||
TEST_CHAMBER_HEADERS = $(TEST_CHAMBERS:%.blend=build/%.h)
|
||||
TEST_CHAMBER_OBJECTS = $(TEST_CHAMBERS:%.blend=build/%_geo.o)
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
#define SCHEDULER_PRIORITY 13
|
||||
#define NUM_FIELDS 1
|
||||
|
||||
#define LEVEL_SEGMENT 2
|
||||
|
||||
#define DMA_QUEUE_SIZE 200
|
||||
|
||||
#define SCENE_SCALE 256
|
||||
|
|
|
@ -9,6 +9,8 @@ struct GraphicsTask gGraphicsTasks[2];
|
|||
extern OSMesgQueue gfxFrameMsgQ;
|
||||
extern OSMesgQueue *schedulerCommandQueue;
|
||||
|
||||
void* gLevelSegment;
|
||||
|
||||
#if WITH_GFX_VALIDATOR
|
||||
#include "../../gfxvalidator/validator.h"
|
||||
#endif
|
||||
|
@ -53,6 +55,7 @@ void graphicsCreateTask(struct GraphicsTask* targetTask, GraphicsCallback callba
|
|||
|
||||
renderStateInit(renderState, targetTask->framebuffer, zbuffer);
|
||||
gSPSegment(renderState->dl++, 0, 0);
|
||||
gSPSegment(renderState->dl++, LEVEL_SEGMENT, gLevelSegment);
|
||||
|
||||
gSPDisplayList(renderState->dl++, setup_rspstate);
|
||||
if (firsttime) {
|
||||
|
|
|
@ -25,6 +25,8 @@ struct GraphicsTask {
|
|||
extern struct GraphicsTask gGraphicsTasks[2];
|
||||
extern Vp fullscreenViewport;
|
||||
|
||||
extern void* gLevelSegment;
|
||||
|
||||
#define GET_GFX_TYPE(gfx) (_SHIFTR((gfx)->words.w0, 24, 8))
|
||||
|
||||
typedef void (*GraphicsCallback)(void* data, struct RenderState* renderState, struct GraphicsTask* task);
|
||||
|
|
13
src/levels/level_metadata.h
Normal file
13
src/levels/level_metadata.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
#ifndef __LEVEL_METADATA_H__
|
||||
#define __LEVEL_METADATA_H__
|
||||
|
||||
#include "level_definition.h"
|
||||
|
||||
struct LevelMetadata {
|
||||
struct LevelDefinition* levelDefinition;
|
||||
char* segmentRomStart;
|
||||
char* segmentRomEnd;
|
||||
char* segmentStart;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -6,6 +6,10 @@
|
|||
#include "physics/collision_scene.h"
|
||||
#include "static_render.h"
|
||||
#include "cutscene_runner.h"
|
||||
#include "../graphics/graphics.h"
|
||||
|
||||
#include "../util/rom.h"
|
||||
#include "../util/memory.h"
|
||||
|
||||
struct LevelDefinition* gCurrentLevel;
|
||||
u64 gTriggeredCutscenes;
|
||||
|
@ -14,12 +18,73 @@ int levelCount() {
|
|||
return LEVEL_COUNT;
|
||||
}
|
||||
|
||||
#define ADJUST_POINTER_POS(ptr, offset) (void*)((ptr) ? (char*)(ptr) + (offset) : 0)
|
||||
|
||||
struct LevelDefinition* levelFixPointers(struct LevelDefinition* from, int pointerOffset) {
|
||||
struct LevelDefinition* result = ADJUST_POINTER_POS(from, pointerOffset);
|
||||
|
||||
result->collisionQuads = ADJUST_POINTER_POS(result->collisionQuads, pointerOffset);
|
||||
|
||||
for (int i = 0; i < result->collisionQuadCount; ++i) {
|
||||
result->collisionQuads[i].collider = ADJUST_POINTER_POS(result->collisionQuads[i].collider, pointerOffset);
|
||||
result->collisionQuads[i].collider->data = ADJUST_POINTER_POS(result->collisionQuads[i].collider->data, pointerOffset);
|
||||
result->collisionQuads[i].body = ADJUST_POINTER_POS(result->collisionQuads[i].body, pointerOffset);
|
||||
result->collisionQuads[i].data = ADJUST_POINTER_POS(result->collisionQuads[i].data, pointerOffset);
|
||||
}
|
||||
|
||||
result->staticContent = ADJUST_POINTER_POS(result->staticContent, pointerOffset);
|
||||
result->roomStaticMapping = ADJUST_POINTER_POS(result->roomStaticMapping, pointerOffset);
|
||||
result->staticBoundingBoxes = ADJUST_POINTER_POS(result->staticBoundingBoxes, pointerOffset);
|
||||
result->portalSurfaces = ADJUST_POINTER_POS(result->portalSurfaces, pointerOffset);
|
||||
|
||||
for (int i = 0; i < result->portalSurfaceCount; ++i) {
|
||||
result->portalSurfaces[i].vertices = ADJUST_POINTER_POS(result->portalSurfaces[i].vertices, pointerOffset);
|
||||
result->portalSurfaces[i].edges = ADJUST_POINTER_POS(result->portalSurfaces[i].edges, pointerOffset);
|
||||
result->portalSurfaces[i].gfxVertices = ADJUST_POINTER_POS(result->portalSurfaces[i].gfxVertices, pointerOffset);
|
||||
}
|
||||
|
||||
result->portalSurfaceMappingRange = ADJUST_POINTER_POS(result->portalSurfaceMappingRange, pointerOffset);
|
||||
result->portalSurfaceMappingIndices = ADJUST_POINTER_POS(result->portalSurfaceMappingIndices, pointerOffset);
|
||||
result->triggers = ADJUST_POINTER_POS(result->triggers, pointerOffset);
|
||||
result->cutscenes = ADJUST_POINTER_POS(result->cutscenes, pointerOffset);
|
||||
|
||||
for (int i = 0; i < result->cutsceneCount; ++i) {
|
||||
result->cutscenes[i].steps = ADJUST_POINTER_POS(result->cutscenes[i].steps, pointerOffset);
|
||||
}
|
||||
|
||||
result->locations = ADJUST_POINTER_POS(result->locations, pointerOffset);
|
||||
result->world.rooms = ADJUST_POINTER_POS(result->world.rooms, pointerOffset);
|
||||
result->world.doorways = ADJUST_POINTER_POS(result->world.doorways, pointerOffset);
|
||||
|
||||
for (int i = 0; i < result->world.roomCount; ++i) {
|
||||
result->world.rooms[i].quadIndices = ADJUST_POINTER_POS(result->world.rooms[i].quadIndices, pointerOffset);
|
||||
result->world.rooms[i].cellContents = ADJUST_POINTER_POS(result->world.rooms[i].cellContents, pointerOffset);
|
||||
result->world.rooms[i].doorwayIndices = ADJUST_POINTER_POS(result->world.rooms[i].doorwayIndices, pointerOffset);
|
||||
}
|
||||
|
||||
result->doors = ADJUST_POINTER_POS(result->doors, pointerOffset);
|
||||
result->buttons = ADJUST_POINTER_POS(result->buttons, pointerOffset);
|
||||
result->signalOperators = ADJUST_POINTER_POS(result->signalOperators, pointerOffset);
|
||||
result->decor = ADJUST_POINTER_POS(result->decor, pointerOffset);
|
||||
result->fizzlers = ADJUST_POINTER_POS(result->fizzlers, pointerOffset);
|
||||
result->elevators = ADJUST_POINTER_POS(result->elevators, pointerOffset);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void levelLoad(int index) {
|
||||
if (index < 0 || index >= LEVEL_COUNT) {
|
||||
return;
|
||||
}
|
||||
|
||||
gCurrentLevel = gLevelList[index];
|
||||
struct LevelMetadata* metadata = &gLevelList[index];
|
||||
|
||||
void* memory = malloc(metadata->segmentRomEnd - metadata->segmentRomStart);
|
||||
romCopy(metadata->segmentRomStart, memory, metadata->segmentRomEnd - metadata->segmentRomStart);
|
||||
|
||||
gLevelSegment = memory;
|
||||
|
||||
gCurrentLevel = levelFixPointers(metadata->levelDefinition, (char*)memory - metadata->segmentStart);
|
||||
gTriggeredCutscenes = 0;
|
||||
|
||||
collisionSceneInit(&gCollisionScene, gCurrentLevel->collisionQuads, gCurrentLevel->collisionQuadCount, &gCurrentLevel->world);
|
||||
|
|
|
@ -3,11 +3,15 @@ const path = require('path');
|
|||
|
||||
const InvalidTokenCharacter = /[^A-Za-z0-9_]/gim;
|
||||
|
||||
function generateLD(objectLocation) {
|
||||
function getSegmentName(objectLocation) {
|
||||
const levelName = path.basename(objectLocation);
|
||||
const noExtension = levelName.slice(0, levelName.length - path.extname(levelName).length);
|
||||
|
||||
const segmentName = noExtension.replace(InvalidTokenCharacter, '_');
|
||||
return noExtension.replace(InvalidTokenCharacter, '_');
|
||||
}
|
||||
|
||||
function generateLD(objectLocation) {
|
||||
const segmentName = getSegmentName(objectLocation);
|
||||
|
||||
return `
|
||||
BEGIN_SEG(${segmentName}, 0x02000000)
|
||||
|
|
|
@ -7,14 +7,41 @@ function generateInclude(outputLocation, headerLocation) {
|
|||
|
||||
const InvalidTokenCharacter = /[^A-Za-z0-9_]/gim;
|
||||
|
||||
function getSegmentName(headerLocation) {
|
||||
const levelName = path.basename(headerLocation);
|
||||
const noExtension = levelName.slice(0, levelName.length - path.extname(levelName).length);
|
||||
|
||||
return noExtension.replace(InvalidTokenCharacter, '_');
|
||||
}
|
||||
|
||||
function generateLevelName(outputLocation, headerLocation) {
|
||||
const relative = path.relative(path.dirname(outputLocation), headerLocation).slice(0, -2);
|
||||
return relative.replace(InvalidTokenCharacter, '_') + '_level';
|
||||
}
|
||||
|
||||
function generateMetadata(outputLocation, headerLocation) {
|
||||
const segmentName = getSegmentName(headerLocation);
|
||||
return ` {
|
||||
&${generateLevelName(outputLocation, headerLocation)},
|
||||
_${segmentName}_geoSegmentRomStart,
|
||||
_${segmentName}_geoSegmentRomEnd,
|
||||
_${segmentName}_geoSegmentStart,
|
||||
},`;
|
||||
}
|
||||
|
||||
function generateExterns(headerLocation) {
|
||||
const segmentName = getSegmentName(headerLocation);
|
||||
return `
|
||||
extern char _${segmentName}_geoSegmentRomStart[];
|
||||
extern char _${segmentName}_geoSegmentRomEnd[];
|
||||
extern char _${segmentName}_geoSegmentStart[];
|
||||
`;
|
||||
|
||||
}
|
||||
|
||||
function generateLevelList(outputLocation, headerLocations) {
|
||||
return `struct LevelDefinition* gLevelList[] = {
|
||||
${headerLocations.map(headerLocation => ` &${generateLevelName(outputLocation, headerLocation)},`).join('\n')}
|
||||
return `struct LevelMetadata gLevelList[] = {
|
||||
${headerLocations.map(headerLocation => generateMetadata(outputLocation, headerLocation)).join('\n')}
|
||||
};
|
||||
`;
|
||||
}
|
||||
|
@ -23,12 +50,14 @@ function generateData(outputLocation, headerLocations) {
|
|||
return `#ifndef __BUILD_LEVEL_LIST_H__
|
||||
#define __BUILD_LEVEL_LIST_H__
|
||||
|
||||
#include "levels/level_definition.h"
|
||||
#include "levels/level_metadata.h"
|
||||
|
||||
${headerLocations.map(headerLocation => generateInclude(outputLocation, headerLocation)).join('\n')}
|
||||
|
||||
#define LEVEL_COUNT ${headerLocations.length}
|
||||
|
||||
${headerLocations.map(generateExterns).join('\n')}
|
||||
|
||||
${generateLevelList(outputLocation, headerLocations)}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue