diff --git a/HTMLshell.html b/HTMLshell.html index 3af5da2..ab7762e 100644 --- a/HTMLshell.html +++ b/HTMLshell.html @@ -65,31 +65,11 @@ { return document.getElementById('canvas'); } - )(), - onRuntimeInitialized: function() - { - pressFunc = Module.cwrap('webButton','', ['number','number']); - } + )() }; - - function down(button) - { - pressFunc(button,1); - } - - function up(button) - { - pressFunc(button,0); - } {{{ SCRIPT }}} - - - - -
- diff --git a/audio.h b/audio.h index aa958b9..4f66d01 100644 --- a/audio.h +++ b/audio.h @@ -66,6 +66,10 @@ void LCR_audioSetEngineIntensity(uint8_t value) */ void LCR_audioPlaySound(uint8_t sound) { +#ifdef LCR_PLAY_SOUND_CALLBACK + LCR_PLAY_SOUND_CALLBACK(sound) +#endif + LCR_LOG2("playing sound"); LCR_audio.soundPlayed = sound; LCR_audio.soundPlayedFrame = 0; diff --git a/data b/data index 2dc5705..a5189eb 100644 --- a/data +++ b/data @@ -142,3 +142,4 @@ details #RLCtiny5 00'10'362;00LCtiny5;5c14d8b6 0000314:00a1:0179:00a1:0089:0071:0093:0031:00c3:0041:0059:0031:0023:0161:0033:0081:0083:0051:0049:0131:0053:0091:0093:0041:00a3:00d1:0063:0051:0093:0041:0293:00a1:0149:0031 #BLCtiny5; #RLCtiny5 00'09'240;00LCtiny5;5c14d8b6 0000280:0011:00b3:0051:0049:0061:0099:0091:0059:0041:0059:0041:0079:0021:0093:0061:0059:0033:0181:0119:0051:0079:0051:0033:0071:00b3:0091:0033:0071:0043:0031:0033:0051:03d3:0031:0079 +#RLCtiny1 00'13'695;00LCtiny1;ae1ab677 0000415:0011:0093:0041:00a9:0041:0119:0031:0073:0031:0059:0031:0063:0021:01a9:00b1:0089:0041:01b3:0051:0023:00b1:0065:0041:00e9:01d1:0029:0171:0083:00f1:0010:0201:0049:0161:0033:0111:0049:00a1:0039:0071:00b9:0011:0183 diff --git a/frontend_saf.c b/frontend_saf.c new file mode 100644 index 0000000..e330844 --- /dev/null +++ b/frontend_saf.c @@ -0,0 +1,80 @@ +/* + SAF frontend for Licar. +*/ + +#define SAF_PLATFORM_SDL2 +#define SAF_SETTING_ENABLE_SAVES 0 +#define SAF_PROGRAM_NAME "Licar" + +#include "saf.h" + +#define LCR_SETTING_RESOLUTION_X SAF_SCREEN_WIDTH +#define LCR_SETTING_RESOLUTION_Y SAF_SCREEN_HEIGHT +#define LCR_SETTING_FPS SAF_FPS +#define LCR_SETTING_MUSIC 0 +#define LCR_SETTING_ENABLE_DATA_FILE 0 +#define LCR_SETTING_332_COLOR 1 +#define LCR_SETTING_SKY_SIZE 1 +#define LCR_SETTING_CAR_ANIMATION_SUBDIVIDE 0 +#define LCR_PLAY_SOUND_CALLBACK(s) playSound(s); + +void playSound(uint8_t sound); + +#include "game.h" + +void playSound(uint8_t sound) +{ + switch (sound) + { + case LCR_SOUND_CLICK: SAF_playSound(SAF_SOUND_CLICK); break; + case LCR_SOUND_CRASH_SMALL: SAF_playSound(SAF_SOUND_BUMP); break; + case LCR_SOUND_CRASH_BIG: SAF_playSound(SAF_SOUND_BOOM); break; + case LCR_SOUND_FAN: SAF_playSound(SAF_SOUND_BEEP); break; + case LCR_SOUND_ACCELERATOR: SAF_playSound(SAF_SOUND_BEEP); break; + default: break; + } +} + +void LCR_drawPixel(unsigned long index, uint16_t color) +{ + SAF_drawPixel(index % SAF_SCREEN_WIDTH,index / SAF_SCREEN_WIDTH,color); +} + +char LCR_getNextDataFileChar(void) +{ + return 0; +} + +void LCR_appendDataStr(const char *str) +{ +} + +uint8_t LCR_keyPressed(uint8_t key) +{ + switch (key) + { + case LCR_KEY_UP: return SAF_buttonPressed(SAF_BUTTON_UP); break; + case LCR_KEY_RIGHT: return SAF_buttonPressed(SAF_BUTTON_RIGHT); break; + case LCR_KEY_DOWN: return SAF_buttonPressed(SAF_BUTTON_DOWN); break; + case LCR_KEY_LEFT: return SAF_buttonPressed(SAF_BUTTON_LEFT); break; + case LCR_KEY_A: return SAF_buttonPressed(SAF_BUTTON_A); break; + case LCR_KEY_B: return SAF_buttonPressed(SAF_BUTTON_B); break; + default: break; + } + + return 0; +} + +void LCR_sleep(uint16_t timeMs) +{ +} + +void SAF_init(void) +{ + LCR_gameInit(0,0); +} + +uint8_t SAF_loop(void) +{ + return LCR_gameStep(SAF_time()); +} diff --git a/frontend_sdl.c b/frontend_sdl.c index aee6773..1829247 100644 --- a/frontend_sdl.c +++ b/frontend_sdl.c @@ -148,13 +148,6 @@ void LCR_sleep(uint16_t timeMs) #endif } -#ifdef __EMSCRIPTEN__ -void webButton(uint8_t key, uint8_t down) // HTML button pressed -{ - // TODO -} -#endif - void LCR_drawPixel(unsigned long index, uint16_t color) { screen[index] = color; diff --git a/game.h b/game.h index e4cf45c..92ddf91 100644 --- a/game.h +++ b/game.h @@ -176,6 +176,15 @@ uint8_t LCR_gameGetNextAudioSample(void); #define LCR_LOADING_COMMAND ; #endif +/** + This macro may be redefined to a command that will be executed upon certain + sound. This can be used if the platform can't play the game's 8 bit audio but + wants to play it's own sounds, e.g. beeps. +*/ +#ifndef LCR_PLAY_SOUND_CALLBACK + #define LCR_PLAY_SOUND_CALLBACK(s) ; +#endif + /* To make the game log FPS define a macro named LCR_FPS_GET_MS to a command that evaluates to the current number of milliseconds since some given time. It @@ -1196,7 +1205,7 @@ void LCR_gameTimeToStr(uint32_t timeMS, char *str) void LCR_gameDrawPopupMessage(void) { -#define _TEXT_SIZE 5 +#define _TEXT_SIZE 1 + 4 * (LCR_EFFECTIVE_RESOLUTION_Y > 96) #define _OFFSET_V (LCR_EFFECTIVE_RESOLUTION_Y / 8) int textH = LCR_rendererComputeTextHeight(_TEXT_SIZE); @@ -1267,28 +1276,31 @@ void LCR_gameDraw3DView(void) str[2] = '0' + val % 10; str[3] = 0; + #define _FONT_SIZE (1 + (LCR_EFFECTIVE_RESOLUTION_Y > 96)) + LCR_rendererDrawText(str,LCR_EFFECTIVE_RESOLUTION_X - // speed (bot., right) - LCR_rendererComputeTextWidth(str,2) - LCR_GUI_GAP, - LCR_EFFECTIVE_RESOLUTION_Y - LCR_rendererComputeTextHeight(2) - - LCR_GUI_GAP,0,2); + LCR_rendererComputeTextWidth(str,_FONT_SIZE) - LCR_GUI_GAP, + LCR_EFFECTIVE_RESOLUTION_Y - LCR_rendererComputeTextHeight(_FONT_SIZE) - + LCR_GUI_GAP,0,_FONT_SIZE); LCR_gameTimeToStr(LCR_timeTicksToMS(LCR_game.runTime),str); if (LCR_game.state != LCR_GAME_STATE_RUN_FINISHED) LCR_rendererDrawText(str,LCR_GUI_GAP,LCR_EFFECTIVE_RESOLUTION_Y - - 2 * (LCR_rendererComputeTextHeight(2) + LCR_GUI_GAP),0,2); + 2 * (LCR_rendererComputeTextHeight(_FONT_SIZE) + LCR_GUI_GAP),0,_FONT_SIZE); else LCR_rendererDrawText(str,((LCR_EFFECTIVE_RESOLUTION_X - LCR_rendererComputeTextWidth(str,4)) / 2), LCR_EFFECTIVE_RESOLUTION_Y / 2, LCR_game.runTime <= LCR_currentMap.targetTime ? - LCR_CONVERT_COLOR(0x0700) : LCR_CONVERT_COLOR(0x4208),4); + LCR_CONVERT_COLOR(0x0700) : LCR_CONVERT_COLOR(0x4208),2 * _FONT_SIZE); LCR_gameTimeToStr(LCR_currentMap.targetTime * LCR_RACING_TICK_MS,str); LCR_rendererDrawText(str,LCR_GUI_GAP,LCR_EFFECTIVE_RESOLUTION_Y - - LCR_rendererComputeTextHeight(2) - LCR_GUI_GAP, - LCR_CONVERT_COLOR(0x4208),2); + LCR_rendererComputeTextHeight(_FONT_SIZE) - LCR_GUI_GAP, + LCR_CONVERT_COLOR(0x4208),_FONT_SIZE); +#undef _FONT_SIZE } void LCR_gameSaveReplay(void) diff --git a/make.sh b/make.sh index 3c59302..f1eeb6b 100755 --- a/make.sh +++ b/make.sh @@ -40,10 +40,17 @@ elif [ $PLATFORM = "csfml" ]; then # - csfml (dev) package COMMAND="${COMPILER} ${C_FLAGS} frontend_csfml.c -lcsfml-graphics -lcsfml-window -lcsfml-system -lcsfml-audio" +elif [ $PLATFORM = "saf" ]; then + # SAF build, requires: + # - saf.h + # - backend libraries (SDL2 by default) + + SDL_FLAGS=`sdl2-config --cflags --libs` + COMMAND="${COMPILER} ${C_FLAGS} frontend_saf.c -lcsfml-graphics -I/use/local/include ${SDL_FLAGS}" elif [ $PLATFORM = "emscripten" ]; then # emscripten (browser Javascript) build, requires: # - emscripten - COMMAND="../emsdk/upstream/emscripten/emcc ./frontend_sdl.c -s USE_SDL=2 -O3 -lopenal --shell-file HTMLshell.html -o licar.html -s EXPORTED_FUNCTIONS='[\"_main\",\"_webButton\"]' -s EXPORTED_RUNTIME_METHODS='[\"ccall\",\"cwrap\"]'" + COMMAND="../emsdk/upstream/emscripten/emcc ./frontend_sdl.c -s USE_SDL=2 -O3 -lopenal --shell-file HTMLshell.html -o licar.html -s EXPORTED_FUNCTIONS='[\"_main\"]' -s EXPORTED_RUNTIME_METHODS='[\"ccall\",\"cwrap\"]'" else echo "unknown frontend" fi diff --git a/renderer.h b/renderer.h index 6be4533..c35e212 100644 --- a/renderer.h +++ b/renderer.h @@ -34,6 +34,7 @@ #define S3L_Z_BUFFER 1 #define LCR_FONT_PIXEL_SIZE (1 + LCR_EFFECTIVE_RESOLUTION_X / 512) #define LCR_ANIMATE_CAR (LCR_SETTING_CAR_ANIMATION_SUBDIVIDE != 0) +#define LCR_ANT_RESOLUTION (LCR_EFFECTIVE_RESOLUTION_Y <= 96) #if LCR_SETTING_POTATO_GRAPHICS #undef S3L_PERSPECTIVE_CORRECTION @@ -1951,8 +1952,14 @@ void LCR_rendererBlitImage(uint8_t index, unsigned int x, unsigned int y, void LCR_rendererDrawMenu(const char *tabName,const char **items, unsigned char itemCount,char selectedItem, char scroll) { +#if !LCR_ANT_RESOLUTION int stripHeight = (2 * LCR_EFFECTIVE_RESOLUTION_Y) / 7; int stripHeight2 = LCR_EFFECTIVE_RESOLUTION_Y / 9; +#else + int stripHeight = 6; + int stripHeight2 = 0; +#endif + int i = 0; #if !(LCR_SETTING_POTATO_GRAPHICS || LCR_SETTING_332_COLOR) uint16_t effect = LCR_renderer.frame >> 1; @@ -1974,7 +1981,7 @@ void LCR_rendererDrawMenu(const char *tabName,const char **items, ++i; } -#if LCR_SETTING_POTATO_GRAPHICS +#if LCR_SETTING_POTATO_GRAPHICS || LCR_ANT_RESOLUTION while (i < stripHeight * LCR_EFFECTIVE_RESOLUTION_X) { LCR_gameDrawPixel(i,LCR_CONVERT_COLOR(0x73ae)); @@ -2041,23 +2048,30 @@ void LCR_rendererDrawMenu(const char *tabName,const char **items, (j == 0 || j == selectedItem + 1) ? LCR_CONVERT_COLOR(0xf79c) : textColor,_FONT_SIZE); +#if LCR_ANT_RESOLUTION + i += LCR_rendererComputeTextHeight(_FONT_SIZE) + 3 * LCR_FONT_PIXEL_SIZE; +#else if (j == 0) i = stripHeight + stripHeight2; i += LCR_rendererComputeTextHeight(_FONT_SIZE) + 6 * LCR_FONT_PIXEL_SIZE; +#endif + #undef _FONT_SIZE } -#if !LCR_SETTING_POTATO_GRAPHICS +#if (!LCR_SETTING_POTATO_GRAPHICS) && (!LCR_ANT_RESOLUTION) LCR_rendererBlitImage(21,(LCR_EFFECTIVE_RESOLUTION_X - LCR_IMAGE_SIZE * (stripHeight / LCR_IMAGE_SIZE)) / 2,0, stripHeight / LCR_IMAGE_SIZE,LCR_CONVERT_COLOR(0xffff)); #endif +#if !LCR_ANT_RESOLUTION LCR_rendererDrawText(LCR_texts[LCR_TEXTS_VERSION], LCR_EFFECTIVE_RESOLUTION_X / 64,LCR_EFFECTIVE_RESOLUTION_Y / 64, LCR_CONVERT_COLOR(0xe71c),2); - +#endif + LCR_renderer.frame++; }