Changeset 616


Ignore:
Timestamp:
May 9, 2011, 12:55:23 AM (12 years ago)
Author:
Sam Hocevar
Message:

music: make the HMI decoder closer to the global coding style.

Location:
abuse/trunk/src/sdlport
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • abuse/trunk/src/sdlport/hmi.cpp

    r494 r616  
     1//
     2//  Abuse - dark 2D side-scrolling platform game
     3//
     4//  Copyright (c) 2011 Jochen Schleu <jjs@jjs.at>
     5//   This program is free software; you can redistribute it and/or
     6//   modify it under the terms of the Do What The Fuck You Want To
     7//   Public License, Version 2, as published by Sam Hocevar. See
     8//   http://sam.zoy.org/projects/COPYING.WTFPL for more details.
     9//
     10
     11#if defined HAVE_CONFIG_H
     12#   include "config.h"
     13#endif
     14
     15#include <cstring>
     16#include <cstdlib>
     17#include <cstdio>
     18
     19#include "common.h"
     20
    121// Load Abuse HMI files and covert them to standard Midi format
    222//
    323// HMI files differ from Midi files in the following ways:
    4 // - there is a header giving offsets to the tracks and various other information (unknown)
    5 // - note-on events include the duration of the note instead of dedicated note-off events
     24// - there is a header giving offsets to the tracks and various other
     25//   information (unknown)
     26// - note-on events include the duration of the note instead of dedicated
     27//   note-off events
    628// - additional 0xFE event with variable length, purpose unknown
    729//
    8 // This converter does the bare minimum to get Abuse HMI files to convert. The bpm and
    9 // header information is fixed and not read from the file (except the number of tracks).
    10 // HMI files make use of running status notation, the converted files don't.
    11 
    12 #include <malloc.h>
    13 #include <stdlib.h>
    14 #include <string.h>
    15 #include <stdio.h>
    16 
     30// This converter does the bare minimum to get Abuse HMI files to convert.
     31// The bpm and header information is fixed and not read from the file (except
     32// the number of tracks). HMI files make use of running status notation, the
     33// converted files don't.
    1734
    1835#define MAX_NOTE_OFF_EVENTS 30
    1936
    20 typedef struct
    21 {
    22     unsigned int time;
    23     unsigned char command;
    24     unsigned char note;
    25 }
    26 midi_note_off_event_t;
    27 
    28 midi_note_off_event_t note_off_events[MAX_NOTE_OFF_EVENTS];
    29 
    30 
    31 
    32 unsigned int get_int_from_buffer(unsigned char* buffer)
    33 {
    34     return (buffer[3] << 24) + (buffer[2] << 16) + (buffer[1] << 8) + (buffer[0]);
    35 }
    36 
    37 
    38 void write_big_endian_number(unsigned int le, unsigned char* buffer)
     37struct NoteOffEvent
     38{
     39    uint32_t time;
     40    uint8_t command;
     41    uint8_t note;
     42};
     43
     44NoteOffEvent note_off_events[MAX_NOTE_OFF_EVENTS];
     45
     46static uint32_t get_int_from_buffer(uint8_t* buffer)
     47{
     48    return (buffer[3] << 24) + (buffer[2] << 16)
     49             + (buffer[1] << 8) + (buffer[0]);
     50}
     51
     52static void write_big_endian_number(uint32_t le, uint8_t* buffer)
    3953{
    4054    buffer[3] = (le & 0x000000FF);
     
    4458}
    4559
    46 
    47 int compare_times(const void* a, const void* b)
    48 {
    49     if (((midi_note_off_event_t*)a)->time < ((midi_note_off_event_t*)b)->time)
    50         return -1;
    51     else if (((midi_note_off_event_t*)a)->time > ((midi_note_off_event_t*)b)->time)
    52         return 1;
    53     else
    54         return 0;
    55 }
    56 
    57 
    58 // Variable length number code from: http://www.chriswareham.demon.co.uk/midifiles/variable_length.html
    59 
    60 unsigned int read_time_value(unsigned char* &buffer)
    61 {
    62     unsigned int value;
    63     unsigned char c;
     60static int compare_times(const void* a, const void* b)
     61{
     62    NoteOffEvent const *ea = (NoteOffEvent const *)a;
     63    NoteOffEvent const *eb = (NoteOffEvent const *)b;
     64
     65    return ea->time < eb->time ? -1 : ea->time == eb->time ? 0 : 1;
     66}
     67
     68// Variable length number code
     69// from: http://www.chriswareham.demon.co.uk/midifiles/variable_length.html
     70static uint32_t read_time_value(uint8_t* &buffer)
     71{
     72    uint32_t value;
     73    uint8_t c;
    6474
    6575    if ((value = *buffer++) & 0x80)
     
    7686}
    7787
    78 
    79 void write_time_value(unsigned int time, unsigned char* &buffer)
    80 {
    81     unsigned int value_buffer = time & 0x7F;
     88static void write_time_value(uint32_t time, uint8_t* &buffer)
     89{
     90    uint32_t value_buffer = time & 0x7F;
    8291
    8392    while (time >>= 7)
     
    97106}
    98107
    99 
    100 void remember_note_off_event(unsigned int time, unsigned char command, unsigned char note)
    101 {
    102     int i;
    103     for (i = 0; i < MAX_NOTE_OFF_EVENTS; i++)
     108static void remember_note_off_event(uint32_t time, uint8_t cmd, uint8_t note)
     109{
     110    for (int i = 0; i < MAX_NOTE_OFF_EVENTS; i++)
    104111    {
    105112        if (note_off_events[i].time == 0xFFFFFFFF)
    106113        {
    107114            note_off_events[i].time = time;
    108             note_off_events[i].command = command;
     115            note_off_events[i].command = cmd;
    109116            note_off_events[i].note = note;
    110117            break;
     
    113120
    114121    // Sort the note off array by the time
    115     qsort(note_off_events, MAX_NOTE_OFF_EVENTS, sizeof(midi_note_off_event_t), compare_times);
    116 }
    117 
    118 
    119 void check_for_note_off_events(unsigned int &current_time, unsigned int &last_time, unsigned char* &buffer)
    120 {
    121     int i;
    122     for (i = 0; i < MAX_NOTE_OFF_EVENTS; i++)
     122    qsort(note_off_events, MAX_NOTE_OFF_EVENTS, sizeof(NoteOffEvent), compare_times);
     123}
     124
     125static void check_for_note_off_events(uint32_t &current_time,
     126                                      uint32_t &last_time, uint8_t* &buffer)
     127{
     128    for (int i = 0; i < MAX_NOTE_OFF_EVENTS; i++)
    123129    {
    124130        if (note_off_events[i].time == 0xFFFFFFFF)
     
    141147
    142148    // Sort the note off array by the time
    143     qsort(note_off_events, MAX_NOTE_OFF_EVENTS, sizeof(midi_note_off_event_t), compare_times);
    144 }
    145 
    146 
    147 void convert_hmi_track(unsigned char* input, unsigned int input_size, unsigned char* &output)
     149    qsort(note_off_events, MAX_NOTE_OFF_EVENTS, sizeof(NoteOffEvent), compare_times);
     150}
     151
     152static void convert_hmi_track(uint8_t* input,
     153                              uint32_t input_size, uint8_t* &output)
    148154{
    149155    int done = 0;
    150     unsigned char current_command = 0;
    151     unsigned char current_value = 0;
    152     unsigned int current_time = 0;
    153     unsigned int last_time = 0;
    154     unsigned char* start_of_buffer = output;
    155     unsigned char* start_of_input = input;
    156 
    157     memset(note_off_events, 0xFF, sizeof(midi_note_off_event_t) * MAX_NOTE_OFF_EVENTS);
     156    uint8_t current_command = 0;
     157    uint8_t current_value = 0;
     158    uint32_t current_time = 0;
     159    uint32_t last_time = 0;
     160    uint8_t* start_of_buffer = output;
     161    uint8_t* start_of_input = input;
     162
     163    memset(note_off_events, 0xFF, sizeof(NoteOffEvent) * MAX_NOTE_OFF_EVENTS);
    158164
    159165    // Midi data offset is at 0x57 from track start
     
    161167
    162168    // Write track header, leave length as zero for now
    163     unsigned char track_header[] = { 0x4D, 0x54, 0x72, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x00};
     169    uint8_t track_header[] = { 0x4D, 0x54, 0x72, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x00};
    164170    memcpy(output, track_header, 8);
    165171    output += 8;
     
    250256        }
    251257
    252         if ((unsigned int)(input - start_of_input) >= input_size)
     258        if ((uint32_t)(input - start_of_input) >= input_size)
    253259            break;
    254260    }
     
    257263    if (done != 1)
    258264    {
    259         unsigned char end_marker[] = { 0x00, 0xFF, 0x2F, 0x00 };
     265        uint8_t end_marker[] = { 0x00, 0xFF, 0x2F, 0x00 };
    260266        memcpy(output, end_marker, 4);
    261267        output += 4;
     
    263269
    264270    // Update header with length of track
    265     write_big_endian_number((unsigned int)(output - start_of_buffer - 8), &start_of_buffer[4]);
    266 }
    267 
    268 
    269 unsigned char* load_hmi(char* filename, unsigned int &data_size)
    270 {
    271     unsigned char* input_buffer;
    272     unsigned char* output_buffer;
     271    write_big_endian_number((uint32_t)(output - start_of_buffer - 8), &start_of_buffer[4]);
     272}
     273
     274uint8_t* load_hmi(char const *filename, uint32_t &data_size)
     275{
     276    uint8_t* input_buffer;
     277    uint8_t* output_buffer;
    273278
    274279    FILE* hmifile = fopen(filename, "rb");
     
    278283
    279284    fseek(hmifile, 0, SEEK_END);
    280     int buffersize = ftell(hmifile);
     285    uint32_t buffersize = ftell(hmifile);
    281286    fseek(hmifile, 0, SEEK_SET);
    282287
    283     input_buffer = (unsigned char*)malloc(buffersize);
     288    input_buffer = (uint8_t*)malloc(buffersize);
    284289    fread(input_buffer, 1, buffersize, hmifile);
    285290    fclose(hmifile);
    286291
    287     output_buffer = (unsigned char*)malloc(buffersize * 10); // Midi files can be larger than HMI files
    288     unsigned char* output_buffer_ptr = output_buffer;
     292    output_buffer = (uint8_t*)malloc(buffersize * 10); // Midi files can be larger than HMI files
     293    uint8_t* output_buffer_ptr = output_buffer;
    289294
    290295    // Offset to tracks is at 0x113
    291     unsigned int offset_tracks = get_int_from_buffer(&input_buffer[0xE8]);
    292     unsigned int next_offset = get_int_from_buffer(&input_buffer[0xF4]);
    293 
    294     unsigned char num_tracks = (next_offset - offset_tracks) / sizeof(int);
     296    uint32_t offset_tracks = get_int_from_buffer(&input_buffer[0xE8]);
     297    uint32_t next_offset = get_int_from_buffer(&input_buffer[0xF4]);
     298
     299    uint8_t num_tracks = (next_offset - offset_tracks) / sizeof(uint32_t);
    295300
    296301    // Write Midi file header
    297     unsigned char midi_header[] = { 0x4D, 0x54, 0x68, 0x64, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, (num_tracks + 1), 0x00, 0xC0 };
     302    uint8_t midi_header[] = { 0x4D, 0x54, 0x68, 0x64, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, (num_tracks + 1), 0x00, 0xC0 };
    298303    memcpy(output_buffer_ptr, midi_header, 14);
    299304    output_buffer_ptr += 14;
    300305
    301306    // Write additional first track with bpm info
    302     unsigned char bpm_track[] = { 0x4D, 0x54, 0x72, 0x6B, 0x00, 0x00, 0x00, 0x0B, 0x00, 0xFF, 0x51, 0x03, 0x18, 0x7F, 0xFF, 0x00, 0xFF, 0x2F, 0x00 };
     307    uint8_t bpm_track[] = { 0x4D, 0x54, 0x72, 0x6B, 0x00, 0x00, 0x00, 0x0B, 0x00, 0xFF, 0x51, 0x03, 0x18, 0x7F, 0xFF, 0x00, 0xFF, 0x2F, 0x00 };
    303308    memcpy(output_buffer_ptr, bpm_track, sizeof(bpm_track));
    304309    output_buffer_ptr += sizeof(bpm_track);
    305310
    306     int i;
    307     for (i = 0; i < num_tracks; i++)
    308     {
    309         unsigned int trackposition = get_int_from_buffer(&input_buffer[offset_tracks + i * (sizeof(int))]);
    310         unsigned int tracksize;
     311    for (int i = 0; i < num_tracks; i++)
     312    {
     313        uint32_t trackposition = get_int_from_buffer(&input_buffer[offset_tracks + i * (sizeof(uint32_t))]);
     314        uint32_t tracksize;
    311315        if (i == num_tracks - 1)
    312316            tracksize = buffersize - trackposition;
    313317        else
    314             tracksize = get_int_from_buffer(&input_buffer[offset_tracks + (i + 1) * (sizeof(int))]) - trackposition;
     318            tracksize = get_int_from_buffer(&input_buffer[offset_tracks + (i + 1) * (sizeof(uint32_t))]) - trackposition;
    315319
    316320        convert_hmi_track(&input_buffer[trackposition], tracksize, output_buffer_ptr);
    317321    }
    318322
    319     data_size = (unsigned int)(output_buffer_ptr - output_buffer);
    320     output_buffer = (unsigned char*)realloc(output_buffer, data_size);
     323    data_size = (uint32_t)(output_buffer_ptr - output_buffer);
     324    output_buffer = (uint8_t*)realloc(output_buffer, data_size);
    321325
    322326    free(input_buffer);
  • abuse/trunk/src/sdlport/hmi.h

    r494 r616  
     1//
     2//  Abuse - dark 2D side-scrolling platform game
     3//
     4//  Copyright (c) 2011 Jochen Schleu <jjs@jjs.at>
     5//   This program is free software; you can redistribute it and/or
     6//   modify it under the terms of the Do What The Fuck You Want To
     7//   Public License, Version 2, as published by Sam Hocevar. See
     8//   http://sam.zoy.org/projects/COPYING.WTFPL for more details.
     9//
     10
    111#ifndef __HMI_HPP_
    212#define __HMI_HPP_
    313
    4 unsigned char* load_hmi(char* filename, unsigned int &data_size);
     14uint8_t* load_hmi(char const *filename, uint32_t &data_size);
    515
    616#endif
     17
  • abuse/trunk/src/sdlport/sound.cpp

    r555 r616  
    180180    strcat(realname, filename);
    181181
    182     unsigned int data_size;
     182    uint32_t data_size;
    183183    data = load_hmi(realname, data_size);
    184184
Note: See TracChangeset for help on using the changeset viewer.