From 23cf4ad82fdfcc2002ec98ccc7588f9db7d0f523 Mon Sep 17 00:00:00 2001 From: Dominik Wenger Date: Mon, 8 Nov 2010 20:25:14 +0000 Subject: update the asap codec to version 2.1.2 git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28535 a1c6a512-1295-4272-9138-f99709370657 --- apps/codecs/libasap/README | 14 ++- apps/codecs/libasap/README.rockbox | 5 +- apps/codecs/libasap/acpu.c | 91 +++++++--------- apps/codecs/libasap/anylang.h | 2 +- apps/codecs/libasap/apokeysnd.c | 7 +- apps/codecs/libasap/asap.c | 207 +++++++++++++++++++++++------------- apps/codecs/libasap/asap.h | 8 +- apps/codecs/libasap/asap_internal.h | 5 +- 8 files changed, 198 insertions(+), 141 deletions(-) diff --git a/apps/codecs/libasap/README b/apps/codecs/libasap/README index 4da0aa7b90..d4fbfe6297 100644 --- a/apps/codecs/libasap/README +++ b/apps/codecs/libasap/README @@ -22,8 +22,9 @@ but the current version has a completely new original emulation core. ASAP includes the following programs: - asapconv - portable command-line converter {asapwin=} -- WASAP - tiny player for Windows {asapwin=} +- WASAP - tiny player for Windows {asapwin=}{asapwince=} - plugin for http://koti.welho.com/hylinen/apollo/[Apollo] {asapwin=} +- plugin for http://audacious-media-player.org/[Audacious] - plugin for http://foobar2000.org/[foobar2000] {asapwin=} - plugin for http://hp.vector.co.jp/authors/VA032810/[GSPlayer] {asapwin=}{asapwince=} - plugin for http://moc.daper.net/[MOC] @@ -31,15 +32,20 @@ ASAP includes the following programs: - plugin for http://www.microsoft.com/windows/windowsmedia/player/[Windows Media Player] {asapwin=} - plugin for http://xbmc.org/[XBMC] {asapwin=} - plugin for http://xmms.org/[XMMS] -- plugin for http://www.un4seen.com/[XMPlay] {asapwin=} +- plugin for http://www.un4seen.com/xmplay.html[XMPlay] {asapwin=} +- add-on for http://www.un4seen.com/bass.html[BASS] (for http://www.aimp.ru/[AIMP] and http://www.un4seen.com/bass_showcase.php[other players]) {asapwin=} - POKEY sound emulation DLL for http://raster.infos.cz/atari/rmt/rmt.htm[Raster Music Tracker] {asapwin=} +- Windows Explorer extension - shows metadata {asapwin=} - Java version of ASAP2WAV - command-line converter to WAV files {asapjava=} - Java applet - for web pages {asapjava=}{asapwww?(see link:applet.html[online demo])} - Java midlet - for mobile devices {asapjava=} - C# version of ASAP2WAV -- experimental JScript version of ASAP2WAV running in Windows Script Host {asapjavascript=} +- JavaScript version of ASAP2WAV running in http://en.wikipedia.org/wiki/Windows_Script_Host[Windows Script Host], https://developer.mozilla.org/en/Rhino_Shell[Rhino Shell], http://code.google.com/p/v8/[V8 Shell], http://en.wikipedia.org/wiki/JScript_.NET[JScript .NET] and http://en.wikipedia.org/wiki/JaegerMonkey[JaegerMonkey] {asapjavascript=} - experimental JavaScript version of ASAP2WAV running in Firefox {asapjavascript=} - Flash player - for web pages {asapflash=}{asapwww?(see link:flash.html[online demo])} +- asapplay - simple command-line player in C# +- http://www.silverlight.net/[Silverlight] player - for web pages {asapwww?(see link:silverlight.html[online demo])} +- AndroidASAP - for mobile devices {asapports}The summary of the differences between the above versions is in link:PORTS.xml[this table]. @@ -117,7 +123,7 @@ include::win32/USAGE[] endif::asapwin[] ifdef::asapwince[] -include::gsplayer/USAGE[] +include::win32/wince/USAGE[] endif::asapwince[] include::NEWS[] diff --git a/apps/codecs/libasap/README.rockbox b/apps/codecs/libasap/README.rockbox index 6ea47e9639..62184822d4 100644 --- a/apps/codecs/libasap/README.rockbox +++ b/apps/codecs/libasap/README.rockbox @@ -1,5 +1,6 @@ -Library: asap-2.1.0 +Library: asap-2.1.2 Imported: 2010-02-02 by Dominik Wenger +Updated: 2010-08-11 by Dominik Wenger This directory contains a local version of asap (http://asap.sourceforge.net/) for decoding Atari 8bit .sap audio streams. @@ -13,7 +14,7 @@ The Licence is the same as the rest of Rockbox. IMPORT DETAILS -The .[ch] files in apps/codec/asap are copied from ASAP. +The .[ch] files in apps/codec/libasap are copied from ASAP. players.h (contains binarys of players) was generated and copied into Rockbox. diff --git a/apps/codecs/libasap/acpu.c b/apps/codecs/libasap/acpu.c index c5bff47a5d..0e91f9083a 100644 --- a/apps/codecs/libasap/acpu.c +++ b/apps/codecs/libasap/acpu.c @@ -1,7 +1,7 @@ /* * acpu.c - another 6502 CPU emulator * - * Copyright (C) 2007-2009 Piotr Fusik + * Copyright (C) 2007-2010 Piotr Fusik * * This file is part of ASAP (Another Slight Atari Player), * see http://asap.sourceforge.net @@ -77,10 +77,8 @@ END_CONST_ARRAY; { \ /* binary mode */ \ V(int, tmp) = a + data + c; \ + vdi = (vdi & (D_FLAG | I_FLAG)) + (((~(data ^ a) & (a ^ tmp)) >> 1) & V_FLAG); \ c = tmp >> 8; \ - vdi &= D_FLAG | I_FLAG; \ - if (((a ^ data) & 0x80) == 0 && ((data ^ tmp) & 0x80) != 0) \ - vdi += V_FLAG; \ nz = a = tmp & 0xff; \ } @@ -88,68 +86,55 @@ END_CONST_ARRAY; { \ /* binary mode */ \ V(int, tmp) = a - data - 1 + c; \ + vdi = (vdi & (D_FLAG | I_FLAG)) + ((((data ^ a) & (a ^ tmp)) >> 1) & V_FLAG); \ c = (tmp >= 0) ? 1 : 0; \ - vdi &= D_FLAG | I_FLAG; \ - if (((a ^ tmp) & 0x80) != 0 && ((a ^ data) & 0x80) != 0) \ - vdi += V_FLAG; \ nz = a = tmp & 0xff; \ } #else /* ACPU_NO_DECIMAL */ #define DO_ADC \ - if ((vdi & D_FLAG) == 0) { \ - /* binary mode */ \ + { \ V(int, tmp) = a + data + c; \ - c = tmp >> 8; \ - vdi &= D_FLAG | I_FLAG; \ - if (((a ^ data) & 0x80) == 0 && ((data ^ tmp) & 0x80) != 0) \ - vdi += V_FLAG; \ - nz = a = tmp & 0xff; \ - } \ - else { \ - /* decimal mode */ \ - V(int, tmp) = (a & 0x0f) + (data & 0x0f) + c; \ - if (tmp >= 10) \ - tmp = (tmp - 10) | 0x10; \ - tmp += (a & 0xf0) + (data & 0xf0); \ - nz = ((tmp & 0x80) << 1) + ((a + data + c) & 0xff); \ - vdi &= D_FLAG | I_FLAG; \ - if (((a ^ data) & 0x80) == 0 && ((data ^ tmp) & 0x80) != 0) \ - vdi += V_FLAG; \ - if (tmp > 0x9f) \ - tmp += 0x60; \ - c = (tmp > 0xff) ? 1 : 0; \ - a = tmp & 0xff; \ + nz = tmp & 0xff; \ + if ((vdi & D_FLAG) == 0) { \ + /* binary mode */ \ + vdi = (vdi & (D_FLAG | I_FLAG)) + (((~(data ^ a) & (a ^ tmp)) >> 1) & V_FLAG); \ + c = tmp >> 8; \ + a = nz; \ + } \ + else { \ + /* decimal mode */ \ + V(int, al) = (a & 0x0f) + (data & 0x0f) + c; \ + if (al >= 10) \ + tmp += (al < 26) ? 6 : -10; \ + nz = ((tmp & 0x80) << 1) + (nz != 0 ? 1 : 0); \ + vdi = (vdi & (D_FLAG | I_FLAG)) + (((~(data ^ a) & (a ^ tmp)) >> 1) & V_FLAG); \ + if (tmp >= 0xa0) { \ + c = 1; \ + a = (tmp + 0x60) & 0xff; \ + } \ + else { \ + c = 0; \ + a = tmp; \ + } \ + } \ } #define DO_SBC \ - if ((vdi & D_FLAG) == 0) { \ - /* binary mode */ \ + {\ V(int, tmp) = a - data - 1 + c; \ + V(int, al) = (a & 0x0f) - (data & 0x0f) - 1 + c; \ + vdi = (vdi & (D_FLAG | I_FLAG)) + ((((data ^ a) & (a ^ tmp)) >> 1) & V_FLAG); \ c = (tmp >= 0) ? 1 : 0; \ - vdi &= D_FLAG | I_FLAG; \ - if (((a ^ tmp) & 0x80) != 0 && ((a ^ data) & 0x80) != 0) \ - vdi += V_FLAG; \ nz = a = tmp & 0xff; \ - } \ - else { \ - /* decimal mode */ \ - V(int, tmp) = a - data - 1 + c; \ - V(int, al) = (a & 0x0f) - (data & 0x0f) - 1 + c; \ - V(int, ah) = (a >> 4) - (data >> 4); \ - if ((al & 0x10) != 0) { \ - al -= 6; \ - ah--; \ + if ((vdi & D_FLAG) != 0) { \ + /* decimal mode */ \ + if (al < 0) \ + a += (al < -10) ? 10 : -6; \ + if (c == 0) \ + a = (a - 0x60) & 0xff; \ } \ - if ((ah & 0x10) != 0) \ - ah -= 6; \ - c = tmp >= 0 ? 1 : 0; \ - vdi &= D_FLAG | I_FLAG; \ - if (((a ^ tmp) & 0x80) != 0 && ((a ^ data) & 0x80) != 0) \ - vdi += V_FLAG; \ - nz = tmp & 0xff; \ - a = ((ah & 0xf) << 4) + (al & 0x0f); \ } #endif /* ACPU_NO_DECIMAL */ @@ -301,7 +286,7 @@ FUNC(void, Cpu_RunScanlines, (P(ASAP_State PTR, ast), P(int, scanlines))) cycle = ast _ cycle; if (cycle >= ast _ nearest_event_cycle) { if (cycle >= ast _ next_scanline_cycle) { - if (++ast _ scanline_number == 312) + if (++ast _ scanline_number == (ast _ module_info.ntsc ? 262 : 312)) ast _ scanline_number = 0; ast _ cycle = cycle += 9; ast _ next_scanline_cycle += 114; @@ -352,7 +337,7 @@ FUNC(void, Cpu_RunScanlines, (P(ASAP_State PTR, ast), P(int, scanlines))) case 0xb2: case 0xd2: case 0xf2: - ast _ scanline_number = (ast _ scanline_number + scanlines - 1) % 312; + ast _ scanline_number = (ast _ scanline_number + scanlines - 1) % (ast _ module_info.ntsc ? 262 : 312); scanlines = 1; ast _ cycle = cycle_limit; break; diff --git a/apps/codecs/libasap/anylang.h b/apps/codecs/libasap/anylang.h index 4d955d6026..e56dfbae0e 100644 --- a/apps/codecs/libasap/anylang.h +++ b/apps/codecs/libasap/anylang.h @@ -156,7 +156,7 @@ #define EMPTY_STRING(s) (s) = string.Empty #define SUBSTR(s, i) (s).Substring(i) #define BYTES_TO_STRING(dest, src, src_offset, len) \ - (dest) = System.Text.Encoding.ASCII.GetString(src, src_offset, len) + (dest) = System.Text.Encoding.UTF8.GetString(src, src_offset, len) #define SUBSTRING(dest, src, src_offset, len) \ (dest) = (src).Substring(src_offset, len) diff --git a/apps/codecs/libasap/apokeysnd.c b/apps/codecs/libasap/apokeysnd.c index ead611be5f..811e2f9b4a 100644 --- a/apps/codecs/libasap/apokeysnd.c +++ b/apps/codecs/libasap/apokeysnd.c @@ -1,7 +1,7 @@ /* * apokeysnd.c - another POKEY sound emulator * - * Copyright (C) 2007-2009 Piotr Fusik + * Copyright (C) 2007-2010 Piotr Fusik * * This file is part of ASAP (Another Slight Atari Player), * see http://asap.sourceforge.net @@ -469,13 +469,14 @@ FUNC(void, PokeySound_StartFrame, (P(ASAP_State PTR, ast))) FUNC(void, PokeySound_EndFrame, (P(ASAP_State PTR, ast), P(int, current_cycle))) { + V(int, clk) = ASAP_MAIN_CLOCK(ast); end_frame(ast, ADDRESSOF ast _ base_pokey, current_cycle); if (ast _ extra_pokey_mask != 0) end_frame(ast, ADDRESSOF ast _ extra_pokey, current_cycle); ast _ sample_offset += current_cycle * ASAP_SAMPLE_RATE; ast _ sample_index = 0; - ast _ samples = TO_INT(ast _ sample_offset / ASAP_MAIN_CLOCK); - ast _ sample_offset %= ASAP_MAIN_CLOCK; + ast _ samples = TO_INT(ast _ sample_offset / clk); + ast _ sample_offset %= clk; } /* Fills buffer with samples from delta_buffer. */ 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 @@ #include "asap_internal.h" +#ifdef ASAP_ONLY_INFO + +#define GET_PLAYER(name) NULL + +#else + +#define GET_PLAYER(name) GET_RESOURCE(name, obx) + FUNC(int, ASAP_GetByte, (P(ASAP_State PTR, ast), P(int, addr))) { - switch (addr & 0xff0f) { + switch (addr & 0xff1f) { + case 0xd014: + return ast _ module_info.ntsc ? 0xf : 1; case 0xd20a: + case 0xd21a: return PokeySound_GetRandom(ast, addr, ast _ cycle); case 0xd20e: - if ((addr & ast _ extra_pokey_mask) != 0) { + return ast _ irqst; + case 0xd21e: + if (ast _ extra_pokey_mask != 0) { /* interrupts in the extra POKEY not emulated at the moment */ return 0xff; } return ast _ irqst; - case 0xd20f: - /* just because some SAP files rely on this */ + case 0xd20c: + case 0xd21c: + case 0xd20f: /* just because some SAP files rely on this */ + case 0xd21f: return 0xff; case 0xd40b: + case 0xd41b: return ast _ scanline_number >> 1; default: return dGetByte(addr); @@ -99,10 +115,14 @@ FUNC(void, ASAP_PutByte, (P(ASAP_State PTR, ast), P(int, addr), P(int, data))) dPutByte(addr, data); } +#endif /* ASAP_ONLY_INFO */ + #define UWORD(array, index) (UBYTE(array[index]) + (UBYTE(array[(index) + 1]) << 8)) #ifndef ASAP_ONLY_SAP +#ifndef ASAP_ONLY_INFO + #ifndef JAVA #include "players.h" #endif @@ -117,6 +137,8 @@ CONST_ARRAY(byte, cmr_bass_table) 0x25, 0x24, 0x21, 0x1F, 0x1E END_CONST_ARRAY; +#endif /* ASAP_ONLY_INFO */ + CONST_ARRAY(int, perframe2fastplay) 312, 312 / 2, 312 / 3, 312 / 4 END_CONST_ARRAY; @@ -126,17 +148,21 @@ PRIVATE FUNC(abool, load_native, ( P(ASAP_State PTR, ast), P(ASAP_ModuleInfo PTR, module_info), P(CONST BYTEARRAY, module), P(int, module_len), P(RESOURCE, player))) { +#ifndef ASAP_ONLY_INFO V(int, player_last_byte); +#endif V(int, music_last_byte); V(int, block_len); if ((UBYTE(module[0]) != 0xff || UBYTE(module[1]) != 0xff) && (module[0] != 0 || module[1] != 0)) /* some CMC and clones start with zeros */ return FALSE; + module_info _ music = UWORD(module, 2); +#ifndef ASAP_ONLY_INFO module_info _ player = UWORD(player, 2); player_last_byte = UWORD(player, 4); - module_info _ music = UWORD(module, 2); if (module_info _ music <= player_last_byte) return FALSE; +#endif music_last_byte = UWORD(module, 4); if (module_info _ music <= 0xd7ff && music_last_byte >= 0xd000) return FALSE; @@ -154,10 +180,12 @@ PRIVATE FUNC(abool, load_native, ( if (10 + block_len + info_len != module_len) return FALSE; } +#ifndef ASAP_ONLY_INFO if (ast != NULL) { COPY_ARRAY(ast _ memory, module_info _ music, module, 6, block_len); COPY_ARRAY(ast _ memory, module_info _ player, player, 6, player_last_byte + 1 - module_info _ player); } +#endif return TRUE; } @@ -256,8 +284,10 @@ PRIVATE FUNC(abool, parse_cmc, ( module_info _ type = type; if (!load_native(ast, module_info, module, module_len, player)) return FALSE; +#ifndef ASAP_ONLY_INFO if (ast != NULL && type == ASAP_TYPE_CMR) COPY_ARRAY(ast _ memory, 0x500 + CMR_BASS_TABLE_OFFSET, cmr_bass_table, 0, sizeof(cmr_bass_table)); +#endif last_pos = 0x54; while (--last_pos >= 0) { if (UBYTE(module[0x206 + last_pos]) < 0xb0 @@ -351,7 +381,7 @@ PRIVATE FUNC(abool, parse_dlt, ( else if (module_len != 0x2c07) return FALSE; module_info _ type = ASAP_TYPE_DLT; - if (!load_native(ast, module_info, module, module_len, GET_RESOURCE(dlt, obx)) + if (!load_native(ast, module_info, module, module_len, GET_PLAYER(dlt)) || module_info _ music != 0x2000) { return FALSE; } @@ -452,7 +482,7 @@ PRIVATE FUNC(abool, parse_mpt, ( if (module_len < 0x1d0) return FALSE; module_info _ type = ASAP_TYPE_MPT; - if (!load_native(ast, module_info, module, module_len, GET_RESOURCE(mpt, obx))) + if (!load_native(ast, module_info, module, module_len, GET_PLAYER(mpt))) return FALSE; track0_addr = UWORD(module, 2) + 0x1ca; if (UBYTE(module[0x1c6]) + (UBYTE(module[0x1ca]) << 8) != track0_addr) @@ -689,7 +719,7 @@ PRIVATE FUNC(abool, parse_rmt, ( return FALSE; module_info _ type = ASAP_TYPE_RMT; if (!load_native(ast, module_info, module, module_len, - module_info _ channels == 2 ? GET_RESOURCE(rmt8, obx) : GET_RESOURCE(rmt4, obx))) + module_info _ channels == 2 ? GET_PLAYER(rmt8) : GET_PLAYER(rmt4))) return FALSE; song_len = UWORD(module, 4) + 1 - UWORD(module, 0x14); if (pos_shift == 3 && (song_len & 4) != 0 @@ -781,7 +811,7 @@ PRIVATE FUNC(abool, parse_tmc, ( if (module_len < 0x1d0) return FALSE; module_info _ type = ASAP_TYPE_TMC; - if (!load_native(ast, module_info, module, module_len, GET_RESOURCE(tmc, obx))) + if (!load_native(ast, module_info, module, module_len, GET_PLAYER(tmc))) return FALSE; module_info _ channels = 2; i = 0; @@ -899,7 +929,7 @@ PRIVATE FUNC(abool, parse_tm2, ( if (module_len < 0x3a4) return FALSE; module_info _ type = ASAP_TYPE_TM2; - if (!load_native(ast, module_info, module, module_len, GET_RESOURCE(tm2, obx))) + if (!load_native(ast, module_info, module, module_len, GET_PLAYER(tm2))) return FALSE; i = module[0x25]; if (i < 1 || i > 4) @@ -1064,6 +1094,7 @@ PRIVATE FUNC(abool, parse_sap_header, ( V(int, duration_index) = 0; if (!has_string_at(module, 0, "SAP\r\n")) return FALSE; + module_info _ fastplay = -1; module_index = 5; while (UBYTE(module[module_index]) != 0xff) { if (module_index + 8 >= module_len) @@ -1093,6 +1124,8 @@ PRIVATE FUNC(abool, parse_sap_header, ( } else if (TAG_IS("STEREO\r")) module_info _ channels = 2; + else if (TAG_IS("NTSC\r")) + module_info _ ntsc = TRUE; else if (TAG_IS("TIME ")) { V(int, i); #ifdef C @@ -1101,7 +1134,7 @@ PRIVATE FUNC(abool, parse_sap_header, ( V(STRING, s); #endif module_index += 5; - for (i = 0; module[module_index + i] != 0xd; i++); + for (i = 0; module[module_index + i] != 0xd; i++) { } if (i > 5 && has_string_at(module, module_index + i - 5, " LOOP")) { module_info _ loops[duration_index] = TRUE; i -= 5; @@ -1171,6 +1204,10 @@ PRIVATE FUNC(abool, parse_sap_header, ( default: return FALSE; } + if (module_info _ fastplay < 0) + module_info _ fastplay = module_info _ ntsc ? 262 : 312; + else if (module_info _ ntsc && module_info _ fastplay > 262) + return FALSE; if (UBYTE(module[module_index + 1]) != 0xff) return FALSE; module_info _ header_len = module_index; @@ -1287,6 +1324,7 @@ PRIVATE FUNC(abool, parse_file, ( module_info _ durations[i] = -1; module_info _ loops[i] = FALSE; } + module_info _ ntsc = FALSE; module_info _ fastplay = 312; module_info _ music = -1; module_info _ init = -1; @@ -1297,17 +1335,17 @@ PRIVATE FUNC(abool, parse_file, ( return parse_sap(ast, module_info, module, module_len); #ifndef ASAP_ONLY_SAP case ASAP_EXT('C', 'M', 'C'): - return parse_cmc(ast, module_info, module, module_len, ASAP_TYPE_CMC, GET_RESOURCE(cmc, obx)); + return parse_cmc(ast, module_info, module, module_len, ASAP_TYPE_CMC, GET_PLAYER(cmc)); case ASAP_EXT('C', 'M', '3'): - return parse_cmc(ast, module_info, module, module_len, ASAP_TYPE_CM3, GET_RESOURCE(cm3, obx)); + return parse_cmc(ast, module_info, module, module_len, ASAP_TYPE_CM3, GET_PLAYER(cm3)); case ASAP_EXT('C', 'M', 'R'): - return parse_cmc(ast, module_info, module, module_len, ASAP_TYPE_CMR, GET_RESOURCE(cmc, obx)); + return parse_cmc(ast, module_info, module, module_len, ASAP_TYPE_CMR, GET_PLAYER(cmc)); case ASAP_EXT('C', 'M', 'S'): module_info _ channels = 2; - return parse_cmc(ast, module_info, module, module_len, ASAP_TYPE_CMS, GET_RESOURCE(cms, obx)); + return parse_cmc(ast, module_info, module, module_len, ASAP_TYPE_CMS, GET_PLAYER(cms)); case ASAP_EXT('D', 'M', 'C'): module_info _ fastplay = 156; - return parse_cmc(ast, module_info, module, module_len, ASAP_TYPE_CMC, GET_RESOURCE(cmc, obx)); + return parse_cmc(ast, module_info, module, module_len, ASAP_TYPE_CMC, GET_PLAYER(cmc)); case ASAP_EXT('D', 'L', 'T'): return parse_dlt(ast, module_info, module, module_len); case ASAP_EXT('M', 'P', 'T'): @@ -1335,6 +1373,8 @@ FUNC(abool, ASAP_GetModuleInfo, ( return parse_file(NULL, module_info, filename, module, module_len); } +#ifndef ASAP_ONLY_INFO + FUNC(abool, ASAP_Load, ( P(ASAP_State PTR, ast), P(STRING, filename), P(CONST BYTEARRAY, module), P(int, module_len))) @@ -1345,7 +1385,7 @@ FUNC(abool, ASAP_Load, ( FUNC(void, ASAP_DetectSilence, (P(ASAP_State PTR, ast), P(int, seconds))) { - ast _ silence_cycles = seconds * ASAP_MAIN_CLOCK; + ast _ silence_cycles = seconds * ASAP_MAIN_CLOCK(ast); } 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, buffer[offset + 3] = TO_BYTE(value >> 24); } -FUNC(void, ASAP_GetWavHeaderForPart, ( - P(CONST ASAP_State PTR, ast), P(BYTEARRAY, buffer), - P(ASAP_SampleFormat, format), P(int, blocks))) +FUNC(void, ASAP_GetWavHeader, ( + P(CONST ASAP_State PTR, ast), P(BYTEARRAY, buffer), P(ASAP_SampleFormat, format))) { V(int, use_16bit) = format != ASAP_FORMAT_U8 ? 1 : 0; V(int, block_size) = ast _ module_info.channels << use_16bit; V(int, bytes_per_second) = ASAP_SAMPLE_RATE * block_size; - V(int, remaining_blocks) = milliseconds_to_blocks(ast _ current_duration) - ast _ blocks_played; - V(int, n_bytes); - if (blocks > remaining_blocks) - blocks = remaining_blocks; - n_bytes = blocks * block_size; + V(int, total_blocks) = milliseconds_to_blocks(ast _ current_duration); + V(int, n_bytes) = (total_blocks - ast _ blocks_played) * block_size; buffer[0] = CAST(byte) CHARCODE('R'); buffer[1] = CAST(byte) CHARCODE('I'); buffer[2] = CAST(byte) CHARCODE('F'); @@ -1608,13 +1644,6 @@ FUNC(void, ASAP_GetWavHeaderForPart, ( serialize_int(buffer, 40, n_bytes); } -FUNC(void, ASAP_GetWavHeader, ( - P(CONST ASAP_State PTR, ast), P(BYTEARRAY, buffer), P(ASAP_SampleFormat, format))) -{ - V(int, remaining_blocks) = milliseconds_to_blocks(ast _ current_duration) - ast _ blocks_played; - ASAP_GetWavHeaderForPart(ast, buffer, format, remaining_blocks); -} - #endif /* ACTIONSCRIPT */ 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 return ASAP_GenerateAt(ast, buffer, 0, buffer_len, format); } -#if defined(C) && !defined(ASAP_ONLY_SAP) +#endif /* ASAP_ONLY_INFO */ + +#ifdef C + +abool ASAP_CanSetModuleInfo(const char *filename) +{ + int ext = get_packed_ext(filename); + return ext == ASAP_EXT('S', 'A', 'P'); +} abool ASAP_ChangeExt(char *filename, const char *ext) { @@ -1668,12 +1705,6 @@ abool ASAP_ChangeExt(char *filename, const char *ext) return TRUE; } -abool ASAP_CanSetModuleInfo(const char *filename) -{ - int ext = get_packed_ext(filename); - return ext == ASAP_EXT('S', 'A', 'P'); -} - static byte *put_string(byte *dest, const char *str) { while (*str != '\0') @@ -1717,21 +1748,6 @@ static byte *put_dec_tag(byte *dest, const char *tag, int value) return dest; } -static byte *put_hex_tag(byte *dest, const char *tag, int value) -{ - int i; - if (value < 0) - return dest; - dest = put_string(dest, tag); - for (i = 12; i >= 0; i -= 4) { - int digit = (value >> i) & 0xf; - *dest++ = (byte) (digit + (digit < 10 ? '0' : 'A' - 10)); - } - *dest++ = '\r'; - *dest++ = '\n'; - return dest; -} - static byte *start_sap_header(byte *dest, const ASAP_ModuleInfo *module_info) { dest = put_string(dest, "SAP\r\n"); @@ -1798,24 +1814,6 @@ static byte *put_durations(byte *dest, const ASAP_ModuleInfo *module_info) return dest; } -static byte *put_sap_header(byte *dest, const ASAP_ModuleInfo *module_info, char type, int music, int init, int player) -{ - dest = start_sap_header(dest, module_info); - if (dest == NULL) - return NULL; - dest = put_string(dest, "TYPE "); - *dest++ = type; - *dest++ = '\r'; - *dest++ = '\n'; - if (module_info->fastplay != 312) - dest = put_dec_tag(dest, "FASTPLAY ", module_info->fastplay); - dest = put_hex_tag(dest, "MUSIC ", music); - dest = put_hex_tag(dest, "INIT ", init); - dest = put_hex_tag(dest, "PLAYER ", player); - dest = put_durations(dest, module_info); - return dest; -} - int ASAP_SetModuleInfo(const ASAP_ModuleInfo *module_info, const BYTEARRAY module, int module_len, BYTEARRAY out_module) { byte *dest; @@ -1851,6 +1849,8 @@ int ASAP_SetModuleInfo(const ASAP_ModuleInfo *module_info, const BYTEARRAY modul return dest - out_module; } +#if !defined(ASAP_ONLY_SAP) && !defined(ASAP_ONLY_INFO) + #define RMT_INIT 0x0c80 #define TM2_INIT 0x1080 @@ -1903,6 +1903,39 @@ const char *ASAP_CanConvert( return NULL; } +static byte *put_hex_tag(byte *dest, const char *tag, int value) +{ + int i; + if (value < 0) + return dest; + dest = put_string(dest, tag); + for (i = 12; i >= 0; i -= 4) { + int digit = (value >> i) & 0xf; + *dest++ = (byte) (digit + (digit < 10 ? '0' : 'A' - 10)); + } + *dest++ = '\r'; + *dest++ = '\n'; + return dest; +} + +static byte *put_sap_header(byte *dest, const ASAP_ModuleInfo *module_info, char type, int music, int init, int player) +{ + dest = start_sap_header(dest, module_info); + if (dest == NULL) + return NULL; + dest = put_string(dest, "TYPE "); + *dest++ = type; + *dest++ = '\r'; + *dest++ = '\n'; + if (module_info->fastplay != 312) + dest = put_dec_tag(dest, "FASTPLAY ", module_info->fastplay); + dest = put_hex_tag(dest, "MUSIC ", music); + dest = put_hex_tag(dest, "INIT ", init); + dest = put_hex_tag(dest, "PLAYER ", player); + dest = put_durations(dest, module_info); + return dest; +} + int ASAP_Convert( const char *filename, const ASAP_ModuleInfo *module_info, const BYTEARRAY module, int module_len, BYTEARRAY out_module) @@ -2203,4 +2236,32 @@ int ASAP_Convert( } } -#endif /* defined(C) && !defined(ASAP_ONLY_SAP) */ +#endif /* !defined(ASAP_ONLY_SAP) && !defined(ASAP_ONLY_INFO) */ + +static abool has_two_digits(const char *s) +{ + return s[0] >= '0' && s[0] <= '9' && s[1] >= '0' && s[1] <= '9'; +} + +/* "DD/MM/YYYY", "MM/YYYY", "YYYY" -> "YYYY" */ +abool ASAP_DateToYear(const char *date, char *year) +{ + if (!has_two_digits(date)) + return FALSE; + if (date[2] == '/') { + date += 3; + if (!has_two_digits(date)) + return FALSE; + if (date[2] == '/') { + date += 3; + if (!has_two_digits(date)) + return FALSE; + } + } + if (!has_two_digits(date + 2) || date[4] != '\0') + return FALSE; + memcpy(year, date, 5); + return TRUE; +} + +#endif /* C */ diff --git a/apps/codecs/libasap/asap.h b/apps/codecs/libasap/asap.h index b43b3ce0c2..0758b60bfb 100644 --- a/apps/codecs/libasap/asap.h +++ b/apps/codecs/libasap/asap.h @@ -31,8 +31,8 @@ extern "C" { /* ASAP version. */ #define ASAP_VERSION_MAJOR 2 #define ASAP_VERSION_MINOR 1 -#define ASAP_VERSION_MICRO 0 -#define ASAP_VERSION "2.1.0" +#define ASAP_VERSION_MICRO 2 +#define ASAP_VERSION "2.1.2" /* Short credits of the ASAP engine. */ #define ASAP_YEARS "2005-2010" @@ -98,6 +98,7 @@ typedef struct { int durations[ASAP_SONGS_MAX]; /* lengths of songs, in milliseconds, -1 = indeterminate */ abool loops[ASAP_SONGS_MAX]; /* whether songs repeat or not */ /* the following technical information should not be used outside ASAP. */ + abool ntsc; int type; int fastplay; int music; @@ -216,6 +217,9 @@ abool ASAP_ChangeExt(char *filename, const char *ext); abool ASAP_GetModuleInfo(ASAP_ModuleInfo *module_info, const char *filename, const byte module[], int module_len); +/* Extracts year from date. */ +abool ASAP_DateToYear(const char *date, char *year); + /* Loads music data. "ast" is the destination structure. "filename" determines file format. diff --git a/apps/codecs/libasap/asap_internal.h b/apps/codecs/libasap/asap_internal.h index 1e38496344..5367085c7e 100644 --- a/apps/codecs/libasap/asap_internal.h +++ b/apps/codecs/libasap/asap_internal.h @@ -76,8 +76,6 @@ void trace_cpu(const ASAP_State *ast, int pc, int a, int x, int y, int s, int nz #endif /* C */ -#define ASAP_MAIN_CLOCK 1773447 - #define V_FLAG 0x40 #define D_FLAG 0x08 #define I_FLAG 0x04 @@ -111,6 +109,7 @@ void trace_cpu(const ASAP_State *ast, int pc, int a, int x, int y, int s, int nz #define PutByte(addr, data) do { if (((addr) & 0xf900) == 0xd000) ASAP_PutByte(ast, addr, data); else dPutByte(addr, data); } while (FALSE) #define RMW_GetByte(dest, addr) do { if (((addr) >> 8) == 0xd2) { dest = ASAP_GetByte(ast, addr); ast _ cycle--; ASAP_PutByte(ast, addr, dest); ast _ cycle++; } else dest = dGetByte(addr); } while (FALSE) -#define CYCLE_TO_SAMPLE(cycle) TO_INT(((cycle) * ASAP_SAMPLE_RATE + ast _ sample_offset) / ASAP_MAIN_CLOCK) +#define ASAP_MAIN_CLOCK(ast) ((ast) _ module_info.ntsc ? 1789772 : 1773447) +#define CYCLE_TO_SAMPLE(cycle) TO_INT(((cycle) * ASAP_SAMPLE_RATE + ast _ sample_offset) / ASAP_MAIN_CLOCK(ast)) #endif /* _ASAP_INTERNAL_H_ */ -- cgit v1.2.3