/** @file frontend_csfml.c CSFML frontend for Licar. */ #include #include #include #include #include #include #ifndef PRESET_QUALITY #define PRESET_QUALITY 3 #endif #include "frontend_helper.h" #include "game.h" #define WINDOW_SIZE (LCR_SETTING_RESOLUTION_X * LCR_SETTING_RESOLUTION_Y) sfUint32 windowPixels[WINDOW_SIZE * 2]; uint8_t fullscreen = 1; FILE *musicFile = 0; sfClock *clock; sfRenderWindow* window; sfSoundStream *sound; #define AUDIO_BUFFER_SIZE 256 int16_t audioBuffer[AUDIO_BUFFER_SIZE]; uint8_t musicBuffer[AUDIO_BUFFER_SIZE]; uint8_t LCR_keyPressed(uint8_t key) { #define k(x) sfKeyboard_isKeyPressed(sfKey ## x) switch (key) { case LCR_KEY_UP: return k(W) || k(Up) || k(Num8); break; case LCR_KEY_RIGHT: return k(E) || k(Right) || k(Num6); break; case LCR_KEY_DOWN: return k(S) || k(Down) || k(Num5) || k(Num2); break; case LCR_KEY_LEFT: return k(Q) || k(Left) || k(Num4); break; case LCR_KEY_A: return k(K) || k(Return); break; case LCR_KEY_B: return k(L) || k(Escape); break; default: break; } return 0; } void LCR_sleep(uint16_t timeMs) { sfTime t; t.microseconds = timeMs * 1000; sfSleep(t); } void LCR_drawPixel(unsigned long index, uint16_t color) { windowPixels[index] = 0xff000000 | ((color & 0x07e0) << 5) | (((color << 19) | (color >> 8)) & 0x00f800f8) ; } void printHelp(void) { printf( "Licar, 3D racing game, v. " LCR_VERSION ", CSFML frontend, args:\n" " -h print help and quit\n" " -wN window (N = 1) or fullscreen (N = 0)\n" LCR_ARG_HELP_STR); } sfBool soundFill(sfSoundStreamChunk *data, void *userdata) { if (musicFile && LCR_gameMusicOn()) { if (!fread(musicBuffer,1,AUDIO_BUFFER_SIZE,musicFile)) rewind(musicFile); for (int i = 0; i < AUDIO_BUFFER_SIZE; ++i) audioBuffer[i] = musicBuffer[i]; } else for (int i = 0; i < AUDIO_BUFFER_SIZE; ++i) audioBuffer[i] = 127; for (int i = 0; i < AUDIO_BUFFER_SIZE; ++i) audioBuffer[i] = (audioBuffer[i] + LCR_gameGetNextAudioSample() - 255) * 64; data->samples = audioBuffer; data->sampleCount = AUDIO_BUFFER_SIZE; return sfTrue; } void soundSeek(sfTime t, void *userData) { } int main(int argc, char *argv[]) { for (int i = 0; i < argc; ++i) if (argv[i][0] == '-') switch (argv[i][1]) { case 'h': printHelp(); return 0; break; case 'w': fullscreen = argv[i][2] == '0'; break; default: break; } openDataFile(); musicFile = fopen("assets/music","rb"); if (!musicFile) fputs("could not open music file",stderr); puts("initializing game"); LCR_gameInit(argc,(const char **) argv); puts("initializing SFML"); sfVideoMode mode = {LCR_SETTING_RESOLUTION_X,LCR_SETTING_RESOLUTION_Y,32}; sfEvent event; clock = sfClock_create(); sfClock_restart(clock); puts("initializing audio"); for (int i = 0; i < AUDIO_BUFFER_SIZE; ++i) audioBuffer[i] = 0; sound = sfSoundStream_create(soundFill,soundSeek,1,8000,0); sfTexture* windowTexture = sfTexture_create(LCR_SETTING_RESOLUTION_X,LCR_SETTING_RESOLUTION_Y); sfTexture_setSmooth(windowTexture,sfTrue); sfSprite* windowSprite = sfSprite_create(); window = sfRenderWindow_create(mode,"Licar", fullscreen ? sfFullscreen : (sfResize | sfClose ),NULL); sfSprite_setTexture(windowSprite,windowTexture,sfTrue); sfWindow_setVerticalSyncEnabled((sfWindow *) window,sfFalse); sfSoundStream_play(sound); puts("starting"); while (sfRenderWindow_isOpen(window)) { while (sfRenderWindow_pollEvent(window,&event)) if (event.type == sfEvtClosed) sfRenderWindow_close(window); if (!LCR_gameStep(sfClock_getElapsedTime(clock).microseconds / 1000)) break; sfTexture_updateFromPixels(windowTexture,(const sfUint8 *) windowPixels, LCR_SETTING_RESOLUTION_X,LCR_SETTING_RESOLUTION_Y,0,0); sfRenderWindow_clear(window,sfBlack); sfRenderWindow_drawSprite(window,windowSprite,NULL); sfRenderWindow_display(window); } puts("ending"); if (musicFile) fclose(musicFile); closeDataFile(); sfSoundStream_stop(sound); sfSoundStream_destroy(sound); sfSprite_destroy(windowSprite); sfTexture_destroy(windowTexture); sfRenderWindow_destroy(window); sfClock_destroy(clock); LCR_gameEnd(); return 0; }