Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 76 additions & 52 deletions src/formats/bk.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,82 @@ void sd_bk_postprocess(sd_bk_file *bk) {
}
}

int sd_bk_load_incremental(sd_bk_file *bk, sd_reader *r) {
int ret = SD_SUCCESS;
switch(bk->load_state) {
case BK_LOAD_INIT:
// Header
bk->file_id = sd_read_udword(r);
bk->unknown_a = sd_read_ubyte(r);
uint16_t img_w = sd_read_uword(r);
uint16_t img_h = sd_read_uword(r);

// Allocate backgroun image
bk->background = omf_calloc(1, sizeof(sd_vga_image));
if((ret = sd_vga_image_create(bk->background, img_w, img_h)) != SD_SUCCESS) {
return ret;
}
bk->load_state = BK_LOAD_ANIMS;
return SD_AGAIN;
case BK_LOAD_ANIMS:
sd_skip(r, 4); // offset of next animation
int animno = sd_read_ubyte(r);
if(animno >= MAX_BK_ANIMS) {
bk->load_state = BK_LOAD_BACKGROUND;
return SD_AGAIN;
}
if(!sd_reader_ok(r)) {
// TODO is this an error?
return SD_INVALID_INPUT;
}

// Initialize animation
bk->anims[animno] = omf_calloc(1, sizeof(sd_bk_anim));
if((ret = sd_bk_anim_create(bk->anims[animno])) != SD_SUCCESS) {
return ret;
}
if((ret = sd_bk_anim_load(r, bk->anims[animno])) != SD_SUCCESS) {
return ret;
}
return SD_AGAIN;
case BK_LOAD_BACKGROUND:
// Read background image
sd_read_buf(r, bk->background->data, bk->background->len);
// Read palatte count
bk->palette_count = sd_read_ubyte(r);
bk->load_state = BK_LOAD_PALETTES;
return SD_AGAIN;
case BK_LOAD_PALETTES:
for(uint8_t i = 0; i < bk->palette_count; i++) {
if(bk->palettes[i] == NULL) {
bk->palettes[i] = omf_malloc(sizeof(vga_palette));
if((ret = palette_load(r, bk->palettes[i])) != SD_SUCCESS) {
return ret;
}
bk->remaps[i] = omf_malloc(sizeof(vga_remap_tables));
if((ret = palette_remaps_load(r, bk->remaps[i])) != SD_SUCCESS) {
return ret;
}
return SD_AGAIN;
}
}
// Read soundtable
sd_read_buf(r, bk->soundtable, 30);
bk->load_state = BK_LOAD_POSTPROCESS;
return SD_AGAIN;
case BK_LOAD_POSTPROCESS:
// Fix missing sprites
sd_bk_postprocess(bk);
bk->load_state = BK_LOAD_DONE;
return SD_SUCCESS;
case BK_LOAD_DONE:
return SD_SUCCESS;
}
// Should never happen
return SD_INVALID_INPUT;
}

