diff options
Diffstat (limited to 'apps/codecs/libasap/asap.c')
-rw-r--r-- | apps/codecs/libasap/asap.c | 207 |
1 files changed, 134 insertions, 73 deletions
diff --git a/apps/codecs/libasap/asap.c b/apps/codecs/libasap/asap.c index c79682c38b..510807362a 100644 --- a/apps/codecs/libasap/asap.c +++ b/apps/codecs/libasap/asap.c | |||
@@ -23,21 +23,37 @@ | |||
23 | 23 | ||
24 | #include "asap_internal.h" | 24 | #include "asap_internal.h" |
25 | 25 | ||
26 | #ifdef ASAP_ONLY_INFO | ||
27 | |||
28 | #define GET_PLAYER(name) NULL | ||
29 | |||
30 | #else | ||
31 | |||
32 | #define GET_PLAYER(name) GET_RESOURCE(name, obx) | ||
33 | |||
26 | FUNC(int, ASAP_GetByte, (P(ASAP_State PTR, ast), P(int, addr))) | 34 | FUNC(int, ASAP_GetByte, (P(ASAP_State PTR, ast), P(int, addr))) |
27 | { | 35 | { |
28 | switch (addr & 0xff0f) { | 36 | switch (addr & 0xff1f) { |
37 | case 0xd014: | ||
38 | return ast _ module_info.ntsc ? 0xf : 1; | ||
29 | case 0xd20a: | 39 | case 0xd20a: |
40 | case 0xd21a: | ||
30 | return PokeySound_GetRandom(ast, addr, ast _ cycle); | 41 | return PokeySound_GetRandom(ast, addr, ast _ cycle); |
31 | case 0xd20e: | 42 | case 0xd20e: |
32 | if ((addr & ast _ extra_pokey_mask) != 0) { | 43 | return ast _ irqst; |
44 | case 0xd21e: | ||
45 | if (ast _ extra_pokey_mask != 0) { | ||
33 | /* interrupts in the extra POKEY not emulated at the moment */ | 46 | /* interrupts in the extra POKEY not emulated at the moment */ |
34 | return 0xff; | 47 | return 0xff; |
35 | } | 48 | } |
36 | return ast _ irqst; | 49 | return ast _ irqst; |
37 | case 0xd20f: | 50 | case 0xd20c: |
38 | /* just because some SAP files rely on this */ | 51 | case 0xd21c: |
52 | case 0xd20f: /* just because some SAP files rely on this */ | ||
53 | case 0xd21f: | ||
39 | return 0xff; | 54 | return 0xff; |
40 | case 0xd40b: | 55 | case 0xd40b: |
56 | case 0xd41b: | ||
41 | return ast _ scanline_number >> 1; | 57 | return ast _ scanline_number >> 1; |
42 | default: | 58 | default: |
43 | return dGetByte(addr); | 59 | return dGetByte(addr); |
@@ -99,10 +115,14 @@ FUNC(void, ASAP_PutByte, (P(ASAP_State PTR, ast), P(int, addr), P(int, data))) | |||
99 | dPutByte(addr, data); | 115 | dPutByte(addr, data); |
100 | } | 116 | } |
101 | 117 | ||
118 | #endif /* ASAP_ONLY_INFO */ | ||
119 | |||
102 | #define UWORD(array, index) (UBYTE(array[index]) + (UBYTE(array[(index) + 1]) << 8)) | 120 | #define UWORD(array, index) (UBYTE(array[index]) + (UBYTE(array[(index) + 1]) << 8)) |
103 | 121 | ||
104 | #ifndef ASAP_ONLY_SAP | 122 | #ifndef ASAP_ONLY_SAP |
105 | 123 | ||
124 | #ifndef ASAP_ONLY_INFO | ||
125 | |||
106 | #ifndef JAVA | 126 | #ifndef JAVA |
107 | #include "players.h" | 127 | #include "players.h" |
108 | #endif | 128 | #endif |
@@ -117,6 +137,8 @@ CONST_ARRAY(byte, cmr_bass_table) | |||
117 | 0x25, 0x24, 0x21, 0x1F, 0x1E | 137 | 0x25, 0x24, 0x21, 0x1F, 0x1E |
118 | END_CONST_ARRAY; | 138 | END_CONST_ARRAY; |
119 | 139 | ||
140 | #endif /* ASAP_ONLY_INFO */ | ||
141 | |||
120 | CONST_ARRAY(int, perframe2fastplay) | 142 | CONST_ARRAY(int, perframe2fastplay) |
121 | 312, 312 / 2, 312 / 3, 312 / 4 | 143 | 312, 312 / 2, 312 / 3, 312 / 4 |
122 | END_CONST_ARRAY; | 144 | END_CONST_ARRAY; |
@@ -126,17 +148,21 @@ PRIVATE FUNC(abool, load_native, ( | |||
126 | P(ASAP_State PTR, ast), P(ASAP_ModuleInfo PTR, module_info), | 148 | P(ASAP_State PTR, ast), P(ASAP_ModuleInfo PTR, module_info), |
127 | P(CONST BYTEARRAY, module), P(int, module_len), P(RESOURCE, player))) | 149 | P(CONST BYTEARRAY, module), P(int, module_len), P(RESOURCE, player))) |
128 | { | 150 | { |
151 | #ifndef ASAP_ONLY_INFO | ||
129 | V(int, player_last_byte); | 152 | V(int, player_last_byte); |
153 | #endif | ||
130 | V(int, music_last_byte); | 154 | V(int, music_last_byte); |
131 | V(int, block_len); | 155 | V(int, block_len); |
132 | if ((UBYTE(module[0]) != 0xff || UBYTE(module[1]) != 0xff) | 156 | if ((UBYTE(module[0]) != 0xff || UBYTE(module[1]) != 0xff) |
133 | && (module[0] != 0 || module[1] != 0)) /* some CMC and clones start with zeros */ | 157 | && (module[0] != 0 || module[1] != 0)) /* some CMC and clones start with zeros */ |
134 | return FALSE; | 158 | return FALSE; |
159 | module_info _ music = UWORD(module, 2); | ||
160 | #ifndef ASAP_ONLY_INFO | ||
135 | module_info _ player = UWORD(player, 2); | 161 | module_info _ player = UWORD(player, 2); |
136 | player_last_byte = UWORD(player, 4); | 162 | player_last_byte = UWORD(player, 4); |
137 | module_info _ music = UWORD(module, 2); | ||
138 | if (module_info _ music <= player_last_byte) | 163 | if (module_info _ music <= player_last_byte) |
139 | return FALSE; | 164 | return FALSE; |
165 | #endif | ||
140 | music_last_byte = UWORD(module, 4); | 166 | music_last_byte = UWORD(module, 4); |
141 | if (module_info _ music <= 0xd7ff && music_last_byte >= 0xd000) | 167 | if (module_info _ music <= 0xd7ff && music_last_byte >= 0xd000) |
142 | return FALSE; | 168 | return FALSE; |
@@ -154,10 +180,12 @@ PRIVATE FUNC(abool, load_native, ( | |||
154 | if (10 + block_len + info_len != module_len) | 180 | if (10 + block_len + info_len != module_len) |
155 | return FALSE; | 181 | return FALSE; |
156 | } | 182 | } |
183 | #ifndef ASAP_ONLY_INFO | ||
157 | if (ast != NULL) { | 184 | if (ast != NULL) { |
158 | COPY_ARRAY(ast _ memory, module_info _ music, module, 6, block_len); | 185 | COPY_ARRAY(ast _ memory, module_info _ music, module, 6, block_len); |
159 | COPY_ARRAY(ast _ memory, module_info _ player, player, 6, player_last_byte + 1 - module_info _ player); | 186 | COPY_ARRAY(ast _ memory, module_info _ player, player, 6, player_last_byte + 1 - module_info _ player); |
160 | } | 187 | } |
188 | #endif | ||
161 | return TRUE; | 189 | return TRUE; |
162 | } | 190 | } |
163 | 191 | ||
@@ -256,8 +284,10 @@ PRIVATE FUNC(abool, parse_cmc, ( | |||
256 | module_info _ type = type; | 284 | module_info _ type = type; |
257 | if (!load_native(ast, module_info, module, module_len, player)) | 285 | if (!load_native(ast, module_info, module, module_len, player)) |
258 | return FALSE; | 286 | return FALSE; |
287 | #ifndef ASAP_ONLY_INFO | ||
259 | if (ast != NULL && type == ASAP_TYPE_CMR) | 288 | if (ast != NULL && type == ASAP_TYPE_CMR) |
260 | COPY_ARRAY(ast _ memory, 0x500 + CMR_BASS_TABLE_OFFSET, cmr_bass_table, 0, sizeof(cmr_bass_table)); | 289 | COPY_ARRAY(ast _ memory, 0x500 + CMR_BASS_TABLE_OFFSET, cmr_bass_table, 0, sizeof(cmr_bass_table)); |
290 | #endif | ||
261 | last_pos = 0x54; | 291 | last_pos = 0x54; |
262 | while (--last_pos >= 0) { | 292 | while (--last_pos >= 0) { |
263 | if (UBYTE(module[0x206 + last_pos]) < 0xb0 | 293 | if (UBYTE(module[0x206 + last_pos]) < 0xb0 |
@@ -351,7 +381,7 @@ PRIVATE FUNC(abool, parse_dlt, ( | |||
351 | else if (module_len != 0x2c07) | 381 | else if (module_len != 0x2c07) |
352 | return FALSE; | 382 | return FALSE; |
353 | module_info _ type = ASAP_TYPE_DLT; | 383 | module_info _ type = ASAP_TYPE_DLT; |
354 | if (!load_native(ast, module_info, module, module_len, GET_RESOURCE(dlt, obx)) | 384 | if (!load_native(ast, module_info, module, module_len, GET_PLAYER(dlt)) |
355 | || module_info _ music != 0x2000) { | 385 | || module_info _ music != 0x2000) { |
356 | return FALSE; | 386 | return FALSE; |
357 | } | 387 | } |
@@ -452,7 +482,7 @@ PRIVATE FUNC(abool, parse_mpt, ( | |||
452 | if (module_len < 0x1d0) | 482 | if (module_len < 0x1d0) |
453 | return FALSE; | 483 | return FALSE; |
454 | module_info _ type = ASAP_TYPE_MPT; | 484 | module_info _ type = ASAP_TYPE_MPT; |
455 | if (!load_native(ast, module_info, module, module_len, GET_RESOURCE(mpt, obx))) | 485 | if (!load_native(ast, module_info, module, module_len, GET_PLAYER(mpt))) |
456 | return FALSE; | 486 | return FALSE; |
457 | track0_addr = UWORD(module, 2) + 0x1ca; | 487 | track0_addr = UWORD(module, 2) + 0x1ca; |
458 | if (UBYTE(module[0x1c6]) + (UBYTE(module[0x1ca]) << 8) != track0_addr) | 488 | if (UBYTE(module[0x1c6]) + (UBYTE(module[0x1ca]) << 8) != track0_addr) |
@@ -689,7 +719,7 @@ PRIVATE FUNC(abool, parse_rmt, ( | |||
689 | return FALSE; | 719 | return FALSE; |
690 | module_info _ type = ASAP_TYPE_RMT; | 720 | module_info _ type = ASAP_TYPE_RMT; |
691 | if (!load_native(ast, module_info, module, module_len, | 721 | if (!load_native(ast, module_info, module, module_len, |
692 | module_info _ channels == 2 ? GET_RESOURCE(rmt8, obx) : GET_RESOURCE(rmt4, obx))) | 722 | module_info _ channels == 2 ? GET_PLAYER(rmt8) : GET_PLAYER(rmt4))) |
693 | return FALSE; | 723 | return FALSE; |
694 | song_len = UWORD(module, 4) + 1 - UWORD(module, 0x14); | 724 | song_len = UWORD(module, 4) + 1 - UWORD(module, 0x14); |
695 | if (pos_shift == 3 && (song_len & 4) != 0 | 725 | if (pos_shift == 3 && (song_len & 4) != 0 |
@@ -781,7 +811,7 @@ PRIVATE FUNC(abool, parse_tmc, ( | |||
781 | if (module_len < 0x1d0) | 811 | if (module_len < 0x1d0) |
782 | return FALSE; | 812 | return FALSE; |
783 | module_info _ type = ASAP_TYPE_TMC; | 813 | module_info _ type = ASAP_TYPE_TMC; |
784 | if (!load_native(ast, module_info, module, module_len, GET_RESOURCE(tmc, obx))) | 814 | if (!load_native(ast, module_info, module, module_len, GET_PLAYER(tmc))) |
785 | return FALSE; | 815 | return FALSE; |
786 | module_info _ channels = 2; | 816 | module_info _ channels = 2; |
787 | i = 0; | 817 | i = 0; |
@@ -899,7 +929,7 @@ PRIVATE FUNC(abool, parse_tm2, ( | |||
899 | if (module_len < 0x3a4) | 929 | if (module_len < 0x3a4) |
900 | return FALSE; | 930 | return FALSE; |
901 | module_info _ type = ASAP_TYPE_TM2; | 931 | module_info _ type = ASAP_TYPE_TM2; |
902 | if (!load_native(ast, module_info, module, module_len, GET_RESOURCE(tm2, obx))) | 932 | if (!load_native(ast, module_info, module, module_len, GET_PLAYER(tm2))) |
903 | return FALSE; | 933 | return FALSE; |
904 | i = module[0x25]; | 934 | i = module[0x25]; |
905 | if (i < 1 || i > 4) | 935 | if (i < 1 || i > 4) |
@@ -1064,6 +1094,7 @@ PRIVATE FUNC(abool, parse_sap_header, ( | |||
1064 | V(int, duration_index) = 0; | 1094 | V(int, duration_index) = 0; |
1065 | if (!has_string_at(module, 0, "SAP\r\n")) | 1095 | if (!has_string_at(module, 0, "SAP\r\n")) |
1066 | return FALSE; | 1096 | return FALSE; |
1097 | module_info _ fastplay = -1; | ||
1067 | module_index = 5; | 1098 | module_index = 5; |
1068 | while (UBYTE(module[module_index]) != 0xff) { | 1099 | while (UBYTE(module[module_index]) != 0xff) { |
1069 | if (module_index + 8 >= module_len) | 1100 | if (module_index + 8 >= module_len) |
@@ -1093,6 +1124,8 @@ PRIVATE FUNC(abool, parse_sap_header, ( | |||
1093 | } | 1124 | } |
1094 | else if (TAG_IS("STEREO\r")) | 1125 | else if (TAG_IS("STEREO\r")) |
1095 | module_info _ channels = 2; | 1126 | module_info _ channels = 2; |
1127 | else if (TAG_IS("NTSC\r")) | ||
1128 | module_info _ ntsc = TRUE; | ||
1096 | else if (TAG_IS("TIME ")) { | 1129 | else if (TAG_IS("TIME ")) { |
1097 | V(int, i); | 1130 | V(int, i); |
1098 | #ifdef C | 1131 | #ifdef C |
@@ -1101,7 +1134,7 @@ PRIVATE FUNC(abool, parse_sap_header, ( | |||
1101 | V(STRING, s); | 1134 | V(STRING, s); |
1102 | #endif | 1135 | #endif |
1103 | module_index += 5; | 1136 | module_index += 5; |
1104 | for (i = 0; module[module_index + i] != 0xd; i++); | 1137 | for (i = 0; module[module_index + i] != 0xd; i++) { } |
1105 | if (i > 5 && has_string_at(module, module_index + i - 5, " LOOP")) { | 1138 | if (i > 5 && has_string_at(module, module_index + i - 5, " LOOP")) { |
1106 | module_info _ loops[duration_index] = TRUE; | 1139 | module_info _ loops[duration_index] = TRUE; |
1107 | i -= 5; | 1140 | i -= 5; |
@@ -1171,6 +1204,10 @@ PRIVATE FUNC(abool, parse_sap_header, ( | |||
1171 | default: | 1204 | default: |
1172 | return FALSE; | 1205 | return FALSE; |
1173 | } | 1206 | } |
1207 | if (module_info _ fastplay < 0) | ||
1208 | module_info _ fastplay = module_info _ ntsc ? 262 : 312; | ||
1209 | else if (module_info _ ntsc && module_info _ fastplay > 262) | ||
1210 | return FALSE; | ||
1174 | if (UBYTE(module[module_index + 1]) != 0xff) | 1211 | if (UBYTE(module[module_index + 1]) != 0xff) |
1175 | return FALSE; | 1212 | return FALSE; |
1176 | module_info _ header_len = module_index; | 1213 | module_info _ header_len = module_index; |
@@ -1287,6 +1324,7 @@ PRIVATE FUNC(abool, parse_file, ( | |||
1287 | module_info _ durations[i] = -1; | 1324 | module_info _ durations[i] = -1; |
1288 | module_info _ loops[i] = FALSE; | 1325 | module_info _ loops[i] = FALSE; |
1289 | } | 1326 | } |
1327 | module_info _ ntsc = FALSE; | ||
1290 | module_info _ fastplay = 312; | 1328 | module_info _ fastplay = 312; |
1291 | module_info _ music = -1; | 1329 | module_info _ music = -1; |
1292 | module_info _ init = -1; | 1330 | module_info _ init = -1; |
@@ -1297,17 +1335,17 @@ PRIVATE FUNC(abool, parse_file, ( | |||
1297 | return parse_sap(ast, module_info, module, module_len); | 1335 | return parse_sap(ast, module_info, module, module_len); |
1298 | #ifndef ASAP_ONLY_SAP | 1336 | #ifndef ASAP_ONLY_SAP |
1299 | case ASAP_EXT('C', 'M', 'C'): | 1337 | case ASAP_EXT('C', 'M', 'C'): |
1300 | return parse_cmc(ast, module_info, module, module_len, ASAP_TYPE_CMC, GET_RESOURCE(cmc, obx)); | 1338 | return parse_cmc(ast, module_info, module, module_len, ASAP_TYPE_CMC, GET_PLAYER(cmc)); |
1301 | case ASAP_EXT('C', 'M', '3'): | 1339 | case ASAP_EXT('C', 'M', '3'): |
1302 | return parse_cmc(ast, module_info, module, module_len, ASAP_TYPE_CM3, GET_RESOURCE(cm3, obx)); | 1340 | return parse_cmc(ast, module_info, module, module_len, ASAP_TYPE_CM3, GET_PLAYER(cm3)); |
1303 | case ASAP_EXT('C', 'M', 'R'): | 1341 | case ASAP_EXT('C', 'M', 'R'): |
1304 | return parse_cmc(ast, module_info, module, module_len, ASAP_TYPE_CMR, GET_RESOURCE(cmc, obx)); | 1342 | return parse_cmc(ast, module_info, module, module_len, ASAP_TYPE_CMR, GET_PLAYER(cmc)); |
1305 | case ASAP_EXT('C', 'M', 'S'): | 1343 | case ASAP_EXT('C', 'M', 'S'): |
1306 | module_info _ channels = 2; | 1344 | module_info _ channels = 2; |
1307 | return parse_cmc(ast, module_info, module, module_len, ASAP_TYPE_CMS, GET_RESOURCE(cms, obx)); | 1345 | return parse_cmc(ast, module_info, module, module_len, ASAP_TYPE_CMS, GET_PLAYER(cms)); |
1308 | case ASAP_EXT('D', 'M', 'C'): | 1346 | case ASAP_EXT('D', 'M', 'C'): |
1309 | module_info _ fastplay = 156; | 1347 | module_info _ fastplay = 156; |
1310 | return parse_cmc(ast, module_info, module, module_len, ASAP_TYPE_CMC, GET_RESOURCE(cmc, obx)); | 1348 | return parse_cmc(ast, module_info, module, module_len, ASAP_TYPE_CMC, GET_PLAYER(cmc)); |
1311 | case ASAP_EXT('D', 'L', 'T'): | 1349 | case ASAP_EXT('D', 'L', 'T'): |
1312 | return parse_dlt(ast, module_info, module, module_len); | 1350 | return parse_dlt(ast, module_info, module, module_len); |
1313 | case ASAP_EXT('M', 'P', 'T'): | 1351 | case ASAP_EXT('M', 'P', 'T'): |
@@ -1335,6 +1373,8 @@ FUNC(abool, ASAP_GetModuleInfo, ( | |||
1335 | return parse_file(NULL, module_info, filename, module, module_len); | 1373 | return parse_file(NULL, module_info, filename, module, module_len); |
1336 | } | 1374 | } |
1337 | 1375 | ||
1376 | #ifndef ASAP_ONLY_INFO | ||
1377 | |||
1338 | FUNC(abool, ASAP_Load, ( | 1378 | FUNC(abool, ASAP_Load, ( |
1339 | P(ASAP_State PTR, ast), P(STRING, filename), | 1379 | P(ASAP_State PTR, ast), P(STRING, filename), |
1340 | P(CONST BYTEARRAY, module), P(int, module_len))) | 1380 | P(CONST BYTEARRAY, module), P(int, module_len))) |
@@ -1345,7 +1385,7 @@ FUNC(abool, ASAP_Load, ( | |||
1345 | 1385 | ||
1346 | FUNC(void, ASAP_DetectSilence, (P(ASAP_State PTR, ast), P(int, seconds))) | 1386 | FUNC(void, ASAP_DetectSilence, (P(ASAP_State PTR, ast), P(int, seconds))) |
1347 | { | 1387 | { |
1348 | ast _ silence_cycles = seconds * ASAP_MAIN_CLOCK; | 1388 | ast _ silence_cycles = seconds * ASAP_MAIN_CLOCK(ast); |
1349 | } | 1389 | } |
1350 | 1390 | ||
1351 | PRIVATE FUNC(void, call_6502, (P(ASAP_State PTR, ast), P(int, addr), P(int, max_scanlines))) | 1391 | PRIVATE FUNC(void, call_6502, (P(ASAP_State PTR, ast), P(int, addr), P(int, max_scanlines))) |
@@ -1562,18 +1602,14 @@ PRIVATE FUNC(void, serialize_int, (P(BYTEARRAY, buffer), P(int, offset), P(int, | |||
1562 | buffer[offset + 3] = TO_BYTE(value >> 24); | 1602 | buffer[offset + 3] = TO_BYTE(value >> 24); |
1563 | } | 1603 | } |
1564 | 1604 | ||
1565 | FUNC(void, ASAP_GetWavHeaderForPart, ( | 1605 | FUNC(void, ASAP_GetWavHeader, ( |
1566 | P(CONST ASAP_State PTR, ast), P(BYTEARRAY, buffer), | 1606 | P(CONST ASAP_State PTR, ast), P(BYTEARRAY, buffer), P(ASAP_SampleFormat, format))) |
1567 | P(ASAP_SampleFormat, format), P(int, blocks))) | ||
1568 | { | 1607 | { |
1569 | V(int, use_16bit) = format != ASAP_FORMAT_U8 ? 1 : 0; | 1608 | V(int, use_16bit) = format != ASAP_FORMAT_U8 ? 1 : 0; |
1570 | V(int, block_size) = ast _ module_info.channels << use_16bit; | 1609 | V(int, block_size) = ast _ module_info.channels << use_16bit; |
1571 | V(int, bytes_per_second) = ASAP_SAMPLE_RATE * block_size; | 1610 | V(int, bytes_per_second) = ASAP_SAMPLE_RATE * block_size; |
1572 | V(int, remaining_blocks) = milliseconds_to_blocks(ast _ current_duration) - ast _ blocks_played; | 1611 | V(int, total_blocks) = milliseconds_to_blocks(ast _ current_duration); |
1573 | V(int, n_bytes); | 1612 | V(int, n_bytes) = (total_blocks - ast _ blocks_played) * block_size; |
1574 | if (blocks > remaining_blocks) | ||
1575 | blocks = remaining_blocks; | ||
1576 | n_bytes = blocks * block_size; | ||
1577 | buffer[0] = CAST(byte) CHARCODE('R'); | 1613 | buffer[0] = CAST(byte) CHARCODE('R'); |
1578 | buffer[1] = CAST(byte) CHARCODE('I'); | 1614 | buffer[1] = CAST(byte) CHARCODE('I'); |
1579 | buffer[2] = CAST(byte) CHARCODE('F'); | 1615 | buffer[2] = CAST(byte) CHARCODE('F'); |
@@ -1608,13 +1644,6 @@ FUNC(void, ASAP_GetWavHeaderForPart, ( | |||
1608 | serialize_int(buffer, 40, n_bytes); | 1644 | serialize_int(buffer, 40, n_bytes); |
1609 | } | 1645 | } |
1610 | 1646 | ||
1611 | FUNC(void, ASAP_GetWavHeader, ( | ||
1612 | P(CONST ASAP_State PTR, ast), P(BYTEARRAY, buffer), P(ASAP_SampleFormat, format))) | ||
1613 | { | ||
1614 | V(int, remaining_blocks) = milliseconds_to_blocks(ast _ current_duration) - ast _ blocks_played; | ||
1615 | ASAP_GetWavHeaderForPart(ast, buffer, format, remaining_blocks); | ||
1616 | } | ||
1617 | |||
1618 | #endif /* ACTIONSCRIPT */ | 1647 | #endif /* ACTIONSCRIPT */ |
1619 | 1648 | ||
1620 | PRIVATE FUNC(int, ASAP_GenerateAt, (P(ASAP_State PTR, ast), P(VOIDPTR, buffer), P(int, buffer_offset), P(int, buffer_len), P(ASAP_SampleFormat, format))) | 1649 | PRIVATE FUNC(int, ASAP_GenerateAt, (P(ASAP_State PTR, ast), P(VOIDPTR, buffer), P(int, buffer_offset), P(int, buffer_len), P(ASAP_SampleFormat, format))) |
@@ -1650,7 +1679,15 @@ FUNC(int, ASAP_Generate, (P(ASAP_State PTR, ast), P(VOIDPTR, buffer), P(int, buf | |||
1650 | return ASAP_GenerateAt(ast, buffer, 0, buffer_len, format); | 1679 | return ASAP_GenerateAt(ast, buffer, 0, buffer_len, format); |
1651 | } | 1680 | } |
1652 | 1681 | ||
1653 | #if defined(C) && !defined(ASAP_ONLY_SAP) | 1682 | #endif /* ASAP_ONLY_INFO */ |
1683 | |||
1684 | #ifdef C | ||
1685 | |||
1686 | abool ASAP_CanSetModuleInfo(const char *filename) | ||
1687 | { | ||
1688 | int ext = get_packed_ext(filename); | ||
1689 | return ext == ASAP_EXT('S', 'A', 'P'); | ||
1690 | } | ||
1654 | 1691 | ||
1655 | abool ASAP_ChangeExt(char *filename, const char *ext) | 1692 | abool ASAP_ChangeExt(char *filename, const char *ext) |
1656 | { | 1693 | { |
@@ -1668,12 +1705,6 @@ abool ASAP_ChangeExt(char *filename, const char *ext) | |||
1668 | return TRUE; | 1705 | return TRUE; |
1669 | } | 1706 | } |
1670 | 1707 | ||
1671 | abool ASAP_CanSetModuleInfo(const char *filename) | ||
1672 | { | ||
1673 | int ext = get_packed_ext(filename); | ||
1674 | return ext == ASAP_EXT('S', 'A', 'P'); | ||
1675 | } | ||
1676 | |||
1677 | static byte *put_string(byte *dest, const char *str) | 1708 | static byte *put_string(byte *dest, const char *str) |
1678 | { | 1709 | { |
1679 | while (*str != '\0') | 1710 | while (*str != '\0') |
@@ -1717,21 +1748,6 @@ static byte *put_dec_tag(byte *dest, const char *tag, int value) | |||
1717 | return dest; | 1748 | return dest; |
1718 | } | 1749 | } |
1719 | 1750 | ||
1720 | static byte *put_hex_tag(byte *dest, const char *tag, int value) | ||
1721 | { | ||
1722 | int i; | ||
1723 | if (value < 0) | ||
1724 | return dest; | ||
1725 | dest = put_string(dest, tag); | ||
1726 | for (i = 12; i >= 0; i -= 4) { | ||
1727 | int digit = (value >> i) & 0xf; | ||
1728 | *dest++ = (byte) (digit + (digit < 10 ? '0' : 'A' - 10)); | ||
1729 | } | ||
1730 | *dest++ = '\r'; | ||
1731 | *dest++ = '\n'; | ||
1732 | return dest; | ||
1733 | } | ||
1734 | |||
1735 | static byte *start_sap_header(byte *dest, const ASAP_ModuleInfo *module_info) | 1751 | static byte *start_sap_header(byte *dest, const ASAP_ModuleInfo *module_info) |
1736 | { | 1752 | { |
1737 | dest = put_string(dest, "SAP\r\n"); | 1753 | dest = put_string(dest, "SAP\r\n"); |
@@ -1798,24 +1814,6 @@ static byte *put_durations(byte *dest, const ASAP_ModuleInfo *module_info) | |||
1798 | return dest; | 1814 | return dest; |
1799 | } | 1815 | } |
1800 | 1816 | ||
1801 | static byte *put_sap_header(byte *dest, const ASAP_ModuleInfo *module_info, char type, int music, int init, int player) | ||
1802 | { | ||
1803 | dest = start_sap_header(dest, module_info); | ||
1804 | if (dest == NULL) | ||
1805 | return NULL; | ||
1806 | dest = put_string(dest, "TYPE "); | ||
1807 | *dest++ = type; | ||
1808 | *dest++ = '\r'; | ||
1809 | *dest++ = '\n'; | ||
1810 | if (module_info->fastplay != 312) | ||
1811 | dest = put_dec_tag(dest, "FASTPLAY ", module_info->fastplay); | ||
1812 | dest = put_hex_tag(dest, "MUSIC ", music); | ||
1813 | dest = put_hex_tag(dest, "INIT ", init); | ||
1814 | dest = put_hex_tag(dest, "PLAYER ", player); | ||
1815 | dest = put_durations(dest, module_info); | ||
1816 | return dest; | ||
1817 | } | ||
1818 | |||
1819 | int ASAP_SetModuleInfo(const ASAP_ModuleInfo *module_info, const BYTEARRAY module, int module_len, BYTEARRAY out_module) | 1817 | int ASAP_SetModuleInfo(const ASAP_ModuleInfo *module_info, const BYTEARRAY module, int module_len, BYTEARRAY out_module) |
1820 | { | 1818 | { |
1821 | byte *dest; | 1819 | byte *dest; |
@@ -1851,6 +1849,8 @@ int ASAP_SetModuleInfo(const ASAP_ModuleInfo *module_info, const BYTEARRAY modul | |||
1851 | return dest - out_module; | 1849 | return dest - out_module; |
1852 | } | 1850 | } |
1853 | 1851 | ||
1852 | #if !defined(ASAP_ONLY_SAP) && !defined(ASAP_ONLY_INFO) | ||
1853 | |||
1854 | #define RMT_INIT 0x0c80 | 1854 | #define RMT_INIT 0x0c80 |
1855 | #define TM2_INIT 0x1080 | 1855 | #define TM2_INIT 0x1080 |
1856 | 1856 | ||
@@ -1903,6 +1903,39 @@ const char *ASAP_CanConvert( | |||
1903 | return NULL; | 1903 | return NULL; |
1904 | } | 1904 | } |
1905 | 1905 | ||
1906 | static byte *put_hex_tag(byte *dest, const char *tag, int value) | ||
1907 | { | ||
1908 | int i; | ||
1909 | if (value < 0) | ||
1910 | return dest; | ||
1911 | dest = put_string(dest, tag); | ||
1912 | for (i = 12; i >= 0; i -= 4) { | ||
1913 | int digit = (value >> i) & 0xf; | ||
1914 | *dest++ = (byte) (digit + (digit < 10 ? '0' : 'A' - 10)); | ||
1915 | } | ||
1916 | *dest++ = '\r'; | ||
1917 | *dest++ = '\n'; | ||
1918 | return dest; | ||
1919 | } | ||
1920 | |||
1921 | static byte *put_sap_header(byte *dest, const ASAP_ModuleInfo *module_info, char type, int music, int init, int player) | ||
1922 | { | ||
1923 | dest = start_sap_header(dest, module_info); | ||
1924 | if (dest == NULL) | ||
1925 | return NULL; | ||
1926 | dest = put_string(dest, "TYPE "); | ||
1927 | *dest++ = type; | ||
1928 | *dest++ = '\r'; | ||
1929 | *dest++ = '\n'; | ||
1930 | if (module_info->fastplay != 312) | ||
1931 | dest = put_dec_tag(dest, "FASTPLAY ", module_info->fastplay); | ||
1932 | dest = put_hex_tag(dest, "MUSIC ", music); | ||
1933 | dest = put_hex_tag(dest, "INIT ", init); | ||
1934 | dest = put_hex_tag(dest, "PLAYER ", player); | ||
1935 | dest = put_durations(dest, module_info); | ||
1936 | return dest; | ||
1937 | } | ||
1938 | |||
1906 | int ASAP_Convert( | 1939 | int ASAP_Convert( |
1907 | const char *filename, const ASAP_ModuleInfo *module_info, | 1940 | const char *filename, const ASAP_ModuleInfo *module_info, |
1908 | const BYTEARRAY module, int module_len, BYTEARRAY out_module) | 1941 | const BYTEARRAY module, int module_len, BYTEARRAY out_module) |
@@ -2203,4 +2236,32 @@ int ASAP_Convert( | |||
2203 | } | 2236 | } |
2204 | } | 2237 | } |
2205 | 2238 | ||
2206 | #endif /* defined(C) && !defined(ASAP_ONLY_SAP) */ | 2239 | #endif /* !defined(ASAP_ONLY_SAP) && !defined(ASAP_ONLY_INFO) */ |
2240 | |||
2241 | static abool has_two_digits(const char *s) | ||
2242 | { | ||
2243 | return s[0] >= '0' && s[0] <= '9' && s[1] >= '0' && s[1] <= '9'; | ||
2244 | } | ||
2245 | |||
2246 | /* "DD/MM/YYYY", "MM/YYYY", "YYYY" -> "YYYY" */ | ||
2247 | abool ASAP_DateToYear(const char *date, char *year) | ||
2248 | { | ||
2249 | if (!has_two_digits(date)) | ||
2250 | return FALSE; | ||
2251 | if (date[2] == '/') { | ||
2252 | date += 3; | ||
2253 | if (!has_two_digits(date)) | ||
2254 | return FALSE; | ||
2255 | if (date[2] == '/') { | ||
2256 | date += 3; | ||
2257 | if (!has_two_digits(date)) | ||
2258 | return FALSE; | ||
2259 | } | ||
2260 | } | ||
2261 | if (!has_two_digits(date + 2) || date[4] != '\0') | ||
2262 | return FALSE; | ||
2263 | memcpy(year, date, 5); | ||
2264 | return TRUE; | ||
2265 | } | ||
2266 | |||
2267 | #endif /* C */ | ||