Continue csfml

This commit is contained in:
Miloslav Číž 2020-10-26 15:51:35 +01:00
parent 72712103cb
commit 4ca5ea4420
2 changed files with 53 additions and 37 deletions

View File

@ -1,7 +1,7 @@
/** /**
@file main_csfml.c @file main_csfml.c
This is an csfml (C binding for SFML) implementation of the game front end. This is a csfml (C binding for SFML) implementation of the game front end.
This is another alternative to the SDL for the PC. This front end is more This is another alternative to the SDL for the PC. This front end is more
minimal and simple than the SDL, so it's better as a learning resource. minimal and simple than the SDL, so it's better as a learning resource.
@ -42,6 +42,8 @@ uint32_t paletteRGB32[256]; // SFML can't do 565, so precompute RGB here
sfClock *clock; sfClock *clock;
sfRenderWindow* window; sfRenderWindow* window;
uint8_t musicOn = 0;
int8_t SFG_keyPressed(uint8_t key) int8_t SFG_keyPressed(uint8_t key)
{ {
#define k(x) sfKeyboard_isKeyPressed(sfKey ## x) #define k(x) sfKeyboard_isKeyPressed(sfKey ## x)
@ -144,6 +146,13 @@ void SFG_setPixel(uint16_t x, uint16_t y, uint8_t colorIndex)
void SFG_setMusic(uint8_t value) void SFG_setMusic(uint8_t value)
{ {
switch (value)
{
case SFG_MUSIC_TURN_ON: musicOn = 1; break;
case SFG_MUSIC_TURN_OFF: musicOn = 0; break;
case SFG_MUSIC_NEXT: SFG_nextMusicTrack(); break;
default: break;
}
} }
void SFG_processEvent(uint8_t event, uint8_t data) void SFG_processEvent(uint8_t event, uint8_t data)
@ -175,10 +184,19 @@ uint8_t SFG_load(uint8_t data[SFG_SAVE_SIZE])
return 1; return 1;
} }
/* Because of the csfml sound API we won't use circular audio buffer, but a
linear buffer that is at each audio update shifted to the left. */
sfSoundStream *sound; sfSoundStream *sound;
#define AUDIO_BUFFER_SIZE (SFG_SFX_SAMPLE_COUNT * 2) #define AUDIO_BUFFER_SIZE (SFG_SFX_SAMPLE_COUNT * 2) // total size of the buffer
#define AUDIO_BUFFER_OFFSET 400 #define AUDIO_BUFFER_OFFSET 400 /* size of the beginning portion of the buffer
that's being played, while the other part
is being filled with audio */
#if AUDIO_BUFFER_OFFSET * 2 > AUDIO_BUFFER_SIZE
#error "AUDIO_BUFFER_OFFSET must be at most half of AUDIO_BUFFER_SIZE"
#endif
int16_t audioBuffer[AUDIO_BUFFER_SIZE]; int16_t audioBuffer[AUDIO_BUFFER_SIZE];
uint32_t audioUpdateFrame = 0; // game frame at which audio buffer fill happened uint32_t audioUpdateFrame = 0; // game frame at which audio buffer fill happened
@ -197,13 +215,13 @@ void SFG_playSound(uint8_t soundIndex, uint8_t volume)
for (int i = 0; i < SFG_SFX_SAMPLE_COUNT; ++i) for (int i = 0; i < SFG_SFX_SAMPLE_COUNT; ++i)
{ {
if (pos >= AUDIO_BUFFER_SIZE)
break;
audioBuffer[pos] = mixSamples(audioBuffer[pos], audioBuffer[pos] = mixSamples(audioBuffer[pos],
(128 - SFG_GET_SFX_SAMPLE(soundIndex,i)) * volumeScale); (128 - SFG_GET_SFX_SAMPLE(soundIndex,i)) * volumeScale);
pos++; pos++;
if (pos >= AUDIO_BUFFER_SIZE)
break;
} }
} }
@ -212,15 +230,17 @@ sfBool soundFill(sfSoundStreamChunk *data, void *userdata)
for (uint32_t i = 0; i < AUDIO_BUFFER_SIZE - AUDIO_BUFFER_OFFSET; ++i) for (uint32_t i = 0; i < AUDIO_BUFFER_SIZE - AUDIO_BUFFER_OFFSET; ++i)
audioBuffer[i] = audioBuffer[i + AUDIO_BUFFER_OFFSET]; audioBuffer[i] = audioBuffer[i + AUDIO_BUFFER_OFFSET];
for (uint32_t i = AUDIO_BUFFER_SIZE - AUDIO_BUFFER_OFFSET; i < AUDIO_BUFFER_SIZE; ++i) for (uint32_t i = AUDIO_BUFFER_SIZE - AUDIO_BUFFER_OFFSET;
i < AUDIO_BUFFER_SIZE; ++i)
audioBuffer[i] = 0; audioBuffer[i] = 0;
for (uint32_t i = 0; i < AUDIO_BUFFER_OFFSET; ++i) // mix in the music if (musicOn)
{ for (uint32_t i = 0; i < AUDIO_BUFFER_OFFSET; ++i) // mix in the music
audioBuffer[i] = mixSamples((SFG_getNextMusicSample() - {
SFG_musicTrackAverages[SFG_MusicState.track]) * MUSIC_VOLUME, audioBuffer[i] = mixSamples((SFG_getNextMusicSample() -
audioBuffer[i]); SFG_musicTrackAverages[SFG_MusicState.track]) * MUSIC_VOLUME,
} audioBuffer[i]);
}
data->samples = audioBuffer; data->samples = audioBuffer;
data->sampleCount = AUDIO_BUFFER_OFFSET; data->sampleCount = AUDIO_BUFFER_OFFSET;
@ -243,15 +263,10 @@ int main()
SFG_init(); SFG_init();
for (int i = 0; i < AUDIO_BUFFER_SIZE; ++i) for (int i = 0; i < AUDIO_BUFFER_SIZE; ++i)
audioBuffer[i] = SFG_getNextMusicSample() * 64; audioBuffer[i] = 0;
sound = sfSoundStream_create( soundFill,soundSeek ,1,8000,0);
sfSoundStream_play(sound);
sound = sfSoundStream_create(soundFill,soundSeek,1,8000,0);
for (int i = 0; i < 256; ++i) // precompute RGB palette for (int i = 0; i < 256; ++i) // precompute RGB palette
{ {
@ -261,7 +276,9 @@ sfSoundStream_play(sound);
((col565 << 5) & 0xfc00) | ((col565 >> 8) & 0xf8); ((col565 << 5) & 0xfc00) | ((col565 >> 8) & 0xf8);
} }
sfTexture* windowTexture = sfTexture_create(SFG_SCREEN_RESOLUTION_X,SFG_SCREEN_RESOLUTION_Y); sfTexture* windowTexture =
sfTexture_create(SFG_SCREEN_RESOLUTION_X,SFG_SCREEN_RESOLUTION_Y);
sfTexture_setSmooth(windowTexture,sfTrue); sfTexture_setSmooth(windowTexture,sfTrue);
sfSprite* windowSprite = sfSprite_create(); sfSprite* windowSprite = sfSprite_create();
@ -272,7 +289,7 @@ sfSoundStream_play(sound);
sfWindow_setMouseCursorVisible((sfWindow *) window,sfFalse); sfWindow_setMouseCursorVisible((sfWindow *) window,sfFalse);
sfWindow_setVerticalSyncEnabled((sfWindow *) window,sfFalse); sfWindow_setVerticalSyncEnabled((sfWindow *) window,sfFalse);
sfSoundStream_play(sound);
while (sfRenderWindow_isOpen(window)) while (sfRenderWindow_isOpen(window))
{ {
@ -283,21 +300,19 @@ sfSoundStream_play(sound);
if (!SFG_mainLoopBody()) if (!SFG_mainLoopBody())
break; break;
sfTexture_updateFromPixels(windowTexture,(const sfUint8 *) windowPixels,SFG_SCREEN_RESOLUTION_X,SFG_SCREEN_RESOLUTION_Y,0,0); sfTexture_updateFromPixels(windowTexture,(const sfUint8 *) windowPixels,
SFG_SCREEN_RESOLUTION_X,SFG_SCREEN_RESOLUTION_Y,0,0);
sfRenderWindow_clear(window, sfBlack); sfRenderWindow_clear(window, sfBlack);
sfRenderWindow_drawSprite(window, windowSprite, NULL); sfRenderWindow_drawSprite(window,windowSprite,NULL);
sfRenderWindow_display(window); sfRenderWindow_display(window);
} }
sfSoundStream_stop(sound); sfSoundStream_stop(sound);
sfSoundStream_destroy(sound); sfSoundStream_destroy(sound);
sfSprite_destroy(windowSprite); sfSprite_destroy(windowSprite);
sfTexture_destroy(windowTexture); sfTexture_destroy(windowTexture);
sfRenderWindow_destroy(window); sfRenderWindow_destroy(window);
sfClock_destroy(clock); sfClock_destroy(clock);
return 0; return 0;
} }

