⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 asap.c

📁 大名鼎鼎的CE下播放软件,TCPPMP的源代码!!!2410下可以流畅的解QVGA的H264,MPEG4等格式.
💻 C
📖 第 1 页 / 共 2 页
字号:
			if (song[j << (2 + sap_stereo)] != 0xfe)				break;			j = song[(j << (2 + sap_stereo)) + 1];		} while (j < song_len && !seen[j]);		song_pos[sap_songs++] = (UBYTE) j;		j++;		while (j < song_len && !seen[j]) {			seen[j] = TRUE;			if (song[j << (2 + sap_stereo)] != 0xfe)				j++;			else				j = song[(j << (2 + sap_stereo)) + 1];		}	}	return sap_songs != 0;}static int load_tmc(const unsigned char *module, unsigned int module_len){	unsigned int i;	if (module_len < 0x1d0)		return FALSE;	if (!load_native(module, module_len, tmc_obx, 't'))		return FALSE;	tmc_per_frame = module[37];	if (tmc_per_frame < 1 || tmc_per_frame > 4)		return FALSE;	sap_fastplay = perframe2fastplay[tmc_per_frame - 1];	i = 0;	/* find first instrument */	while (module[0x66 + i] == 0) {		if (++i >= 64)			return FALSE; /* no instrument */	}	i = (module[0x66 + i] << 8) + module[0x26 + i] - sap_music - 1 + 6;	if (i >= module_len)		return FALSE;	/* skip trailing jumps */	do {		if (i <= 0x1b5)			return FALSE; /* no pattern to play */		i -= 16;	} while (module[i] >= 0x80);	while (i >= 0x1b5) {		if (module[i] >= 0x80)			sap_songs++;		i -= 16;	}	return TRUE;}static int load_tm2(const unsigned char *module, unsigned int module_len){	unsigned int i;	unsigned int song_end;	unsigned char c;	if (module_len < 0x3a4)		return FALSE;	i = module[0x25];	if (i < 1 || i > 4)		return FALSE;	sap_fastplay = perframe2fastplay[i - 1];	if (!load_native(module, module_len, tm2_obx, 'T'))		return FALSE;	/* TODO: quadrophonic */	if (module[0x1f] != 0)#ifdef STEREO_SOUND		sap_stereo = 1;#else		return FALSE;#endif	sap_player = 0x500;	song_end = 0xffff;	for (i = 0; i < 0x80; i++) {		unsigned int instr_addr = module[0x86 + i] + (module[0x306 + i] << 8);		if (instr_addr != 0 && instr_addr < song_end)			song_end = instr_addr;	}	for (i = 0; i < 0x100; i++) {		unsigned int pattern_addr = module[0x106 + i] + (module[0x206 + i] << 8);		if (pattern_addr != 0 && pattern_addr < song_end)			song_end = pattern_addr;	}	if (song_end < sap_music + 0x380U + 2U * 17U)		return FALSE;	i = song_end - sap_music - 0x380;	if (0x386 + i >= module_len)		return FALSE;	i -= i % 17;	/* skip trailing stop/jump commands */	do {		if (i == 0)			return FALSE;		i -= 17;		c = module[0x386 + 16 + i];	} while (c == 0 || c >= 0x80);	/* count stop/jump commands */	while (i > 0) {		i -= 17;		c = module[0x386 + 16 + i];		if (c == 0 || c >= 0x80)			sap_songs++;	}	return TRUE;}static int tag_matches(const char *tag, const UBYTE *sap_ptr, const UBYTE *sap_end){	size_t len = strlen(tag);	return (sap_ptr + len + 8 < sap_end) && memcmp(tag, sap_ptr, len) == 0;}static int parse_hex(const UBYTE **ps, UWORD *retval){	int chars = 0;	*retval = 0;	while (**ps != 0x0d) {		char c;		if (++chars > 4)			return FALSE;		c = (char) *(*ps)++;		*retval <<= 4;		if (c >= '0' && c <= '9')			*retval += c - '0';		else if (c >= 'A' && c <= 'F')			*retval += c - 'A' + 10;		else if (c >= 'a' && c <= 'f')			*retval += c - 'a' + 10;		else			return FALSE;	}	return chars != 0;}static int parse_dec(const UBYTE **ps, unsigned int *retval){	int chars = 0;	*retval = 0;	while (**ps != 0x0d) {		char c;		if (++chars > 3)			return FALSE;		c = (char) *(*ps)++;		*retval *= 10;		if (c >= '0' && c <= '9')			*retval += c - '0';		else			return FALSE;	}	return chars != 0;}static int load_sap(const UBYTE *sap_ptr, const UBYTE * const sap_end){	if (!tag_matches("SAP", sap_ptr, sap_end))		return FALSE;	sap_type = '?';	sap_player = 0xffff;	sap_music = 0xffff;	sap_init = 0xffff;	sap_ptr += 3;	for (;;) {		if (sap_ptr + 8 >= sap_end || sap_ptr[0] != 0x0d || sap_ptr[1] != 0x0a)			return FALSE;		sap_ptr += 2;		if (sap_ptr[0] == 0xff)			break;		if (tag_matches("TYPE ", sap_ptr, sap_end)) {			sap_ptr += 5;			sap_type = *sap_ptr++;		}		else if (tag_matches("PLAYER ", sap_ptr, sap_end)) {			sap_ptr += 7;			if (!parse_hex(&sap_ptr, &sap_player))				return FALSE;		}		else if (tag_matches("MUSIC ", sap_ptr, sap_end)) {			sap_ptr += 6;			if (!parse_hex(&sap_ptr, &sap_music))				return FALSE;		}		else if (tag_matches("INIT ", sap_ptr, sap_end)) {			sap_ptr += 5;			if (!parse_hex(&sap_ptr, &sap_init))				return FALSE;		}		else if (tag_matches("SONGS ", sap_ptr, sap_end)) {			sap_ptr += 6;			if (!parse_dec(&sap_ptr, &sap_songs) || sap_songs < 1 || sap_songs > 255)				return FALSE;		}		else if (tag_matches("DEFSONG ", sap_ptr, sap_end)) {			sap_ptr += 8;			if (!parse_dec(&sap_ptr, &sap_defsong))				return FALSE;		}		else if (tag_matches("FASTPLAY ", sap_ptr, sap_end)) {			sap_ptr += 9;			if (!parse_dec(&sap_ptr, &sap_fastplay) || sap_fastplay < 1 || sap_fastplay > 312)				return FALSE;		}		else if (tag_matches("STEREO", sap_ptr, sap_end))#ifdef STEREO_SOUND			sap_stereo = 1;#else			return FALSE;#endif		/* ignore unknown tags */		while (sap_ptr[0] != 0x0d) {			sap_ptr++;			if (sap_ptr >= sap_end)				return FALSE;		}	}	if (sap_defsong >= sap_songs)		return FALSE;	switch (sap_type) {	case 'B':		if (sap_player == 0xffff || sap_init == 0xffff)			return FALSE;		break;	case 'C':		if (sap_player == 0xffff || sap_music == 0xffff)			return FALSE;		break;	default:		return FALSE;	}	if (sap_ptr[1] != 0xff)		return FALSE;	memset(memory, 0, sizeof(memory));	sap_ptr += 2;	while (sap_ptr + 5 <= sap_end) {		int start_addr = sap_ptr[0] + (sap_ptr[1] << 8);		int block_len = sap_ptr[2] + (sap_ptr[3] << 8) + 1 - start_addr;		if (block_len <= 0 || sap_ptr + block_len > sap_end)			return FALSE;		sap_ptr += 4;		memcpy(memory + start_addr, sap_ptr, block_len);		sap_ptr += block_len;		if (sap_ptr == sap_end)			return TRUE;		if (sap_ptr + 7 <= sap_end && sap_ptr[0] == 0xff && sap_ptr[1] == 0xff)			sap_ptr += 2;	}	return FALSE;}#define EXT(c1, c2, c3) ((c1 + (c2 << 8) + (c3 << 16)) | 0x202020)int ASAP_Load(const char *filename, const unsigned char *module, unsigned int module_len){	const char *p;	int ext;	for (p = filename; *p != '\0'; p++);	ext = 0;	for (;;) {		if (--p <= filename || *p < ' ')			return FALSE; /* no filename extension or invalid character */		if (*p == '.')			break;		ext = (ext << 8) + (*p & 0xff);	}	sap_stereo = 0;	sap_songs = 1;	sap_defsong = 0;	sap_fastplay = 312;	switch (ext | 0x202020) {	case EXT('C', 'M', 'C'):		return load_cmc(module, module_len, FALSE);	case EXT('C', 'M', 'R'):		return load_cmc(module, module_len, TRUE);	case EXT('D', 'M', 'C'):		sap_fastplay = 156;		return load_cmc(module, module_len, FALSE);	case EXT('M', 'P', 'D'):		sap_fastplay = 156;		return load_mpt(module, module_len);	case EXT('M', 'P', 'T'):		return load_mpt(module, module_len);	case EXT('R', 'M', 'T'):		return load_rmt(module, module_len);	case EXT('S', 'A', 'P'):		return load_sap(module, module + module_len);	case EXT('T', 'M', '2'):		return load_tm2(module, module_len);#ifdef STEREO_SOUND	case EXT('T', 'M', '8'):		sap_stereo = 1;		return load_tmc(module, module_len);#endif	case EXT('T', 'M', 'C'):		return load_tmc(module, module_len);	default:		return FALSE;	}}unsigned int ASAP_GetChannels(void){	return 1 << sap_stereo;}unsigned int ASAP_GetSongs(void){	return sap_songs;}unsigned int ASAP_GetDefSong(void){	return sap_defsong;}static void call_6502(UWORD addr, int max_scanlines){	regPC = addr;	/* put a CIM at 0xd20a and a return address on stack */	dPutByte(0xd20a, 0xd2);	dPutByte(0x01fe, 0x09);	dPutByte(0x01ff, 0xd2);	regS = 0xfd;	xpos = 0;	GO(max_scanlines * (LINE_C - DMAR));}/* 50 Atari frames for the initialization routine - some SAPs are self-extracting. */#define SCANLINES_FOR_INIT  (50 * 312)void ASAP_PlaySong(unsigned int song){	UWORD addr;	if (enable_stereo != sap_stereo) {		Pokey_sound_init(ASAP_MAIN_CLOCK, (uint16) block_rate,			1 << sap_stereo, sample_16bit ? SND_BIT16 : 0);		enable_stereo = sap_stereo;	}	for (addr = _AUDF1; addr <= _STIMER; addr++)		POKEY_PutByte(addr, 0);	if (sap_stereo)		for (addr = _AUDF1 + _POKEY2; addr <= _STIMER + _POKEY2; addr++)			POKEY_PutByte(addr, 0);	blockclocks = 0;	blockclocks_per_player = 114U * sap_fastplay * block_rate;	regP = 0x30;	switch (sap_type) {	case 'B':		regA = (UBYTE) song;		regX = 0x00;		regY = 0x00;		/* 5 frames should be enough */		call_6502(sap_init, SCANLINES_FOR_INIT);		break;	case 'C':		regA = 0x70;		regX = (UBYTE) sap_music;		regY = (UBYTE) (sap_music >> 8);		call_6502((UWORD) (sap_player + 3), SCANLINES_FOR_INIT);		regA = 0x00;		regX = (UBYTE) song;		call_6502((UWORD) (sap_player + 3), SCANLINES_FOR_INIT);		break;	case 'm':		regA = 0x00;		regX = (UBYTE) (sap_music >> 8);		regY = (UBYTE) sap_music;		call_6502(sap_player, SCANLINES_FOR_INIT);		regA = 0x02;		regX = song_pos[song];		call_6502(sap_player, SCANLINES_FOR_INIT);		break;	case 'r':		regA = song_pos[song];		regX = (UBYTE) sap_music;		regY = (UBYTE) (sap_music >> 8);		call_6502(sap_player, SCANLINES_FOR_INIT);		break;	case 't':	case 'T':		regA = 0x70;		regX = (UBYTE) (sap_music >> 8);		regY = (UBYTE) sap_music;		call_6502(sap_player, SCANLINES_FOR_INIT);		regA = 0x00;		regX = (UBYTE) song;		call_6502(sap_player, SCANLINES_FOR_INIT);		tmc_per_frame_counter = 1;		break;	}}void ASAP_Generate(void *buffer, unsigned int buffer_len){	/* convert number of bytes to number of blocks */	buffer_len >>= sample_16bit + enable_stereo;	if (buffer_len == 0U)		return;	for (;;) {		unsigned int blocks = blockclocks / ASAP_MAIN_CLOCK;		if (blocks != 0U) {			unsigned int samples;			if (blocks > buffer_len)				blocks = buffer_len;			buffer_len -= blocks;			samples = blocks << enable_stereo;			blockclocks -= blocks * ASAP_MAIN_CLOCK;			Pokey_process(buffer, samples);			/* swap bytes in non-native words if necessary */			if (sample_format ==#ifdef WORDS_BIGENDIAN				AUDIO_FORMAT_S16_LE#else				AUDIO_FORMAT_S16_BE#endif				) {				unsigned char *p = (unsigned char *) buffer;				unsigned int n = samples;				do {					unsigned char t = p[0];					p[0] = p[1];					p[1] = t;					p += 2;				} while (--n != 0U);			}			if (buffer_len == 0U)				return;			buffer = (void *) ((unsigned char *) buffer +				(samples << sample_16bit));		}		switch (sap_type) {		case 'B':			call_6502(sap_player, sap_fastplay);			break;		case 'C':			call_6502((UWORD) (sap_player + 6), sap_fastplay);			break;		case 'm':		case 'r':		case 'T':			call_6502((UWORD) (sap_player + 3), sap_fastplay);			break;		case 't':			if (--tmc_per_frame_counter <= 0) {				tmc_per_frame_counter = tmc_per_frame;				call_6502((UWORD) (sap_player + 3), sap_fastplay);			}			else				call_6502((UWORD) (sap_player + 6), sap_fastplay);			break;		}		random_scanline_counter = (random_scanline_counter + LINE_C * sap_fastplay)		                          % ((AUDCTL[0] & POLY9) ? POLY9_SIZE : POLY17_SIZE);		blockclocks += blockclocks_per_player;	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -