Add X11 frontend
This commit is contained in:
parent
eb640d27a1
commit
f7a24f2aa1
4 changed files with 204 additions and 15 deletions
10
TODO.txt
10
TODO.txt
|
@ -11,13 +11,8 @@ fuck issue trackers :D
|
|||
- Nibble, should hopefully be powerful enough.
|
||||
- ESPboy?
|
||||
- linux framebuffer?
|
||||
- make car turned on its back behave nicer? but how?
|
||||
- press forward map??? :-D only when physics is frozen
|
||||
- make some kinda repo for world record runs? how will they submit it?
|
||||
- Try doing the bouncy car body? Just keep a point and its velocity, change
|
||||
its velocity by a proportion of car's velocity change (this minus prev.
|
||||
frame), then offset car body by this. However we'll also have to transform
|
||||
inbetween world space and model space.
|
||||
- final tests:
|
||||
- very long replay
|
||||
- different resolutions
|
||||
|
@ -43,6 +38,11 @@ fuck issue trackers :D
|
|||
=========== HANDLED ==============
|
||||
|
||||
- should drifting make a sound? NO NEED
|
||||
- make car turned on its back behave nicer? but how? PROLLY NOT
|
||||
- Try doing the bouncy car body? Just keep a point and its velocity, change
|
||||
its velocity by a proportion of car's velocity change (this minus prev.
|
||||
frame), then offset car body by this. However we'll also have to transform
|
||||
inbetween world space and model space. LEAVE FOR A MOD
|
||||
- add display of inputs on the screen (option in setting? arg?)
|
||||
- viewing replay during countdown bugs!
|
||||
- sometimes after restart the timer shows not 0:0:0, but something like 0:0:033
|
||||
|
|
2
data
2
data
|
@ -135,4 +135,4 @@ details
|
|||
#RLC2 00'24'948;00LC2;3c5ba5dd 0000756:0001:0143:0021:01a9:0051:00b5:0031:01d9:0041:0069:0031:00c9:0041:0079:0021:01d3:0061:0063:0031:0073:0072:0043:0041:0033:0061:0243:0041:0189:0021:0129:0021:0133:0021:0085:0031:0053:0041:0033:0041:0043:00d1:02f9:0031:00c9:0031:00a3:0051:00f9:0061:00d9:0031:01d3:0101:0043:0041:0059:00a1:0093:0031:00b9:0031:00a3:00e7:0046:0092:0043:00d1:00f9:0031:0033:0031:0033:0051:0093:0051:00a9:0031:00a9:0041
|
||||
#RLC5 00'25'971;00LC5;90f26004 0000787:0001:0023:0071:0063:0031:0155:0031:0139:0031:01d9:0021:0179:0031:0064:006c:0038:0029:0171:0063:0091:0033:0061:00e9:0041:0029:0031:0093:0081:0079:0091:00a9:0051:0019:0061:0039:0031:0099:0031:0029:0041:0089:0041:0029:0031:0049:0031:0019:0071:0029:0031:0193:0031:00a3:0021:00d3:0051:0063:0021:0139:0068:001c:0070:0028:0059:00b1:0033:00d1:0043:0041:0043:0051:0319:00d1:0043:0051:0189:0061:0029:0031:0099:0031:00b5:0051:00c9:0051:0039:0051:0049:0061:0039:0041:0169:0051:0105:0031:01f3:0031:0053:0012:0076:0062:0043:0101:00b9:0021
|
||||
#RLCtiny2 00'05'181;00LCtiny2;833ee4b2 0000157:0011:0320:0034:00a0:00d4:00f0
|
||||
#RLCtiny3 00'12'342;00LCtiny3;df0bd8ce
|
||||
#RLCtiny1 00'12'276;00LCtiny1;ae1ab677 0000372:0001:02e9:0021:01e9:0051:00c9:0151:0073:0091:0059:0051:0073:0041:00a9:0031:0033:0031:0063:0031:0063:0021:0023:0087:0073:0131:0023:00a1:0069:0091:0103:0031:0205:0021:00b3:0091:0113:0021:00b9:0031:0053:0051:0039
|
||||
|
|
183
frontend_x11.c
Normal file
183
frontend_x11.c
Normal file
|
@ -0,0 +1,183 @@
|
|||
/** @file frontend_sdl.c
|
||||
X11 frontend for Licar.
|
||||
*/
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h> // for usleep
|
||||
|
||||
#define LCR_SETTING_LOG_LEVEL 2
|
||||
#define LCR_SETTING_RESOLUTION_X 320
|
||||
#define LCR_SETTING_RESOLUTION_Y 240
|
||||
#define LCR_SETTING_MUSIC 0
|
||||
|
||||
#define DATA_FILE_NAME "data"
|
||||
|
||||
#include "game.h"
|
||||
|
||||
char framebuffer[LCR_SETTING_RESOLUTION_X * LCR_SETTING_RESOLUTION_Y * 4];
|
||||
FILE *dataFile = 0;
|
||||
uint8_t buttonStates[8];
|
||||
|
||||
void LCR_drawPixel(unsigned long index, uint16_t color)
|
||||
{
|
||||
char *p = framebuffer + 4 * index;
|
||||
|
||||
*p = (color << 3) & 0xff;
|
||||
p++;
|
||||
*p = (color >> 3) & 0xfc;
|
||||
p++;
|
||||
*p = (color >> 8) & 0xf8;
|
||||
}
|
||||
|
||||
char LCR_getNextDataFileChar(void)
|
||||
{
|
||||
if (!dataFile)
|
||||
return 0;
|
||||
|
||||
int c = fgetc(dataFile);
|
||||
|
||||
if (c == EOF)
|
||||
{
|
||||
rewind(dataFile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void LCR_appendDataStr(const char *str)
|
||||
{
|
||||
if (!dataFile)
|
||||
return;
|
||||
|
||||
if (str == 0 || *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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t LCR_keyPressed(uint8_t key)
|
||||
{
|
||||
return buttonStates[key % 8];
|
||||
}
|
||||
|
||||
void LCR_sleep(uint16_t timeMs)
|
||||
{
|
||||
usleep(timeMs * 1000);
|
||||
}
|
||||
|
||||
void LCR_log(const char *str)
|
||||
{
|
||||
printf("LOG: %s\n",str);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int running = 1;
|
||||
struct timeval now;
|
||||
|
||||
LCR_gameInit(argc,(const char **) argv);
|
||||
|
||||
Display *display = XOpenDisplay(0);
|
||||
int screen = DefaultScreen(display);
|
||||
|
||||
dataFile = fopen(DATA_FILE_NAME,"r");
|
||||
|
||||
if (!dataFile)
|
||||
LCR_log("couldn't open data file");
|
||||
|
||||
Window window = XCreateSimpleWindow(display,RootWindow(display,screen),10,10,
|
||||
LCR_SETTING_RESOLUTION_X,LCR_SETTING_RESOLUTION_Y,1,
|
||||
BlackPixel(display,screen),WhitePixel(display,screen));
|
||||
|
||||
XSizeHints *sizeHints = XAllocSizeHints();
|
||||
sizeHints->flags = PMaxSize | PMinSize;
|
||||
sizeHints->max_width = LCR_SETTING_RESOLUTION_X;
|
||||
sizeHints->min_width = LCR_SETTING_RESOLUTION_X;
|
||||
sizeHints->max_height = LCR_SETTING_RESOLUTION_Y;
|
||||
sizeHints->min_height = LCR_SETTING_RESOLUTION_Y;
|
||||
XSetWMNormalHints(display,window,sizeHints);
|
||||
XFree(sizeHints);
|
||||
|
||||
XMapWindow(display,window);
|
||||
|
||||
XSelectInput(display,window,KeyPressMask | KeyReleaseMask);
|
||||
|
||||
GC context = DefaultGC(display,screen);
|
||||
|
||||
XStoreName(display,window,"Licar");
|
||||
|
||||
/*
|
||||
Hardcoded constants here may perhaps cause trouble on some platforms, but
|
||||
doing X11 "the right way" would mean 1 billion lines of code, so fuck it.
|
||||
*/
|
||||
XImage *image = XCreateImage(display,DefaultVisual(display,screen),
|
||||
/*DefaultDepth(display,screen)*/24,ZPixmap,0,framebuffer,
|
||||
LCR_SETTING_RESOLUTION_X,LCR_SETTING_RESOLUTION_Y,8,0);
|
||||
|
||||
while (running) // main loop
|
||||
{
|
||||
XEvent event;
|
||||
|
||||
gettimeofday(&now,NULL);
|
||||
running &= LCR_gameStep(now.tv_sec * 1000 + now.tv_usec / 1000);
|
||||
|
||||
XPutImage(display,window,context,image,0,0,0,0,LCR_SETTING_RESOLUTION_X,
|
||||
LCR_SETTING_RESOLUTION_Y);
|
||||
|
||||
while (XCheckWindowEvent(display,window,KeyPressMask |
|
||||
KeyReleaseMask,&event) != False)
|
||||
{
|
||||
uint8_t state = event.xkey.type == KeyPress;
|
||||
|
||||
switch (XKeycodeToKeysym(display,event.xkey.keycode,0))
|
||||
{
|
||||
case XK_Up: case XK_w:
|
||||
buttonStates[LCR_KEY_UP % 8] = state; break;
|
||||
|
||||
case XK_Left: case XK_a:
|
||||
buttonStates[LCR_KEY_LEFT % 8] = state; break;
|
||||
|
||||
case XK_Right: case XK_d:
|
||||
buttonStates[LCR_KEY_RIGHT % 8] = state; break;
|
||||
|
||||
case XK_Down: case XK_s:
|
||||
buttonStates[LCR_KEY_DOWN % 8] = state; break;
|
||||
|
||||
case XK_j: case XK_Return:
|
||||
buttonStates[LCR_KEY_A % 8] = state; break;
|
||||
|
||||
case XK_k: case XK_Escape:
|
||||
buttonStates[LCR_KEY_B % 8] = state; break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XDestroyImage(image);
|
||||
XCloseDisplay(display);
|
||||
|
||||
if (dataFile)
|
||||
fclose(dataFile);
|
||||
|
||||
LCR_gameEnd();
|
||||
|
||||
return 0;
|
||||
}
|
24
make.sh
24
make.sh
|
@ -30,30 +30,36 @@ if [ $# -gt 0 ]; then
|
|||
fi
|
||||
|
||||
if [ $PLATFORM = "sdl" ]; then
|
||||
# PC SDL build, requires:
|
||||
# - SDL2 (dev) package
|
||||
# PC SDL build, requires: SDL2 (dev) package
|
||||
# preferred, should support all features
|
||||
|
||||
SDL_FLAGS=`sdl2-config --cflags --libs`
|
||||
COMMAND="${COMPILER} ${C_FLAGS} frontend_sdl.c -I/usr/local/include ${SDL_FLAGS}"
|
||||
elif [ $PLATFORM = "csfml" ]; then
|
||||
# PC CMFML build, requires:
|
||||
# - csfml (dev) package
|
||||
# PC CMFML build, requires: csfml (dev) package
|
||||
# similar to SDL, should support all features
|
||||
|
||||
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)
|
||||
# SAF build, requires: saf.h, backend libraries (SDL2 by default)
|
||||
# limited by SAF (low resoulution, few colors, no files, simple sound, ...)
|
||||
|
||||
SDL_FLAGS=`sdl2-config --cflags --libs`
|
||||
COMMAND="${COMPILER} ${C_FLAGS} frontend_saf.c -lcsfml-graphics -I/use/local/include ${SDL_FLAGS}"
|
||||
elif [ $PLATFORM = "test" ]; then
|
||||
# autotest build
|
||||
# unplayable, only serves for development
|
||||
|
||||
COMMAND="${COMPILER} ${C_FLAGS} frontend_test.c"
|
||||
elif [ $PLATFORM = "x11" ]; then
|
||||
# X11 build, requires: xlib
|
||||
# has no sound
|
||||
|
||||
COMMAND="${COMPILER} ${C_FLAGS} -lX11 frontend_x11.c"
|
||||
elif [ $PLATFORM = "emscripten" ]; then
|
||||
# emscripten (browser Javascript) build, requires:
|
||||
# - emscripten
|
||||
# emscripten (browser Javascript) build, requires: emscripten
|
||||
# limited, low quality, no files
|
||||
|
||||
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"
|
||||
|
|
Loading…
Reference in a new issue