Licar/frontend_sdl.c

253 lines
4.9 KiB
C
Raw Normal View History

2023-09-10 14:43:20 +02:00
#include <stdio.h>
#include <SDL2/SDL.h>
2024-09-28 01:47:05 +02:00
#define LCR_SETTING_LOG_LEVEL 2
2024-09-27 00:08:52 +02:00
2025-01-20 21:33:05 +01:00
#define DATA_FILE_NAME "data"
2023-08-03 21:12:23 +02:00
#include "game.h"
2023-09-10 14:43:20 +02:00
SDL_Window *window;
SDL_Renderer *renderer;
SDL_Texture *texture;
SDL_Surface *screenSurface;
uint16_t screen[LCR_SETTING_RESOLUTION_X * LCR_SETTING_RESOLUTION_Y];
2024-12-21 17:50:27 +01:00
FILE *musicFile = 0;
2025-01-20 21:33:05 +01:00
FILE *dataFile = 0;
2024-12-21 17:50:27 +01:00
2025-01-20 19:58:56 +01:00
char LCR_getNextDataFileChar(void)
2024-12-30 00:49:41 +01:00
{
2025-01-20 21:33:05 +01:00
if (!dataFile)
return 0;
int c = fgetc(dataFile);
if (c == EOF)
{
rewind(dataFile);
return 0;
}
return c;
2024-12-30 00:49:41 +01:00
}
2025-01-20 19:58:56 +01:00
void LCR_appendDataStr(const char *str)
2024-12-30 00:49:41 +01:00
{
2025-01-20 21:33:05 +01:00
if (!dataFile)
return;
if (*str == 0)
rewind(dataFile);
else
{
fclose(dataFile);
dataFile = fopen(DATA_FILE_NAME,"a");
if (dataFile)
{
fprintf(dataFile,"%s",str);
fclose(dataFile);
dataFile = fopen(DATA_FILE_NAME,"r");
}
}
2024-12-30 00:49:41 +01:00
}
2024-12-21 17:50:27 +01:00
void audioFillCallback(void *userdata, uint8_t *s, int l)
{
2025-01-07 13:17:41 +01:00
if (musicFile && LCR_gameMusicOn())
2024-12-21 17:50:27 +01:00
{
2024-12-27 07:45:27 +01:00
if (!fread(s,1,l,musicFile))
rewind(musicFile);
2024-12-21 17:50:27 +01:00
}
2025-01-07 13:17:41 +01:00
else
for (int i = 0; i < l; ++i)
s[i] = 128;
2024-12-27 07:45:27 +01:00
for (int i = 0; i < l; ++i)
s[i] = s[i] / 2 + LCR_gameGetNextAudioSample() / 2;
2024-12-21 17:50:27 +01:00
}
2023-09-10 14:43:20 +02:00
const uint8_t *keyboardState;
uint8_t LCR_keyPressed(uint8_t key)
{
switch (key)
{
case LCR_KEY_UP: return
keyboardState[SDL_SCANCODE_W] | keyboardState[SDL_SCANCODE_UP]; break;
case LCR_KEY_RIGHT: return
keyboardState[SDL_SCANCODE_D] | keyboardState[SDL_SCANCODE_RIGHT]; break;
case LCR_KEY_DOWN: return
2025-02-04 00:15:45 +01:00
keyboardState[SDL_SCANCODE_S] | keyboardState[SDL_SCANCODE_DOWN] |
keyboardState[SDL_SCANCODE_SPACE]; break;
2023-09-10 14:43:20 +02:00
case LCR_KEY_LEFT: return
keyboardState[SDL_SCANCODE_A] | keyboardState[SDL_SCANCODE_LEFT]; break;
case LCR_KEY_A: return
keyboardState[SDL_SCANCODE_K] | keyboardState[SDL_SCANCODE_RETURN]; break;
case LCR_KEY_B: return
keyboardState[SDL_SCANCODE_L] | keyboardState[SDL_SCANCODE_ESCAPE]; break;
default: break;
}
return 0;
}
void LCR_sleep(uint16_t timeMs)
{
2023-09-17 13:21:19 +02:00
usleep(timeMs * 1000);
2023-09-10 14:43:20 +02:00
}
2024-07-22 01:16:16 +02:00
void LCR_drawPixel(unsigned long index, uint16_t color)
2023-09-10 14:43:20 +02:00
{
2024-07-22 01:16:16 +02:00
screen[index] = color;
2023-09-10 14:43:20 +02:00
}
2024-08-02 00:05:03 +02:00
void LCR_log(const char *str)
{
printf("LOG: %s\n",str);
}
2025-03-05 17:10:01 +01:00
void printHelp(void)
{
printf(
2025-03-05 20:16:22 +01:00
"Licar, 3D racing game, v. " LCR_VERSION ", SDL frontend, args:\n"
2025-03-05 17:10:01 +01:00
" -h print help and quit\n"
2025-03-05 20:16:22 +01:00
" -wN window (N = 1) or fullscreen (N = 0)\n"
2025-03-05 17:10:01 +01:00
LCR_ARG_HELP_STR);
}
2023-09-10 14:43:20 +02:00
int main(int argc, char *argv[])
{
2025-03-05 20:16:22 +01:00
uint8_t running = 1, fullscreen = 1;
2024-12-21 17:50:27 +01:00
2025-03-05 17:10:01 +01:00
for (int i = 0; i < argc; ++i)
if (argv[i][0] == '-')
switch (argv[i][1])
{
case 'h':
2025-03-05 20:16:22 +01:00
printHelp();
return 0;
break;
2025-03-05 17:10:01 +01:00
2025-03-05 20:16:22 +01:00
case 'w':
fullscreen = argv[i][2] == '1';
2025-03-05 17:10:01 +01:00
break;
default: break;
}
2025-01-20 21:33:05 +01:00
dataFile = fopen(DATA_FILE_NAME,"r");
if (!dataFile)
LCR_log("couldn't open data file");
2024-12-21 17:50:27 +01:00
LCR_log("initializing game");
2025-01-28 00:10:47 +01:00
LCR_gameInit(argc,(const char **) argv);
2023-09-10 14:43:20 +02:00
2024-12-21 17:50:27 +01:00
LCR_log("initializing SDL");
SDL_Init(SDL_INIT_AUDIO);
LCR_log("initializing audio");
SDL_AudioSpec audioSpec;
SDL_memset(&audioSpec, 0, sizeof(audioSpec));
audioSpec.callback = audioFillCallback;
audioSpec.freq = 8000;
audioSpec.format = AUDIO_U8;
audioSpec.channels = 1;
2024-12-27 07:45:27 +01:00
audioSpec.samples = 64;
2024-12-21 17:50:27 +01:00
if (SDL_OpenAudio(&audioSpec,NULL) < 0)
fputs("could not initialize audio",stderr);
SDL_PauseAudio(0);
musicFile = fopen("assets/music","rb");
if (!musicFile)
fputs("could not open music file",stderr);
2023-09-10 14:43:20 +02:00
window =
SDL_CreateWindow("Licar", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, LCR_SETTING_RESOLUTION_X, LCR_SETTING_RESOLUTION_Y,
SDL_WINDOW_SHOWN);
2024-09-27 00:08:52 +02:00
if (!window)
{
fputs("ERROR: couldn't create window",stderr);
return 1;
}
2025-03-05 20:16:22 +01:00
if (fullscreen)
SDL_SetWindowFullscreen(window,SDL_WINDOW_FULLSCREEN_DESKTOP);
2023-09-10 14:43:20 +02:00
renderer = SDL_CreateRenderer(window,-1,0);
2024-09-27 00:08:52 +02:00
if (!renderer)
{
fputs("ERROR: couldn't create renderer",stderr);
return 1;
}
2023-09-10 14:43:20 +02:00
texture =
SDL_CreateTexture(renderer,SDL_PIXELFORMAT_RGB565,SDL_TEXTUREACCESS_STATIC,
LCR_SETTING_RESOLUTION_X,LCR_SETTING_RESOLUTION_Y);
2024-09-27 00:08:52 +02:00
if (!texture)
{
fputs("ERROR: couldn't create texture",stderr);
return 1;
}
2023-09-10 14:43:20 +02:00
screenSurface = SDL_GetWindowSurface(window);
SDL_ShowCursor(0);
SDL_PumpEvents();
keyboardState = SDL_GetKeyboardState(NULL);
2024-12-21 17:50:27 +01:00
LCR_log("starting game loop");
2023-09-10 14:43:20 +02:00
while (running)
{
SDL_PumpEvents();
keyboardState = SDL_GetKeyboardState(NULL);
running = !keyboardState[SDL_SCANCODE_Q];
running &= LCR_gameStep(SDL_GetTicks());
SDL_UpdateTexture(texture,NULL,screen,
LCR_SETTING_RESOLUTION_X * sizeof(uint16_t));
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer,texture,NULL,NULL);
SDL_RenderPresent(renderer);
}
2024-12-21 17:50:27 +01:00
LCR_log("ending");
if (musicFile)
fclose(musicFile);
2025-01-20 21:33:05 +01:00
if (dataFile)
fclose(dataFile);
2024-12-21 17:50:27 +01:00
SDL_PauseAudio(1);
SDL_CloseAudio();
2023-09-10 14:43:20 +02:00
SDL_DestroyTexture(texture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
LCR_gameEnd();
return 0;
}