1 #include <stdio.h> 2 #ifndef LOCUTUS_TYPES_HPP_ 3 #define LOCUTUS_TYPES_HPP_ 4 5 #include <list> 6 #include <vector> 7 #include <map> 8 #include <utility> 9 #include <bitset> 10 #include <stdint.h> 11 #include <cstring> 12 #include <assert.h> 13 #include <iterator> 14 #include <algorithm> 15 #include "metadata/metadata.h" 16 17 static const int LOCUTUS_PERM_READ = 0; 18 static const int LOCUTUS_PERM_WRITE = 1; 19 static const int LOCUTUS_PERM_NARROW = 2; // allow writes to 8 LSBs only 20 static const int LOCUTUS_PERM_BANKSW = 3; // Bankswitch / Pageflip enable 21 22 typedef std::bitset< 4 > t_perm; 23 typedef std::pair< uint32_t, uint32_t > t_addr_span; 24 typedef std::list< t_addr_span > t_addr_list; 25 typedef std::vector< uint8_t > t_byte_vec; 26 typedef std::vector< uint16_t > t_word_vec; 27 typedef std::vector< std::string > t_string_vec; 28 typedef std::vector< game_date_t > t_game_date_vec; 29 typedef std::pair< std::string, std::string > t_var; 30 typedef std::vector< t_var > t_var_vec; 31 32 static const int PAGE_NONE = 0xFF; 33 34 35 // ------------------------------------------------------------------------ // 36 // T_BIN_HUNK // 37 // ------------------------------------------------------------------------ // 38 struct t_bin_hunk 39 { 40 uint32_t s_addr, e_addr; // Locutus addresses 41 uint8_t page; // ECS page (0xFF if none) 42 bool mapped; // True == map to INTV space at s_addr 43 t_word_vec data; // actual ROM data 44 t_perm perm; // permissions 45 t_bin_hunkt_bin_hunk46 t_bin_hunk( const uint32_t s_addr_, 47 const uint32_t e_addr_, 48 const uint8_t page_, 49 const bool mapped_, 50 const t_word_vec data_, 51 const t_perm perm_ = 0 ) 52 : 53 s_addr( s_addr_ ), e_addr( e_addr_ ), page( page_ ), mapped( mapped_ ), 54 data( data_ ), perm( perm_ ) 55 { } 56 t_bin_hunkt_bin_hunk57 t_bin_hunk( const uint32_t s_addr_, 58 const uint32_t e_addr_, 59 const uint8_t page_, 60 const bool mapped_, 61 const uint16_t* data_, 62 const t_perm perm_ = 0 ) 63 : 64 s_addr( s_addr_ ), e_addr( e_addr_ ), page( page_ ), mapped( mapped_ ), 65 data( ), perm( perm_ ) 66 { 67 data.resize( e_addr_ - s_addr_ + 1, 0 ); 68 69 if ( data_ ) 70 std::memcpy( static_cast<void*>(&data[0]), 71 static_cast<const void *>(&data_[0]), 72 sizeof( uint16_t ) * data.size() ); 73 } 74 75 operator <t_bin_hunk76 inline bool operator < ( const t_bin_hunk& rhs ) const 77 { 78 return page < rhs.page ? true 79 : page == rhs.page && s_addr < rhs.s_addr ? true 80 : false; 81 } 82 page_then_addrt_bin_hunk83 static bool page_then_addr( const t_bin_hunk& lhs, const t_bin_hunk& rhs ) 84 { 85 return lhs.page < rhs.page ? true 86 : lhs.page == rhs.page && lhs.s_addr < rhs.s_addr ? true 87 : false; 88 } 89 addr_then_paget_bin_hunk90 static bool addr_then_page( const t_bin_hunk& lhs, const t_bin_hunk& rhs ) 91 { 92 return lhs.s_addr < rhs.s_addr ? true 93 : lhs.s_addr == rhs.s_addr &&lhs.page < rhs.page ? true 94 : false; 95 } 96 can_merge_witht_bin_hunk97 inline bool can_merge_with( const t_bin_hunk& rhs ) const 98 { 99 return e_addr == rhs.s_addr - 1 100 && page == rhs.page 101 && mapped == rhs.mapped; 102 } 103 merge_witht_bin_hunk104 inline void merge_with( const t_bin_hunk& rhs ) 105 { 106 assert( can_merge_with( rhs ) ); 107 108 e_addr = rhs.e_addr; 109 data.insert( data.end(), rhs.data.begin(), rhs.data.end() ); 110 } 111 112 // After split, e_addr = split_addr - 1, and we return a new hunk starting 113 // at split_addr ending at the old e_addr. That is: 114 // this => [ s_addr, split_addr ) 115 // new => [ split_addr, e_addr ] split_att_bin_hunk116 t_bin_hunk split_at( const uint32_t split_addr ) 117 { 118 assert( split_addr > s_addr && split_addr <= e_addr ); 119 120 t_bin_hunk new_hunk( split_addr, e_addr, page, mapped, 121 &data[split_addr - s_addr] ); 122 123 e_addr = split_addr - 1; 124 data.resize( e_addr - s_addr + 1 ); 125 126 return new_hunk; 127 } 128 }; 129 130 typedef std::vector< t_bin_hunk > t_hunk_vec; 131 132 // ------------------------------------------------------------------------ // 133 // T_MEMATTR_SPAN // 134 // ------------------------------------------------------------------------ // 135 static const uint8_t MEMATTR_BAD = 0; 136 static const uint8_t MEMATTR_ROM = 1; 137 static const uint8_t MEMATTR_WOM = 2; 138 static const uint8_t MEMATTR_RAM = 3; 139 140 struct t_memattr_span 141 { 142 uint16_t s_addr, e_addr; 143 uint8_t type, width; 144 t_memattr_spant_memattr_span145 t_memattr_span( const uint16_t s_addr_, const uint16_t e_addr_, 146 const uint8_t type_, const uint8_t width_ ) 147 : s_addr( s_addr_ ), e_addr( e_addr_ ), type( type_ ), width( width_ ) 148 { } 149 operator <t_memattr_span150 inline bool operator < ( const t_memattr_span& rhs ) const 151 { 152 return s_addr < rhs.s_addr ? true : false; 153 } 154 can_merge_witht_memattr_span155 inline bool can_merge_with( const t_memattr_span& rhs ) const 156 { 157 return e_addr == rhs.s_addr - 1 158 && type == rhs.type 159 && width == rhs.width; 160 } 161 merge_witht_memattr_span162 inline void merge_with( const t_memattr_span& rhs ) 163 { 164 assert( can_merge_with( rhs ) ); 165 166 e_addr = rhs.e_addr; 167 } 168 }; 169 170 typedef std::vector< t_memattr_span > t_memattr_vec; 171 172 // ------------------------------------------------------------------------ // 173 // T_BANKSW_SPAN // 174 // ------------------------------------------------------------------------ // 175 struct t_banksw_span 176 { 177 uint16_t s_addr, e_addr; 178 t_banksw_spant_banksw_span179 t_banksw_span( const uint16_t s_addr_, const uint16_t e_addr_ ) 180 : s_addr( s_addr_ ), e_addr( e_addr_ ) 181 { } 182 operator <t_banksw_span183 inline bool operator < ( const t_banksw_span& rhs ) const 184 { 185 return s_addr < rhs.s_addr ? true : false; 186 } 187 can_merge_witht_banksw_span188 inline bool can_merge_with( const t_banksw_span& rhs ) const 189 { 190 return e_addr == rhs.s_addr - 1; 191 } 192 merge_witht_banksw_span193 inline void merge_with( const t_banksw_span& rhs ) 194 { 195 assert( can_merge_with( rhs ) ); 196 197 e_addr = rhs.e_addr; 198 } 199 }; 200 201 typedef std::vector< t_banksw_span > t_banksw_vec; 202 203 // ------------------------------------------------------------------------ // 204 // T_METADATA // 205 // ------------------------------------------------------------------------ // 206 struct t_metadata 207 { 208 private: 209 void pack_string( uint8_t tag, t_byte_vec& v, const std::string& s ) const; 210 211 template <typename T> 212 void unpack_string( std::string& str, T& si, uint8_t len ); 213 214 template <typename T> 215 void unpack_string( t_string_vec& vec, T& si, uint8_t len ); 216 217 public: 218 219 std::string name; 220 std::string short_name; 221 t_string_vec authors; 222 t_string_vec game_artists; 223 t_string_vec composers; 224 t_string_vec sfx_artists; 225 t_string_vec voice_actors; 226 t_string_vec doc_writers; 227 t_string_vec conceptualizers; 228 t_string_vec box_artists; 229 t_string_vec more_infos; 230 t_string_vec publishers; 231 t_game_date_vec release_dates; 232 t_string_vec licenses; 233 t_string_vec descriptions; 234 t_string_vec misc; 235 236 compat_level_t ecs_compat; 237 compat_level_t voice_compat; 238 compat_level_t intv2_compat; 239 compat_level_t kc_compat; 240 compat_level_t tv_compat; 241 bool lto_mapper; 242 jlp_accel_t jlp_accel; 243 int jlp_flash; 244 bool is_defaults; 245 246 game_metadata_t* to_game_metadata() const; 247 void from_game_metadata( const game_metadata_t* ); 248 249 bool empty( ) const; 250 void clear( ); 251 252 t_byte_vec serialize( ) const; 253 void deserialize( const t_byte_vec& serial ); 254 }; 255 256 #endif 257