merge ui_ncurses, back to multi-UIs
This commit is contained in:
parent
19a11f513d
commit
236b046998
12 changed files with 1727 additions and 1130 deletions
11
Makefile
11
Makefile
|
@ -6,9 +6,11 @@ PKG_CONFIG ?= pkg-config
|
||||||
|
|
||||||
MAKEFLAGS +=-j$(NUM_CORES) -l$(NUM_CORES)
|
MAKEFLAGS +=-j$(NUM_CORES) -l$(NUM_CORES)
|
||||||
|
|
||||||
DOTOS = src/ui.o \
|
DOTOS = src/config.o \
|
||||||
src/config.o \
|
|
||||||
src/emulator.o \
|
src/emulator.o \
|
||||||
|
src/ui_sdl2.o \
|
||||||
|
src/ui_ncurses.o \
|
||||||
|
src/ui.o \
|
||||||
src/main.o
|
src/main.o
|
||||||
|
|
||||||
cc-option = $(shell if $(CC) $(1) -c -x c /dev/null -o /dev/null > /dev/null 2>&1; \
|
cc-option = $(shell if $(CC) $(1) -c -x c /dev/null -o /dev/null > /dev/null 2>&1; \
|
||||||
|
@ -46,6 +48,7 @@ override CFLAGS := -std=c11 \
|
||||||
$(call cc-option,-Wno-unknown-warning-option) \
|
$(call cc-option,-Wno-unknown-warning-option) \
|
||||||
$(EXTRA_WARNING_FLAGS) \
|
$(EXTRA_WARNING_FLAGS) \
|
||||||
$(shell "$(PKG_CONFIG)" --cflags sdl2) \
|
$(shell "$(PKG_CONFIG)" --cflags sdl2) \
|
||||||
|
$(shell "$(PKG_CONFIG)" --cflags ncursesw) -DNCURSES_WIDECHAR=1 \
|
||||||
$(CFLAGS)
|
$(CFLAGS)
|
||||||
|
|
||||||
override CPPFLAGS := -I./src/ -D_GNU_SOURCE=1 \
|
override CPPFLAGS := -I./src/ -D_GNU_SOURCE=1 \
|
||||||
|
@ -54,7 +57,9 @@ override CPPFLAGS := -I./src/ -D_GNU_SOURCE=1 \
|
||||||
-DPATCHLEVEL=$(PATCHLEVEL) \
|
-DPATCHLEVEL=$(PATCHLEVEL) \
|
||||||
$(CPPFLAGS)
|
$(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)
|
# SDLCFLAGS = $(shell "$(PKG_CONFIG)" --cflags sdl2)
|
||||||
# SDLLIBS = $(shell "$(PKG_CONFIG)" --libs sdl2)
|
# SDLLIBS = $(shell "$(PKG_CONFIG)" --libs sdl2)
|
||||||
|
|
34
src/config.c
34
src/config.c
|
@ -19,14 +19,18 @@ static config_t config = {
|
||||||
.verbose = false,
|
.verbose = false,
|
||||||
.leave_shift_keys = false,
|
.leave_shift_keys = false,
|
||||||
|
|
||||||
|
.frontend = -1,
|
||||||
|
|
||||||
.mono = false,
|
.mono = false,
|
||||||
.gray = false,
|
.gray = false,
|
||||||
|
|
||||||
/* sdl */
|
|
||||||
.hide_chrome = false,
|
.hide_chrome = false,
|
||||||
.show_ui_fullscreen = false,
|
.show_ui_fullscreen = false,
|
||||||
.scale = 1.0,
|
.scale = 1.0,
|
||||||
|
|
||||||
|
.tiny = false,
|
||||||
|
.small = false,
|
||||||
|
|
||||||
.wire_name = ( char* )"/dev/wire",
|
.wire_name = ( char* )"/dev/wire",
|
||||||
.ir_name = ( char* )"/dev/ir",
|
.ir_name = ( char* )"/dev/ir",
|
||||||
};
|
};
|
||||||
|
@ -39,20 +43,28 @@ config_t* config_init( int argc, char* argv[] )
|
||||||
int clopt_gx = -1;
|
int clopt_gx = -1;
|
||||||
int clopt_verbose = -1;
|
int clopt_verbose = -1;
|
||||||
int clopt_leave_shift_keys = -1;
|
int clopt_leave_shift_keys = -1;
|
||||||
|
int clopt_frontend = -1;
|
||||||
int clopt_mono = -1;
|
int clopt_mono = -1;
|
||||||
int clopt_gray = -1;
|
int clopt_gray = -1;
|
||||||
int clopt_hide_chrome = -1;
|
int clopt_hide_chrome = -1;
|
||||||
int clopt_show_ui_fullscreen = -1;
|
int clopt_show_ui_fullscreen = -1;
|
||||||
double clopt_scale = -1.0;
|
double clopt_scale = -1.0;
|
||||||
|
|
||||||
|
int clopt_tiny = -1;
|
||||||
|
int clopt_small = -1;
|
||||||
|
|
||||||
const char* optstring = "c:hvVtsirT";
|
const char* optstring = "c:hvVtsirT";
|
||||||
struct option long_options[] = {
|
struct option long_options[] = {
|
||||||
{"help", no_argument, NULL, 'h' },
|
{"help", no_argument, NULL, 'h' },
|
||||||
|
|
||||||
{"gx", no_argument, &clopt_gx, true },
|
{"gx", no_argument, &clopt_gx, true },
|
||||||
{"sx", no_argument, &clopt_gx, false},
|
{"sx", no_argument, &clopt_gx, false },
|
||||||
{"verbose", no_argument, &clopt_verbose, true },
|
{"verbose", no_argument, &clopt_verbose, true },
|
||||||
{"leave-shift-keys", no_argument, &clopt_leave_shift_keys, 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 },
|
{"mono", no_argument, &clopt_mono, true },
|
||||||
{"gray", no_argument, &clopt_gray, true },
|
{"gray", no_argument, &clopt_gray, true },
|
||||||
{"no-chrome", no_argument, &clopt_hide_chrome, true },
|
{"no-chrome", no_argument, &clopt_hide_chrome, true },
|
||||||
|
@ -78,6 +90,14 @@ config_t* config_init( int argc, char* argv[] )
|
||||||
fprintf( stderr, help_text, config.progname );
|
fprintf( stderr, help_text, config.progname );
|
||||||
exit( 0 );
|
exit( 0 );
|
||||||
break;
|
break;
|
||||||
|
case 6110:
|
||||||
|
clopt_frontend = FRONTEND_NCURSES;
|
||||||
|
clopt_small = true;
|
||||||
|
break;
|
||||||
|
case 6120:
|
||||||
|
clopt_frontend = FRONTEND_NCURSES;
|
||||||
|
clopt_tiny = true;
|
||||||
|
break;
|
||||||
case 7110:
|
case 7110:
|
||||||
clopt_scale = atof( optarg );
|
clopt_scale = atof( optarg );
|
||||||
break;
|
break;
|
||||||
|
@ -96,10 +116,12 @@ config_t* config_init( int argc, char* argv[] )
|
||||||
/****************************************************/
|
/****************************************************/
|
||||||
/* 2. treat command-line params which have priority */
|
/* 2. treat command-line params which have priority */
|
||||||
/****************************************************/
|
/****************************************************/
|
||||||
if ( clopt_gx != -1 )
|
|
||||||
config.gx = clopt_gx;
|
|
||||||
if ( clopt_verbose != -1 )
|
if ( clopt_verbose != -1 )
|
||||||
config.verbose = clopt_verbose;
|
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 )
|
if ( clopt_hide_chrome != -1 )
|
||||||
config.hide_chrome = clopt_hide_chrome;
|
config.hide_chrome = clopt_hide_chrome;
|
||||||
if ( clopt_show_ui_fullscreen != -1 )
|
if ( clopt_show_ui_fullscreen != -1 )
|
||||||
|
@ -108,6 +130,10 @@ config_t* config_init( int argc, char* argv[] )
|
||||||
config.scale = clopt_scale;
|
config.scale = clopt_scale;
|
||||||
if ( clopt_mono != -1 )
|
if ( clopt_mono != -1 )
|
||||||
config.mono = clopt_mono;
|
config.mono = clopt_mono;
|
||||||
|
if ( clopt_small != -1 )
|
||||||
|
config.small = clopt_small;
|
||||||
|
if ( clopt_tiny != -1 )
|
||||||
|
config.tiny = clopt_tiny;
|
||||||
if ( clopt_gray != -1 )
|
if ( clopt_gray != -1 )
|
||||||
config.gray = clopt_gray;
|
config.gray = clopt_gray;
|
||||||
if ( clopt_leave_shift_keys != -1 )
|
if ( clopt_leave_shift_keys != -1 )
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#define FRONTEND_SDL 1
|
||||||
|
#define FRONTEND_NCURSES 2
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char* progname;
|
char* progname;
|
||||||
|
|
||||||
|
@ -10,12 +13,17 @@ typedef struct {
|
||||||
bool verbose;
|
bool verbose;
|
||||||
bool leave_shift_keys;
|
bool leave_shift_keys;
|
||||||
|
|
||||||
|
int frontend;
|
||||||
bool mono;
|
bool mono;
|
||||||
bool gray;
|
bool gray;
|
||||||
|
|
||||||
bool hide_chrome;
|
bool hide_chrome;
|
||||||
bool show_ui_fullscreen;
|
bool show_ui_fullscreen;
|
||||||
double scale;
|
double scale;
|
||||||
|
|
||||||
|
bool tiny;
|
||||||
|
bool small;
|
||||||
|
|
||||||
char* wire_name;
|
char* wire_name;
|
||||||
char* ir_name;
|
char* ir_name;
|
||||||
} config_t;
|
} config_t;
|
||||||
|
|
|
@ -83,15 +83,19 @@
|
||||||
#define LCD_WIDTH 131
|
#define LCD_WIDTH 131
|
||||||
#define LCD_HEIGHT 64
|
#define LCD_HEIGHT 64
|
||||||
|
|
||||||
void press_key( int hpkey );
|
/*************************************************/
|
||||||
void release_key( int hpkey );
|
/* public API: if it's there it's used elsewhere */
|
||||||
bool is_key_pressed( int hpkey );
|
/*************************************************/
|
||||||
|
extern void press_key( int hpkey );
|
||||||
|
extern void release_key( int hpkey );
|
||||||
|
extern bool is_key_pressed( int hpkey );
|
||||||
|
|
||||||
void init_emulator( void );
|
extern void init_emulator( void );
|
||||||
void exit_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 */
|
#endif /* !_EMULATOR_H */
|
||||||
|
|
|
@ -5,10 +5,14 @@
|
||||||
|
|
||||||
int main( int argc, char** argv )
|
int main( int argc, char** argv )
|
||||||
{
|
{
|
||||||
|
|
||||||
|
config_t* config = config_init( argc, argv );
|
||||||
|
|
||||||
init_emulator();
|
init_emulator();
|
||||||
|
|
||||||
/* (G)UI */
|
/* (G)UI */
|
||||||
ui_start( config_init( argc, argv ) );
|
setup_ui( config );
|
||||||
|
ui_start( config );
|
||||||
|
|
||||||
while ( true ) {
|
while ( true ) {
|
||||||
ui_get_event();
|
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 */
|
/* public API: if it's there it's used elsewhere */
|
||||||
/*************************************************/
|
/*************************************************/
|
||||||
extern void ui_get_event( void );
|
extern void ( *ui_get_event )( void );
|
||||||
extern void ui_update_display( void );
|
extern void ( *ui_update_display )( void );
|
||||||
|
|
||||||
extern void ui_start( config_t* config );
|
extern void ( *ui_start )( config_t* config );
|
||||||
extern void ui_stop( void );
|
extern void ( *ui_stop )( void );
|
||||||
|
|
||||||
|
extern void setup_ui( config_t* config );
|
||||||
extern void close_and_exit( void );
|
extern void close_and_exit( void );
|
||||||
|
|
||||||
#endif /* !_UI_H */
|
#endif /* !_UI_H */
|
||||||
|
|
|
@ -69,14 +69,6 @@ typedef struct button_t {
|
||||||
const char* sub;
|
const char* sub;
|
||||||
} button_t;
|
} button_t;
|
||||||
|
|
||||||
typedef struct ann_struct_t {
|
|
||||||
int x;
|
|
||||||
int y;
|
|
||||||
unsigned int width;
|
|
||||||
unsigned int height;
|
|
||||||
unsigned char* bits;
|
|
||||||
} ann_struct_t;
|
|
||||||
|
|
||||||
/*************/
|
/*************/
|
||||||
/* variables */
|
/* variables */
|
||||||
/*************/
|
/*************/
|
||||||
|
@ -89,8 +81,6 @@ extern color_t colors_gx[ NB_COLORS ];
|
||||||
extern button_t buttons_sx[ NB_KEYS ];
|
extern button_t buttons_sx[ NB_KEYS ];
|
||||||
extern button_t buttons_gx[ NB_KEYS ];
|
extern button_t buttons_gx[ NB_KEYS ];
|
||||||
|
|
||||||
extern ann_struct_t ann_tbl[ NB_ANNUNCIATORS ];
|
|
||||||
|
|
||||||
#define small_ascent 8
|
#define small_ascent 8
|
||||||
#define small_descent 4
|
#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 >", config.progname );
|
||||||
|
|
||||||
|
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