#include #include #include #include "pokey.h" #define ROM_FILE "../jumpmanjr.rom" #define ROM_SIZE 0x4000 #define FREQ 44100 #define PAL_BUF_SIZE 882 #define NTSC_BUF_SIZE 735 #define PAL_DELAY 20 #define NTSC_DELAY 17 unsigned char sndbuf[PAL_BUF_SIZE + 1]; int buf_size = NTSC_BUF_SIZE; int delay = NTSC_DELAY; unsigned char rom[ROM_SIZE]; void usage(void) { fprintf(stderr, "usage: playsnd [-p] 0xaddr\n"); exit(1); } void load_rom(void) { int size; FILE *f; f = fopen(ROM_FILE, "rb"); if(!f) { perror(ROM_FILE); usage(); } size = fread(rom, 1, ROM_SIZE, f); if(size != ROM_SIZE) { fprintf(stderr, "file %s should be %d bytes long, not %d\n", ROM_FILE, ROM_SIZE, size); usage(); } fprintf(stderr, "loaded ROM %s, %d bytes\n", ROM_FILE, size); } void play_frames(unsigned char count) { fprintf(stderr, "playing for %d frames\n", count); while(count--) { SDL_Delay(delay); } } void play_sfx(int addr) { unsigned char *p = rom + (addr - 0x8000); while(1) { fprintf(stderr, "$%04lx: $%02x\n", (p - rom + 0x8000), *p); switch(*p) { case 0: fprintf(stderr, "opcode 0 (snd_end)\n"); return; case 1: fprintf(stderr, "opcode 1 (snd_audc)\n"); Update_pokey_sound(audc1, *++p); play_frames(*++p); ++p; break; case 2: fprintf(stderr, "opcode 2 (snd_jump)\n"); addr = *++p; addr |= ( (*++p) << 8); addr -= 0x8000; p = rom + addr; break; case 3: fprintf(stderr, "opcode 3 (snd_rest)\n"); Update_pokey_sound(audc1, 0); play_frames(*++p); ++p; break; default: fprintf(stderr, "opcode $%02x (snd_note)\n", *p); Update_pokey_sound(audf1, *p); play_frames(*++p); ++p; break; } } } void sdl_audio_callback(void *userdata, Uint8* stream, int len) { Pokey_process(stream, len); } void init_sdl_audio(void) { SDL_AudioSpec want, have; SDL_AudioDeviceID dev; if(SDL_Init(SDL_INIT_AUDIO) < 0) { fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); exit(-1); } atexit(SDL_Quit); SDL_memset(&want, 0, sizeof(want)); want.freq = FREQ; want.format = AUDIO_U8; want.channels = 1; want.samples = buf_size; want.callback = sdl_audio_callback; dev = SDL_OpenAudioDevice(0, 0, &want, &have, 0); if(!dev) { fprintf(stderr, "Failed to open audio: %s\n", SDL_GetError()); exit(-1); } SDL_PauseAudioDevice(dev, 0); } int main(int argc, char **argv) { int addr; if(argc < 2 || argc > 3) usage(); if(argc == 3) { buf_size = PAL_BUF_SIZE; delay = PAL_DELAY; addr = (int)strtol(argv[2], 0, 16); } else { addr = (int)strtol(argv[1], 0, 16); } if(addr < 0x8000 || addr > 0xbfff) { fprintf(stderr, "invalid address, must be 0x8fff thru 0xbfff\n"); usage(); } load_rom(); fprintf(stderr, "playing sfx at $%04x, buf_size %d\n", addr, buf_size); Pokey_sound_init(FREQ_17_APPROX, FREQ); init_sdl_audio(); play_sfx(addr); return(0); }