Compare commits

...

2 commits

Author SHA1 Message Date
Gwenhael Le Moine
50329fff2d
binary and project now named ui48 2024-09-12 15:16:04 +02:00
Gwenhael Le Moine
236b046998
merge ui_ncurses, back to multi-UIs 2024-09-12 15:05:48 +02:00
14 changed files with 1765 additions and 1143 deletions

2
.gitignore vendored
View file

@ -52,4 +52,4 @@ Module.symvers
Mkfile.old
dkms.conf
/hp48-sdl2
/ui48

View file

@ -1,14 +1,19 @@
# Makefile
TARGETS = hp48-sdl2
TARGETS = ui48
VERSION_MAJOR = 0
VERSION_MINOR = 0
PATCHLEVEL = 0
PKG_CONFIG ?= pkg-config
MAKEFLAGS +=-j$(NUM_CORES) -l$(NUM_CORES)
DOTOS = src/ui.o \
src/config.o \
DOTOS = src/config.o \
src/emulator.o \
src/ui_sdl2.o \
src/ui_ncurses.o \
src/ui.o \
src/main.o
cc-option = $(shell if $(CC) $(1) -c -x c /dev/null -o /dev/null > /dev/null 2>&1; \
@ -46,6 +51,7 @@ override CFLAGS := -std=c11 \
$(call cc-option,-Wno-unknown-warning-option) \
$(EXTRA_WARNING_FLAGS) \
$(shell "$(PKG_CONFIG)" --cflags sdl2) \
$(shell "$(PKG_CONFIG)" --cflags ncursesw) -DNCURSES_WIDECHAR=1 \
$(CFLAGS)
override CPPFLAGS := -I./src/ -D_GNU_SOURCE=1 \
@ -54,7 +60,9 @@ override CPPFLAGS := -I./src/ -D_GNU_SOURCE=1 \
-DPATCHLEVEL=$(PATCHLEVEL) \
$(CPPFLAGS)
LIBS = -lm $(shell "$(PKG_CONFIG)" --libs sdl2)
LIBS = -lm \
$(shell "$(PKG_CONFIG)" --libs sdl2) \
$(shell "$(PKG_CONFIG)" --libs ncursesw)
# SDLCFLAGS = $(shell "$(PKG_CONFIG)" --cflags sdl2)
# SDLLIBS = $(shell "$(PKG_CONFIG)" --libs sdl2)
@ -66,7 +74,7 @@ LIBS = -lm $(shell "$(PKG_CONFIG)" --libs sdl2)
all: $(TARGETS)
hp48-sdl2: $(DOTOS)
ui48: $(DOTOS)
# Binaries
$(TARGETS):

View file

@ -1,3 +1,7 @@
# hp48-sdl2
# ui48
HP48 UI in sdl2 (standalone)
Standalone HP 48(SX/GX) front-end ready to be plugged into emulators.
Provide both GUI implemented in SDL2 and TUI in ncurses.
Extracted from x48ng.

View file

@ -13,20 +13,24 @@
#include "config.h"
static config_t config = {
.progname = ( char* )"ui48ng",
.progname = ( char* )"ui48",
.gx = true,
.verbose = false,
.leave_shift_keys = false,
.frontend = -1,
.mono = false,
.gray = false,
/* sdl */
.hide_chrome = false,
.show_ui_fullscreen = false,
.scale = 1.0,
.tiny = false,
.small = false,
.wire_name = ( char* )"/dev/wire",
.ir_name = ( char* )"/dev/ir",
};
@ -39,36 +43,62 @@ config_t* config_init( int argc, char* argv[] )
int clopt_gx = -1;
int clopt_verbose = -1;
int clopt_leave_shift_keys = -1;
int clopt_frontend = -1;
int clopt_mono = -1;
int clopt_gray = -1;
int clopt_hide_chrome = -1;
int clopt_show_ui_fullscreen = -1;
double clopt_scale = -1.0;
int clopt_tiny = -1;
int clopt_small = -1;
const char* optstring = "c:hvVtsirT";
struct option long_options[] = {
{"help", no_argument, NULL, 'h' },
{"help", no_argument, NULL, 'h' },
{"gx", no_argument, &clopt_gx, true },
{"sx", no_argument, &clopt_gx, false},
{"verbose", no_argument, &clopt_verbose, true },
{"leave-shift-keys", no_argument, &clopt_leave_shift_keys, true },
{"mono", no_argument, &clopt_mono, true },
{"gray", no_argument, &clopt_gray, true },
{"no-chrome", no_argument, &clopt_hide_chrome, true },
{"fullscreen", no_argument, &clopt_show_ui_fullscreen, true },
{"scale", required_argument, NULL, 7110 },
{"gx", no_argument, &clopt_gx, true },
{"sx", no_argument, &clopt_gx, false },
{"verbose", no_argument, &clopt_verbose, true },
{"leave-shift-keys", no_argument, &clopt_leave_shift_keys, true },
{"gui", no_argument, &clopt_frontend, FRONTEND_SDL },
{"tui", no_argument, &clopt_frontend, FRONTEND_NCURSES},
{"tui-small", no_argument, NULL, 6110 },
{"tui-tiny", no_argument, NULL, 6120 },
{"mono", no_argument, &clopt_mono, true },
{"gray", no_argument, &clopt_gray, true },
{"no-chrome", no_argument, &clopt_hide_chrome, true },
{"fullscreen", no_argument, &clopt_show_ui_fullscreen, true },
{"scale", required_argument, NULL, 7110 },
{0, 0, 0, 0 }
{0, 0, 0, 0 }
};
const char* help_text = "usage: %s [options]\n options:\n -h --help what you "
"are reading\n -V --verbose be verbose (default: false)\n "
" --no-chrome only display the LCD (default: false)\n --fullscreen make the "
"UI fullscreen (default: false)\n --scale=<number> make the UI scale <number> times "
"(default: 1.0)\n --mono make the UI monochrome (default: false)\n "
" --gray make the UI grayscale (default: false)\n "
"--leave-shift-keys _not_ mapping the shift keys to let them free for numbers (default: false)\n";
const char* help_text = "usage: %s [options]\n"
"options:\n"
" -h --help what you are reading\n"
" --gui use graphical (SDL2) front-end (default: true)\n"
" --tui use text front-end (default: false)\n"
" --tui-small use text small front-end (2×2 pixels per character) (default: "
"false)\n"
" --tui-tiny use text tiny front-end (2×4 pixels per character) (default: "
"false)\n"
" --no-chrome only display the LCD (default: "
"false)\n"
" --fullscreen make the UI fullscreen "
"(default: false)\n"
" --scale=<number> make the UI scale <number> times "
"(default: 1.0)\n"
" --mono make the UI monochrome (default: "
"false)\n"
" --gray make the UI grayscale (default: "
"false)\n"
" --gx make the GUI looks like a HP 48GX (default: "
"auto)\n"
" --sx make the GUI looks like a HP 48SX (default: "
"auto)\n"
" --leave-shift-keys _not_ mapping the shift keys to let them free for numbers (default: "
"false)\n";
while ( c != EOF ) {
c = getopt_long( argc, argv, optstring, long_options, &option_index );
@ -78,6 +108,14 @@ config_t* config_init( int argc, char* argv[] )
fprintf( stderr, help_text, config.progname );
exit( 0 );
break;
case 6110:
clopt_frontend = FRONTEND_NCURSES;
clopt_small = true;
break;
case 6120:
clopt_frontend = FRONTEND_NCURSES;
clopt_tiny = true;
break;
case 7110:
clopt_scale = atof( optarg );
break;
@ -96,10 +134,12 @@ config_t* config_init( int argc, char* argv[] )
/****************************************************/
/* 2. treat command-line params which have priority */
/****************************************************/
if ( clopt_gx != -1 )
config.gx = clopt_gx;
if ( clopt_verbose != -1 )
config.verbose = clopt_verbose;
if ( clopt_gx != -1 )
config.gx = clopt_gx;
if ( clopt_frontend != -1 )
config.frontend = clopt_frontend;
if ( clopt_hide_chrome != -1 )
config.hide_chrome = clopt_hide_chrome;
if ( clopt_show_ui_fullscreen != -1 )
@ -108,6 +148,10 @@ config_t* config_init( int argc, char* argv[] )
config.scale = clopt_scale;
if ( clopt_mono != -1 )
config.mono = clopt_mono;
if ( clopt_small != -1 )
config.small = clopt_small;
if ( clopt_tiny != -1 )
config.tiny = clopt_tiny;
if ( clopt_gray != -1 )
config.gray = clopt_gray;
if ( clopt_leave_shift_keys != -1 )

View file

@ -3,6 +3,9 @@
#include <stdbool.h>
#define FRONTEND_SDL 1
#define FRONTEND_NCURSES 2
typedef struct {
char* progname;
@ -10,12 +13,17 @@ typedef struct {
bool verbose;
bool leave_shift_keys;
int frontend;
bool mono;
bool gray;
bool hide_chrome;
bool show_ui_fullscreen;
double scale;
bool tiny;
bool small;
char* wire_name;
char* ir_name;
} config_t;

View file

@ -83,15 +83,19 @@
#define LCD_WIDTH 131
#define LCD_HEIGHT 64
void press_key( int hpkey );
void release_key( int hpkey );
bool is_key_pressed( int hpkey );
/*************************************************/
/* public API: if it's there it's used elsewhere */
/*************************************************/
extern void press_key( int hpkey );
extern void release_key( int hpkey );
extern bool is_key_pressed( int hpkey );
void init_emulator( void );
void exit_emulator( void );
extern void init_emulator( void );
extern void exit_emulator( void );
extern unsigned char get_annunciators( void );
extern bool get_display_state( void );
extern void get_lcd_buffer( int* target );
extern int get_contrast( void );
unsigned char get_annunciators( void );
bool get_display_state( void );
void get_lcd_buffer( int* target );
int get_contrast( void );
#endif /* !_EMULATOR_H */

View file

@ -5,10 +5,14 @@
int main( int argc, char** argv )
{
config_t* config = config_init( argc, argv );
init_emulator();
/* (G)UI */
ui_start( config_init( argc, argv ) );
setup_ui( config );
ui_start( config );
while ( true ) {
ui_get_event();

1103
src/ui.c

File diff suppressed because it is too large Load diff

View file

@ -6,12 +6,13 @@
/*************************************************/
/* public API: if it's there it's used elsewhere */
/*************************************************/
extern void ui_get_event( void );
extern void ui_update_display( void );
extern void ( *ui_get_event )( void );
extern void ( *ui_update_display )( void );
extern void ui_start( config_t* config );
extern void ui_stop( void );
extern void ( *ui_start )( config_t* config );
extern void ( *ui_stop )( void );
extern void setup_ui( config_t* config );
extern void close_and_exit( void );
#endif /* !_UI_H */

View file

@ -69,14 +69,6 @@ typedef struct button_t {
const char* sub;
} button_t;
typedef struct ann_struct_t {
int x;
int y;
unsigned int width;
unsigned int height;
unsigned char* bits;
} ann_struct_t;
/*************/
/* variables */
/*************/
@ -89,8 +81,6 @@ extern color_t colors_gx[ NB_COLORS ];
extern button_t buttons_sx[ NB_KEYS ];
extern button_t buttons_gx[ NB_KEYS ];
extern ann_struct_t ann_tbl[ NB_ANNUNCIATORS ];
#define small_ascent 8
#define small_descent 4

504
src/ui_ncurses.c Normal file
View file

@ -0,0 +1,504 @@
#include <ctype.h>
#include <fcntl.h>
#include <pwd.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <unistd.h>
#include <locale.h>
#include <wchar.h>
#include <curses.h>
#include "config.h"
#include "emulator.h"
#include "ui.h"
#include "ui_inner.h"
#define COLORS ( config.gx ? colors_gx : colors_sx )
#define BUTTONS ( config.gx ? buttons_gx : buttons_sx )
#define LCD_OFFSET_X 1
#define LCD_OFFSET_Y 1
#define LCD_BOTTOM LCD_OFFSET_Y + ( config.small ? ( LCD_HEIGHT / 2 ) : config.tiny ? ( LCD_HEIGHT / 4 ) : LCD_HEIGHT )
#define LCD_RIGHT LCD_OFFSET_X + ( ( config.small || config.tiny ) ? ( LCD_WIDTH / 2 ) + 1 : LCD_WIDTH )
#define LCD_COLOR_BG 48
#define LCD_COLOR_FG 49
#define LCD_PIXEL_ON 1
#define LCD_PIXEL_OFF 2
#define LCD_COLORS_PAIR 3
/*************/
/* variables */
/*************/
static config_t config;
static int lcd_pixels_buffer[ LCD_WIDTH * LCD_HEIGHT ];
static int last_annunciators = -1;
// static int last_contrast = -1;
/****************************/
/* functions implementation */
/****************************/
static inline wchar_t eight_bits_to_braille_char( bool b1, bool b2, bool b3, bool b4, bool b5, bool b6, bool b7, bool b8 )
{
/*********/
/* b1 b4 */
/* b2 b5 */
/* b3 b6 */
/* b7 b8 */
/*********/
wchar_t chr = 0x2800;
if ( b1 )
chr |= 1; // 0b0000000000000001;
if ( b2 )
chr |= 2; // 0b0000000000000010;
if ( b3 )
chr |= 4; // 0b0000000000000100;
if ( b4 )
chr |= 8; // 0b0000000000001000;
if ( b5 )
chr |= 16; // 0b0000000000010000;
if ( b6 )
chr |= 32; // 0b0000000000100000;
if ( b7 )
chr |= 64; // 0b0000000001000000;
if ( b8 )
chr |= 128; // 0b0000000010000000;
return chr;
}
static inline void ncurses_draw_lcd_tiny( void )
{
bool b1, b2, b3, b4, b5, b6, b7, b8;
int step_x = 2;
int step_y = 4;
wchar_t line[ 66 ]; /* ( LCD_WIDTH / step_x ) + 1 */
if ( !config.mono && has_colors() )
attron( COLOR_PAIR( LCD_COLORS_PAIR ) );
for ( int y = 0; y < LCD_HEIGHT; y += step_y ) {
wcscpy( line, L"" );
for ( int x = 0; x < LCD_WIDTH; x += step_x ) {
b1 = lcd_pixels_buffer[ ( y * LCD_WIDTH ) + x ];
b4 = lcd_pixels_buffer[ ( y * LCD_WIDTH ) + x + 1 ];
b2 = lcd_pixels_buffer[ ( ( y + 1 ) * LCD_WIDTH ) + x ];
b5 = lcd_pixels_buffer[ ( ( y + 1 ) * LCD_WIDTH ) + x + 1 ];
b3 = lcd_pixels_buffer[ ( ( y + 2 ) * LCD_WIDTH ) + x ];
b6 = lcd_pixels_buffer[ ( ( y + 2 ) * LCD_WIDTH ) + x + 1 ];
b7 = lcd_pixels_buffer[ ( ( y + 3 ) * LCD_WIDTH ) + x ];
b8 = lcd_pixels_buffer[ ( ( y + 3 ) * LCD_WIDTH ) + x + 1 ];
wchar_t pixels = eight_bits_to_braille_char( b1, b2, b3, b4, b5, b6, b7, b8 );
wcsncat( line, &pixels, 1 );
}
mvaddwstr( LCD_OFFSET_Y + ( y / step_y ), LCD_OFFSET_X, line );
}
if ( !config.mono && has_colors() )
attroff( COLOR_PAIR( LCD_COLORS_PAIR ) );
wrefresh( stdscr );
}
static inline wchar_t four_bits_to_quadrant_char( bool top_left, bool top_right, bool bottom_left, bool bottom_right )
{
if ( top_left ) {
if ( top_right ) {
if ( bottom_left )
return bottom_right ? L'' : L''; /* 0x2588 0x2598 */
else
return bottom_right ? L'' : L''; /* 0x259C 0x2580 */
} else {
if ( bottom_left )
return bottom_right ? L'' : L'';
else
return bottom_right ? L'' : L'';
}
} else {
if ( top_right ) {
if ( bottom_left )
return bottom_right ? L'' : L'';
else
return bottom_right ? L'' : L'';
} else {
if ( bottom_left )
return bottom_right ? L'' : L'';
else
return bottom_right ? L'' : L' ';
}
}
}
static inline void ncurses_draw_lcd_small( void )
{
bool top_left, top_right, bottom_left, bottom_right;
int step_x = 2;
int step_y = 2;
wchar_t line[ 66 ]; /* ( LCD_WIDTH / step_x ) + 1 */
if ( !config.mono && has_colors() )
attron( COLOR_PAIR( LCD_COLORS_PAIR ) );
for ( int y = 0; y < LCD_HEIGHT; y += step_y ) {
wcscpy( line, L"" );
for ( int x = 0; x < LCD_WIDTH; x += step_x ) {
top_left = lcd_pixels_buffer[ ( y * LCD_WIDTH ) + x ];
top_right = lcd_pixels_buffer[ ( y * LCD_WIDTH ) + x + 1 ];
bottom_left = lcd_pixels_buffer[ ( ( y + 1 ) * LCD_WIDTH ) + x ];
bottom_right = lcd_pixels_buffer[ ( ( y + 1 ) * LCD_WIDTH ) + x + 1 ];
wchar_t pixels = four_bits_to_quadrant_char( top_left, top_right, bottom_left, bottom_right );
wcsncat( line, &pixels, 1 );
}
mvaddwstr( LCD_OFFSET_Y + ( y / step_y ), LCD_OFFSET_X, line );
}
if ( !config.mono && has_colors() )
attroff( COLOR_PAIR( LCD_COLORS_PAIR ) );
wrefresh( stdscr );
}
static inline void ncurses_draw_lcd_fullsize( void )
{
bool bit;
wchar_t line[ LCD_WIDTH ];
if ( !config.mono && has_colors() )
attron( COLOR_PAIR( LCD_COLORS_PAIR ) );
for ( int y = 0; y < LCD_HEIGHT; ++y ) {
wcscpy( line, L"" );
for ( int x = 0; x < LCD_WIDTH; ++x ) {
bit = lcd_pixels_buffer[ ( y * LCD_WIDTH ) + x ];
wchar_t pixel = bit ? L'' : L' ';
wcsncat( line, &pixel, 1 );
}
mvaddwstr( LCD_OFFSET_Y + y, LCD_OFFSET_X, line );
}
if ( !config.mono && has_colors() )
attroff( COLOR_PAIR( LCD_COLORS_PAIR ) );
wrefresh( stdscr );
}
static inline void ncurses_draw_lcd( void )
{
if ( config.tiny )
ncurses_draw_lcd_tiny();
else if ( config.small )
ncurses_draw_lcd_small();
else
ncurses_draw_lcd_fullsize();
}
static void ui_init_LCD( void ) { memset( lcd_pixels_buffer, 0, sizeof( lcd_pixels_buffer ) ); }
static void ncurses_update_annunciators( void )
{
const wchar_t* annunciators_icons[ 6 ] = { L"", L"", L"α", L"🪫", L"", L"" };
const int annunciators_bits[ NB_ANNUNCIATORS ] = { ANN_LEFT, ANN_RIGHT, ANN_ALPHA, ANN_BATTERY, ANN_BUSY, ANN_IO };
int annunciators = get_annunciators();
if ( last_annunciators == annunciators )
return;
last_annunciators = annunciators;
for ( int i = 0; i < NB_ANNUNCIATORS; i++ )
mvaddwstr( 0, 4 + ( i * 4 ),
( ( annunciators_bits[ i ] & annunciators ) == annunciators_bits[ i ] ) ? annunciators_icons[ i ] : L" " );
}
/**********/
/* public */
/**********/
void ui_update_display_ncurses( void )
{
// apply_contrast();
if ( get_display_state() ) {
get_lcd_buffer( lcd_pixels_buffer );
} else
ui_init_LCD();
ncurses_update_annunciators();
ncurses_draw_lcd();
}
void ui_get_event_ncurses( void )
{
int hpkey = -1;
uint32_t k;
/* Start fresh and mark all keys as released */
// release_all_keys();
/* Iterate over all currently pressed keys and mark them as pressed */
while ( ( k = getch() ) ) {
if ( k == ( uint32_t )ERR )
break;
switch ( k ) {
case '0':
hpkey = HPKEY_0;
break;
case '1':
hpkey = HPKEY_1;
break;
case '2':
hpkey = HPKEY_2;
break;
case '3':
hpkey = HPKEY_3;
break;
case '4':
hpkey = HPKEY_4;
break;
case '5':
hpkey = HPKEY_5;
break;
case '6':
hpkey = HPKEY_6;
break;
case '7':
hpkey = HPKEY_7;
break;
case '8':
hpkey = HPKEY_8;
break;
case '9':
hpkey = HPKEY_9;
break;
case 'a':
hpkey = HPKEY_A;
break;
case 'b':
hpkey = HPKEY_B;
break;
case 'c':
hpkey = HPKEY_C;
break;
case 'd':
hpkey = HPKEY_D;
break;
case 'e':
hpkey = HPKEY_E;
break;
case 'f':
hpkey = HPKEY_F;
break;
case 'g':
hpkey = HPKEY_MTH;
break;
case 'h':
hpkey = HPKEY_PRG;
break;
case 'i':
hpkey = HPKEY_CST;
break;
case 'j':
hpkey = HPKEY_VAR;
break;
case 'k':
case KEY_UP:
hpkey = HPKEY_UP;
break;
case 'l':
hpkey = HPKEY_NXT;
break;
case 'm':
hpkey = HPKEY_QUOTE;
break;
case 'n':
hpkey = HPKEY_STO;
break;
case 'o':
hpkey = HPKEY_EVAL;
break;
case 'p':
case KEY_LEFT:
hpkey = HPKEY_LEFT;
break;
case 'q':
case KEY_DOWN:
hpkey = HPKEY_DOWN;
break;
case 'r':
case KEY_RIGHT:
hpkey = HPKEY_RIGHT;
break;
case 's':
hpkey = HPKEY_SIN;
break;
case 't':
hpkey = HPKEY_COS;
break;
case 'u':
hpkey = HPKEY_TAN;
break;
case 'v':
hpkey = HPKEY_SQRT;
break;
case 'w':
hpkey = HPKEY_POWER;
break;
case 'x':
hpkey = HPKEY_INV;
break;
case 'y':
hpkey = HPKEY_NEG;
break;
case 'z':
hpkey = HPKEY_EEX;
break;
case ' ':
hpkey = HPKEY_SPC;
break;
case KEY_DC:
hpkey = HPKEY_DEL;
break;
case '.':
hpkey = HPKEY_PERIOD;
break;
case '+':
hpkey = HPKEY_PLUS;
break;
case '-':
hpkey = HPKEY_MINUS;
break;
case '*':
hpkey = HPKEY_MUL;
break;
case '/':
hpkey = HPKEY_DIV;
break;
case KEY_F( 1 ):
case KEY_ENTER:
case '\n':
case ',':
hpkey = HPKEY_ENTER;
break;
case KEY_BACKSPACE:
case 127:
case '\b':
hpkey = HPKEY_BS;
break;
case KEY_F( 2 ):
case '[':
case 339: /* PgUp */
hpkey = HPKEY_SHL;
break;
case KEY_F( 3 ):
case ']':
case 338: /* PgDn */
hpkey = HPKEY_SHR;
break;
case KEY_F( 4 ):
case ';':
case KEY_IC: /* Ins */
hpkey = HPKEY_ALPHA;
break;
case KEY_F( 5 ):
case '\\':
case 27: /* Esc */
case 262: /* Home */
hpkey = HPKEY_ON;
break;
case KEY_F( 7 ):
case '|': /* Shift+\ */
case KEY_SEND: /* Shift+End */
case KEY_F( 10 ):
// please_exit = true;
close_and_exit();
break;
}
if ( !is_key_pressed( hpkey ) )
press_key( hpkey );
}
}
void ui_stop_ncurses( void )
{
nodelay( stdscr, FALSE );
echo();
endwin();
}
void ui_start_ncurses( config_t* conf )
{
if ( config.verbose )
fprintf( stderr, "UI is ncurses\n" );
config = *conf;
setlocale( LC_ALL, "" );
initscr(); /* initialize the curses library */
keypad( stdscr, TRUE ); /* enable keyboard mapping */
nodelay( stdscr, TRUE );
curs_set( 0 );
cbreak(); /* take input chars one at a time, no wait for \n */
noecho();
nonl(); /* tell curses not to do NL->CR/NL on output */
if ( !config.mono && has_colors() ) {
start_color();
if ( config.gray ) {
init_color( LCD_COLOR_BG, COLORS[ LCD ].gray_rgb, COLORS[ LCD ].gray_rgb, COLORS[ LCD ].gray_rgb );
init_color( LCD_COLOR_FG, COLORS[ PIXEL ].gray_rgb, COLORS[ PIXEL ].gray_rgb, COLORS[ PIXEL ].gray_rgb );
} else {
init_color( LCD_COLOR_BG, COLORS[ LCD ].r, COLORS[ LCD ].g, COLORS[ LCD ].b );
init_color( LCD_COLOR_FG, COLORS[ PIXEL ].r, COLORS[ PIXEL ].g, COLORS[ PIXEL ].b );
}
init_pair( LCD_PIXEL_OFF, LCD_COLOR_BG, LCD_COLOR_BG );
init_pair( LCD_PIXEL_ON, LCD_COLOR_FG, LCD_COLOR_FG );
init_pair( LCD_COLORS_PAIR, LCD_COLOR_FG, LCD_COLOR_BG );
}
mvaddch( 0, 0, ACS_ULCORNER );
mvaddch( LCD_BOTTOM, 0, ACS_LLCORNER );
mvaddch( 0, LCD_RIGHT, ACS_URCORNER );
mvaddch( LCD_BOTTOM, LCD_RIGHT, ACS_LRCORNER );
mvhline( 0, 1, ACS_HLINE, LCD_RIGHT - 1 );
mvhline( LCD_BOTTOM, 1, ACS_HLINE, LCD_RIGHT - 1 );
mvvline( 1, 0, ACS_VLINE, LCD_BOTTOM - 1 );
mvvline( 1, LCD_RIGHT, ACS_VLINE, LCD_BOTTOM - 1 );
mvprintw( 0, 2, "[ | | | | | ]" ); /* annunciators */
mvprintw( 0, LCD_RIGHT - 18, "< %s v%i.%i.%i >", config.progname, VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL );
mvprintw( LCD_BOTTOM, 2, "[ wire: %s ]-[ IR: %s ]-[ contrast: %i ]", config.wire_name, config.ir_name, get_contrast() );
mvprintw( LCD_BOTTOM + 1, 0, "F1: Enter, F2: Left-Shift, F3: Right-Shift, F4: Alpha, F5: On, F7: Quit" );
}
void setup_frontend_ncurses( void )
{
ui_get_event = ui_get_event_ncurses;
ui_update_display = ui_update_display_ncurses;
ui_start = ui_start_ncurses;
ui_stop = ui_stop_ncurses;
}

6
src/ui_ncurses.h Normal file
View file

@ -0,0 +1,6 @@
#ifndef _UI_NCURSES_H
#define _UI_NCURSES_H 1
extern void setup_frontend_ncurses( void );
#endif /* _UI_NCURSES_H */

1118
src/ui_sdl2.c Normal file

File diff suppressed because it is too large Load diff

6
src/ui_sdl2.h Normal file
View file

@ -0,0 +1,6 @@
#ifndef _UI_SDL2_H
#define _UI_SDL2_H 1
extern void setup_frontend_sdl( void );
#endif /* _UI_SDL2_H */