Example #1
0
int sd_animation_load(sd_reader *r, sd_animation *ani) {
    // Animation header
    ani->start_x = sd_read_word(r);
    ani->start_y = sd_read_word(r);
    sd_read_buf(r, ani->unknown_a, 4);
    ani->col_coord_count = sd_read_uword(r);
    ani->frame_count = sd_read_ubyte(r);
    
    // Read collision point data
    ani->col_coord_table = (col_coord*)malloc(sizeof(col_coord)*ani->col_coord_count);
    uint32_t tmp;
    int32_t a,b;
    for(int i = 0; i < ani->col_coord_count; i++) {
        tmp = sd_read_udword(r);
        a = tmp & 0xffff;
        b = (tmp & 0xffff0000) >> 16;
        ani->col_coord_table[i].x = ((a & 0x3ff) << (6+16)) >> (6+16);
        ani->col_coord_table[i].x_ext = (a >> 10);
        ani->col_coord_table[i].y = ((b & 0x3ff) << (6+16)) >> (6+16);
        ani->col_coord_table[i].y_ext = (b >> 10);
    }

    // Animation string header
    uint16_t anim_string_len = sd_read_uword(r);
    ani->anim_string = (char*)malloc(anim_string_len + 1);
    sd_read_buf(r, ani->anim_string, anim_string_len + 1);
    if(ani->anim_string[anim_string_len] != 0) {
        return SD_FILE_PARSE_ERROR;
    }

    // Extra animation strings
    ani->extra_string_count = sd_read_ubyte(r);
    ani->extra_strings = (char**)malloc(sizeof(char*)*ani->extra_string_count);
    for(int i = 0; i < ani->extra_string_count; i++) {
        uint16_t size = sd_read_uword(r);
        ani->extra_strings[i] = malloc(size+1);
        sd_read_buf(r, ani->extra_strings[i], size+1);
        if(ani->extra_strings[i][size] != 0) {
            return SD_FILE_PARSE_ERROR;
        }
    }

    // Sprites
    ani->sprites = (sd_sprite**)malloc(sizeof(sd_sprite*) * ani->frame_count);
    for(int i = 0; i < ani->frame_count; i++) {
        // finally, the actual sprite!
        ani->sprites[i] = sd_sprite_create();
        if(sd_sprite_load(r, ani->sprites[i])) {
            return SD_FILE_PARSE_ERROR;
        }
    }

    // Return success
    return SD_SUCCESS;
}
Example #2
0
int sd_tournament_load(sd_tournament_file *trn, const char *filename) {
    int ret = SD_FILE_PARSE_ERROR;
    if(trn == NULL || filename == NULL) {
        return SD_INVALID_INPUT;
    }

    sd_reader *r = sd_reader_open(filename);
    if(!r) {
        return SD_FILE_OPEN_ERROR;
    }

    // Make sure that the file looks at least relatively okay
    // TODO: Add other checks.
    if(sd_reader_filesize(r) < 1582) {
        goto error_0;
    }

    // Read enemy count and make sure it seems somwhat correct
    int32_t enemy_count  = sd_read_dword(r);
    if(enemy_count >= MAX_TRN_ENEMIES || enemy_count <= 0) {
        goto error_0;
    }

    trn->enemy_count = (int16_t)enemy_count;

    // Read tournament data
    int victory_text_offset = sd_read_dword(r);
    sd_read_buf(r, trn->bk_name, 14);
    trn->winnings_multiplier = sd_read_float(r);
    trn->unknown_a = sd_read_dword(r);
    trn->registration_fee = sd_read_dword(r);
    trn->assumed_initial_value = sd_read_dword(r);
    trn->tournament_id = sd_read_dword(r);

    // Read enemy block offsets
    sd_reader_set(r, 300);
    int offset_list[MAX_TRN_ENEMIES + 2]; // Should be large enough
    memset(offset_list, 0, sizeof(offset_list));
    for(int i = 0; i < trn->enemy_count + 1; i++) {
        offset_list[i] = sd_read_dword(r);
    }

    // Read enemy data
    for(int i = 0; i < trn->enemy_count; i++) {
        trn->enemies[i] = malloc(sizeof(sd_pilot));

        // Find data length
        sd_reader_set(r, offset_list[i]);

        // Read enemy pilot information
        sd_pilot_create(trn->enemies[i]);
        sd_pilot_load(r, trn->enemies[i]);

        // Check for errors
        if(!sd_reader_ok(r)) {
            goto error_1;
        }
    }

    // Seek sprite start offset
    sd_reader_set(r, offset_list[trn->enemy_count]);

    // Allocate locales
    for(int i = 0; i < MAX_TRN_LOCALES; i++) {
        trn->locales[i] = malloc(sizeof(sd_tournament_locale));
        trn->locales[i]->logo = NULL;
        trn->locales[i]->description = NULL;
        trn->locales[i]->title = NULL;
        for(int har = 0; har < 11; har++) {
            for(int page = 0; page < 10; page++) {
                trn->locales[i]->end_texts[har][page] = NULL;
            }
        }
    }

    // Load logos to locales
    for(int i = 0; i < MAX_TRN_LOCALES; i++) {
        trn->locales[i]->logo = malloc(sizeof(sd_sprite));
        sd_sprite_create(trn->locales[i]->logo);
        if((ret = sd_sprite_load(r, trn->locales[i]->logo)) != SD_SUCCESS) {
            goto error_2;
        }
    }

    // Read palette. Only 40 colors are defined, starting
    // from palette position 128. Remember to convert VGA pal.
    memset((void*)&trn->pal, 0, sizeof(sd_palette));
    sd_palette_load_range(r, &trn->pal, 128, 40);

    // Read pic filename
    trn->pic_file = sd_read_variable_str(r);

    // Read tournament descriptions
    for(int i = 0; i < MAX_TRN_LOCALES; i++) {
        trn->locales[i]->title = sd_read_variable_str(r);
        trn->locales[i]->description = sd_read_variable_str(r);
    }

    // Make sure we are in correct position
    if(sd_reader_pos(r) != victory_text_offset) {
        goto error_2;
    }

    // Load texts
    for(int i = 0; i < MAX_TRN_LOCALES; i++) {
        for(int har = 0; har < 11; har++) {
            for(int page = 0; page < 10; page++) {
                trn->locales[i]->end_texts[har][page] = sd_read_variable_str(r);
            }
        }
    }

    // Close & return
    sd_reader_close(r);
    return SD_SUCCESS;

error_2:
    free_locales(trn);

error_1:
    free_enemies(trn);

error_0:
    sd_reader_close(r);
    return ret;
}