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 ...
This commit is contained in:
Gered 2019-03-31 17:13:55 -04:00
parent 92e80aa11c
commit 43d7eb4f73
3 changed files with 111 additions and 7 deletions

View file

@ -22,6 +22,7 @@
#include "sysdep.h"
#include "console.h"
#include "gui.h"
#include "c_config.h"
#include <stdlib.h>
#include <process.h>
@ -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;
}

2
port.h
View file

@ -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.

View file

@ -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