fixup! Add display server.
This commit is contained in:
parent
6c6880ea31
commit
ce3b519991
|
@ -15,7 +15,7 @@ BINARIES:=\
|
||||||
asteroids \
|
asteroids \
|
||||||
aquatinspitz \
|
aquatinspitz \
|
||||||
|
|
||||||
LIBS:=-ldispd -ldisplay
|
LIBS:=-ldisplay
|
||||||
|
|
||||||
all: $(BINARIES)
|
all: $(BINARIES)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, 2015, 2016 Jonas 'Sortie' Termansen.
|
* Copyright (c) 2014, 2015, 2016, 2023 Jonas 'Sortie' Termansen.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -22,6 +22,7 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <error.h>
|
#include <error.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
@ -34,12 +35,15 @@
|
||||||
#include <timespec.h>
|
#include <timespec.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <dispd.h>
|
#include <display.h>
|
||||||
|
|
||||||
// Utility global variables every game will need.
|
// Utility global variables every game will need.
|
||||||
|
uint32_t window_id = 0;
|
||||||
|
static size_t framesize;
|
||||||
|
static uint32_t* fb;
|
||||||
static bool game_running = true;
|
static bool game_running = true;
|
||||||
static size_t game_width = 1280;
|
static size_t game_width = 800;
|
||||||
static size_t game_height = 720;
|
static size_t game_height = 512;
|
||||||
#define MAX_KEY_NUMBER 512
|
#define MAX_KEY_NUMBER 512
|
||||||
static bool keys_down[MAX_KEY_NUMBER];
|
static bool keys_down[MAX_KEY_NUMBER];
|
||||||
static bool keys_pending[MAX_KEY_NUMBER];
|
static bool keys_pending[MAX_KEY_NUMBER];
|
||||||
|
@ -200,20 +204,16 @@ void update(float deltatime)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render the game into the framebuffer.
|
// Render the game into the framebuffer.
|
||||||
void render(struct dispd_window* window)
|
void render(struct display_connection* connection)
|
||||||
{
|
{
|
||||||
struct dispd_framebuffer* window_fb = dispd_begin_render(window);
|
size_t old_framesize = framesize;
|
||||||
if ( !window_fb )
|
|
||||||
{
|
|
||||||
error(0, 0, "unable to begin rendering dispd window");
|
|
||||||
game_running = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t* fb = (uint32_t*) dispd_get_framebuffer_data(window_fb);
|
size_t xres = game_width;
|
||||||
size_t xres = dispd_get_framebuffer_width(window_fb);
|
size_t yres = game_height;
|
||||||
size_t yres = dispd_get_framebuffer_height(window_fb);
|
size_t pitch = xres;
|
||||||
size_t pitch = dispd_get_framebuffer_pitch(window_fb) / sizeof(uint32_t);
|
framesize = xres * yres * sizeof(uint32_t);
|
||||||
|
if ( old_framesize != framesize && !(fb = realloc(fb, framesize)) )
|
||||||
|
err(1, "malloc");
|
||||||
|
|
||||||
// Render a colorful background.
|
// Render a colorful background.
|
||||||
for ( size_t y = 0; y < yres; y++ )
|
for ( size_t y = 0; y < yres; y++ )
|
||||||
|
@ -273,7 +273,9 @@ void render(struct dispd_window* window)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dispd_finish_render(window_fb);
|
display_render_window(connection, window_id, 0, 0,
|
||||||
|
game_width, game_height, fb);
|
||||||
|
display_show_window(connection, window_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ... to here. No need to edit stuff below.
|
// ... to here. No need to edit stuff below.
|
||||||
|
@ -310,50 +312,68 @@ bool pop_is_key_just_down(int abskbkey)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read input from the keyboard.
|
// When the connection to the display server has disconnected.
|
||||||
void input(void)
|
void on_disconnect(void* ctx)
|
||||||
{
|
{
|
||||||
// Read the keyboard input from the user.
|
(void) ctx;
|
||||||
unsigned termmode = TERMMODE_KBKEY | TERMMODE_SIGNAL | TERMMODE_NONBLOCK;
|
exit(0);
|
||||||
if ( settermmode(0, termmode) )
|
}
|
||||||
error(1, errno, "settermmode");
|
|
||||||
uint32_t codepoint;
|
// When the window is asked to quit.
|
||||||
ssize_t numbytes;
|
void on_quit(void* ctx, uint32_t window_id)
|
||||||
while ( 0 < (numbytes = read(0, &codepoint, sizeof(codepoint))) )
|
{
|
||||||
{
|
(void) ctx;
|
||||||
int kbkey = KBKEY_DECODE(codepoint);
|
(void) window_id;
|
||||||
if( !kbkey )
|
exit(0);
|
||||||
continue;
|
}
|
||||||
int abskbkey = (kbkey < 0) ? -kbkey : kbkey;
|
|
||||||
if ( MAX_KEY_NUMBER <= (size_t) abskbkey )
|
// When the window has been resized.
|
||||||
continue;
|
void on_resize(void* ctx, uint32_t window_id, uint32_t width, uint32_t height)
|
||||||
bool is_key_down_event = 0 < kbkey;
|
{
|
||||||
if ( !keys_down[abskbkey] && is_key_down_event )
|
(void) ctx;
|
||||||
keys_pending[abskbkey] = true;
|
if ( window_id != window_id )
|
||||||
keys_down[abskbkey] = is_key_down_event;
|
return;
|
||||||
}
|
game_width = width;
|
||||||
|
game_height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
// When a key has been pressed.
|
||||||
|
void on_keyboard(void* ctx, uint32_t window_id, uint32_t codepoint)
|
||||||
|
{
|
||||||
|
(void) ctx;
|
||||||
|
if ( window_id != window_id )
|
||||||
|
return;
|
||||||
|
int kbkey = KBKEY_DECODE(codepoint);
|
||||||
|
if ( !kbkey )
|
||||||
|
return;
|
||||||
|
int abskbkey = (kbkey < 0) ? -kbkey : kbkey;
|
||||||
|
if ( MAX_KEY_NUMBER <= (size_t) abskbkey )
|
||||||
|
return;
|
||||||
|
bool is_key_down_event = 0 < kbkey;
|
||||||
|
if ( !keys_down[abskbkey] && is_key_down_event )
|
||||||
|
keys_pending[abskbkey] = true;
|
||||||
|
keys_down[abskbkey] = is_key_down_event;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run the game until no longer needed.
|
// Run the game until no longer needed.
|
||||||
void mainloop(struct dispd_window* window)
|
void mainloop(struct display_connection* connection)
|
||||||
{
|
{
|
||||||
struct dispd_framebuffer* window_fb = dispd_begin_render(window);
|
struct display_event_handlers handlers = {0};
|
||||||
if ( window_fb )
|
handlers.disconnect_handler = on_disconnect;
|
||||||
{
|
handlers.quit_handler = on_quit;
|
||||||
game_width = dispd_get_framebuffer_width(window_fb);
|
handlers.resize_handler = on_resize;
|
||||||
game_height = dispd_get_framebuffer_height(window_fb);
|
handlers.keyboard_handler = on_keyboard;
|
||||||
dispd_finish_render(window_fb);
|
|
||||||
}
|
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
|
||||||
struct timespec last_frame_time;
|
struct timespec last_frame_time;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &last_frame_time);
|
clock_gettime(CLOCK_MONOTONIC, &last_frame_time);
|
||||||
|
|
||||||
render(window);
|
render(connection);
|
||||||
|
|
||||||
while ( game_running )
|
while ( game_running )
|
||||||
{
|
{
|
||||||
|
|
||||||
struct timespec current_frame_time;
|
struct timespec current_frame_time;
|
||||||
clock_gettime(CLOCK_MONOTONIC, ¤t_frame_time);
|
clock_gettime(CLOCK_MONOTONIC, ¤t_frame_time);
|
||||||
|
|
||||||
|
@ -361,71 +381,31 @@ void mainloop(struct dispd_window* window)
|
||||||
timespec_sub(current_frame_time, last_frame_time);
|
timespec_sub(current_frame_time, last_frame_time);
|
||||||
float deltatime = deltatime_ts.tv_sec + deltatime_ts.tv_nsec / 1E9f;
|
float deltatime = deltatime_ts.tv_sec + deltatime_ts.tv_nsec / 1E9f;
|
||||||
|
|
||||||
input();
|
while ( display_poll_event(connection, &handlers) == 0 );
|
||||||
|
|
||||||
update(deltatime);
|
update(deltatime);
|
||||||
render(window);
|
render(connection);
|
||||||
|
|
||||||
last_frame_time = current_frame_time;
|
last_frame_time = current_frame_time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the terminal state when the process terminates.
|
|
||||||
static struct termios saved_tio;
|
|
||||||
|
|
||||||
static void restore_terminal_on_exit(void)
|
|
||||||
{
|
|
||||||
tcsetattr(0, TCSAFLUSH, &saved_tio);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void restore_terminal_on_signal(int signum)
|
|
||||||
{
|
|
||||||
if ( signum == SIGTSTP )
|
|
||||||
{
|
|
||||||
struct termios tio;
|
|
||||||
tcgetattr(0, &tio);
|
|
||||||
tcsetattr(0, TCSAFLUSH, &saved_tio);
|
|
||||||
raise(SIGSTOP);
|
|
||||||
tcgetattr(0, &saved_tio);
|
|
||||||
tcsetattr(0, TCSAFLUSH, &tio);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
tcsetattr(0, TCSAFLUSH, &saved_tio);
|
|
||||||
raise(signum);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a display context, run the game, and then cleanly exit.
|
// Create a display context, run the game, and then cleanly exit.
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
if ( !isatty(0) )
|
struct display_connection* connection = display_connect_default();
|
||||||
error(1, errno, "standard input");
|
if ( !connection && errno == ECONNREFUSED )
|
||||||
if ( tcgetattr(0, &saved_tio) < 0 )
|
display_spawn(argc, argv);
|
||||||
error(1, errno, "tcsetattr: standard input");
|
if ( !connection )
|
||||||
if ( atexit(restore_terminal_on_exit) != 0 )
|
error(1, errno, "Could not connect to display server");
|
||||||
error(1, errno, "atexit");
|
|
||||||
struct sigaction sa;
|
|
||||||
memset(&sa, 0, sizeof(sa));
|
|
||||||
sa.sa_handler = restore_terminal_on_signal;
|
|
||||||
sigaction(SIGTSTP, &sa, NULL);
|
|
||||||
sa.sa_flags = SA_RESETHAND;
|
|
||||||
sigaction(SIGINT, &sa, NULL);
|
|
||||||
sigaction(SIGQUIT, &sa, NULL);
|
|
||||||
sigaction(SIGTERM, &sa, NULL);
|
|
||||||
|
|
||||||
if ( !dispd_initialize(&argc, &argv) )
|
display_create_window(connection, window_id);
|
||||||
error(1, 0, "couldn't initialize dispd library");
|
display_resize_window(connection, window_id, game_width, game_height);
|
||||||
struct dispd_session* session = dispd_attach_default_session();
|
display_title_window(connection, window_id, "Aquatinspitz");
|
||||||
if ( !session )
|
|
||||||
error(1, 0, "couldn't attach to dispd default session");
|
|
||||||
if ( !dispd_session_setup_game_rgba(session) )
|
|
||||||
error(1, 0, "couldn't setup dispd rgba session");
|
|
||||||
struct dispd_window* window = dispd_create_window_game_rgba(session);
|
|
||||||
if ( !window )
|
|
||||||
error(1, 0, "couldn't create dispd rgba window");
|
|
||||||
|
|
||||||
mainloop(window);
|
mainloop(connection);
|
||||||
|
|
||||||
dispd_destroy_window(window);
|
display_disconnect(connection);
|
||||||
dispd_detach_session(session);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <sys/termmode.h>
|
#include <sys/termmode.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <error.h>
|
#include <error.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
@ -1179,6 +1180,8 @@ void RunFrame(struct display_connection* connection)
|
||||||
{
|
{
|
||||||
free(buf);
|
free(buf);
|
||||||
buf = (uint32_t*) malloc(framesize);
|
buf = (uint32_t*) malloc(framesize);
|
||||||
|
if ( !buf )
|
||||||
|
err(1, "malloc");
|
||||||
}
|
}
|
||||||
|
|
||||||
GameLogic();
|
GameLogic();
|
||||||
|
@ -1199,7 +1202,8 @@ void RunFrame(struct display_connection* connection)
|
||||||
last_frame_sec = now.tv_sec;
|
last_frame_sec = now.tv_sec;
|
||||||
}
|
}
|
||||||
|
|
||||||
display_render_window(connection, WINDOW_ID, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, buf);
|
display_render_window(connection, WINDOW_ID, 0, 0,
|
||||||
|
WINDOW_WIDTH, WINDOW_HEIGHT, buf);
|
||||||
display_show_window(connection, WINDOW_ID);
|
display_show_window(connection, WINDOW_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue