mirror of
https://github.com/autc04/Retro68.git
synced 2024-06-21 18:29:57 +00:00
Console improvements
This commit is contained in:
parent
e7d2e37e22
commit
1048b06ce4
|
@ -21,6 +21,8 @@ set(CMAKE_CXX_FLAGS "-std=c++11")
|
||||||
add_library(RetroConsole
|
add_library(RetroConsole
|
||||||
Console.cc
|
Console.cc
|
||||||
Console.h
|
Console.h
|
||||||
|
ConsoleWindow.cc
|
||||||
|
ConsoleWindow.h
|
||||||
MacUtils.h
|
MacUtils.h
|
||||||
InitConsole.cc
|
InitConsole.cc
|
||||||
)
|
)
|
||||||
|
@ -31,4 +33,3 @@ add_application(ConsoleTest
|
||||||
ConsoleTest.cc
|
ConsoleTest.cc
|
||||||
)
|
)
|
||||||
target_link_libraries(ConsoleTest RetroConsole)
|
target_link_libraries(ConsoleTest RetroConsole)
|
||||||
|
|
||||||
|
|
|
@ -29,10 +29,17 @@ using namespace Retro;
|
||||||
|
|
||||||
Console *Console::currentInstance = NULL;
|
Console *Console::currentInstance = NULL;
|
||||||
|
|
||||||
Console::Console(GrafPtr port, Rect r)
|
Console::Console()
|
||||||
: consolePort(port), bounds(r), dirtyRect(),
|
: consolePort(NULL), dirtyRect(),
|
||||||
blinkTicks(0), cursorDrawn(false), cursorVisible(true)
|
blinkTicks(0), cursorDrawn(false), cursorVisible(true)
|
||||||
{
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console::Init(GrafPtr port, Rect r)
|
||||||
|
{
|
||||||
|
consolePort = port;
|
||||||
|
bounds = r;
|
||||||
|
|
||||||
if(currentInstance == NULL)
|
if(currentInstance == NULL)
|
||||||
currentInstance = (Console*) -1;
|
currentInstance = (Console*) -1;
|
||||||
PortSetter setport(consolePort);
|
PortSetter setport(consolePort);
|
||||||
|
@ -52,9 +59,16 @@ Console::Console(GrafPtr port, Rect r)
|
||||||
onscreen = chars;
|
onscreen = chars;
|
||||||
|
|
||||||
cursorX = cursorY = 0;
|
cursorX = cursorY = 0;
|
||||||
|
|
||||||
currentInstance = this;
|
currentInstance = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Console::Console(GrafPtr port, Rect r)
|
||||||
|
: consolePort(NULL), dirtyRect(),
|
||||||
|
blinkTicks(0), cursorDrawn(false), cursorVisible(true)
|
||||||
|
{
|
||||||
|
Init(port, r);
|
||||||
|
}
|
||||||
|
|
||||||
Console::~Console()
|
Console::~Console()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -103,16 +117,25 @@ void Console::DrawCells(short x1, short x2, short y, bool erase)
|
||||||
DrawText(&chars[y * cols + x1], 0, x2 - x1);
|
DrawText(&chars[y * cols + x1], 0, x2 - x1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Console::Draw()
|
void Console::Draw(Rect r)
|
||||||
{
|
{
|
||||||
PortSetter setport(consolePort);
|
PortSetter setport(consolePort);
|
||||||
|
|
||||||
for(short row = 0; row < rows; ++row)
|
short minRow = std::max(0, (r.top - bounds.top) / cellSizeY);
|
||||||
|
short maxRow = std::min((int)rows, (r.bottom - bounds.top + cellSizeY - 1) / cellSizeY);
|
||||||
|
|
||||||
|
short minCol = std::max(0, (r.left - bounds.left) / cellSizeX);
|
||||||
|
short maxCol = std::min((int)cols, (r.right - bounds.left + cellSizeX - 1) / cellSizeX);
|
||||||
|
|
||||||
|
EraseRect(&r);
|
||||||
|
for(short row = minRow; row < maxRow; ++row)
|
||||||
{
|
{
|
||||||
for(short col = 0; col < cols; ++col)
|
DrawCells(minCol, maxCol, row, false);
|
||||||
{
|
}
|
||||||
DrawCell(col, row);
|
if(cursorDrawn)
|
||||||
}
|
{
|
||||||
|
Rect cursor = CellRect(cursorX, cursorY);
|
||||||
|
InvertRect(&cursor);
|
||||||
}
|
}
|
||||||
onscreen = chars;
|
onscreen = chars;
|
||||||
}
|
}
|
||||||
|
@ -231,15 +254,8 @@ std::string Console::ReadLine()
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
do
|
c = WaitNextChar();
|
||||||
{
|
|
||||||
Idle();
|
|
||||||
while(!GetNextEvent(everyEvent, &event))
|
|
||||||
Idle();
|
|
||||||
} while(event.what != keyDown && event.what != autoKey);
|
|
||||||
|
|
||||||
c = event.message & charCodeMask;
|
|
||||||
|
|
||||||
if(c == '\r')
|
if(c == '\r')
|
||||||
c = '\n';
|
c = '\n';
|
||||||
|
@ -288,3 +304,49 @@ void Console::Idle()
|
||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Console::Reshape(Rect newBounds)
|
||||||
|
{
|
||||||
|
InsetRect(&newBounds, 2,2);
|
||||||
|
|
||||||
|
bounds = newBounds;
|
||||||
|
short newRows = (bounds.bottom - bounds.top) / cellSizeY;
|
||||||
|
short newCols = (bounds.right - bounds.left) / cellSizeX;
|
||||||
|
|
||||||
|
short upshift = 0;
|
||||||
|
if(cursorY >= newRows)
|
||||||
|
{
|
||||||
|
upshift = cursorY - (newRows - 1);
|
||||||
|
|
||||||
|
InvalidateCursor();
|
||||||
|
cursorY = newRows - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<char> newChars(newRows*newCols, ' ');
|
||||||
|
for(short row = 0; row < newRows && row + upshift < rows; row++)
|
||||||
|
{
|
||||||
|
char *src = &chars[(row+upshift) * cols];
|
||||||
|
char *dst = &newChars[row * newCols];
|
||||||
|
std::copy(src, src + std::min(cols, newCols), dst);
|
||||||
|
}
|
||||||
|
chars.swap(newChars);
|
||||||
|
/*newChars = std::vector<char>(newRows*newCols, ' ');
|
||||||
|
for(short row = 0; row < newRows && row < rows; row++)
|
||||||
|
{
|
||||||
|
char *src = &chars[row * cols];
|
||||||
|
char *dst = &newChars[row * newCols];
|
||||||
|
std::copy(src, src + std::min(cols, newCols), dst);
|
||||||
|
}
|
||||||
|
onscreen.swap(newChars);*/
|
||||||
|
onscreen = newChars;
|
||||||
|
|
||||||
|
rows = newRows;
|
||||||
|
cols = newCols;
|
||||||
|
|
||||||
|
if(upshift)
|
||||||
|
{
|
||||||
|
//dirtyRect = Rect { 0, 0, rows, cols };
|
||||||
|
//Update();
|
||||||
|
Draw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with Retro68. If not, see <http://www.gnu.org/licenses/>.
|
along with Retro68. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
#ifndef RETRO68_CONSOLE_H_
|
||||||
|
#define RETRO68_CONSOLE_H_
|
||||||
|
|
||||||
#include <Quickdraw.h>
|
#include <Quickdraw.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -29,7 +31,8 @@ namespace Retro
|
||||||
public:
|
public:
|
||||||
Console(GrafPtr port, Rect r);
|
Console(GrafPtr port, Rect r);
|
||||||
~Console();
|
~Console();
|
||||||
void Draw();
|
void Draw(Rect r);
|
||||||
|
void Draw() { Draw(bounds); }
|
||||||
void putch(char c);
|
void putch(char c);
|
||||||
|
|
||||||
void write(const char *s, int n);
|
void write(const char *s, int n);
|
||||||
|
@ -39,6 +42,8 @@ namespace Retro
|
||||||
|
|
||||||
short GetRows() const { return rows; }
|
short GetRows() const { return rows; }
|
||||||
short GetCols() const { return cols; }
|
short GetCols() const { return cols; }
|
||||||
|
|
||||||
|
void Idle();
|
||||||
private:
|
private:
|
||||||
GrafPtr consolePort;
|
GrafPtr consolePort;
|
||||||
Rect bounds;
|
Rect bounds;
|
||||||
|
@ -67,8 +72,17 @@ namespace Retro
|
||||||
void ScrollUp(short n = 1);
|
void ScrollUp(short n = 1);
|
||||||
|
|
||||||
void InvalidateCursor();
|
void InvalidateCursor();
|
||||||
void Idle();
|
|
||||||
|
virtual char WaitNextChar() = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Console();
|
||||||
|
void Init(GrafPtr port, Rect r);
|
||||||
|
|
||||||
|
void Reshape(Rect newBounds);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* RETRO68_CONSOLE_H_ */
|
||||||
|
|
|
@ -9,8 +9,15 @@ namespace Retro
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
Retro::InitConsole();
|
Retro::InitConsole();
|
||||||
const char *s = "Hello, world.\n";
|
std::string out = "Hello, world.\nEnter \"exit\" to quit.\n";
|
||||||
Retro::Console::currentInstance->write(s, strlen(s));
|
Retro::Console::currentInstance->write(out.data(), out.size());
|
||||||
Retro::Console::currentInstance->ReadLine();
|
|
||||||
|
std::string in;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
in = Retro::Console::currentInstance->ReadLine();
|
||||||
|
out = "You Entered: " + in;
|
||||||
|
Retro::Console::currentInstance->write(out.data(), out.size());
|
||||||
|
} while(in != "exit\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
116
Console/ConsoleWindow.cc
Normal file
116
Console/ConsoleWindow.cc
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
Copyright 2012 Wolfgang Thaller.
|
||||||
|
|
||||||
|
This file is part of Retro68.
|
||||||
|
|
||||||
|
Retro68 is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Retro68 is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Retro68. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ConsoleWindow.h"
|
||||||
|
#include "Events.h"
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
using namespace Retro;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
std::unordered_map<WindowPtr, ConsoleWindow*> windows;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConsoleWindow::ConsoleWindow(Rect r, ConstStr255Param title)
|
||||||
|
{
|
||||||
|
GrafPtr port;
|
||||||
|
|
||||||
|
win = NewWindow(NULL, &r, "\pRetro68 Console", true, 0, (WindowPtr)-1, false, 0);
|
||||||
|
|
||||||
|
#if !TARGET_API_MAC_CARBON
|
||||||
|
port = win;
|
||||||
|
Rect portRect = port->portRect;
|
||||||
|
#else
|
||||||
|
port = GetWindowPort(win);
|
||||||
|
Rect portRect;
|
||||||
|
GetPortBounds(port, &portRect);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SetPort(port);
|
||||||
|
EraseRect(&portRect);
|
||||||
|
|
||||||
|
windows[win] = this;
|
||||||
|
|
||||||
|
Init(port, portRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
ConsoleWindow::~ConsoleWindow()
|
||||||
|
{
|
||||||
|
windows.erase(win);
|
||||||
|
DisposeWindow(win);
|
||||||
|
}
|
||||||
|
|
||||||
|
char ConsoleWindow::WaitNextChar()
|
||||||
|
{
|
||||||
|
EventRecord event;
|
||||||
|
WindowPtr eventWin;
|
||||||
|
ConsoleWindow *realConsole;
|
||||||
|
#if TARGET_API_MAC_CARBON
|
||||||
|
Rect *boundsPtr = NULL;
|
||||||
|
#else
|
||||||
|
Rect *boundsPtr = &qd.screenBits.bounds;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
#if TARGET_API_MAC_CARBON
|
||||||
|
#define SystemTask()
|
||||||
|
#endif
|
||||||
|
SystemTask();
|
||||||
|
Idle();
|
||||||
|
while(!GetNextEvent(everyEvent, &event))
|
||||||
|
{
|
||||||
|
SystemTask();
|
||||||
|
Idle();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(event.what)
|
||||||
|
{
|
||||||
|
case updateEvt:
|
||||||
|
eventWin = (WindowPtr)event.message;
|
||||||
|
realConsole = windows[(WindowPtr)event.message];
|
||||||
|
if(realConsole)
|
||||||
|
{
|
||||||
|
BeginUpdate(eventWin);
|
||||||
|
realConsole->Draw((*qd.thePort->visRgn)->rgnBBox);
|
||||||
|
EndUpdate(eventWin);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case mouseDown:
|
||||||
|
|
||||||
|
switch(FindWindow(event.where, &eventWin))
|
||||||
|
{
|
||||||
|
case inDrag:
|
||||||
|
DragWindow(eventWin, event.where, boundsPtr);
|
||||||
|
break;
|
||||||
|
case inGrow:
|
||||||
|
{
|
||||||
|
long growResult = GrowWindow(eventWin, event.where, boundsPtr);
|
||||||
|
SizeWindow(eventWin, growResult & 0xFFFF, growResult >> 16, true);
|
||||||
|
Reshape(Rect {0, 0, (short) (growResult >> 16), (short) (growResult & 0xFFFF) });
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while(event.what != keyDown && event.what != autoKey);
|
||||||
|
|
||||||
|
return event.message & charCodeMask;
|
||||||
|
}
|
38
Console/ConsoleWindow.h
Normal file
38
Console/ConsoleWindow.h
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
Copyright 2012 Wolfgang Thaller.
|
||||||
|
|
||||||
|
This file is part of Retro68.
|
||||||
|
|
||||||
|
Retro68 is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Retro68 is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Retro68. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "Console.h"
|
||||||
|
|
||||||
|
namespace Retro
|
||||||
|
{
|
||||||
|
class ConsoleWindow : public Console
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ConsoleWindow(Rect r, ConstStr255Param title);
|
||||||
|
~ConsoleWindow();
|
||||||
|
private:
|
||||||
|
WindowPtr win;
|
||||||
|
|
||||||
|
virtual char WaitNextChar();
|
||||||
|
};
|
||||||
|
}
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#include "MacUtils.h"
|
#include "MacUtils.h"
|
||||||
#include "Console.h"
|
#include "Console.h"
|
||||||
|
#include "ConsoleWindow.h"
|
||||||
|
|
||||||
namespace Retro
|
namespace Retro
|
||||||
{
|
{
|
||||||
|
@ -42,9 +43,6 @@ void Retro::InitConsole()
|
||||||
{
|
{
|
||||||
if(Console::currentInstance)
|
if(Console::currentInstance)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
WindowPtr win;
|
|
||||||
GrafPtr port;
|
|
||||||
|
|
||||||
#if !TARGET_API_MAC_CARBON
|
#if !TARGET_API_MAC_CARBON
|
||||||
InitGraf(&qd.thePort);
|
InitGraf(&qd.thePort);
|
||||||
|
@ -59,21 +57,9 @@ void Retro::InitConsole()
|
||||||
|
|
||||||
r.top += 40;
|
r.top += 40;
|
||||||
InsetRect(&r, 5,5);
|
InsetRect(&r, 5,5);
|
||||||
win = NewWindow(NULL, &r, "\pRetro68 Console", true, 0, (WindowPtr)-1, false, 0);
|
|
||||||
|
new ConsoleWindow(r, "\pRetro68 Console");
|
||||||
#if !TARGET_API_MAC_CARBON
|
InitCursor();
|
||||||
port = win;
|
|
||||||
Rect portRect = port->portRect;
|
|
||||||
#else
|
|
||||||
port = GetWindowPort(win);
|
|
||||||
Rect portRect;
|
|
||||||
GetPortBounds(port, &portRect);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SetPort(port);
|
|
||||||
EraseRect(&portRect);
|
|
||||||
|
|
||||||
Console *console = new Console(port, portRect);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" ssize_t _consolewrite(int fd, const void *buf, size_t count)
|
extern "C" ssize_t _consolewrite(int fd, const void *buf, size_t count)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user