Compare commits
2 commits
19a11f513d
...
50329fff2d
Author | SHA1 | Date | |
---|---|---|---|
|
50329fff2d | ||
|
236b046998 |
14 changed files with 1765 additions and 1143 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -52,4 +52,4 @@ Module.symvers
|
|||
Mkfile.old
|
||||
dkms.conf
|
||||
|
||||
/hp48-sdl2
|
||||
/ui48
|
||||
|
|
18
Makefile
18
Makefile
|
@ -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):
|
||||
|
|
|
@ -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.
|
||||
|
|
66
src/config.c
66
src/config.c
|
@ -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,12 +43,16 @@ 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' },
|
||||
|
@ -53,6 +61,10 @@ config_t* config_init( int argc, char* argv[] )
|
|||
{"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 },
|
||||
|
@ -62,13 +74,31 @@ config_t* config_init( int argc, char* argv[] )
|
|||
{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 )
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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();
|
||||
|
|
9
src/ui.h
9
src/ui.h
|
@ -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 */
|
||||
|
|
|
@ -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
504
src/ui_ncurses.c
Normal 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
6
src/ui_ncurses.h
Normal 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
1118
src/ui_sdl2.c
Normal file
File diff suppressed because it is too large
Load diff
6
src/ui_sdl2.h
Normal file
6
src/ui_sdl2.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef _UI_SDL2_H
|
||||
#define _UI_SDL2_H 1
|
||||
|
||||
extern void setup_frontend_sdl( void );
|
||||
|
||||
#endif /* _UI_SDL2_H */
|
Loading…
Reference in a new issue