View File

@ -34,7 +34,7 @@
// #define SFG_TIME_MULTIPLIER 512 // #define SFG_TIME_MULTIPLIER 512
// uncomment for perfomance debug // uncomment for perfomance debug
#define SFG_CPU_LOAD(percent) printf("CPU load: %d%\n",percent); // #define SFG_CPU_LOAD(percent) printf("CPU load: %d%\n",percent);
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
#ifndef GAME_LQ #ifndef GAME_LQ
@ -229,7 +229,7 @@ int8_t SFG_keyPressed(uint8_t key)
if (sdlMouseWheelState > 0) if (sdlMouseWheelState > 0)
{ {
sdlMouseWheelState--; sdlMouseWheelState = 0;
return 1; return 1;
} }
@ -242,7 +242,7 @@ int8_t SFG_keyPressed(uint8_t key)
if (sdlMouseWheelState < 0) if (sdlMouseWheelState < 0)
{ {
sdlMouseWheelState++; sdlMouseWheelState = 0;
return 1; return 1;
} }
@ -273,9 +273,9 @@ void mainLoopIteration()
if (event.type == SDL_MOUSEWHEEL) if (event.type == SDL_MOUSEWHEEL)
{ {
if (event.wheel.y > 0) // scroll up if (event.wheel.y > 0) // scroll up
sdlMouseWheelState++; sdlMouseWheelState = 1;
else if (event.wheel.y < 0) // scroll down else if (event.wheel.y < 0) // scroll down
sdlMouseWheelState--; sdlMouseWheelState = -1;
} }
else if (event.type == SDL_QUIT) else if (event.type == SDL_QUIT)
running = 0; running = 0;
@ -343,8 +343,9 @@ void SFG_setMusic(uint8_t value)
void SFG_playSound(uint8_t soundIndex, uint8_t volume) void SFG_playSound(uint8_t soundIndex, uint8_t volume)
{ {
uint16_t pos = audioPos + uint16_t pos = (audioPos +
((SFG_game.frame - audioUpdateFrame) * SFG_MS_PER_FRAME * 8); ((SFG_game.frame - audioUpdateFrame) * SFG_MS_PER_FRAME * 8)) %
SFG_SFX_SAMPLE_COUNT;
uint16_t volumeScale = 1 << (volume / 37); uint16_t volumeScale = 1 << (volume / 37);