From 43d7eb4f73d30fa858939eb30df3a0ae56434005 Mon Sep 17 00:00:00 2001 From: gered Date: Sun, 31 Mar 2019 17:13:55 -0400 Subject: [PATCH] properly hook up ScreenSizeX/Y global options & fix related mouse issues note that 80x43 text mode is not currently working. if the int 10h can be adjusted to set this mode correctly, the mouse fixes should all work properly with it too ... --- con_dosx.cpp | 40 ++++++++++++++++++++++----- port.h | 2 ++ portdos.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+), 7 deletions(-) diff --git a/con_dosx.cpp b/con_dosx.cpp index 0e0a248..7fe7d6d 100644 --- a/con_dosx.cpp +++ b/con_dosx.cpp @@ -22,6 +22,7 @@ #include "sysdep.h" #include "console.h" #include "gui.h" +#include "c_config.h" #include #include @@ -734,6 +735,13 @@ int ConScroll(int Way, int X, int Y, int W, int H, TAttr Fill, int Count) } int ConSetSize(int X, int Y) { + // explicitly turn off/on the mouse and reset it's boundaries at the + // same time. the turn off/on thing ensures the cursor doesn't disappear + // after the screen mode switch + MOUSCursen(FALSE); + plScnSetSize(X, Y); + MOUSSetBounds(); + MOUSCursen(TRUE); return 0; } @@ -825,6 +833,7 @@ int ConInit(int XSize, int YSize) if(Initialized) return 0; EventBuf.What = evNone; + ConSetSize(XSize, YSize); MousePresent = MOUSInit(); ConContinue(); Initialized = 1; @@ -949,6 +958,7 @@ int SaveScreen() { int RestoreScreen() { if (SavedScreen) { + ConSetSize(SavedX, SavedY); ConPutBox(0, 0, SavedX, SavedY, SavedScreen); ConSetCursorPos(SaveCursorPosX, SaveCursorPosY); } @@ -959,9 +969,8 @@ int RestoreScreen() { GUI::GUI(int &argc, char **argv, int XSize, int YSize) { fArgc = argc; fArgv = argv; - ::ConInit(-1, -1); SaveScreen(); - ::ConSetSize(XSize, YSize); + ::ConInit(XSize, YSize); gui = this; #ifdef DJGPP // speed up directory access by turning off unused stat functionality @@ -976,6 +985,10 @@ GUI::GUI(int &argc, char **argv, int XSize, int YSize) { GUI::~GUI() { RestoreScreen(); + // HACK: clearing the screen to hide the fact that there's something + // screwy going on with the screen restore when using non-80x25 mode + // that i cannot pin down ... + ::ConClear(); ::ConDone(); if(SavedScreen) @@ -1003,6 +1016,7 @@ int GUI::ShowEntryScreen() { ConHideMouse(); RestoreScreen(); do { gui->ConGetEvent(evKeyDown, &E, -1, 1, 0); } while (E.What != evKeyDown); + ConSetSize(ScreenSizeX, ScreenSizeY); ConShowMouse(); if (frames) frames->Repaint(); @@ -1026,7 +1040,16 @@ int GUI::OpenPipe(char *Command, EModel *notify) { Pipes[i].notify = notify; Pipes[i].stopped = 1; + // when a long-ish running command gets run here, sometimes + // the mouse cursor disappears on returning from the command, + // so we turn it off/on here just to be safe + MOUSCursen(FALSE); + Pipes[i].fp = xpopen(Command,"r"); + + MOUSSetBounds(); + MOUSCursen(TRUE); + if (Pipes[i].fp == NULL) return -1; Pipes[i].used = 1; @@ -1088,7 +1111,7 @@ int GUI::ClosePipe(int id) { } int GUI::RunProgram(int mode, char *Command) { - int rc, W, H, W1, H1; + int rc, W, H; ConQuerySize(&W, &H); ConHideMouse(); @@ -1103,11 +1126,14 @@ int GUI::RunProgram(int mode, char *Command) { ConContinue(); ConShowMouse(); - ConQuerySize(&W1, &H1); - if (W != W1 || H != H1) { - frames->Resize(W1, H1); - } + // HACK: there used to be conditional logic here to check if a screen + // resize was actually needed using another call to ConQuerySize() to + // check the current size... i might need to revisit this again, but + // i opted to just always resize and repaint to ensure a consistent + // screen state always. + ConSetSize(W, H); + frames->Resize(W, H); frames->Repaint(); return rc; } diff --git a/port.h b/port.h index 6dec6f1..b315e5b 100644 --- a/port.h +++ b/port.h @@ -192,6 +192,7 @@ void MOUSSaveCurs(void); void MOUSRestCurs(void); boolean MOUSIsPresent(void); ULONG MOUSPressCount(void); +boolean MOUSSetBounds(void); //** Timer calls //** =========== @@ -246,6 +247,7 @@ void plScnSetFlash(boolean on); void plScnCursorOn(boolean on); void plScnCursorShape(int start, int end); void plScnCursorPos(int x, int y); +void plScnSetSize(int xSize, int ySize); //** Writing the screen. diff --git a/portdos.c b/portdos.c index 3b0d428..7e26967 100644 --- a/portdos.c +++ b/portdos.c @@ -260,6 +260,41 @@ static void getCurInfo(void) } +/* + * plScnSetSize() sets the screen textmode to correspond to the specified + * dimensions. note that it only actually supports standard DOS textmodes + * 80x25, 80x43 and 80x50 + */ +void plScnSetSize(int xSize, int ySize) { + union dosxReg r; + + // set text mode + memset(&r, 0, sizeof(r)); + r.w.ax = 0x0003; + dosxIntr(0x10, &r); + + memset(&r, 0, sizeof(r)); + + if (xSize == 80 && ySize == 25) { + // the previous int 10h call already set 80x25. do nothing here + } else if (xSize == 80 && ySize == 43) { + // TODO: doesn't work? what is the correct way to set 8x14 font? + // i know my video card supports this as i can use 80x43 in other + // applications ... will revisit this + r.w.ax = 0x1122; + dosxIntr(0x10, &r); + } else if (xSize == 80 && ySize == 50) { + r.w.ax = 0x1112; + dosxIntr(0x10, &r); + } + + //plScnI.s_inited = FALSE; + getType(); + getSize(); + getCurInfo(); +} + + /* * plScnInit() is called to get most of the info required to do screen I/O. * Depending on the "inited" flag it will get the current screen size, the @@ -956,5 +991,46 @@ boolean MOUSPressed(UWORD *x, UWORD *y) } +/* + * MOUSSetBounds() attempts to automatically set appropriate mouse cursor + * boundaries based on the current screen textmode. + * NOTE: This is currently written assuming 80 column text modes, with + * the only possible screen heights being 25, 43 or 80. + */ +boolean MOUSSetBounds(void) +{ + union dosxReg r; + int rows; + int height; + + rows = plScnHeight(); + + if (rows == 43) { + height = 350; + } else if (rows == 50) { + height = 400; + } else { + height = 200; + } + + if(MousePresent) + { + memset(&r, 0, sizeof(r)); + r.w.ax = MC_SETXRANGE; + r.w.cx = 0; + r.w.dx = 639; + dosxIntr(0x33, &r); + + memset(&r, 0, sizeof(r)); + r.w.ax = MC_SETYRANGE; + r.w.cx = 0; + r.w.dx = (height - 1); + dosxIntr(0x33, &r); + + return TRUE; + } + return FALSE; +} + #endif // DOS || DOSP32