Changeset 616
- Timestamp:
- May 9, 2011, 12:55:23 AM (12 years ago)
- 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 1 21 // Load Abuse HMI files and covert them to standard Midi format 2 22 // 3 23 // 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 6 28 // - additional 0xFE event with variable length, purpose unknown 7 29 // 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. 17 34 18 35 #define MAX_NOTE_OFF_EVENTS 30 19 36 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) 37 struct NoteOffEvent 38 { 39 uint32_t time; 40 uint8_t command; 41 uint8_t note; 42 }; 43 44 NoteOffEvent note_off_events[MAX_NOTE_OFF_EVENTS]; 45 46 static 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 52 static void write_big_endian_number(uint32_t le, uint8_t* buffer) 39 53 { 40 54 buffer[3] = (le & 0x000000FF); … … 44 58 } 45 59 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; 60 static 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 70 static uint32_t read_time_value(uint8_t* &buffer) 71 { 72 uint32_t value; 73 uint8_t c; 64 74 65 75 if ((value = *buffer++) & 0x80) … … 76 86 } 77 87 78 79 void write_time_value(unsigned int time, unsigned char* &buffer) 80 { 81 unsigned int value_buffer = time & 0x7F; 88 static void write_time_value(uint32_t time, uint8_t* &buffer) 89 { 90 uint32_t value_buffer = time & 0x7F; 82 91 83 92 while (time >>= 7) … … 97 106 } 98 107 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++) 108 static 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++) 104 111 { 105 112 if (note_off_events[i].time == 0xFFFFFFFF) 106 113 { 107 114 note_off_events[i].time = time; 108 note_off_events[i].command = c ommand;115 note_off_events[i].command = cmd; 109 116 note_off_events[i].note = note; 110 117 break; … … 113 120 114 121 // 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 ¤t_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 125 static void check_for_note_off_events(uint32_t ¤t_time, 126 uint32_t &last_time, uint8_t* &buffer) 127 { 128 for (int i = 0; i < MAX_NOTE_OFF_EVENTS; i++) 123 129 { 124 130 if (note_off_events[i].time == 0xFFFFFFFF) … … 141 147 142 148 // 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 152 static void convert_hmi_track(uint8_t* input, 153 uint32_t input_size, uint8_t* &output) 148 154 { 149 155 int done = 0; 150 u nsigned charcurrent_command = 0;151 u nsigned charcurrent_value = 0;152 u nsigned int current_time = 0;153 u nsigned int last_time = 0;154 u nsigned char* start_of_buffer = output;155 u nsigned 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); 158 164 159 165 // Midi data offset is at 0x57 from track start … … 161 167 162 168 // Write track header, leave length as zero for now 163 u nsigned chartrack_header[] = { 0x4D, 0x54, 0x72, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x00};169 uint8_t track_header[] = { 0x4D, 0x54, 0x72, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x00}; 164 170 memcpy(output, track_header, 8); 165 171 output += 8; … … 250 256 } 251 257 252 if ((u nsigned int)(input - start_of_input) >= input_size)258 if ((uint32_t)(input - start_of_input) >= input_size) 253 259 break; 254 260 } … … 257 263 if (done != 1) 258 264 { 259 u nsigned charend_marker[] = { 0x00, 0xFF, 0x2F, 0x00 };265 uint8_t end_marker[] = { 0x00, 0xFF, 0x2F, 0x00 }; 260 266 memcpy(output, end_marker, 4); 261 267 output += 4; … … 263 269 264 270 // 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 274 uint8_t* load_hmi(char const *filename, uint32_t &data_size) 275 { 276 uint8_t* input_buffer; 277 uint8_t* output_buffer; 273 278 274 279 FILE* hmifile = fopen(filename, "rb"); … … 278 283 279 284 fseek(hmifile, 0, SEEK_END); 280 int buffersize = ftell(hmifile);285 uint32_t buffersize = ftell(hmifile); 281 286 fseek(hmifile, 0, SEEK_SET); 282 287 283 input_buffer = (u nsigned char*)malloc(buffersize);288 input_buffer = (uint8_t*)malloc(buffersize); 284 289 fread(input_buffer, 1, buffersize, hmifile); 285 290 fclose(hmifile); 286 291 287 output_buffer = (u nsigned char*)malloc(buffersize * 10); // Midi files can be larger than HMI files288 u nsigned 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; 289 294 290 295 // Offset to tracks is at 0x113 291 u nsigned int offset_tracks = get_int_from_buffer(&input_buffer[0xE8]);292 u nsigned int next_offset = get_int_from_buffer(&input_buffer[0xF4]);293 294 u nsigned 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); 295 300 296 301 // Write Midi file header 297 u nsigned charmidi_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 }; 298 303 memcpy(output_buffer_ptr, midi_header, 14); 299 304 output_buffer_ptr += 14; 300 305 301 306 // Write additional first track with bpm info 302 u nsigned charbpm_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 }; 303 308 memcpy(output_buffer_ptr, bpm_track, sizeof(bpm_track)); 304 309 output_buffer_ptr += sizeof(bpm_track); 305 310 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; 311 315 if (i == num_tracks - 1) 312 316 tracksize = buffersize - trackposition; 313 317 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; 315 319 316 320 convert_hmi_track(&input_buffer[trackposition], tracksize, output_buffer_ptr); 317 321 } 318 322 319 data_size = (u nsigned int)(output_buffer_ptr - output_buffer);320 output_buffer = (u nsigned 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); 321 325 322 326 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 1 11 #ifndef __HMI_HPP_ 2 12 #define __HMI_HPP_ 3 13 4 u nsigned char* load_hmi(char* filename, unsigned int &data_size);14 uint8_t* load_hmi(char const *filename, uint32_t &data_size); 5 15 6 16 #endif 17 -
abuse/trunk/src/sdlport/sound.cpp
r555 r616 180 180 strcat(realname, filename); 181 181 182 u nsigned int data_size;182 uint32_t data_size; 183 183 data = load_hmi(realname, data_size); 184 184
Note: See TracChangeset
for help on using the changeset viewer.