Mercurial > repos > blastem
comparison blastem.c @ 1683:7e044a84268d
Add support for SMD format ROMs in ZIP files
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Thu, 17 Jan 2019 23:55:49 -0800 |
parents | a0aa9e3c9508 |
children | f6bd4962b8f5 |
comparison
equal
deleted
inserted
replaced
1682:a0aa9e3c9508 | 1683:7e044a84268d |
---|---|
67 #define romseek gzseek | 67 #define romseek gzseek |
68 #define romgetc gzgetc | 68 #define romgetc gzgetc |
69 #define romclose gzclose | 69 #define romclose gzclose |
70 #endif | 70 #endif |
71 | 71 |
72 uint16_t *process_smd_block(uint16_t *dst, uint8_t *src, size_t bytes) | |
73 { | |
74 for (uint8_t *low = src, *high = (src+bytes/2), *end = src+bytes; high < end; high++, low++) { | |
75 *(dst++) = *low << 8 | *high; | |
76 } | |
77 return dst; | |
78 } | |
79 | |
72 int load_smd_rom(ROMFILE f, void **buffer) | 80 int load_smd_rom(ROMFILE f, void **buffer) |
73 { | 81 { |
74 uint8_t block[SMD_BLOCK_SIZE]; | 82 uint8_t block[SMD_BLOCK_SIZE]; |
75 romseek(f, SMD_HEADER_SIZE, SEEK_SET); | 83 romseek(f, SMD_HEADER_SIZE, SEEK_SET); |
76 | 84 |
87 buf = realloc(buf, filesize); | 95 buf = realloc(buf, filesize); |
88 dst = buf + readsize/sizeof(uint16_t); | 96 dst = buf + readsize/sizeof(uint16_t); |
89 } | 97 } |
90 read = romread(block, 1, SMD_BLOCK_SIZE, f); | 98 read = romread(block, 1, SMD_BLOCK_SIZE, f); |
91 if (read > 0) { | 99 if (read > 0) { |
92 for (uint8_t *low = block, *high = (block+read/2), *end = block+read; high < end; high++, low++) { | 100 dst = process_smd_block(dst, block, read); |
93 *(dst++) = *low << 8 | *high; | |
94 } | |
95 readsize += read; | 101 readsize += read; |
96 } | 102 } |
97 } while(read > 0); | 103 } while(read > 0); |
98 romclose(f); | 104 romclose(f); |
99 | 105 |
100 *buffer = buf; | 106 *buffer = buf; |
101 | 107 |
102 return readsize; | 108 return readsize; |
103 } | 109 } |
104 | 110 |
111 uint8_t is_smd_format(const char *filename, uint8_t *header) | |
112 { | |
113 if (header[1] == SMD_MAGIC1 && header[8] == SMD_MAGIC2 && header[9] == SMD_MAGIC3) { | |
114 int i; | |
115 for (i = 3; i < 8; i++) { | |
116 if (header[i] != 0) { | |
117 return 0; | |
118 } | |
119 } | |
120 if (i == 8) { | |
121 if (header[2]) { | |
122 fatal_error("%s is a split SMD ROM which is not currently supported", filename); | |
123 } | |
124 return 1; | |
125 } | |
126 } | |
127 return 0; | |
128 } | |
129 | |
105 uint32_t load_rom_zip(const char *filename, void **dst) | 130 uint32_t load_rom_zip(const char *filename, void **dst) |
106 { | 131 { |
107 static const char *valid_exts[] = {"bin", "md", "gen", "sms", "rom"}; | 132 static const char *valid_exts[] = {"bin", "md", "gen", "sms", "rom", "smd"}; |
108 const uint32_t num_exts = sizeof(valid_exts)/sizeof(*valid_exts); | 133 const uint32_t num_exts = sizeof(valid_exts)/sizeof(*valid_exts); |
109 zip_file *z = zip_open(filename); | 134 zip_file *z = zip_open(filename); |
110 if (!z) { | 135 if (!z) { |
111 return 0; | 136 return 0; |
112 } | 137 } |
121 { | 146 { |
122 if (!strcasecmp(ext, valid_exts[j])) { | 147 if (!strcasecmp(ext, valid_exts[j])) { |
123 size_t out_size = nearest_pow2(z->entries[i].size); | 148 size_t out_size = nearest_pow2(z->entries[i].size); |
124 *dst = zip_read(z, i, &out_size); | 149 *dst = zip_read(z, i, &out_size); |
125 if (*dst) { | 150 if (*dst) { |
151 if (is_smd_format(z->entries[i].name, *dst)) { | |
152 size_t offset; | |
153 for (offset = 0; offset + SMD_BLOCK_SIZE + SMD_HEADER_SIZE < out_size; offset += SMD_BLOCK_SIZE) | |
154 { | |
155 uint8_t tmp[SMD_BLOCK_SIZE]; | |
156 memcpy(tmp, *dst + offset + SMD_HEADER_SIZE, SMD_BLOCK_SIZE); | |
157 process_smd_block(*dst + offset, tmp, SMD_BLOCK_SIZE); | |
158 } | |
159 out_size = offset; | |
160 } | |
126 free(ext); | 161 free(ext); |
127 zip_close(z); | 162 zip_close(z); |
128 return out_size; | 163 return out_size; |
129 } | 164 } |
130 } | 165 } |
150 } | 185 } |
151 if (sizeof(header) != romread(header, 1, sizeof(header), f)) { | 186 if (sizeof(header) != romread(header, 1, sizeof(header), f)) { |
152 fatal_error("Error reading from %s\n", filename); | 187 fatal_error("Error reading from %s\n", filename); |
153 } | 188 } |
154 | 189 |
155 if (header[1] == SMD_MAGIC1 && header[8] == SMD_MAGIC2 && header[9] == SMD_MAGIC3) { | 190 if (is_smd_format(filename, header)) { |
156 int i; | 191 if (stype) { |
157 for (i = 3; i < 8; i++) { | 192 *stype = SYSTEM_GENESIS; |
158 if (header[i] != 0) { | 193 } |
159 break; | 194 return load_smd_rom(f, dst); |
160 } | |
161 } | |
162 if (i == 8) { | |
163 if (header[2]) { | |
164 fatal_error("%s is a split SMD ROM which is not currently supported", filename); | |
165 } | |
166 if (stype) { | |
167 *stype = SYSTEM_GENESIS; | |
168 } | |
169 return load_smd_rom(f, dst); | |
170 } | |
171 } | 195 } |
172 | 196 |
173 size_t filesize = 512 * 1024; | 197 size_t filesize = 512 * 1024; |
174 size_t readsize = sizeof(header); | 198 size_t readsize = sizeof(header); |
175 | 199 |