void playstreamedsample(int channel,signed char *data,int len,int freq,int volume,int pan,int bits) { static int playing[NUMVOICES]; static int c[NUMVOICES]; /* backwards compatibility with old 0-255 volume range */ if (volume > 100) volume = volume * 25 / 255; if (seal_sample_rate == 0 || channel >= NUMVOICES) return; if (!playing[channel]) { if (lpWave[channel]) { AStopVoice(hVoice[channel]); ADestroyAudioData(lpWave[channel]); free(lpWave[channel]); lpWave[channel] = 0; } if ((lpWave[channel] = (LPAUDIOWAVE)malloc(sizeof(AUDIOWAVE))) == 0) return; lpWave[channel]->wFormat = (bits == 8 ? AUDIO_FORMAT_8BITS : AUDIO_FORMAT_16BITS) | AUDIO_FORMAT_MONO | AUDIO_FORMAT_LOOP; lpWave[channel]->nSampleRate = nominal_sample_rate; lpWave[channel]->dwLength = 3*len; lpWave[channel]->dwLoopStart = 0; lpWave[channel]->dwLoopEnd = 3*len; if (ACreateAudioData(lpWave[channel]) != AUDIO_ERROR_NONE) { free(lpWave[channel]); lpWave[channel] = 0; return; } memset(lpWave[channel]->lpData,0,3*len); memcpy(lpWave[channel]->lpData,data,len); /* upload the data to the audio DRAM local memory */ AWriteAudioData(lpWave[channel],0,3*len); APrimeVoice(hVoice[channel],lpWave[channel]); /* need to cast to double because freq*nominal_sample_rate can exceed the size of an int */ ASetVoiceFrequency(hVoice[channel],(double)freq*nominal_sample_rate/seal_sample_rate); AStartVoice(hVoice[channel]); playing[channel] = 1; c[channel] = 1; } else { LONG pos; for(;;) { AGetVoicePosition(hVoice[channel],&pos); if (c[channel] == 0 && pos >= len) break; if (c[channel] == 1 && (pos < len || pos >= 2*len)) break; if (c[channel] == 2 && pos < 2*len) break; osd_update_audio(); } memcpy(&lpWave[channel]->lpData[len * c[channel]],data,len); AWriteAudioData(lpWave[channel],len*c[channel],len); c[channel]++; if (c[channel] == 3) c[channel] = 0; } ASetVoiceVolume(hVoice[channel],volume * 64 / 100); ASetVoicePanning(hVoice[channel],(pan + 100) * 255 / 200); }
int msdos_init_sound(int *rate, int card) { int i; seal_sample_rate = *rate; seal_sound_card = card; if (AInitialize() != AUDIO_ERROR_NONE) return 1; /* Ask the user if no sound card was chosen */ if (seal_sound_card == -1) { unsigned int k; printf("\n SELECT YOUR AUDIO DEVICE :\n\n" " AWE32/64 playback requires onboard DRAM,\n" " Sound Blaster playback is the most compatible & better for emulation\n\n"); for (k = 0;k < AGetAudioNumDevs();k++) { if (AGetAudioDevCaps(k,&caps) == AUDIO_ERROR_NONE) printf(" %2d. %s\n",k,caps.szProductName); } printf("\n"); if (k < 10) { i = getch(); seal_sound_card = i - '0'; } else scanf("%d",&seal_sound_card); } /* initialize SEAL audio library */ if (seal_sound_card == 0) /* silence */ { /* update the Machine structure to show that sound is disabled */ seal_sample_rate = 0; exit(0); return 0; } /* open audio device */ /* info.nDeviceId = AUDIO_DEVICE_MAPPER;*/ info.nDeviceId = seal_sound_card; /* always use 16 bit mixing if possible - better quality and same speed of 8 bit */ info.wFormat = AUDIO_FORMAT_16BITS | AUDIO_FORMAT_STEREO | AUDIO_FORMAT_RAW_SAMPLE; info.nSampleRate = seal_sample_rate; if (AOpenAudio(&info) != AUDIO_ERROR_NONE) { return (1); } AGetAudioDevCaps(info.nDeviceId,&caps); printf("Using `%s' at %d-bit %s %u Hz\n", caps.szProductName, info.wFormat & AUDIO_FORMAT_16BITS ? 16 : 8, info.wFormat & AUDIO_FORMAT_STEREO ? "stereo" : "mono", info.nSampleRate); /* open and allocate voices, allocate waveforms */ if (AOpenVoices(NUMVOICES) != AUDIO_ERROR_NONE) { printf("voices initialization failed\n"); return 1; } for (i = 0; i < NUMVOICES; i++) { if (ACreateAudioVoice(&hVoice[i]) != AUDIO_ERROR_NONE) { printf("voice #%d creation failed\n",i); return 1; } ASetVoicePanning(hVoice[i],128); lpWave[i] = 0; } /* update the Machine structure to reflect the actual sample rate */ *rate = seal_sample_rate = info.nSampleRate; { uclock_t a,b; LONG start,end; if ((lpWave[0] = (LPAUDIOWAVE)malloc(sizeof(AUDIOWAVE))) == 0) return 1; lpWave[0]->wFormat = AUDIO_FORMAT_8BITS | AUDIO_FORMAT_MONO; lpWave[0]->nSampleRate = seal_sample_rate; lpWave[0]->dwLength = 3*seal_sample_rate; lpWave[0]->dwLoopStart = 0; lpWave[0]->dwLoopEnd = 3*seal_sample_rate; if (ACreateAudioData(lpWave[0]) != AUDIO_ERROR_NONE) { free(lpWave[0]); lpWave[0] = 0; return 1; } memset(lpWave[0]->lpData,0,3*seal_sample_rate); /* upload the data to the audio DRAM local memory */ AWriteAudioData(lpWave[0],0,3*seal_sample_rate); APrimeVoice(hVoice[0],lpWave[0]); ASetVoiceFrequency(hVoice[0],seal_sample_rate); ASetVoiceVolume(hVoice[0],0); AStartVoice(hVoice[0]); a = uclock(); /* wait some time to let everything stabilize */ do { osd_update_audio(); b = uclock(); } while (b-a < UCLOCKS_PER_SEC/10); a = uclock(); AGetVoicePosition(hVoice[0],&start); do { osd_update_audio(); b = uclock(); } while (b-a < UCLOCKS_PER_SEC); AGetVoicePosition(hVoice[0],&end); nominal_sample_rate = seal_sample_rate; seal_sample_rate = end - start; AStopVoice(hVoice[0]); ADestroyAudioData(lpWave[0]); free(lpWave[0]); lpWave[0] = 0; } osd_set_mastervolume(0); /* start at maximum volume */ return 0; }
/*************************************************************************** This function takes care of refreshing the screen, processing user input, and throttling the emulation speed to obtain the required frames per second. ***************************************************************************/ int updatescreen(void) { static int framecount = 0; /* read hi scores from disk */ if (hiscoreloaded == 0 && *gamedrv->hiscore_load) hiscoreloaded = (*gamedrv->hiscore_load)(hiscorename); /* if the user pressed ESC, stop the emulation */ if (osd_key_pressed(OSD_KEY_ESC)) return 1; /* if the user pressed F3, reset the emulation */ if (osd_key_pressed(OSD_KEY_F3)) { /* write hi scores to disk */ if (hiscoreloaded != 0 && *gamedrv->hiscore_save) (*gamedrv->hiscore_save)(hiscorename); hiscoreloaded = 0; return 2; } if (osd_key_pressed(OSD_KEY_F9)) { if (++VolumePTR > 4) VolumePTR = 0; ActualVolume = VolumiDefault[VolumePTR]; osd_set_mastervolume(ActualVolume); while (osd_key_pressed(OSD_KEY_F9)) { if (*drv->sh_update) { (*drv->sh_update)(); /* update sound */ osd_update_audio(); } } } if (osd_key_pressed(OSD_KEY_P)) /* pause the game */ { struct DisplayText dt[2]; int key; dt[0].text = "PAUSED"; dt[0].color = gamedrv->paused_color; dt[0].x = gamedrv->paused_x; dt[0].y = gamedrv->paused_y; dt[1].text = 0; displaytext(dt,0); osd_set_mastervolume(0); while (osd_key_pressed(OSD_KEY_P)) { if (*drv->sh_update) { (*drv->sh_update)(); /* update sound */ osd_update_audio(); } } /* wait for key release */ do { key = osd_read_key(); if (key == OSD_KEY_ESC) return 1; else if (key == OSD_KEY_TAB) { if (setdipswitches()) return 1; (*drv->vh_update)(Machine->scrbitmap); /* redraw screen */ displaytext(dt,0); } } while (key != OSD_KEY_P); while (osd_key_pressed(key)); osd_set_mastervolume(ActualVolume); } /* if the user pressed TAB, go to dipswitch setup menu */ if (osd_key_pressed(OSD_KEY_TAB)) { osd_set_mastervolume(0); while (osd_key_pressed(OSD_KEY_TAB)) { if (*drv->sh_update) { (*drv->sh_update)(); /* update sound */ osd_update_audio(); } } if (setdipswitches()) return 1; osd_set_mastervolume(ActualVolume); } /* if the user pressed F8, go to keys setup menu */ if (osd_key_pressed(OSD_KEY_F8)) { osd_set_mastervolume(0); while (osd_key_pressed(OSD_KEY_F8)) { if (*drv->sh_update) { (*drv->sh_update)(); /* update sound */ osd_update_audio(); } } if (setkeysettings()) return 1; osd_set_mastervolume(ActualVolume); } /* if the user pressed F4, show the character set */ if (osd_key_pressed(OSD_KEY_F4)) { osd_set_mastervolume(0); while (osd_key_pressed(OSD_KEY_F4)) { if (*drv->sh_update) { (*drv->sh_update)(); /* update sound */ osd_update_audio(); } } if (showcharset()) return 1; osd_set_mastervolume(ActualVolume); } if (*drv->sh_update) { (*drv->sh_update)(); /* update sound */ osd_update_audio(); } if (++framecount > frameskip) { static int showfps,f11pressed; static int throttle = 1,f10pressed; uclock_t curr,mtpf; #define MEMORY 10 static uclock_t prev[MEMORY]; static int i,fps; framecount = 0; if (osd_key_pressed(OSD_KEY_F11)) { if (f11pressed == 0) { showfps ^= 1; if (showfps == 0) clearbitmap(Machine->scrbitmap); } f11pressed = 1; } else f11pressed = 0; if (osd_key_pressed(OSD_KEY_F10)) { if (f10pressed == 0) throttle ^= 1; f10pressed = 1; } else f10pressed = 0; (*drv->vh_update)(Machine->scrbitmap); /* update screen */ if (showfps) { drawgfx(Machine->scrbitmap,Machine->gfx[0],gamedrv->charset[(fps%1000)/100],gamedrv->white_text,0,0,0,0,0,TRANSPARENCY_NONE,0); drawgfx(Machine->scrbitmap,Machine->gfx[0],gamedrv->charset[(fps%100)/10],gamedrv->white_text,0,0,Machine->gfx[0]->width,0,0,TRANSPARENCY_NONE,0); drawgfx(Machine->scrbitmap,Machine->gfx[0],gamedrv->charset[fps%10],gamedrv->white_text,0,0,2*Machine->gfx[0]->width,0,0,TRANSPARENCY_NONE,0); } osd_update_display(); osd_poll_joystick(); /* now wait until it's time to trigger the interrupt */ do { curr = uclock(); } while (video_sync == 0 && throttle != 0 && (curr - prev[i]) < (frameskip+1) * UCLOCKS_PER_SEC/drv->frames_per_second); i = (i+1) % MEMORY; mtpf = ((curr - prev[i])/(MEMORY))/2; if (mtpf) fps = (UCLOCKS_PER_SEC+mtpf)/2/mtpf; prev[i] = curr; } return 0; }