mirror of
https://github.com/luksamuk/engine-psx.git
synced 2025-04-28 13:28:02 +03:00
Load common object table and object placement data
This commit is contained in:
parent
5812d18f13
commit
d296245b32
11 changed files with 423 additions and 24 deletions
|
@ -4,6 +4,8 @@
|
|||
#include <stdint.h>
|
||||
#include <psxgpu.h>
|
||||
|
||||
#include "object_state.h"
|
||||
|
||||
#define LEVEL_MAX_X_CHUNKS 255
|
||||
#define LEVEL_MAX_Y_CHUNKS 31
|
||||
#define LEVEL_ARENA_SIZE 131072
|
||||
|
@ -51,10 +53,18 @@ typedef struct {
|
|||
uint16_t *tiles;
|
||||
} LevelLayerData;
|
||||
|
||||
#define MAX_OBJECTS_PER_CHUNK 15
|
||||
|
||||
typedef struct {
|
||||
uint8_t num_objects;
|
||||
ObjectState objects[MAX_OBJECTS_PER_CHUNK];
|
||||
} ChunkObjectData;
|
||||
|
||||
typedef struct {
|
||||
uint8_t num_layers;
|
||||
uint8_t _unused0;
|
||||
LevelLayerData *layers;
|
||||
ChunkObjectData **objects;
|
||||
|
||||
uint16_t crectx, crecty;
|
||||
uint16_t prectx, precty;
|
||||
|
@ -75,4 +85,7 @@ void render_lvl(
|
|||
int32_t cam_x, int32_t cam_y);
|
||||
|
||||
|
||||
// Object-related. These are defined in object_state.c
|
||||
void load_object_placement(const char *filename, LevelData *lvl);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2,22 +2,23 @@
|
|||
#define MEMALLOC_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct {
|
||||
uint32_t start;
|
||||
uint32_t ptr;
|
||||
uint32_t size;
|
||||
uintptr_t start;
|
||||
uintptr_t ptr;
|
||||
size_t size;
|
||||
} ArenaAllocator;
|
||||
|
||||
void alloc_arena_init(ArenaAllocator *arena, void *start, uint32_t size);
|
||||
void alloc_arena_init(ArenaAllocator *arena, void *start, uintptr_t size);
|
||||
void alloc_arena_free(ArenaAllocator *arena);
|
||||
void *alloc_arena_malloc(ArenaAllocator *arena, uint32_t size);
|
||||
void *alloc_arena_malloc(ArenaAllocator *arena, size_t size);
|
||||
|
||||
uint32_t alloc_arena_bytes_used(ArenaAllocator *arena);
|
||||
uint32_t alloc_arena_bytes_free(ArenaAllocator *arena);
|
||||
|
||||
void fastalloc_init();
|
||||
void fastalloc_free();
|
||||
void *fastalloc_malloc(uint32_t size);
|
||||
void *fastalloc_malloc(size_t size);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef OBJECT_H
|
||||
#define OBJECT_H
|
||||
#ifndef MODEL_H
|
||||
#define MODEL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <psxgpu.h>
|
||||
|
|
89
include/object.h
Normal file
89
include/object.h
Normal file
|
@ -0,0 +1,89 @@
|
|||
#ifndef OBJECT_H
|
||||
#define OBJECT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "level.h"
|
||||
|
||||
/* ======================== */
|
||||
/* OBJECT PROPERTY DATA */
|
||||
/* ======================== */
|
||||
|
||||
typedef enum int8_t {
|
||||
// Dummy objects
|
||||
OBJ_DUMMY_RINGS_3V = -2,
|
||||
OBJ_DUMMY_RINGS_3H = -1,
|
||||
|
||||
// Actual objects
|
||||
OBJ_RING = 0x00,
|
||||
OBJ_MONITOR = 0x01,
|
||||
OBJ_SPIKES = 0x02,
|
||||
OBJ_CHECKPOINT = 0x03,
|
||||
OBJ_SPRING_YELLOW = 0x04,
|
||||
OBJ_SPRING_RED = 0x05,
|
||||
OBJ_SPRING_YELLOW_DIAGONAL = 0x06,
|
||||
OBJ_SPRING_RED_DIAGONAL = 0x07,
|
||||
OBJ_GOAL_SIGN = 0x08,
|
||||
OBJ_SWITCH = 0x09,
|
||||
} ObjectType;
|
||||
|
||||
#define MASK_FLIP_FLIPX 0x1 // Flip on X axis
|
||||
#define MASK_FLIP_FLIPY 0x2 // Flip on Y axis
|
||||
#define MASK_FLIP_ROTCW 0x4 // Rotated clockwise
|
||||
#define MASK_FLIP_ROTCT 0x8 // Rotated counterclockwise
|
||||
|
||||
typedef enum uint8_t {
|
||||
MONITOR_KIND_NONE = 0,
|
||||
MONITOR_KIND_RING = 1,
|
||||
MONITOR_KIND_SPEEDSHOES = 2,
|
||||
MONITOR_KIND_SHIELD = 3,
|
||||
MONITOR_KIND_INVINCIBILITY = 4,
|
||||
MONITOR_KIND_1UP = 5,
|
||||
MONITOR_KIND_SUPER = 6,
|
||||
} ObjectMonitorKind;
|
||||
|
||||
|
||||
/* ======================== */
|
||||
/* OBJECT TABLE STRUCTURE */
|
||||
/* ======================== */
|
||||
|
||||
typedef struct {
|
||||
uint8_t u0, v0;
|
||||
uint8_t w, h;
|
||||
uint8_t flipmask;
|
||||
} ObjectAnimFrame;
|
||||
|
||||
typedef struct {
|
||||
ObjectAnimFrame *frames;
|
||||
uint16_t num_frames;
|
||||
int8_t loopback;
|
||||
// TODO: number of animation frames?
|
||||
} ObjectAnim;
|
||||
|
||||
typedef struct {
|
||||
int16_t offsetx, offsety;
|
||||
ObjectAnim *animations;
|
||||
uint16_t num_animations;
|
||||
} ObjectFrag;
|
||||
|
||||
// TODO: ObjectAnimState
|
||||
|
||||
typedef struct {
|
||||
ObjectAnim *animations;
|
||||
ObjectFrag *fragment;
|
||||
// TODO: Global animation state here, could be NULL
|
||||
uint16_t num_animations;
|
||||
} ObjectTableEntry;
|
||||
|
||||
typedef struct {
|
||||
uint8_t is_level_specific;
|
||||
uint16_t num_entries;
|
||||
ObjectTableEntry *entries;
|
||||
} ObjectTable;
|
||||
|
||||
|
||||
void load_object_table(const char *filename, ObjectTable *tbl);
|
||||
void unload_object_table(ObjectTable *tbl);
|
||||
|
||||
|
||||
#endif
|
22
include/object_state.h
Normal file
22
include/object_state.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
#ifndef OBJECT_STATE_H
|
||||
#define OBJECT_STATE_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* ======================== */
|
||||
/* OBJECT STATE STRUCTURE */
|
||||
/* ======================== */
|
||||
|
||||
typedef struct {
|
||||
uint8_t kind;
|
||||
} MonitorExtra;
|
||||
|
||||
typedef struct {
|
||||
uint16_t id;
|
||||
uint8_t flipmask;
|
||||
uint8_t props;
|
||||
int16_t rx, ry; // Positions relative to chunk top-left corner
|
||||
void *extra;
|
||||
} ObjectState;
|
||||
|
||||
#endif
|
14
src/level.c
14
src/level.c
|
@ -7,7 +7,7 @@
|
|||
|
||||
#define MAX_TILES 1400
|
||||
|
||||
static ArenaAllocator _level_arena = { 0 };
|
||||
ArenaAllocator _level_arena = { 0 };
|
||||
static uint8_t _arena_mem[LEVEL_ARENA_SIZE];
|
||||
|
||||
extern int debug_mode;
|
||||
|
@ -174,18 +174,23 @@ load_lvl(LevelData *lvl, const char *filename)
|
|||
lvl->num_layers = get_byte(bytes, &b);
|
||||
lvl->_unused0 = 0; b += 1;
|
||||
|
||||
uint16_t max_tiles = 0;
|
||||
|
||||
lvl->layers = alloc_arena_malloc(&_level_arena, lvl->num_layers * sizeof(LevelLayerData));
|
||||
for(uint8_t n_layer = 0; n_layer < lvl->num_layers; n_layer++) {
|
||||
LevelLayerData *layer = &lvl->layers[n_layer];
|
||||
layer->width = get_byte(bytes, &b);
|
||||
layer->height = get_byte(bytes, &b);
|
||||
uint16_t num_tiles = (uint16_t)layer->width * (uint16_t)layer->height;
|
||||
if(num_tiles > max_tiles) max_tiles = num_tiles;
|
||||
layer->tiles = alloc_arena_malloc(&_level_arena, num_tiles * sizeof(uint16_t));
|
||||
for(uint16_t i = 0; i < num_tiles; i++) {
|
||||
layer->tiles[i] = get_short_be(bytes, &b);
|
||||
}
|
||||
}
|
||||
|
||||
free(bytes);
|
||||
|
||||
// These values are static because we're always using the same
|
||||
// coordinates for tpage and clut info. For some reason they're
|
||||
// not loading correctly, but we don't really need them
|
||||
|
@ -196,7 +201,12 @@ load_lvl(LevelData *lvl, const char *filename)
|
|||
//lvl->clutmode = 0; // NOTE: This was set to tim->mode previously.
|
||||
lvl->_unused1 = 0;
|
||||
|
||||
free(bytes);
|
||||
// Initialize object state array within level map
|
||||
printf("Allocating object array\n");
|
||||
lvl->objects = alloc_arena_malloc(&_level_arena, max_tiles * sizeof(ChunkObjectData *));
|
||||
for(uint16_t i = 0; i < max_tiles; i++) {
|
||||
lvl->objects[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Level sprite buffer.
|
||||
|
|
|
@ -7,11 +7,12 @@ ArenaAllocator scratchpad_arena;
|
|||
#define SCRATCHPAD_SIZE 1024
|
||||
|
||||
void
|
||||
alloc_arena_init(ArenaAllocator *arena, void *start, uint32_t size)
|
||||
alloc_arena_init(ArenaAllocator *arena, void *start, size_t size)
|
||||
{
|
||||
arena->start = (uint32_t)start;
|
||||
uintptr_t st = (uintptr_t)start;
|
||||
arena->start = st;
|
||||
arena->ptr = arena->start;
|
||||
arena->size = (uint32_t)size;
|
||||
arena->size = size;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -21,12 +22,19 @@ alloc_arena_free(ArenaAllocator *arena)
|
|||
}
|
||||
|
||||
void *
|
||||
alloc_arena_malloc(ArenaAllocator *arena, uint32_t size)
|
||||
alloc_arena_malloc(ArenaAllocator *arena, size_t size)
|
||||
{
|
||||
void *p = (void *)arena->ptr;
|
||||
assert(arena->ptr + size < arena->start + arena->size);
|
||||
arena->ptr += size;
|
||||
return p;
|
||||
// Align size so we don't get unaligned memory access
|
||||
size += 8 - (size % 8);
|
||||
|
||||
uintptr_t p = (uintptr_t)arena->ptr;
|
||||
uintptr_t align_diff = p % 8;
|
||||
/* printf("Alotted size so far: %d / %d, requested: %lu\n", */
|
||||
/* alloc_arena_bytes_used(arena), alloc_arena_bytes_free(arena), */
|
||||
/* size); */
|
||||
assert((arena->ptr + size) < (arena->start + arena->size));
|
||||
arena->ptr += size + align_diff;
|
||||
return (void *)p;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
|
@ -54,7 +62,7 @@ fastalloc_free()
|
|||
}
|
||||
|
||||
void *
|
||||
fastalloc_malloc(uint32_t size)
|
||||
fastalloc_malloc(size_t size)
|
||||
{
|
||||
return alloc_arena_malloc(&scratchpad_arena, size);
|
||||
}
|
||||
|
|
134
src/object.c
Normal file
134
src/object.c
Normal file
|
@ -0,0 +1,134 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "object.h"
|
||||
#include "memalloc.h"
|
||||
#include "util.h"
|
||||
|
||||
extern ArenaAllocator _level_arena;
|
||||
|
||||
void
|
||||
_load_animation(ObjectAnim *animation, uint8_t *bytes, uint32_t *b)
|
||||
{
|
||||
animation->frames = NULL;
|
||||
animation->num_frames = get_short_be(bytes, b);
|
||||
animation->loopback = get_byte(bytes, b);
|
||||
if(animation->num_frames > 0) {
|
||||
animation->frames = alloc_arena_malloc(
|
||||
&_level_arena,
|
||||
sizeof(ObjectAnimFrame) * animation->num_frames);
|
||||
|
||||
for(uint16_t i = 0; i < animation->num_frames; i++) {
|
||||
ObjectAnimFrame *frame = &animation->frames[i];
|
||||
frame->u0 = get_byte(bytes, b);
|
||||
frame->v0 = get_byte(bytes, b);
|
||||
frame->w = get_byte(bytes, b);
|
||||
frame->h = get_byte(bytes, b);
|
||||
frame->flipmask = get_byte(bytes, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
load_object_table(const char *filename, ObjectTable *tbl)
|
||||
{
|
||||
uint8_t *bytes;
|
||||
uint32_t b, length;
|
||||
|
||||
bytes = file_read(filename, &length);
|
||||
if(bytes == NULL) {
|
||||
printf("Error reading OTD file %s from the CD.\n", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
b = 0;
|
||||
|
||||
tbl->is_level_specific = get_byte(bytes, &b);
|
||||
tbl->num_entries = get_short_be(bytes, &b);
|
||||
|
||||
if(tbl->num_entries == 0) goto end;
|
||||
|
||||
tbl->entries = alloc_arena_malloc(
|
||||
&_level_arena,
|
||||
sizeof(ObjectTableEntry) * tbl->num_entries);
|
||||
|
||||
printf("Entries at %p\n", tbl->entries);
|
||||
|
||||
|
||||
for(uint16_t i = 0; i < tbl->num_entries; i++) {
|
||||
printf("Reading entry %d.\n", i);
|
||||
ObjectTableEntry *entry = &tbl->entries[i];
|
||||
printf("Init animations and fragment\n");
|
||||
entry->animations = NULL;
|
||||
entry->fragment = NULL;
|
||||
printf("OK\n");
|
||||
|
||||
uint8_t _id = get_byte(bytes, &b); // Entry ID, always sequential; discarded
|
||||
printf("Registered id: %d\n", _id);
|
||||
uint8_t has_fragment = get_byte(bytes, &b);
|
||||
entry->num_animations = get_short_be(bytes, &b);
|
||||
|
||||
if(entry->num_animations > 0) {
|
||||
printf("Start reading animations...\n");
|
||||
entry->animations = alloc_arena_malloc(
|
||||
&_level_arena,
|
||||
sizeof(ObjectAnim) * entry->num_animations);
|
||||
|
||||
for(uint16_t j = 0; j < entry->num_animations; j++) {
|
||||
printf("Reading animation %d.\n", j);
|
||||
ObjectAnim *animation = &entry->animations[j];
|
||||
_load_animation(animation, bytes, &b);
|
||||
}
|
||||
}
|
||||
|
||||
if(has_fragment) {
|
||||
printf("Start reading fragment...\n");
|
||||
ObjectFrag *fragment = alloc_arena_malloc(
|
||||
&_level_arena,
|
||||
sizeof(ObjectFrag));
|
||||
entry->fragment = fragment;
|
||||
|
||||
fragment->offsetx = get_short_be(bytes, &b);
|
||||
fragment->offsety = get_short_be(bytes, &b);
|
||||
fragment->num_animations = get_short_be(bytes, &b);
|
||||
fragment->animations = alloc_arena_malloc(
|
||||
&_level_arena,
|
||||
sizeof(ObjectAnim) * fragment->num_animations);
|
||||
|
||||
for(uint16_t j = 0; j < fragment->num_animations; j++) {
|
||||
printf("Reading fragment animation %d.\n", j);
|
||||
ObjectAnim *animation = &fragment->animations[j];
|
||||
_load_animation(animation, bytes, &b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
free(bytes);
|
||||
printf("Loaded %d object types.\n", tbl->num_entries);
|
||||
}
|
||||
|
||||
void
|
||||
unload_object_table(ObjectTable *tbl)
|
||||
{
|
||||
// Since the object table has to be heap-allocated, we need to unload it
|
||||
for(uint16_t i = 0; i < tbl->num_entries; i++) {
|
||||
ObjectTableEntry *entry = &tbl->entries[i];
|
||||
for(uint16_t j = 0; j < entry->num_animations; j++) {
|
||||
ObjectAnim *animation = &entry->animations[j];
|
||||
free(animation->frames);
|
||||
}
|
||||
if(entry->num_animations > 0) free(entry->animations);
|
||||
|
||||
if(entry->fragment) {
|
||||
for(uint16_t j = 0; j < entry->fragment->num_animations; j++) {
|
||||
ObjectAnim *animation = &entry->fragment->animations[j];
|
||||
free(animation->frames);
|
||||
}
|
||||
if(entry->fragment->num_animations > 0)
|
||||
free(entry->fragment->animations);
|
||||
free(entry->fragment);
|
||||
}
|
||||
}
|
||||
free(tbl->entries);
|
||||
}
|
100
src/object_state.c
Normal file
100
src/object_state.c
Normal file
|
@ -0,0 +1,100 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "object.h"
|
||||
#include "object_state.h"
|
||||
#include "util.h"
|
||||
#include "memalloc.h"
|
||||
|
||||
extern ArenaAllocator _level_arena;
|
||||
|
||||
void
|
||||
_emplace_object(
|
||||
ChunkObjectData *data,
|
||||
uint8_t is_level_specific,
|
||||
int8_t type, uint8_t flipmask, int32_t vx, int32_t vy, void *extra)
|
||||
{
|
||||
ObjectState *state = &data->objects[data->num_objects++];
|
||||
assert(data->num_objects < MAX_OBJECTS_PER_CHUNK);
|
||||
|
||||
state->id = type + (is_level_specific ? 100 : 0);
|
||||
state->flipmask = flipmask;
|
||||
state->rx = vx & 0x7f;
|
||||
state->ry = vy & 0x7f;
|
||||
state->extra = extra;
|
||||
}
|
||||
|
||||
void
|
||||
load_object_placement(const char *filename, LevelData *lvl)
|
||||
{
|
||||
uint8_t *bytes;
|
||||
uint32_t b, length;
|
||||
|
||||
bytes = file_read(filename, &length);
|
||||
if(bytes == NULL) {
|
||||
printf("Error reading OTD file %s from the CD.\n", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
b = 0;
|
||||
|
||||
uint16_t created_objects = 0;
|
||||
uint16_t num_objects = get_short_be(bytes, &b);
|
||||
for(uint16_t i = 0; i < num_objects; i++) {
|
||||
uint8_t is_level_specific = get_byte(bytes, &b);
|
||||
int8_t type = get_byte(bytes, &b);
|
||||
uint8_t flipmask = get_byte(bytes, &b);
|
||||
int32_t vx = get_long_be(bytes, &b);
|
||||
int32_t vy = get_long_be(bytes, &b);
|
||||
void *extra = NULL;
|
||||
|
||||
switch(type) {
|
||||
default: break;
|
||||
case OBJ_MONITOR:
|
||||
extra = alloc_arena_malloc(&_level_arena, sizeof(MonitorExtra));
|
||||
((MonitorExtra *)extra)->kind = get_byte(bytes, &b);
|
||||
break;
|
||||
}
|
||||
|
||||
// Get chunk at position
|
||||
int32_t cx = vx >> 7;
|
||||
int32_t cy = vy >> 7;
|
||||
int32_t chunk_pos;
|
||||
if((cx < 0) || (cx >= lvl->layers[0].width)) chunk_pos = -1;
|
||||
else if((cy < 0) || (cy >= lvl->layers[0].height)) chunk_pos = -1;
|
||||
else chunk_pos = (cy * lvl->layers[0].width) + cx;
|
||||
|
||||
ChunkObjectData *data = lvl->objects[chunk_pos];
|
||||
if(!data) {
|
||||
data = alloc_arena_malloc(&_level_arena, sizeof(ChunkObjectData));
|
||||
lvl->objects[chunk_pos] = data;
|
||||
}
|
||||
|
||||
if(type < 0) {
|
||||
// This is a dummy object, so create others in its place.
|
||||
switch(type) {
|
||||
case OBJ_DUMMY_RINGS_3V:
|
||||
_emplace_object(data, 0, OBJ_RING, 0, vx, vy - 24, NULL);
|
||||
_emplace_object(data, 0, OBJ_RING, 0, vx, vy, NULL);
|
||||
_emplace_object(data, 0, OBJ_RING, 0, vx, vy + 24, NULL);
|
||||
created_objects += 3;
|
||||
break;
|
||||
case OBJ_DUMMY_RINGS_3H:
|
||||
_emplace_object(data, 0, OBJ_RING, 0, vx - 24, vy, NULL);
|
||||
_emplace_object(data, 0, OBJ_RING, 0, vx, vy, NULL);
|
||||
_emplace_object(data, 0, OBJ_RING, 0, vx + 24, vy, NULL);
|
||||
created_objects += 3;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
} else {
|
||||
_emplace_object(data, is_level_specific, type, flipmask, vx, vy, extra);
|
||||
created_objects++;
|
||||
}
|
||||
}
|
||||
|
||||
printf("Loaded %d objects.\n", created_objects);
|
||||
|
||||
free(bytes);
|
||||
}
|
|
@ -23,7 +23,7 @@ void
|
|||
screen_disclaimer_load()
|
||||
{
|
||||
screen_disclaimer_data *data = screen_alloc(sizeof(screen_disclaimer_data));
|
||||
uint32_t length;
|
||||
uint32_t length; // 153624 B
|
||||
data->disclaimer_bg = file_read("\\MISC\\DISK.TIM;1", &length);
|
||||
data->disclaimer_timer = 0;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "level.h"
|
||||
#include "timer.h"
|
||||
#include "model.h"
|
||||
#include "object.h"
|
||||
|
||||
extern int debug_mode;
|
||||
|
||||
|
@ -24,10 +25,11 @@ static uint8_t music_channel = 0;
|
|||
|
||||
static Player player;
|
||||
|
||||
TileMap16 map16;
|
||||
TileMap128 map128;
|
||||
LevelData leveldata;
|
||||
Camera camera;
|
||||
TileMap16 map16;
|
||||
TileMap128 map128;
|
||||
LevelData leveldata;
|
||||
Camera camera;
|
||||
ObjectTable obj_table_common;
|
||||
|
||||
#define CHANNELS_PER_BGM 3
|
||||
static uint32_t bgm_loop_sectors[] = {
|
||||
|
@ -73,6 +75,7 @@ static uint32_t bgm_loop_sectors[] = {
|
|||
// Forward function declarations
|
||||
static void level_load_player();
|
||||
static void level_load_level();
|
||||
static void level_unload_level();
|
||||
|
||||
// TODO!!!
|
||||
typedef struct {
|
||||
|
@ -99,6 +102,7 @@ screen_level_unload(void *)
|
|||
{
|
||||
sound_stop_xa();
|
||||
level_reset();
|
||||
level_unload_level();
|
||||
sound_reset_mem();
|
||||
screen_free();
|
||||
}
|
||||
|
@ -356,6 +360,17 @@ level_load_level()
|
|||
printf("Loading %s...\n", filename0);
|
||||
load_lvl(&leveldata, filename0);
|
||||
|
||||
// Load common objects
|
||||
printf("Loading common object table...\n");
|
||||
load_object_table("\\LEVELS\\COMMON\\OBJ.OTD", &obj_table_common);
|
||||
|
||||
// Load level objects
|
||||
// TODO
|
||||
|
||||
// Load object positioning on level
|
||||
snprintf(filename0, 255, "%s\\Z%1u.OMP;1", basepath, (level & 0x01) + 1);
|
||||
load_object_placement(filename0, &leveldata);
|
||||
|
||||
|
||||
// Pre-allocate and initialize level primitive buffer
|
||||
prepare_renderer(&leveldata);
|
||||
|
@ -376,3 +391,10 @@ level_load_level()
|
|||
|
||||
sound_play_xa(filename0, 0, music_channel, bgm_loop_sectors[level]);
|
||||
}
|
||||
|
||||
static void
|
||||
level_unload_level()
|
||||
{
|
||||
// Object tables are heap-allocated
|
||||
//unload_object_table(&obj_table_common);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue