applen: make --headless really skip ncurses initialisation.

Stop with Ctrl-C.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
This commit is contained in:
Andrea Odetti 2020-12-19 15:02:04 +00:00
parent 10eeeda581
commit ba6aaf6775
5 changed files with 102 additions and 38 deletions

View file

@ -21,6 +21,7 @@
#include "frontends/common2/programoptions.h" #include "frontends/common2/programoptions.h"
#include "frontends/common2/utils.h" #include "frontends/common2/utils.h"
#include "frontends/ncurses/world.h" #include "frontends/ncurses/world.h"
#include "frontends/ncurses/nframe.h"
namespace namespace
{ {
@ -111,9 +112,12 @@ namespace
std::this_thread::sleep_for(duration); std::this_thread::sleep_for(duration);
} }
} }
return true;
}
else
{
return !g_stop;
} }
return true;
} }
void EnterMessageLoop(const EmulatorOptions & options) void EnterMessageLoop(const EmulatorOptions & options)
@ -143,7 +147,7 @@ namespace
g_nMemoryClearType = options.memclear; g_nMemoryClearType = options.memclear;
initialiseEmulator(); initialiseEmulator();
NVideoInitialize(); NVideoInitialize(options.headless);
applyOptions(options); applyOptions(options);
CardManager & cardManager = GetCardMgr(); CardManager & cardManager = GetCardMgr();
@ -159,7 +163,7 @@ namespace
EnterMessageLoop(options); EnterMessageLoop(options);
} }
NVideoUninitialize(); Frame::unInitialise();
uninitialiseEmulator(); uninitialiseEmulator();
return 0; return 0;

View file

