void TEDDeath(void) { ShutdownId(); // REFKEEN - DISABLED BE_ST_ExitWithErrorMsg("Sorry, but TED5.EXE cannot be launched from game in this source port."); //execlp("TED5.EXE","TED5.EXE","/LAUNCH",NULL); }
void BE_Cross_Bfarfree(void *ptr) { if (ptr == NULL) return; BE_MemoryBlock_T *block = g_farBlocks; for (int i = 0; i < g_numOfFarBlocks; ++i, ++block) if (block->ptr == ptr) { --g_numOfFarBlocks; memmove(block, block+1, (g_numOfFarBlocks-(block-g_farBlocks))*sizeof(*block)); BE_Cross_RefreshFarBytesLeft(); return; } BE_ST_ExitWithErrorMsg("BE_Cross_Bfarfree: Got an invalid pointer!"); }
void *BE_Cross_Bfarmalloc(uint32_t size) { // Define vars here so C++ compilation doesn't fail with gotos uint8_t *prevBlockEnd, *endOfFarMem; BE_MemoryBlock_T *block; if (g_numOfFarBlocks == MAX_NO_OF_BLOCKS_PER_CLASS) goto outofmemory; prevBlockEnd = g_be_emulatedMemSpace + 16*EMULATED_FAR_SEG; block = g_farBlocks; for (int i = 0; i < g_numOfFarBlocks; ++i, ++block) { if (block->ptr - prevBlockEnd >= size) // Sufficiently large gap found { memmove(block+1, block, (g_numOfFarBlocks-(block-g_farBlocks))*sizeof(*block)); // "block" points to a new block here goto addnewblock; } prevBlockEnd = block->ptr + block->len; } endOfFarMem = g_be_emulatedMemSpace + 16*(EMULATED_FAR_SEG+EMULATED_FAR_PARAGRAPHS); if (endOfFarMem - prevBlockEnd >= size) // Add a new block at the end { addnewblock: ++g_numOfFarBlocks; block->ptr = prevBlockEnd; block->len = size; BE_Cross_RefreshFarBytesLeft(); return block->ptr; } // REFKEEN NOTE - Plain malloc should return NULL, // but we rather do the following for debugging outofmemory: BE_ST_ExitWithErrorMsg("BE_Cross_Bfarmalloc: Out of memory!"); return NULL; // Mute compiler warning }
void BE_ST_InitAudio(void) { g_sdlAudioSubsystemUp = false; g_sdlEmulatedOPLChipReady = false; int inSampleRate = BE_Cross_GetSelectedGameVerSampleRate(); bool doDigitized = (inSampleRate != 0); if (!doDigitized) inSampleRate = OPL_SAMPLE_RATE; if (g_refKeenCfg.sndSubSystem) { if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { BE_Cross_LogMessage(BE_LOG_MSG_WARNING, "SDL audio system initialization failed,\n%s\n", SDL_GetError()); } else { g_sdlAudioSpec.freq = g_refKeenCfg.sndSampleRate; #ifdef MIXER_SAMPLE_FORMAT_FLOAT g_sdlAudioSpec.format = AUDIO_F32SYS; #elif (defined MIXER_SAMPLE_FORMAT_SINT16) g_sdlAudioSpec.format = AUDIO_S16SYS; #endif g_sdlAudioSpec.channels = 1; // Should be some power-of-two roughly proportional to the sample rate; Using 1024 for 48000Hz. for (g_sdlAudioSpec.samples = 1; g_sdlAudioSpec.samples < g_refKeenCfg.sndSampleRate/64; g_sdlAudioSpec.samples *= 2) { } if (doDigitized) g_sdlAudioSpec.callback = (g_refKeenCfg.sndSampleRate == inSampleRate) ? BEL_ST_Simple_DigiCallBack : BEL_ST_Resampling_DigiCallBack; else g_sdlAudioSpec.callback = ((g_refKeenCfg.sndSampleRate == inSampleRate) || !g_refKeenCfg.oplEmulation) ? BEL_ST_Simple_EmuCallBack : BEL_ST_Resampling_EmuCallBack; g_sdlAudioSpec.userdata = NULL; if (SDL_OpenAudio(&g_sdlAudioSpec, NULL)) { BE_Cross_LogMessage(BE_LOG_MSG_WARNING, "Cannot open SDL audio device,\n%s\n", SDL_GetError()); SDL_QuitSubSystem(SDL_INIT_AUDIO); } else { #ifdef REFKEEN_CONFIG_THREADS g_sdlCallbackMutex = SDL_CreateMutex(); if (!g_sdlCallbackMutex) { BE_Cross_LogMessage(BE_LOG_MSG_ERROR, "Cannot create recursive mutex for SDL audio callback,\n%s\nClosing SDL audio subsystem\n", SDL_GetError()); SDL_CloseAudio(); SDL_QuitSubSystem(SDL_INIT_AUDIO); } else #endif { BE_Cross_LogMessage(BE_LOG_MSG_NORMAL, "Audio subsystem initialized, requested spec: freq %d, format %u, channels %d, samples %u\n", (int)g_sdlAudioSpec.freq, (unsigned int)g_sdlAudioSpec.format, (int)g_sdlAudioSpec.channels, (unsigned int)g_sdlAudioSpec.samples); g_sdlAudioSubsystemUp = true; } } } } // If the audio subsystem is off, let us simulate a byte rate // of 1000Hz (same as SDL_GetTicks() time units) if (!g_sdlAudioSubsystemUp) { g_sdlAudioSpec.freq = doDigitized ? inSampleRate : (NUM_OF_BYTES_FOR_SOUND_CALLBACK_WITH_DISABLED_SUBSYSTEM / sizeof(BE_ST_SndSample_T)); g_sdlAudioSpec.callback = doDigitized ? BEL_ST_Resampling_DigiCallBack : BEL_ST_Resampling_EmuCallBack; return; } if (g_refKeenCfg.oplEmulation) { YM3812Init(1, 3579545, OPL_SAMPLE_RATE); g_sdlEmulatedOPLChipReady = true; } if ((doDigitized || g_sdlEmulatedOPLChipReady) && (g_sdlAudioSpec.freq != inSampleRate)) { // Should allocate this first, for g_sdlSrcData.data_in g_sdlMiscOutNumOfSamples = 2*g_sdlAudioSpec.samples; g_sdlMiscOutSamples = (BE_ST_SndSample_T *)malloc(sizeof(BE_ST_SndSample_T) * g_sdlMiscOutNumOfSamples); if (g_sdlMiscOutSamples == NULL) BE_ST_ExitWithErrorMsg("BE_ST_InitAudio: Out of memory! (Failed to allocate g_sdlMiscOutSamples.)"); #ifndef REFKEEN_RESAMPLER_NONE if (g_refKeenCfg.useResampler) { #if (!defined REFKEEN_RESAMPLER_LIBRESAMPLE) && (!defined REFKEEN_RESAMPLER_LIBAVCODEC) char errMsg[160]; #endif #if (defined REFKEEN_RESAMPLER_LIBSWRESAMPLE) g_sdlSwrContext = swr_alloc_set_opts( NULL, // allocating a new context AV_CH_LAYOUT_MONO, // out channels layout AV_SAMPLE_FMT_S16, // out format g_sdlAudioSpec.freq, // out rate AV_CH_LAYOUT_MONO, // in channels layout AV_SAMPLE_FMT_S16, // in format inSampleRate, // in rate 0, NULL ); if (g_sdlSwrContext == NULL) BE_ST_ExitWithErrorMsg("BE_ST_InitAudio: swr_alloc_set_opts failed!"); int error = swr_init(g_sdlSwrContext); if (error != 0) { // av_err2str requires libavutil/libavutil-ffmpeg, so don't convert code to string snprintf(errMsg, sizeof(errMsg), "BE_ST_InitAudio: swr_init failed! Error code: %d", error); BE_ST_ExitWithErrorMsg(errMsg); } #elif (defined REFKEEN_RESAMPLER_LIBAVRESAMPLE) g_sdlAvAudioResampleContext = avresample_alloc_context(); if (g_sdlAvAudioResampleContext == NULL) BE_ST_ExitWithErrorMsg("BE_ST_InitAudio: avresample_alloc_context failed!"); av_opt_set_int(g_sdlAvAudioResampleContext, "in_channel_layout", AV_CH_LAYOUT_MONO, 0); av_opt_set_int(g_sdlAvAudioResampleContext, "out_channel_layout", AV_CH_LAYOUT_MONO, 0); av_opt_set_int(g_sdlAvAudioResampleContext, "in_sample_rate", inSampleRate, 0); av_opt_set_int(g_sdlAvAudioResampleContext, "out_sample_rate", g_sdlAudioSpec.freq, 0); av_opt_set_int(g_sdlAvAudioResampleContext, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0); av_opt_set_int(g_sdlAvAudioResampleContext, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0); int error = avresample_open(g_sdlAvAudioResampleContext); if (error != 0) { // av_err2str requires libavutil/libavutil-ffmpeg, so don't convert code to string snprintf(errMsg, sizeof(errMsg), "BE_ST_InitAudio: swr_init failed! Error code: %d", error); BE_ST_ExitWithErrorMsg(errMsg); } #elif (defined REFKEEN_RESAMPLER_LIBAVCODEC) avcodec_register_all(); g_sdlAvResampleContext = av_resample_init( g_sdlAudioSpec.freq, // out rate inSampleRate, // in rate 16, // filter length 10, // phase count 0, // linear FIR filter 1.0 // cutoff frequency ); if (g_sdlAvResampleContext == NULL) BE_ST_ExitWithErrorMsg("BE_ST_InitAudio: av_resample_init failed!"); #elif (defined REFKEEN_RESAMPLER_LIBRESAMPLE) g_sdlResampleFactor = (double)g_sdlAudioSpec.freq/inSampleRate; g_sdlResampleHandle = resample_open(0, g_sdlResampleFactor, g_sdlResampleFactor); if (g_sdlResampleHandle == NULL) BE_ST_ExitWithErrorMsg("BE_ST_InitAudio: resample_open failed!"); #elif (defined REFKEEN_RESAMPLER_LIBSOXR) soxr_io_spec_t io_spec = soxr_io_spec(SOXR_INT16, SOXR_INT16); soxr_quality_spec_t q_spec = soxr_quality_spec(SOXR_LQ, 0); // Default quality spec adds an audible latency for resampling to 8000Hz soxr_error_t error; g_sdlSoxr = soxr_create( inSampleRate, // in rate g_sdlAudioSpec.freq, // out rate 1, // channels &error, &io_spec, &q_spec, NULL // runtime spec ); if (g_sdlSoxr == NULL) { snprintf(errMsg, sizeof(errMsg), "BE_ST_InitAudio: soxr_create failed!\nError: %s", soxr_strerror(error)); BE_ST_ExitWithErrorMsg(errMsg); } #elif (defined REFKEEN_RESAMPLER_LIBSPEEXDSP) int error; g_sdlSpeexResamplerState = speex_resampler_init( 1, // channels inSampleRate, // in rate g_sdlAudioSpec.freq, // out rate 0, // quality in the range 0-10 (10 is higher) &error ); if (g_sdlSpeexResamplerState == NULL) { snprintf(errMsg, sizeof(errMsg), "BE_ST_InitAudio: speex_resampler_init failed! Error code: %d\nError: %s", error, speex_resampler_strerror(error)); BE_ST_ExitWithErrorMsg(errMsg); } #elif (defined REFKEEN_RESAMPLER_LIBSAMPLERATE) int error; g_sdlSrcResampler = src_new(SRC_SINC_FASTEST, 1, &error); if (g_sdlSrcResampler == NULL) { snprintf(errMsg, sizeof(errMsg), "BE_ST_InitAudio: src_new failed!\nError code: %d", error); BE_ST_ExitWithErrorMsg(errMsg); } g_sdlSrcData.data_in = doDigitized ? g_sdlMiscOutSamples : g_sdlALOutSamples; g_sdlSrcData.src_ratio = (double)g_sdlAudioSpec.freq / inSampleRate; #endif } else #endif // REFKEEN_RESAMPLER_NONE { // The sum of all entries should be g_sdlAudioSpec.freq, // "uniformly" distributed over g_sdlALSampleRateConvTable g_sdlSampleRateConvTable = (int *)malloc(sizeof(int) * inSampleRate); if (g_sdlSampleRateConvTable == NULL) BE_ST_ExitWithErrorMsg("BE_ST_InitAudio: Failed to allocate memory for sample rate conversion!"); g_sdlSampleRateConvTableSize = inSampleRate; for (int i = 0; i < inSampleRate; ++i) { // Using uint64_t cause an overflow is possible g_sdlSampleRateConvTable[i] = ((uint64_t)(i+1)*(uint64_t)g_sdlAudioSpec.freq/inSampleRate)-(uint64_t)i*(uint64_t)g_sdlAudioSpec.freq/inSampleRate; } g_sdlSampleRateConvCurrIndex = 0; g_sdlSampleRateConvCounter = 0; } } }
// gameVer should be BE_GAMEVER_LAST if no specific version is desired void BE_Cross_SelectGameInstallation(int gameVerVal) { if (gameVerVal == BE_GAMEVER_LAST) { if (!g_be_gameinstallations_num) { BE_ST_ExitWithErrorMsg("BE_Cross_SelectGameInstallation: No compatible game installation found!"); } g_be_selectedGameInstallation = &g_be_gameinstallations[0]; } else { int gameInstNum; for (gameInstNum = 0; gameInstNum < g_be_gameinstallations_num; ++gameInstNum) { if (g_be_gameinstallations[gameInstNum].verId == gameVerVal) { break; } } if (gameInstNum == g_be_gameinstallations_num) { char errorBuffer[80]; BE_Cross_safeandfastcstringcopy_2strs(errorBuffer, errorBuffer+sizeof(errorBuffer), "BE_Cross_SelectGameInstallation: Can't find game installation: ", refkeen_gamever_strs[gameVerVal]); BE_ST_ExitWithErrorMsg(errorBuffer); } g_be_selectedGameInstallation = &g_be_gameinstallations[gameInstNum]; } refkeen_current_gamever = g_be_selectedGameInstallation->verId; //extern void RefKeen_Patch_id_ca(void); //RefKeen_Patch_id_ca(); extern void RefKeen_Patch_id_us(void); RefKeen_Patch_id_us(); #ifdef REFKEEN_VER_KDREAMS extern void RefKeen_Patch_id_rf(void); RefKeen_Patch_id_rf(); //extern void RefKeen_Patch_kd_play(void); //RefKeen_Patch_kd_play(); #endif #ifdef REFKEEN_VER_CAT3D extern void RefKeen_Patch_c3_game(void); RefKeen_Patch_c3_game(); extern void RefKeen_Patch_c3_play(void); RefKeen_Patch_c3_play(); #endif #ifdef REFKEEN_VER_CATABYSS extern void RefKeen_Patch_c4_main(void); RefKeen_Patch_c4_main(); extern void RefKeen_Patch_c4_play(void); RefKeen_Patch_c4_play(); extern void RefKeen_Patch_gelib(void); RefKeen_Patch_gelib(); #endif #ifdef REFKEEN_VER_CATADVENTURES extern void RefKeen_Patch_intro(void); RefKeen_Patch_intro(); #endif /*extern void RefKeen_FillObjStatesWithDOSPointers(void); RefKeen_FillObjStatesWithDOSPointers(); // Saved games compatibility*/ }