Submit initial patch from FS#12176. Adds support for several new game music formats...
[kugel-rb.git] / apps / codecs / libgme / rom_data.c
blob5fe311513040ecf46218d0c8f4ef0b3a650960a4
1 // Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
3 #include "rom_data.h"
5 /* Copyright (C) 2003-2006 Shay Green. This module is free software; you
6 can redistribute it and/or modify it under the terms of the GNU Lesser
7 General Public License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version. This
9 module is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12 details. You should have received a copy of the GNU Lesser General Public
13 License along with this module; if not, write to the Free Software Foundation,
14 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
16 #include <string.h>
17 #include "blargg_source.h"
19 // Rom_Data
21 blargg_err_t Rom_load( struct Rom_Data* this, const void* data, long size,
22 int header_size, void* header_out, int fill )
24 long file_offset = this->pad_size;
26 this->rom_addr = 0;
27 this->mask = 0;
28 this->size = 0;
30 if ( size <= header_size ) // <= because there must be data after header
31 return gme_wrong_file_type;
33 // Read header
34 memcpy( header_out, data, header_size );
36 this->file_size = size - header_size;
37 this->file_data = (byte*) data + header_size;
39 memset( this->unmapped, fill, this->rom_size );
40 memcpy( &this->unmapped [file_offset], this->file_data,
41 this->file_size < this->pad_size ? this->file_size : this->pad_size );
43 return 0;
46 void Rom_set_addr( struct Rom_Data* this, long addr )
48 this->rom_addr = addr - this->bank_size - pad_extra;
50 long rounded = (addr + this->file_size + this->bank_size - 1) / this->bank_size * this->bank_size;
51 if ( rounded <= 0 )
53 rounded = 0;
55 else
57 int shift = 0;
58 unsigned long max_addr = (unsigned long) (rounded - 1);
59 while ( max_addr >> shift )
60 shift++;
61 this->mask = (1L << shift) - 1;
64 if ( addr < 0 )
65 addr = 0;
66 this->size = rounded;
67 this->rsize_ = rounded - this->rom_addr + pad_extra;