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