Esempio n. 1
1
int main(void) {

    PlatformState state;
    SDL_Event e;
    SDL_Window *window;
    SDL_Renderer *renderer;
    SDLInputContext sdlIC;
    SDLSoundRingBuffer srb;
    GameSoundOutput sb;
    GameMemory gameMemory;

    //controller input state
    InputContext inputStates[2]; //contains old and new state
    InputContext* newInputState = &inputStates[0];
    InputContext* oldInputState = &inputStates[1];
    real32_t secsSinceLastFrame = 0;


    sb.volume = 2500;

    gameMemory.permanentStorageSize = MB(64);
    gameMemory.transientStorageSize = MB(64);
    state.gameMemorySize = gameMemory.transientStorageSize + gameMemory.permanentStorageSize;
    state.memoryBlock = mmap(nullptr, state.gameMemorySize, PROT_READ | PROT_WRITE,
            MAP_ANONYMOUS | MAP_PRIVATE ,
            -1,
            0);
    gameMemory.permanentStorage = state.memoryBlock;
    gameMemory.transientStorage = (uint8_t*)(gameMemory.transientStorage) + gameMemory.transientStorageSize;


    initSDL(&window, &renderer, &gOsb, &sdlIC, &srb);

    GameCode gameCode = loadGameCode();

    assert(gameCode.guarf);

    uint64_t startCount = SDL_GetPerformanceCounter();
    real32_t targetFrameSeconds = 1./getRefreshRate(window);

    SDL_PauseAudio(0);
    while(state.running) {

        if(getCreateTimeOfFile(GAME_LIB_PATH) != gameCode.dateLastModified) {
            reloadGameCode(&gameCode);
        }

        //keyboard input
        ControllerInput* newKeyInput = getContoller(newInputState, 0);

        //TODO: figure out why this is special
        ControllerInput* oldKeyInput = getContoller(oldInputState, 0);
        *newKeyInput = {};

        for(size_t i = 0; i < ARRAY_SIZE(oldKeyInput->buttons); i++) {
            newKeyInput->buttons[i] = oldKeyInput->buttons[i];
        }
        while(SDL_PollEvent(&e)) {
            processEvent(&e, newInputState, &state);
        }


        //controller input
        for(int i = 0; i < MAX_SDL_CONTROLLERS; i++) {
            if(sdlIC.controllers[i] != nullptr && SDL_GameControllerGetAttached(sdlIC.controllers[i])) {

                ControllerInput* newCIState = getContoller(newInputState, i+1);
                ControllerInput* oldCIState = getContoller(oldInputState, i+1);


                int16_t xVal = SDL_GameControllerGetAxis(sdlIC.controllers[i], SDL_CONTROLLER_AXIS_LEFTX);
                int16_t yVal = SDL_GameControllerGetAxis(sdlIC.controllers[i], SDL_CONTROLLER_AXIS_LEFTY);

                newCIState->avgX = normalizeStickInput(xVal, LEFT_THUMB_DEADZONE);
                newCIState->avgY = normalizeStickInput(yVal, LEFT_THUMB_DEADZONE);

                if(newCIState->avgX != 0 || newCIState->avgY != 0) {
                    newCIState->isAnalog = true;
                }

                processControllerButtonInput(&newCIState->actionDown, &oldCIState->actionDown, &newCIState->isAnalog, sdlIC.controllers[i], SDL_CONTROLLER_BUTTON_A);
                processControllerButtonInput(&newCIState->actionUp, &oldCIState->actionUp, &newCIState->isAnalog, sdlIC.controllers[i], SDL_CONTROLLER_BUTTON_Y);
                processControllerButtonInput(&newCIState->actionLeft, &oldCIState->actionLeft, &newCIState->isAnalog, sdlIC.controllers[i], SDL_CONTROLLER_BUTTON_X);
                processControllerButtonInput(&newCIState->actionRight, &oldCIState->actionRight, &newCIState->isAnalog, sdlIC.controllers[i], SDL_CONTROLLER_BUTTON_B);

                processControllerButtonInput(&newCIState->directionDown, &oldCIState->directionDown, &newCIState->isAnalog, sdlIC.controllers[i], SDL_CONTROLLER_BUTTON_DPAD_DOWN);
                processControllerButtonInput(&newCIState->directionUp, &oldCIState->directionUp, &newCIState->isAnalog, sdlIC.controllers[i], SDL_CONTROLLER_BUTTON_DPAD_UP);
                processControllerButtonInput(&newCIState->directionLeft, &oldCIState->directionLeft, &newCIState->isAnalog, sdlIC.controllers[i], SDL_CONTROLLER_BUTTON_DPAD_LEFT);
                processControllerButtonInput(&newCIState->directionRight, &oldCIState->directionRight, &newCIState->isAnalog, sdlIC.controllers[i], SDL_CONTROLLER_BUTTON_DPAD_RIGHT);

                oldCIState->isAnalog = newCIState->isAnalog;


            }
            else {
                //TODO: Logging
            }
        }


        //TODO: Do this instead of processing input, not after
        //process recording/playback
        assert(!(state.isRecording && state.isPlayingBack));

        if(state.isRecording) {
            recordInput(newInputState, state.inputRecordFile);
        }

        if(state.isPlayingBack) {
            playInput(newInputState, state.inputRecordFile);
        }

        //calculate audio buffers' indicies and sizes
        SDL_LockAudioDevice(1);
        uint32_t startIndex = srb.runningIndex % ARRAY_SIZE(srb.samples);
        uint32_t endIndex = (srb.sampleToPlay + SOUND_LATENCY) % ARRAY_SIZE(srb.samples);
        uint32_t samplesToGetFromGame = (startIndex <= endIndex) ? endIndex - startIndex : (ARRAY_SIZE(srb.samples) - startIndex) + endIndex; 
        sb.numSamples = samplesToGetFromGame;
        SDL_UnlockAudioDevice(1);



        gameCode.guarf(&gameMemory, &gOsb, &sb, newInputState, secsSinceLastFrame);

        updateSDLSoundBuffer(&srb, &sb, startIndex, endIndex);
        updateWindow(window, gTexture);

        InputContext* temp = newInputState;
        newInputState = oldInputState;
        oldInputState = temp;

        //benchmark stuff

        real32_t secsElapsed = secondsForCountRange(startCount, SDL_GetPerformanceCounter());

        //sleep to lock frame rate
        if(secsElapsed < targetFrameSeconds) {


            //NOTE: .5 denotes the amount we will spin manually since
            //      SDL_Delay is not 100% accurate
            real32_t timeToSleep = (targetFrameSeconds - secsElapsed)*1000 - .5;
            SDL_Delay(timeToSleep);
            secsElapsed = secondsForCountRange(startCount, SDL_GetPerformanceCounter());
            
            //This assert will fire if the window is moved
            //assert(secondsForCountRange(startCount, SDL_GetPerformanceCounter()) < targetFrameSeconds); 
            
            while(secondsForCountRange(startCount, SDL_GetPerformanceCounter()) < targetFrameSeconds) {
                //wait
            }
            secsElapsed = secondsForCountRange(startCount, SDL_GetPerformanceCounter());
        }
        uint64_t endCount = SDL_GetPerformanceCounter();
        real32_t fpsCount =  ((1./secsElapsed));
        real32_t mcPerFrame = (real32_t)(endCount-startCount) / (1000 * 1000 );


        printf("TPF: %.2fms FPS: %.2f MCPF: %.2f\n", secsElapsed*1000, fpsCount, mcPerFrame);

        startCount = endCount;
        secsSinceLastFrame = secsElapsed;
    }

    cleanUp(&state, &gameCode);
    return 0;
}
Esempio n. 2
0
void snd_PlayStreaming( int streamID, float volume, float pan ) // todo: fade in?
{
	assert( ( streamID >= 0 ) && ( streamID < MAX_STREAMING_SOUNDS ) );
	SDL_LockAudioDevice( devID ); {
		if( ( streamingSounds[streamID].access != NULL ) && !streamingSounds[streamID].playing ) {

			streamingSounds[streamID].sdlStream = SDL_NewAudioStream( AUDIO_S16,
				(Uint8)( streamingSounds[streamID].access->channels ), streamingSounds[streamID].access->sample_rate,
				WORKING_FORMAT, streamingSounds[streamID].channels, WORKING_RATE );

			if( streamingSounds[streamID].sdlStream == NULL ) {
				llog( LOG_ERROR, "Unable to create SDL_AudioStream for streaming sound." );
				return;
			}

			streamingSounds[streamID].playing = true;
			streamingSounds[streamID].volume = volume;
			streamingSounds[streamID].pan = pan;

			stb_vorbis_seek_start( streamingSounds[streamID].access );

			streamingSounds[streamID].readDone = false;
		}
	} SDL_UnlockAudioDevice( devID );
}
Esempio n. 3
0
void snd_ChangeStreamPan( int streamID, float pan )
{
	assert( ( streamID >= 0 ) && ( streamID < MAX_STREAMING_SOUNDS ) );
	SDL_LockAudioDevice( devID ); {
		streamingSounds[streamID].pan = pan;
	} SDL_UnlockAudioDevice( devID );
}
Esempio n. 4
0
void snd_ChangeStreamVolume( int streamID, float volume )
{
	assert( ( streamID >= 0 ) && ( streamID < MAX_STREAMING_SOUNDS ) );
	SDL_LockAudioDevice( devID ); {
		streamingSounds[streamID].volume = volume;
	} SDL_UnlockAudioDevice( devID );
}
Esempio n. 5
0
void SDL2Sink::EnqueueSamples(const s16* samples, size_t sample_count) {
    if (impl->audio_device_id <= 0)
        return;

    SDL_LockAudioDevice(impl->audio_device_id);
    impl->queue.emplace_back(samples, samples + sample_count * 2);
    SDL_UnlockAudioDevice(impl->audio_device_id);
}
void SDLAudioContext::PauseAudio(AudioObject& ao)
{
	SDL_LockAudioDevice(m_device);

	RemoveAudio(ao);

	SDL_UnlockAudioDevice(m_device);
}
Esempio n. 7
0
// Volume is assumed to be [0,1]
void snd_ChangeSoundVolume( EntityID soundID, float volume )
{
	SDL_LockAudioDevice( devID ); {
		if( idSet_IsIDValid( &playingIDSet, soundID ) ) {
			int idx = idSet_GetIndex( soundID );
			playingSounds[idx].volume = volume;
		}
	} SDL_UnlockAudioDevice( devID );
}
Esempio n. 8
0
void snd_StopStreaming( int streamID )
{
	assert( ( streamID >= 0 ) && ( streamID < MAX_STREAMING_SOUNDS ) );
	SDL_LockAudioDevice( devID ); {
		streamingSounds[streamID].playing = false;
		SDL_FreeAudioStream( streamingSounds[streamID].sdlStream );
		streamingSounds[streamID].sdlStream = NULL;
	} SDL_UnlockAudioDevice( devID );
}
Esempio n. 9
0
void snd_SetVolume( float volume, unsigned int group )
{
	assert( group < sb_Count( sbSoundGroups ) );
	assert( ( volume >= 0.0f ) && ( volume <= 1.0f ) );

	SDL_LockAudioDevice( devID ); {
		sbSoundGroups[group].volume = volume;
	} SDL_UnlockAudioDevice( devID );
}
Esempio n. 10
0
// Pan is assumed to be [-1,1]
void snd_ChangeSoundPan( EntityID soundID, float pan )
{
	SDL_LockAudioDevice( devID ); {
		if( idSet_IsIDValid( &playingIDSet, soundID ) ) {
			int idx = idSet_GetIndex( soundID );
			playingSounds[idx].pan = pan;
		}
	} SDL_UnlockAudioDevice( devID );
}
void SDLAudioContext::PlayAudio(AudioObject& ao)
{
	SDL_LockAudioDevice(m_device);

	// This prevents duplicates
	RemoveAudio(ao);
	m_playingAudio.push_back(&ao);

	SDL_UnlockAudioDevice(m_device);
}
Esempio n. 12
0
static void *SSDL_LockBuffer(soundcardinfo_t *sc, unsigned int *sampidx)
{
#if SDL_MAJOR_VERSION >= 2
	SDL_LockAudioDevice(sc->audio_fd);
#else
	SDL_LockAudio();
#endif

	return sc->sn.buffer;
}
Esempio n. 13
0
void AudioManager::add_sound(std::shared_ptr<SoundImpl> sound) {
	SDL_LockAudioDevice(device_id);

	auto category = sound->get_category();
	auto &playing_list = playing_sounds.find(category)->second;
	// TODO probably check if sound already exists in playing list
	playing_list.push_back(sound);

	SDL_UnlockAudioDevice(device_id);
}
Esempio n. 14
0
/**
 * \brief Locks and unlocks open audio device.
 *
 * \sa https://wiki.libsdl.org/SDL_LockAudioDevice
 * \sa https://wiki.libsdl.org/SDL_UnlockAudioDevice
 */
int audio_lockUnlockOpenAudioDevice()
{
   int i;
   int count;
   char *device;
   SDL_AudioDeviceID id;
   SDL_AudioSpec desired, obtained;

   /* Get number of devices. */
   count = SDL_GetNumAudioDevices(0);
   SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(0)");
   if (count > 0) {
     for (i = 0; i < count; i++) {
       /* Get device name */
       device = (char *)SDL_GetAudioDeviceName(i, 0);
       SDLTest_AssertPass("SDL_GetAudioDeviceName(%i,0)", i);
       SDLTest_AssertCheck(device != NULL, "Validate device name is not NULL; got: %s", (device != NULL) ? device : "NULL");
       if (device == NULL) return TEST_ABORTED;

       /* Set standard desired spec */
       desired.freq=22050;
       desired.format=AUDIO_S16SYS;
       desired.channels=2;
       desired.samples=4096;
       desired.callback=_audio_testCallback;
       desired.userdata=NULL;

       /* Open device */
       id = SDL_OpenAudioDevice((const char *)device, 0, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE);
       SDLTest_AssertPass("SDL_OpenAudioDevice('%s',...)", device);
       SDLTest_AssertCheck(id > 1, "Validate device ID; expected: >=2, got: %i", id);
       if (id > 1) {
         /* Lock to protect callback */
         SDL_LockAudioDevice(id);
         SDLTest_AssertPass("SDL_LockAudioDevice(%i)", id);

         /* Simulate callback processing */
         SDL_Delay(10);
         SDLTest_Log("Simulate callback processing - delay");

         /* Unlock again */
         SDL_UnlockAudioDevice(id);
         SDLTest_AssertPass("SDL_UnlockAudioDevice(%i)", id);

         /* Close device again */
         SDL_CloseAudioDevice(id);
         SDLTest_AssertPass("Call to SDL_CloseAudioDevice()");
       }
     }
   } else {
     SDLTest_Log("No devices to test with");
   }

   return TEST_COMPLETED;
}
void SDLAudioContext::StopAudio(AudioObject& ao)
{
	SDL_LockAudioDevice(m_device);

	if(RemoveAudio(ao))
	{
		ao.SetPos(0.0);
	}

	SDL_UnlockAudioDevice(m_device);
}
Esempio n. 16
0
void snd_UnloadStream( int streamID )
{
	assert( ( streamID >= 0 ) && ( streamID < MAX_STREAMING_SOUNDS ) );
	SDL_LockAudioDevice( devID ); {
		streamingSounds[streamID].playing = false;
		stb_vorbis_close( streamingSounds[streamID].access );
		streamingSounds[streamID].access = NULL;
		SDL_FreeAudioStream( streamingSounds[streamID].sdlStream );
		streamingSounds[streamID].sdlStream = NULL;
	} SDL_UnlockAudioDevice( devID );
}
Esempio n. 17
0
void snd_SetMasterVolume( float volume )
{
	SDL_LockAudioDevice( devID ); {
		masterVolume = volume;
	} SDL_UnlockAudioDevice( devID );

	// just save this out every single time
	if( soundCfgFile != NULL ) {
		cfg_SetInt( soundCfgFile, "vol", (int)volume );
		cfg_SaveFile( soundCfgFile );
	}
}
Esempio n. 18
0
void snd_StopStreamingAllBut( int streamID )
{
	SDL_LockAudioDevice( devID ); {
		for( int i = 0; i < MAX_STREAMING_SOUNDS; ++i ) {
			if( i == streamID ) continue;
			if( ( streamingSounds[i].access != NULL ) && streamingSounds[i].playing ) {
				streamingSounds[i].playing = false;
				SDL_FreeAudioStream( streamingSounds[streamID].sdlStream );
				streamingSounds[streamID].sdlStream = NULL;
			}
		}
	} SDL_UnlockAudioDevice( devID );
}
Esempio n. 19
0
void snd_CleanUp( )
{
	snd_StopStreamingAllBut( -1 );
	if( workingBuffer != NULL ) {
		SDL_LockAudioDevice( devID ); {
			sb_Release( sbStreamWorkingBuffer );
			mem_Release( workingBuffer );
			workingBuffer = NULL;
		} SDL_UnlockAudioDevice( devID );
	}

	if( devID == 0 ) return;
	SDL_CloseAudioDevice( devID );
}
Esempio n. 20
0
void AudioManager::remove_sound(std::shared_ptr<SoundImpl> sound) {
	SDL_LockAudioDevice(device_id);

	auto category = sound->get_category();
	auto &playing_list = playing_sounds.find(category)->second;

	for (size_t i = 0; i < playing_list.size(); i++) {
		if (playing_list[i] == sound) {
			remove_from_vector(playing_list, i);
			break;
		}
	}

	SDL_UnlockAudioDevice(device_id);
}
Esempio n. 21
0
size_t SDL2Sink::SamplesInQueue() const {
    if (impl->audio_device_id <= 0)
        return 0;

    SDL_LockAudioDevice(impl->audio_device_id);

    size_t total_size = std::accumulate(impl->queue.begin(), impl->queue.end(), static_cast<size_t>(0),
        [](size_t sum, const auto& buffer) {
            // Division by two because each stereo sample is made of two s16.
            return sum + buffer.size() / 2;
        });

    SDL_UnlockAudioDevice(impl->audio_device_id);

    return total_size;
}
Esempio n. 22
0
static void sdl_fill_audio_ring_buffer(sdl_audio_ring_buffer_t* ring_buffer, memory_block_t* sound_samples, int32_t bytes_to_write)
{
	int32_t region1_size, region2_size;
	int16_t* region1;
	int16_t* region2;

	SDL_LockAudioDevice(1);
	region1_size = bytes_to_write;
	region2_size = 0;
	if ((ring_buffer->write_index + region1_size) > ring_buffer->size) {
		region1_size = ring_buffer->size - ring_buffer->write_index;
		region2_size = bytes_to_write - region1_size;
	}

	memcpy(ring_buffer->data + ring_buffer->write_index, sound_samples->base, region1_size);
	memcpy(ring_buffer->data, (uint8_t*)sound_samples->base + region1_size, region2_size);
	ring_buffer->write_index = (ring_buffer->write_index + bytes_to_write) % ring_buffer->size;
	SDL_UnlockAudioDevice(1);
}
Esempio n. 23
0
// Returns an id that can be used to change the volume and pitch
//  loops - if the sound will loop back to the start once it's over
//  volume - how loud the sound will be, in the range [0,1], 0 being off, 1 being loudest
//  pitch - pitch change for the sound, multiplies the sample rate, 1 for normal, lesser for slower, higher for faster
//  pan - how far left or right the sound is, 0 is center, -1 is left, +1 is right
// TODO: Some sort of event system so we can get when a sound has finished playing?
EntityID snd_Play( int sampleID, float volume, float pitch, float pan, unsigned int group )
{
	assert( group >= 0 );
	assert( group < sb_Count( sbSoundGroups ) );

	EntityID playingID = INVALID_ENTITY_ID;
	SDL_LockAudioDevice( devID ); {
		playingID = idSet_ClaimID( &playingIDSet );
		if( playingID != INVALID_ENTITY_ID ) {
			int idx = idSet_GetIndex( playingID );
			playingSounds[idx].sample = sampleID;
			playingSounds[idx].volume = volume;
			playingSounds[idx].pitch = pitch;
			playingSounds[idx].pan = pan;
			playingSounds[idx].pos = 0.0f;
			playingSounds[idx].group = group;
		}
	} SDL_UnlockAudioDevice( devID );

	return playingID;
}
Esempio n. 24
0
void snd_UnloadSample( int sampleID )
{
	assert( sampleID >= 0 );
	assert( sampleID < MAX_SAMPLES );

	if( samples[sampleID].data == NULL ) {
		return;
	}

	SDL_LockAudioDevice( devID ); {
		// find all playing sounds using this sample and stop them
		for( EntityID id = idSet_GetFirstValidID( &playingIDSet ); id != INVALID_ENTITY_ID; id = idSet_GetNextValidID( &playingIDSet, id ) ) {
			int idx = idSet_GetIndex( id );
			if( playingSounds[idx].sample == sampleID ) {
				idSet_ReleaseID( &playingIDSet, id );
			}
		}

		mem_Release( samples[sampleID].data );
		samples[sampleID].data = NULL;
	} SDL_UnlockAudioDevice( devID );
}
Esempio n. 25
0
void lock_audio() { SDL_LockAudioDevice(audio_device_id); }
Esempio n. 26
0
void snd_SetFocus( bool hasFocus )
{
	SDL_LockAudioDevice( devID ); {
		SDL_PauseAudioDevice( devID, hasFocus ? 0 : 1 );
	} SDL_UnlockAudioDevice( devID );
}
Esempio n. 27
0
void snd_Stop( EntityID soundID )
{
	SDL_LockAudioDevice( devID ); {
		idSet_ReleaseID( &playingIDSet, soundID );
	} SDL_UnlockAudioDevice( devID );
}
Esempio n. 28
0
void Mixer::Lock()
{
	SDL_LockAudioDevice(deviceid);
}
Esempio n. 29
0
void Mix_LockAudio()
{
    SDL_LockAudioDevice(audio_device);
}
Esempio n. 30
0
/* Sets up the SDL mixer. Returns 0 on success. */
int snd_Init( unsigned int numGroups )
{
	assert( numGroups > 0 );

	// clear out the samples storage
	SDL_memset( samples, 0, ARRAY_SIZE( samples ) * sizeof( samples[0] ) );
	for( int i = 0; i < MAX_STREAMING_SOUNDS; ++i ) {
		streamingSounds[i].access = NULL;
		streamingSounds[i].sdlStream = NULL;
		streamingSounds[i].playing = false;
	}

	SDL_AudioSpec desired;
	SDL_memset( &desired, 0, sizeof( desired ) );
	desired.freq = WORKING_RATE;
	desired.format = WORKING_FORMAT;
	desired.channels = WORKING_CHANNELS;
	desired.samples = AUDIO_SAMPLES;
	desired.callback = mixerCallback;
	desired.userdata = NULL;

	if( idSet_Init( &playingIDSet, MAX_PLAYING_SOUNDS ) != 0 ) {
		llog( LOG_CRITICAL, "Failed to create playing sounds id set."  );
		return -1;
	}

	// sending 0 will cause SDL to convert everything automatically
	devID = SDL_OpenAudioDevice( NULL, 0, &desired, NULL, 0 );

	if( devID == 0 ) {
		llog( LOG_CRITICAL, "Failed to open audio device: %s", SDL_GetError( ) );
		return -1;
	}
	SDL_PauseAudioDevice( devID, 0 );

	workingSilence = desired.silence;

	workingBufferSize = desired.samples * desired.channels * ( ( SDL_AUDIO_MASK_BITSIZE & WORKING_FORMAT ) / 8 );

	SDL_LockAudioDevice( devID );
	workingBuffer = mem_Allocate( workingBufferSize );
	SDL_UnlockAudioDevice( devID );
	if( workingBuffer == NULL ) {
		llog( LOG_CRITICAL, "Failed to create audio working buffer." );
		return -1;
	}

	sb_Add( sbSoundGroups, numGroups );
	for( size_t i = 0; i < sb_Count( sbSoundGroups ); ++i ) {
		sbSoundGroups[i].volume = 1.0f;
	}

	// load the master volume
	soundCfgFile = cfg_OpenFile( "snd.cfg" );
	if( soundCfgFile != NULL ) {
		int vol;
		cfg_GetInt( soundCfgFile, "vol", 1, &vol );
		masterVolume = (float)vol;
	} else {
		masterVolume = 1.0f;
	}

	return 0;
}