mirror of
https://gitlab.com/drummyfish/anarch.git
synced 2024-11-24 01:42:19 -05:00
Add terminal frontend
This commit is contained in:
parent
535155a60d
commit
ffe5dda22e
20
constants.h
20
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 \
|
||||
|
12
game.h
12
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;
|
||||
|
@ -12,10 +12,14 @@
|
||||
whatsoever.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// #define SFG_START_LEVEL 8
|
||||
|
||||
#include <stdio.h>
|
||||
#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;
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
191
main_terminal.c
Normal file
191
main_terminal.c
Normal file
@ -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 <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <linux/input.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user