mirror of
https://gitlab.com/drummyfish/anarch.git
synced 2024-11-24 09:52:20 -05:00
Add linux terminal support
This commit is contained in:
parent
3899c0f993
commit
3ce97dbf33
@ -27,7 +27,7 @@ This game got some attention on 4chan: [1](https://archive.li/Yzcwt), [2](https:
|
|||||||
- **Extemely low HW demands** (much less than Doom, no GPU, no FPU, just kilobytes of RAM and storage).
|
- **Extemely low HW demands** (much less than Doom, no GPU, no FPU, just kilobytes of RAM and storage).
|
||||||
- **Suckless, KISS, minimal, simple**, short code (~10000 LOC).
|
- **Suckless, KISS, minimal, simple**, short code (~10000 LOC).
|
||||||
- **Extremely portable**. So far officially ported to and tested on:
|
- **Extremely portable**. So far officially ported to and tested on:
|
||||||
- GNU/Linux PC: SDL, csfml, terminal
|
- GNU/Linux PC: SDL, csfml, terminal (experimental), Linux framebuffer (experimental)
|
||||||
- Winshit XP SDL
|
- Winshit XP SDL
|
||||||
- Browser
|
- Browser
|
||||||
- Pokitto (220 x 116, 48 MHz ARM, 36 KB RAM, 256 KB flash)
|
- Pokitto (220 x 116, 48 MHz ARM, 36 KB RAM, 256 KB flash)
|
||||||
|
117
main_terminal.c
117
main_terminal.c
@ -1,5 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
@file main_pokitto.cpp
|
@file main_terminal.c
|
||||||
|
|
||||||
|
WARNING: VERY EXPERIMENTAL
|
||||||
|
|
||||||
This is Linux terminal implementation of the game front end. If you replace
|
This is Linux terminal implementation of the game front end. If you replace
|
||||||
the input methods, it will most likely run in other terminals as well. This
|
the input methods, it will most likely run in other terminals as well. This
|
||||||
@ -15,6 +17,16 @@
|
|||||||
whatsoever.
|
whatsoever.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef USE_LINUX_FRAMEBUFFER
|
||||||
|
#define USE_LINUX_FRAMEBUFFER 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// IMPORTANT: You must set these files correctly:
|
||||||
|
#define DEV_KEYBOARD "/dev/input/event3"
|
||||||
|
#define DEV_MOUSE "/dev/input/event1"
|
||||||
|
#define DEV_TTY "/dev/tty3"
|
||||||
|
#define DEV_FRAMBUFFER "/dev/fb0"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
@ -26,8 +38,22 @@
|
|||||||
|
|
||||||
#include "smallinput.h"
|
#include "smallinput.h"
|
||||||
|
|
||||||
#define SFG_SCREEN_RESOLUTION_X 127
|
#if USE_LINUX_FRAMEBUFFER
|
||||||
#define SFG_SCREEN_RESOLUTION_Y 42
|
#include <stdlib.h>
|
||||||
|
#include <linux/fb.h>
|
||||||
|
#include <linux/kd.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if USE_LINUX_FRAMEBUFFER
|
||||||
|
#define SFG_SCREEN_RESOLUTION_X 640
|
||||||
|
#define SFG_SCREEN_RESOLUTION_Y 480
|
||||||
|
#else
|
||||||
|
#define SFG_SCREEN_RESOLUTION_X 127
|
||||||
|
#define SFG_SCREEN_RESOLUTION_Y 42
|
||||||
|
#endif
|
||||||
|
|
||||||
#define SFG_DITHERED_SHADOW 1
|
#define SFG_DITHERED_SHADOW 1
|
||||||
#define SFG_FPS 30
|
#define SFG_FPS 30
|
||||||
|
|
||||||
@ -36,6 +62,7 @@
|
|||||||
#define SCREENSIZE ((SFG_SCREEN_RESOLUTION_X + 1) * SFG_SCREEN_RESOLUTION_Y + 1)
|
#define SCREENSIZE ((SFG_SCREEN_RESOLUTION_X + 1) * SFG_SCREEN_RESOLUTION_Y + 1)
|
||||||
|
|
||||||
char screen[SCREENSIZE];
|
char screen[SCREENSIZE];
|
||||||
|
uint8_t *screenUnsigned = (uint8_t *) screen;
|
||||||
|
|
||||||
const char shades[] = // adjust according to your terminal
|
const char shades[] = // adjust according to your terminal
|
||||||
{
|
{
|
||||||
@ -54,8 +81,13 @@ uint32_t getTime()
|
|||||||
|
|
||||||
void SFG_setPixel(uint16_t x, uint16_t y, uint8_t colorIndex)
|
void SFG_setPixel(uint16_t x, uint16_t y, uint8_t colorIndex)
|
||||||
{
|
{
|
||||||
|
#if USE_LINUX_FRAMEBUFFER
|
||||||
|
screenUnsigned[y * SFG_SCREEN_RESOLUTION_X + x] =
|
||||||
|
colorIndex;
|
||||||
|
#else
|
||||||
screen[y * (SFG_SCREEN_RESOLUTION_X + 1) + x] =
|
screen[y * (SFG_SCREEN_RESOLUTION_X + 1) + x] =
|
||||||
shades[(colorIndex > 7) * 8 + colorIndex % 8];
|
shades[(colorIndex > 7) * 8 + colorIndex % 8];
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t SFG_getTimeMs()
|
uint32_t SFG_getTimeMs()
|
||||||
@ -125,7 +157,9 @@ int running = 1;
|
|||||||
|
|
||||||
void handleSignal(int signal)
|
void handleSignal(int signal)
|
||||||
{
|
{
|
||||||
|
#if !USE_LINUX_FRAMEBUFFER
|
||||||
puts("\033[?25h"); // show cursor
|
puts("\033[?25h"); // show cursor
|
||||||
|
#endif
|
||||||
running = 0;
|
running = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,6 +176,38 @@ int main()
|
|||||||
|
|
||||||
screen[SCREENSIZE - 1] = 0; // string terminator
|
screen[SCREENSIZE - 1] = 0; // string terminator
|
||||||
|
|
||||||
|
#if USE_LINUX_FRAMEBUFFER
|
||||||
|
|
||||||
|
#define CHECK(w,err,msg)\
|
||||||
|
if ((w) == (err)) { puts(msg); return 1; }
|
||||||
|
|
||||||
|
int tty = open(DEV_TTY,O_RDWR);
|
||||||
|
CHECK(tty,-1,"couldn't open TTY device")
|
||||||
|
|
||||||
|
CHECK(ioctl(tty,KDSETMODE,KD_GRAPHICS),-1,"couldn't set graphic mode")
|
||||||
|
|
||||||
|
int fb = open(DEV_FRAMBUFFER,O_RDWR);
|
||||||
|
CHECK(fb,-1,"couldn't open framebuffer device")
|
||||||
|
|
||||||
|
struct fb_fix_screeninfo fixInfo;
|
||||||
|
struct fb_var_screeninfo varInfo;
|
||||||
|
|
||||||
|
CHECK(ioctl(fb,FBIOGET_FSCREENINFO,&fixInfo),-1,"couldn't get fixInfo")
|
||||||
|
CHECK(ioctl(fb,FBIOGET_VSCREENINFO,&varInfo),-1,"couldn't get varInfo")
|
||||||
|
|
||||||
|
int bpp = varInfo.bits_per_pixel / 8;
|
||||||
|
uint64_t screenSize = varInfo.xres * varInfo.yres * bpp;
|
||||||
|
|
||||||
|
char *fbScreen = mmap(0,screenSize,PROT_READ | PROT_WRITE,MAP_SHARED,fb,0);
|
||||||
|
|
||||||
|
CHECK(fbScreen,MAP_FAILED,"couldn't map framebuffer")
|
||||||
|
|
||||||
|
int r = varInfo.red.offset / 8,
|
||||||
|
g = varInfo.green.offset / 8,
|
||||||
|
b = varInfo.blue.offset / 8,
|
||||||
|
t = varInfo.transp.offset / 8;
|
||||||
|
|
||||||
|
#else
|
||||||
for (uint16_t i = 1; i <= SFG_SCREEN_RESOLUTION_Y; ++i)
|
for (uint16_t i = 1; i <= SFG_SCREEN_RESOLUTION_Y; ++i)
|
||||||
screen[i * (SFG_SCREEN_RESOLUTION_X + 1) - 1] = '\n';
|
screen[i * (SFG_SCREEN_RESOLUTION_X + 1) - 1] = '\n';
|
||||||
|
|
||||||
@ -151,20 +217,61 @@ int main()
|
|||||||
putchar('\n');
|
putchar('\n');
|
||||||
|
|
||||||
puts("\033[?25l"); // hide cursor
|
puts("\033[?25l"); // hide cursor
|
||||||
|
#endif
|
||||||
|
|
||||||
while (running)
|
while (running)
|
||||||
{
|
{
|
||||||
input_update();
|
input_update();
|
||||||
|
|
||||||
|
#if USE_LINUX_FRAMEBUFFER
|
||||||
|
|
||||||
|
char *p = fbScreen;
|
||||||
|
|
||||||
|
int linePad = fixInfo.line_length - SFG_SCREEN_RESOLUTION_X * bpp;
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
for (int y = 0; y < SFG_SCREEN_RESOLUTION_Y; ++y)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < SFG_SCREEN_RESOLUTION_X; ++x)
|
||||||
|
{
|
||||||
|
// inefficient, should be a precomputed RGB32 palette
|
||||||
|
uint16_t c = paletteRGB565[screenUnsigned[index]];
|
||||||
|
|
||||||
|
*(p + b) = (c << 3) & 0xf8;
|
||||||
|
*(p + g) = (c >> 3) & 0xfc;
|
||||||
|
*(p + r) = (c >> 8) & 0xf8;
|
||||||
|
p += bpp;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
p += linePad;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
puts("\033[0;0H"); // move cursor to 0;0
|
puts("\033[0;0H"); // move cursor to 0;0
|
||||||
puts(screen);
|
puts(screen);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!SFG_mainLoopBody())
|
if (!SFG_mainLoopBody())
|
||||||
running = 0;
|
running = 0;
|
||||||
|
|
||||||
|
// if (SFG_game.frame > 1000) break; // uncomment for testing, prevents locking
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
puts("\033[?25h"); // show cursor
|
|
||||||
|
|
||||||
input_end();
|
input_end();
|
||||||
|
|
||||||
|
#if USE_LINUX_FRAMEBUFFER
|
||||||
|
munmap(screen,screenSize);
|
||||||
|
|
||||||
|
ioctl(tty,KDSETMODE,KD_TEXT); // set back to text mode
|
||||||
|
|
||||||
|
close(fb);
|
||||||
|
close(tty);
|
||||||
|
#else
|
||||||
|
puts("\033[?25h"); // show cursor
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user