int sd_bk_load(sd_bk_file *bk, const char *filename) {
uint16_t img_w, img_h;
uint8_t animno = 0;
sd_reader *r;
int ret = SD_SUCCESS;

Expand All @@ -108,58 +181,9 @@ int sd_bk_load(sd_bk_file *bk, const char *filename) {
return SD_FILE_OPEN_ERROR;
}

// Header
bk->file_id = sd_read_udword(r);
bk->unknown_a = sd_read_ubyte(r);
img_w = sd_read_uword(r);
img_h = sd_read_uword(r);

// Read animations
while(1) {
sd_skip(r, 4); // offset of next animation
animno = sd_read_ubyte(r);
if(animno >= MAX_BK_ANIMS || !sd_reader_ok(r)) {
break;
}

// Initialize animation
bk->anims[animno] = omf_calloc(1, sizeof(sd_bk_anim));
if((ret = sd_bk_anim_create(bk->anims[animno])) != SD_SUCCESS) {
goto exit_0;
}
if((ret = sd_bk_anim_load(r, bk->anims[animno])) != SD_SUCCESS) {
goto exit_0;
}
}

// Read background image
bk->background = omf_calloc(1, sizeof(sd_vga_image));
if((ret = sd_vga_image_create(bk->background, img_w, img_h)) != SD_SUCCESS) {
goto exit_0;
while((ret = sd_bk_load_incremental(bk, r)) == SD_AGAIN) {
}
int bsize = img_w * img_h;
sd_read_buf(r, bk->background->data, bsize);

// Read palettes and their remaps
bk->palette_count = sd_read_ubyte(r);
for(uint8_t i = 0; i < bk->palette_count; i++) {
bk->palettes[i] = omf_malloc(sizeof(vga_palette));
if((ret = palette_load(r, bk->palettes[i])) != SD_SUCCESS) {
goto exit_0;
}
bk->remaps[i] = omf_malloc(sizeof(vga_remap_tables));
if((ret = palette_remaps_load(r, bk->remaps[i])) != SD_SUCCESS) {
goto exit_0;
}
}

// Read soundtable
sd_read_buf(r, bk->soundtable, 30);

// Fix missing sprites
sd_bk_postprocess(bk);

exit_0:
sd_reader_close(r);
return ret;
}
Expand Down
13 changes: 13 additions & 0 deletions src/formats/bk.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,22 @@
#define MAX_BK_ANIMS 50 ///< Amount of animations in the BK file. This is fixed!
#define MAX_BK_PALETTES 8 ///< Maximum amount of palettes allowed in BK file.

typedef enum
{
BK_LOAD_INIT = 0,
BK_LOAD_ANIMS,
BK_LOAD_BACKGROUND,
BK_LOAD_PALETTES,
BK_LOAD_POSTPROCESS,
BK_LOAD_DONE,
} bk_load_state;

/*! \brief BK file information
*
* Contains information about an OMF:2097 scene. Eg. arenas, menus, intro, etc.
*/
typedef struct {
bk_load_state load_state;
uint32_t file_id; ///< File ID
uint8_t unknown_a; ///< Unknown value
uint8_t palette_count; ///< Number of palettes in the BK file
Expand Down Expand Up @@ -183,6 +194,8 @@ int sd_bk_pop_palette(sd_bk_file *bk);
*/
vga_palette *sd_bk_get_palette(const sd_bk_file *bk, int index);

int sd_bk_load_incremental(sd_bk_file *bk, sd_reader *r);

/*! \brief Load .BK file
*
* Loads the given BK file to memory. The structure must be initialized with sd_bk_create()
Expand Down
2 changes: 2 additions & 0 deletions src/formats/error.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ const char *sd_get_error(enum SD_ERRORCODE error_code) {
return "File could not be unlinked";
case SD_FAILURE:
return "General failure";
case SD_AGAIN:
return "Function not finished, call it again";
}
abort();
}
1 change: 1 addition & 0 deletions src/formats/error.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ enum SD_ERRORCODE
SD_FILE_READ_ERROR, ///< File could not be read
SD_FILE_UNLINK_ERROR, ///< File could not be unlinked
SD_FAILURE, ///< General failure
SD_AGAIN, ///< Function isn't done, needs to be called again
};

/*! \brief Get text error for error ID
Expand Down
46 changes: 33 additions & 13 deletions src/game/game_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -542,8 +542,24 @@ void game_state_debug(game_state *gs) {

int game_load_new(game_state *gs, int scene_id) {
// Free old scene
scene_free(gs->sc);
omf_free(gs->sc);
// scene_free(gs->sc);
// omf_free(gs->sc);

// Initialize new scene with BK data etc.
// gs->sc = omf_calloc(1, sizeof(scene));
int ret = scene_create_incremental(gs->sc, gs, scene_id);

if(ret == SD_AGAIN) {
return SD_AGAIN;
}

if(ret) {
log_error("Error while loading scene %d: %d.", scene_id, ret);
goto error_0;
}

// Free texture items, we are going to create new ones.
video_signal_scene_change();

// Remove old objects
render_obj *robj;
Expand All @@ -557,19 +573,9 @@ int game_load_new(game_state *gs, int scene_id) {
}
}

// Free texture items, we are going to create new ones.
video_signal_scene_change();

gs->this_id = scene_id;
gs->next_id = scene_id;

// Initialize new scene with BK data etc.
gs->sc = omf_calloc(1, sizeof(scene));
if(scene_create(gs->sc, gs, scene_id)) {
log_error("Error while loading scene %d.", scene_id);
goto error_0;
}

// Load scene specifics
switch(scene_id) {
case SCENE_OPENOMF:
Expand Down Expand Up @@ -844,6 +850,9 @@ void game_state_merge_sounds(game_state *old, game_state *new) {

// This function is always called with the same interval, and game speed does not affect it
void game_state_static_tick(game_state *gs, bool replay) {
uint64_t ticks = SDL_GetTicks64();
uint64_t limit = game_state_ms_per_dyntick(gs) / 2;

// Set scene crossfade values
if(gs->this_wait_ticks > 0) {
gs->this_wait_ticks--;
Expand All @@ -862,11 +871,22 @@ void game_state_static_tick(game_state *gs, bool replay) {
}

// Load up new scene
if(game_load_new(gs, gs->next_id)) {
int ret;
while((ret = game_load_new(gs, gs->next_id)) == SD_AGAIN) {
uint64_t now = SDL_GetTicks64();
if(now - ticks > limit) {
// taking too long for the dynamic tick time
break;
}
}
if(ret > 0 && ret != SD_AGAIN) {
log_error("Error while loading new scene! bailing.");
gs->run = 0;
return;
}
if(ret == SD_AGAIN) {
return;
}
if(settings_get()->video.crossfade_on) {
gs->this_wait_ticks = FRAME_WAIT_TICKS;
} else {
Expand Down
60 changes: 59 additions & 1 deletion src/game/protos/scene.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
#include "game/game_player.h"
#include "game/game_state_type.h"
#include "resources/af_loader.h"
#include "resources/bk_loader.h"
#include "resources/ids.h"
#include "utils/allocator.h"
#include "utils/log.h"
Expand Down Expand Up @@ -64,6 +63,64 @@ int scene_create(scene *scene, game_state *gs, int scene_id) {
return 0;
}

// Loads BK file etc.
int scene_create_incremental(scene *scene, game_state *gs, int scene_id) {
if(scene_id == SCENE_NONE) {
return 1;
}

// Load BK
int resource_id = scene_to_resource(scene_id);
if(!scene->next_bk_data) {
scene->next_bk_data = omf_calloc(1, sizeof(bk_inc));
}
int ret = load_bk_file_incremental(scene->next_bk_data, resource_id);
if(ret != SD_SUCCESS && ret != SD_AGAIN) {
log_error("Unable to load scene %s (%s)!", scene_get_name(scene_id), get_resource_name(resource_id));
return ret;
} else if(ret == SD_AGAIN) {
// not done loading yet
return SD_AGAIN;
}
scene_free(scene);
scene->bk_data = scene->next_bk_data->bk;

log_debug("setting bk_data %p", scene->bk_data);
omf_free(scene->next_bk_data);
scene->id = scene_id;
scene->gs = gs;
scene->af_data[0] = NULL;
scene->af_data[1] = NULL;
scene->static_ticks_since_start = 0;

// Init functions
scene->userdata = NULL;
scene->free = NULL;
scene->event = NULL;
scene->render = NULL;
scene->render_overlay = NULL;
scene->dynamic_tick = NULL;
scene->static_tick = NULL;
scene->input_poll = NULL;
scene->startup = NULL;
scene->prio_override = NULL;

// Set base palette
vga_state_set_base_palette_from(bk_get_palette(scene->bk_data, 0));
vga_state_set_remaps_from(bk_get_remaps(scene->bk_data, 0));

// Set menu colors to the correct position
palette_set_menu_colors();

// Index 0 is always black.
vga_color c = {0, 0, 0};
vga_state_set_base_palette_index(0, &c);

// All done.
log_debug("Loaded scene %s (%s).", scene_get_name(scene_id), get_resource_name(resource_id));
return 0;
}

int scene_load_har(scene *scene, int player_id) {
game_player *player = game_state_get_player(scene->gs, player_id);
if(scene->af_data[player_id]) {
Expand Down Expand Up @@ -223,6 +280,7 @@ void scene_free(scene *scene) {
if(scene->free != NULL) {
scene->free(scene);
}
log_debug("freeing %p", scene->bk_data);
bk_free(scene->bk_data);
omf_free(scene->bk_data);
if(scene->af_data[0]) {
Expand Down
3 changes: 3 additions & 0 deletions src/game/protos/scene.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "game/utils/serial.h"
#include "game/utils/ticktimer.h"
#include "resources/bk.h"
#include "resources/bk_loader.h"
#include "video/surface.h"
#include <SDL.h>

Expand All @@ -31,6 +32,7 @@ typedef void (*scene_clone_free_cb)(scene *scene);
struct scene_t {
game_state *gs;
int id;
bk_inc *next_bk_data;
bk *bk_data;
af *af_data[2];
void *userdata;
Expand All @@ -52,6 +54,7 @@ struct scene_t {
};

int scene_create(scene *scene, game_state *gs, int scene_id);
int scene_create_incremental(scene *scene, game_state *gs, int scene_id);
int scene_load_har(scene *scene, int player_id);
void scene_init(scene *scene);
void scene_free(scene *scene);
Expand Down
Loading
Loading