@ -1,14 +1,24 @@
#include "frontends/ncurses/nframe.h" #include "frontends/ncurses/nframe.h"
#include "frontends/ncurses/colors.h"
#include <signal.h>
#include <locale.h>
#include <stdlib.h>
bool Frame::ourInitialised = false;
std::shared_ptr<GraphicsColors> Frame::ourColors;
Frame::Frame() : myColumns(-1), myRows(-1) Frame::Frame() : myColumns(-1), myRows(-1)
{ {
init(24, 40); // only initialise if actually used
// so we can run headless
} }
void Frame::init(int rows, int columns) void Frame::init(int rows, int columns)
{ {
if (myRows != rows || myColumns != columns) if (myRows != rows || myColumns != columns)
{ {
initialise();
if (columns < myColumns || rows < myRows) if (columns < myColumns || rows < myRows)
{ {
werase(myStatus.get()); werase(myStatus.get());
@ -50,3 +60,41 @@ int Frame::getColumns() const
{ {
return myColumns; return myColumns;
} }
void Frame::initialise()
{
if (!ourInitialised)
{
setlocale(LC_ALL, "");
initscr();
// does not seem to be a problem calling endwin() multiple times
std::atexit(Frame::unInitialise);
curs_set(0);
noecho();
cbreak();
set_escdelay(0);
// make sure this happens when ncurses is indeed initialised
ourColors.reset(new GraphicsColors(20, 20, 32));
ourInitialised = true;
}
}
void Frame::unInitialise()
{
if (ourInitialised)
{
ourColors.reset();
endwin();
ourInitialised = false;
}
}
GraphicsColors & Frame::getColors()
{
return *ourColors;
}

View file

@ -4,6 +4,8 @@
#include <ncurses.h> #include <ncurses.h>
class GraphicsColors;
class Frame class Frame
{ {
public: public:
@ -15,6 +17,10 @@ class Frame
void init(int rows, int columns); void init(int rows, int columns);
int getColumns() const; int getColumns() const;
static GraphicsColors & getColors();
static void unInitialise();
private: private:
int myRows; int myRows;
@ -23,4 +29,7 @@ class Frame
std::shared_ptr<WINDOW> myFrame; std::shared_ptr<WINDOW> myFrame;
std::shared_ptr<WINDOW> myStatus; std::shared_ptr<WINDOW> myStatus;
static std::shared_ptr<GraphicsColors> ourColors;
static bool ourInitialised;
static void initialise();
}; };

View file

@ -30,7 +30,6 @@ namespace
{ {
std::shared_ptr<Frame> frame; std::shared_ptr<Frame> frame;
std::shared_ptr<GraphicsColors> colors;
std::shared_ptr<ASCIIArt> asciiArt; std::shared_ptr<ASCIIArt> asciiArt;
std::shared_ptr<EvDevPaddle> paddle; std::shared_ptr<EvDevPaddle> paddle;
@ -60,7 +59,7 @@ namespace
bool g_bTextFlashState = false; bool g_bTextFlashState = false;
void sig_handler(int signo) void sig_handler_pass(int signo)
{ {
// Ctrl-C // Ctrl-C
// is there a race condition here? // is there a race condition here?
@ -68,6 +67,11 @@ namespace
addKeyToBuffer(0x03); addKeyToBuffer(0x03);
} }
void sig_handler_exit(int signo)
{
g_stop = true;
}
chtype mapCharacter(BYTE ch) chtype mapCharacter(BYTE ch)
{ {
const char low = ch & 0x7f; const char low = ch & 0x7f;
@ -173,7 +177,7 @@ namespace
{ {
BYTE val = *(g_pTextBank0+offset); BYTE val = *(g_pTextBank0+offset);
const int pair = colors->getPair(val); const int pair = frame->getColors().getPair(val);
WINDOW * win = frame->getWindow(); WINDOW * win = frame->getWindow();
@ -209,11 +213,13 @@ namespace
frame->init(24 * rows, 40 * cols); frame->init(24 * rows, 40 * cols);
WINDOW * win = frame->getWindow(); WINDOW * win = frame->getWindow();
const GraphicsColors & colors = frame->getColors();
for (size_t i = 0; i < rows; ++i) for (size_t i = 0; i < rows; ++i)
{ {
for (size_t j = 0; j < cols; ++j) for (size_t j = 0; j < cols; ++j)
{ {
const int pair = colors->getGrey(chs[i][j].foreground, chs[i][j].background); const int pair = colors.getGrey(chs[i][j].foreground, chs[i][j].background);
wcolor_set(win, pair, NULL); wcolor_set(win, pair, NULL);
mvwaddstr(win, 1 + rows * y + i, 1 + cols * x + j, chs[i][j].c); mvwaddstr(win, 1 + rows * y + i, 1 + cols * x + j, chs[i][j].c);
@ -232,13 +238,17 @@ namespace
} }
double g_relativeSpeed = 1.0; double g_relativeSpeed = 1.0;
bool g_stop = false;
void FrameRefresh() void FrameRefresh()
{ {
WINDOW * status = frame->getStatus(); WINDOW * status = frame->getStatus();
mvwprintw(status, 1, 2, "D1: %d, %s, %s", g_eStatusDrive1, g_sTrackDrive1, g_sSectorDrive1); if (status)
mvwprintw(status, 2, 2, "D2: %d, %s, %s", g_eStatusDrive2, g_sTrackDrive2, g_sSectorDrive2); {
mvwprintw(status, 1, 2, "D1: %d, %s, %s", g_eStatusDrive1, g_sTrackDrive1, g_sSectorDrive1);
mvwprintw(status, 2, 2, "D2: %d, %s, %s", g_eStatusDrive2, g_sTrackDrive2, g_sSectorDrive2);
}
} }
void FrameDrawDiskLEDS(HDC x) void FrameDrawDiskLEDS(HDC x)
@ -345,24 +355,8 @@ void FrameRefreshStatus(int x, bool)
// std::cerr << "Status: " << x << std::endl; // std::cerr << "Status: " << x << std::endl;
} }
void NVideoInitialize() void NVideoInitialize(const bool headless)
{ {
VideoSwitchVideocardPalette(RGB_GetVideocard(), GetVideoType());
setlocale(LC_ALL, "");
initscr();
// does not seem to be a problem calling endwin() multiple times
std::atexit(NVideoUninitialize);
colors.reset(new GraphicsColors(20, 20, 32));
curs_set(0);
noecho();
cbreak();
set_escdelay(0);
frame.reset(new Frame()); frame.reset(new Frame());
asciiArt.reset(new ASCIIArt()); asciiArt.reset(new ASCIIArt());
@ -370,15 +364,17 @@ void NVideoInitialize()
Paddle::instance() = paddle; Paddle::instance() = paddle;
signal(SIGINT, sig_handler); if (headless)
{
signal(SIGINT, sig_handler_exit);
}
else
{
signal(SIGINT, sig_handler_pass);
// pass Ctrl-C to the emulator
}
} }
void NVideoUninitialize()
{
endwin();
}
void VideoRedrawScreen() void VideoRedrawScreen()
{ {
VideoUpdateFlash(); VideoUpdateFlash();
@ -440,7 +436,13 @@ void VideoRedrawScreen()
int ProcessKeyboard() int ProcessKeyboard()
{ {
const int inch = wgetch(frame->getWindow()); WINDOW * window = frame->getWindow();
if (!window)
{
return ERR;
}
const int inch = wgetch(window);
int ch = ERR; int ch = ERR;

View file

@ -2,8 +2,9 @@
int ProcessKeyboard(); int ProcessKeyboard();
void ProcessInput(); void ProcessInput();
void NVideoInitialize(); void NVideoInitialize(const bool headless);
void NVideoUninitialize();
void VideoRedrawScreen(); void VideoRedrawScreen();
extern double g_relativeSpeed; extern double g_relativeSpeed;
extern bool g_stop;