diff --git a/constants.h b/constants.h index fdb0067..194f5d3 100644 --- a/constants.h +++ b/constants.h @@ -210,13 +210,6 @@ */ #define SFG_BASE_SPRITE_SIZE RCL_UNITS_PER_SQUARE -/** - Says whether the game is running in very low resolution, which triggers some - simple rendering so that things fit the screen. -*/ -#define SFG_VERY_LOW_RESOLUTION\ - ((SFG_GAME_RESOLUTION_X < 90) || (SFG_GAME_RESOLUTION_Y < 70)) - // ---------------------------- // derived constants @@ -263,8 +256,13 @@ #define SFG_WEAPON_IMAGE_POSITION_X \ (SFG_GAME_RESOLUTION_X / 2 - (SFG_WEAPON_IMAGE_SCALE * SFG_TEXTURE_SIZE) / 2) -#define SFG_WEAPON_IMAGE_POSITION_Y \ - (SFG_GAME_RESOLUTION_Y - (SFG_WEAPON_IMAGE_SCALE * SFG_TEXTURE_SIZE)) +#if SFG_GAME_RESOLUTION_Y > 50 + #define SFG_WEAPON_IMAGE_POSITION_Y \ + (SFG_GAME_RESOLUTION_Y - (SFG_WEAPON_IMAGE_SCALE * SFG_TEXTURE_SIZE)) +#else + #define SFG_WEAPON_IMAGE_POSITION_Y \ + (SFG_GAME_RESOLUTION_Y - SFG_TEXTURE_SIZE / 2) +#endif #define SFG_PLAYER_TURN_UNITS_PER_FRAME \ ((SFG_PLAYER_TURN_SPEED * RCL_UNITS_PER_SQUARE) / (360 * SFG_FPS)) @@ -378,8 +376,8 @@ #define SFG_MAP_PIXEL_SIZE (SFG_GAME_RESOLUTION_Y / SFG_MAP_SIZE) #if SFG_MAP_PIXEL_SIZE == 0 - #undef SFG_PIXEL_SIZE - #define SFG_PIXEL_SIZE 1 + #undef SFG_MAP_PIXEL_SIZE + #define SFG_MAP_PIXEL_SIZE 1 #endif #define SFG_AI_UPDATE_FRAME_INTERVAL \ diff --git a/game.h b/game.h index adbbbc3..3e4228e 100755 --- a/game.h +++ b/game.h @@ -3909,7 +3909,7 @@ static inline void SFG_clearScreen(uint8_t color) void SFG_drawMap() { SFG_clearScreen(0); - + uint16_t maxJ = (SFG_MAP_PIXEL_SIZE * SFG_MAP_SIZE) < SFG_GAME_RESOLUTION_Y ? (SFG_MAP_SIZE) : (SFG_GAME_RESOLUTION_Y / SFG_MAP_PIXEL_SIZE); @@ -4215,7 +4215,11 @@ void SFG_drawMenu() SFG_GAME_RESOLUTION_X / 2 - 16 * SFG_FONT_SIZE_MEDIUM,y, SFG_FONT_SIZE_MEDIUM); +#if SFG_GAME_RESOLUTION_Y > 50 y += 32 * SFG_FONT_SIZE_MEDIUM + SFG_characterSize(SFG_FONT_SIZE_MEDIUM); +#else + y = 2; +#endif uint8_t i = 0; @@ -4226,8 +4230,10 @@ void SFG_drawMenu() if (item == SFG_MENU_ITEM_NONE) break; -#if SFG_VERY_LOW_RESOLUTION - if (i != SFG_game.selectedMenuItem) // only display selected item +# if SFG_GAME_RESOLUTION_Y < 70 + // with low resolution only display the selected item + + if (i != SFG_game.selectedMenuItem) { i++; continue; diff --git a/main_pokitto.cpp b/main_pokitto.cpp index a2a5fa5..5788484 100644 --- a/main_pokitto.cpp +++ b/main_pokitto.cpp @@ -12,10 +12,14 @@ whatsoever. */ - - // #define SFG_START_LEVEL 8 + #include + #define SFG_LOG(s) puts(s); + +// #define SFG_UNLOCK_DOOR 1 +// #define SFG_INFINITE_AMMO 1 + #define SFG_FPS 25 #define SFG_CAN_EXIT 0 //#define SFG_TEXTURE_DISTANCE 6000 @@ -23,6 +27,7 @@ #define SFG_SCREEN_RESOLUTION_Y 88 #define SFG_RESOLUTION_SCALEDOWN 1 #define SFG_DITHERED_SHADOW 0 +#define SFG_DIMINISH_SPRITES 0 #define SFG_FOG_DIMINISH_STEP 2048 #define SFG_RAYCASTING_MAX_STEPS 20 #define SFG_RAYCASTING_MAX_HITS 5 @@ -162,8 +167,8 @@ void SFG_playSound(uint8_t soundIndex, uint8_t volume) for (int i = 0; i < SFG_SFX_SAMPLE_COUNT; ++i) { - audioBuff[pos] = mixSamples(audioBuff[pos],SFG_GET_SFX_SAMPLE(soundIndex,i) - >> volumeShift); + audioBuff[pos] = mixSamples(audioBuff[pos],baseLevel + + (SFG_GET_SFX_SAMPLE(soundIndex,i) >> volumeShift)); pos = (pos < SFG_SFX_SAMPLE_COUNT - 1) ? (pos + 1) : 0; } diff --git a/main_sdl.c b/main_sdl.c index 9acfb8d..1d43663 100644 --- a/main_sdl.c +++ b/main_sdl.c @@ -27,12 +27,15 @@ #define SFG_LOG(str) puts(str); -// #define SFG_START_LEVEL 6 + #define SFG_START_LEVEL 1 // #define SFG_IMMORTAL 1 #define SFG_UNLOCK_DOOR 1 -// #define SFG_REVEAL_MAP 1 + #define SFG_REVEAL_MAP 1 // #define SFG_INFINITE_AMMO 1 + #define SFG_SCREEN_RESOLUTION_X 127 + #define SFG_SCREEN_RESOLUTION_Y 42 + // #define SFG_SCREEN_RESOLUTION_X 80 // #define SFG_SCREEN_RESOLUTION_Y 64 diff --git a/main_terminal.c b/main_terminal.c new file mode 100644 index 0000000..154b48e --- /dev/null +++ b/main_terminal.c @@ -0,0 +1,191 @@ +/** + @file main_pokitto.cpp + + This is Linux terminal implementation of the game front end. This needs root + priviledges (sudo) to work! This frontend is more of an experiment, don't + expect it to work perfectly and everywhere. + + by Miloslav Ciz (drummyfish), 2019 + + Released under CC0 1.0 (https://creativecommons.org/publicdomain/zero/1.0/) + plus a waiver of all other intellectual property. The goal of this work is + be and remain completely in the public domain forever, available for any use + whatsoever. +*/ + +#include +#include +#include +#include +#include +#include +#include + +#define SFG_SCREEN_RESOLUTION_X 95 +#define SFG_SCREEN_RESOLUTION_Y 43 +#define SFG_DITHERED_SHADOW 1 +#define SFG_FPS 20 + +#include "game.h" + +#define NEWLINES 10 + +#define SCREENSIZE \ + (NEWLINES + (SFG_SCREEN_RESOLUTION_X + 1) * SFG_SCREEN_RESOLUTION_Y) + +char screen[SCREENSIZE]; + +const char shades[] = // adjust according to your terminal + { + ' ','.','-',':','\\','h','M','@', // grey + '`','.',',',';','/','r','=','n' // non-grey + }; + +uint32_t timeStart; + +typedef struct +{ + struct timeval time; + __u16 type; + __u16 code; + __s32 value; +} InputEvent; + +InputEvent event; + +#define TOTAL_KEYS 9 + +uint16_t keyCodes[TOTAL_KEYS] = + { + KEY_W, + KEY_S, + KEY_A, + KEY_D, + KEY_SPACE, + KEY_H, + KEY_J, + KEY_K, + KEY_Q + }; + +uint8_t keyStates[TOTAL_KEYS]; + +uint32_t getTime() +{ + struct timeval now; + gettimeofday(&now, NULL); + return now.tv_sec * 1000 + now.tv_usec / 1000; +} + +void SFG_setPixel(uint16_t x, uint16_t y, uint8_t colorIndex) +{ + screen[NEWLINES + y * (SFG_SCREEN_RESOLUTION_X + 1) + x] = + shades[(colorIndex > 7) * 8 + colorIndex % 8]; +} + +uint32_t SFG_getTimeMs() +{ + clock_t timeNow = clock(); + return getTime() - timeStart; +} + +void SFG_save(uint8_t data[SFG_SAVE_SIZE]) +{ +} + +uint8_t SFG_load(uint8_t data[SFG_SAVE_SIZE]) +{ + return 0; +} + +void SFG_sleepMs(uint16_t timeMs) +{ + usleep(timeMs * 1000); +} + +void SFG_getMouseOffset(int16_t *x, int16_t *y) +{ +} + +int8_t SFG_keyPressed(uint8_t key) +{ + switch (key) + { + case SFG_KEY_UP: return keyStates[0]; break; + case SFG_KEY_RIGHT: return keyStates[3]; break; + case SFG_KEY_DOWN: return keyStates[1]; break; + case SFG_KEY_LEFT: return keyStates[2]; break; + case SFG_KEY_A: return keyStates[5]; break; + case SFG_KEY_B: return keyStates[6]; break; + case SFG_KEY_C: return keyStates[7]; break; + case SFG_KEY_MAP: return keyStates[8]; break; + default: return 0; break; + } +} + +void SFG_enableMusic(uint8_t enable) +{ +} + +void SFG_playSound(uint8_t soundIndex, uint8_t volume) +{ +} + +int nextFlush = 0; + +int main() +{ + int devFile; + + timeStart = getTime(); + + devFile = open("/dev/input/event0", O_RDONLY); + + fcntl(devFile, F_SETFL, O_NONBLOCK); + + SFG_init(); + + for (uint16_t i = 0; i < TOTAL_KEYS; ++i) + keyStates[i] = 0; + + for (uint16_t i = 0; i < NEWLINES; ++i) + screen[i] = '\n'; + + for (uint16_t i = 1; i <= SFG_SCREEN_RESOLUTION_Y; ++i) + screen[NEWLINES + i * (SFG_SCREEN_RESOLUTION_X + 1) - 1] = '\n'; + + setvbuf(stdout, NULL, _IOFBF, SCREENSIZE + 1); + + while (1) + { + while (1) + { + int n = read(devFile, &event, sizeof(event)); + + if (n <= 0) + break; + + if (event.type == EV_KEY && (event.value == 1 || event.value == 0)) + { + for (uint8_t i = 0; i < TOTAL_KEYS; ++i) + if (event.code == keyCodes[i]) + { + keyStates[i] = event.value; + break; + } + } + } + + uint32_t t = SFG_getTimeMs(); + + if (t >= nextFlush) + { + puts(screen); + fflush(stdout); + nextFlush = t + 200; // 5 rendering FPS + } + + if (!SFG_mainLoopBody()) + break; + } +}