diff --git a/Console/CMakeLists.txt b/Console/CMakeLists.txt
deleted file mode 100644
index 8121b652f7..0000000000
--- a/Console/CMakeLists.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright 2014 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 .
-
-add_library(RetroConsole
- retro/Console.cc
- retro/Console.h
- retro/ConsoleWindow.cc
- retro/ConsoleWindow.h
- retro/MacUtils.h
- retro/InitConsole.cc
- )
-set_target_properties(retrocrt
- PROPERTIES
- COMPILE_OPTIONS -ffunction-sections)
-
-# different library name for Carbon
-# (Carbon shares the powerpc-apple-macos/ directory with Classic PPC)
-if(CMAKE_SYSTEM_NAME MATCHES RetroCarbon)
- set_target_properties(RetroConsole PROPERTIES OUTPUT_NAME RetroConsoleCarbon)
-endif()
-target_include_directories(RetroConsole PUBLIC .)
-
-install(TARGETS RetroConsole DESTINATION lib)
-
-add_application(ConsoleTest
- ConsoleTest.cc
- )
-target_link_libraries(ConsoleTest RetroConsole)
diff --git a/Console/ConsoleTest.cc b/Console/ConsoleTest.cc
index 587490fddb..b32da0ea83 100644
--- a/Console/ConsoleTest.cc
+++ b/Console/ConsoleTest.cc
@@ -9,7 +9,7 @@ namespace retro
int main()
{
retro::InitConsole();
- std::string out = "Hello, world.\nEnter \"exit\" to quit.\n";
+ std::string out = "Hello, \033[1mexternal world of \033[0m\033[3mtrue beauty and \033[4mgreatness\033[0m.\nEnter \"exit\" to quit.\n";
retro::Console::currentInstance->write(out.data(), out.size());
std::string in;
diff --git a/IConsole/Makefile b/Console/Makefile
similarity index 54%
rename from IConsole/Makefile
rename to Console/Makefile
index 4ea7c1636a..c9a0114ab4 100644
--- a/IConsole/Makefile
+++ b/Console/Makefile
@@ -6,21 +6,21 @@ CC=$(RETRO68)/bin/m68k-apple-macos-gcc
CXX=$(RETRO68)/bin/m68k-apple-macos-g++
REZ=$(RETRO68)/bin/Rez
-LDFLAGS=retro/libIConsole.a
+LDFLAGS=retro/libConsole.a
RINCLUDES=$(PREFIX)/RIncludes
REZFLAGS=-I$(RINCLUDES)
-IConsoleTest.bin IConsoleTest.APPL IConsoleTest.dsk: IConsoleTest.code.bin
+ConsoleTest.bin ConsoleTest.APPL ConsoleTest.dsk: ConsoleTest.code.bin
$(REZ) $(REZFLAGS) \
- --copy "IConsoleTest.code.bin" \
+ --copy "ConsoleTest.code.bin" \
"$(RINCLUDES)/Retro68APPL.r" \
-t "APPL" -c "????" \
- -o IConsoleTest.bin --cc IConsoleTest.APPL --cc IConsoleTest.dsk
+ -o ConsoleTest.bin --cc ConsoleTest.APPL --cc ConsoleTest.dsk
-IConsoleTest.code.bin: IConsoleTest.o
+ConsoleTest.code.bin: ConsoleTest.o
$(CXX) $< -o $@ $(LDFLAGS) # C++ used for linking because RetroConsole needs it
.PHONY: clean
clean:
- rm -f IConsoleTest.bin IConsoleTest.APPL IConsoleTest.dsk IConsoleTest.code.bin IConsoleTest.code.bin.gdb IConsoleTest.o
+ rm -f ConsoleTest.bin ConsoleTest.APPL ConsoleTest.dsk ConsoleTest.code.bin ConsoleTest.code.bin.gdb ConsoleTest.o
diff --git a/IConsole/readme.txt b/Console/readme.txt
similarity index 100%
rename from IConsole/readme.txt
rename to Console/readme.txt
diff --git a/Console/retro/Console.cc b/Console/retro/Console.cc
index bc10bf582b..47681da9eb 100644
--- a/Console/retro/Console.cc
+++ b/Console/retro/Console.cc
@@ -1,5 +1,5 @@
/*
- Copyright 2012 Wolfgang Thaller.
+ Copyright 2012-2020 Wolfgang Thaller, Davide Bucci
This file is part of Retro68.
@@ -28,11 +28,73 @@ using namespace retro;
Console *Console::currentInstance = NULL;
+Attributes::Attributes(void)
+{
+ reset();
+}
+void Attributes::reset(void)
+{
+ cBold=false;
+ cUnderline=false;
+ cItalic=false;
+}
+
+bool Attributes::isBold(void) const
+{
+ return cBold;
+}
+
+
+bool Attributes::isUnderline(void) const
+{
+ return cUnderline;
+}
+
+bool Attributes::isItalic(void) const
+{
+ return cItalic;
+}
+
+void Attributes::setBold(const bool v)
+{
+ cBold=v;
+}
+
+void Attributes::setItalic(const bool v)
+{
+ cItalic=v;
+}
+
+void Attributes::setUnderline(const bool v)
+{
+ cUnderline=v;
+}
+
+inline bool operator==(const Attributes& lhs, const Attributes& rhs)
+{
+ return lhs.isBold()==rhs.isBold() && lhs.isUnderline()==rhs.isUnderline() && lhs.isItalic()==rhs.isItalic();
+}
+
+inline bool operator!=(const Attributes& lhs, const Attributes& rhs)
+{
+ return !(lhs == rhs);
+}
+
+inline bool operator==(const AttributedChar& lhs, const AttributedChar& rhs)
+{
+ return lhs.c==rhs.c && lhs.attrs==rhs.attrs;
+}
+
+inline bool operator!=(const AttributedChar& lhs, const AttributedChar& rhs)
+{
+ return !(lhs == rhs);
+}
+
namespace
{
class FontSetup
{
- short saveFont, saveSize;
+ short saveFont, saveSize, saveFace;
public:
FontSetup()
{
@@ -44,15 +106,18 @@ namespace
#else
saveFont = qd.thePort->txFont;
saveSize = qd.thePort->txSize;
+ saveFace = qd.thePort->txFace;
#endif
TextFont(kFontIDMonaco);
TextSize(9);
+ TextFace(normal);
}
~FontSetup()
{
TextFont(saveFont);
TextSize(saveSize);
+ TextFace(saveFace);
}
};
}
@@ -88,11 +153,17 @@ void Console::Init(GrafPtr port, Rect r)
rows = (bounds.bottom - bounds.top) / cellSizeY;
cols = (bounds.right - bounds.left) / cellSizeX;
- chars = std::vector(rows*cols, ' ');
+ chars = std::vector(rows*cols, AttributedChar(' ',currentAttr));
onscreen = chars;
cursorX = cursorY = 0;
+ isProcessingEscSequence=false;
+}
+
+void Console::SetAttributes(Attributes aa)
+{
+ TextFace(aa.isBold()?bold+condense:0 + aa.isUnderline()?underline:0 + aa.isItalic()?italic:0);
}
Rect Console::CellRect(short x, short y)
@@ -116,14 +187,13 @@ void Console::DrawCell(short x, short y, bool erase)
if(erase)
EraseRect(&r);
MoveTo(r.left, r.bottom - 2);
- DrawChar(chars[y * cols + x]);
+ DrawChar(chars[y * cols + x].c);
}
void Console::DrawCells(short x1, short x2, short y, bool erase)
{
Rect r = { (short) (bounds.top + y * cellSizeY), (short) (bounds.left + x1 * cellSizeX),
- (short) (bounds.top + (y+1) * cellSizeY), (short) (bounds.left + x2 * cellSizeX) };
-
+ (short) (bounds.top + (y+1) * cellSizeY), (short) (bounds.left + x2 * cellSizeX) };
if(cursorDrawn)
{
if(y == cursorY && x1 <= cursorX && x2 > cursorX)
@@ -136,7 +206,17 @@ void Console::DrawCells(short x1, short x2, short y, bool erase)
if(erase)
EraseRect(&r);
MoveTo(r.left, r.bottom - 2);
- DrawText(&chars[y * cols + x1], 0, x2 - x1);
+
+ Attributes a=chars[y * cols + x1].attrs;
+ SetAttributes(a);
+ for(int i=x1; i 0 ? dirtyRect.bottom - 1 : 0;
}
+void Console::ProcessEscSequence(char c)
+{
+ switch(sequenceStep)
+ {
+ case 0:
+ if(c=='[')
+ ++sequenceStep;
+ else
+ isProcessingEscSequence=false;
+ break;
+ case 1:
+ ++sequenceStep;
+ switch(c)
+ {
+ case '0': // Normal character
+ currentAttr.reset();
+ break;
+ case '1': // Bold
+ currentAttr.setBold(true);
+ break;
+ case '3': // Italic
+ currentAttr.setItalic(true);
+ break;
+ case '4': // Underline
+ currentAttr.setUnderline(true);
+ break;
+ default:
+ isProcessingEscSequence=false;
+ }
+ break;
+ case 2:
+ if(c=='m')
+ isProcessingEscSequence=false;
+ else if(c==';')
+ sequenceStep=1;
+ else
+ isProcessingEscSequence=false;
+ break;
+ default:
+ sequenceStep=0;
+ }
+}
void Console::PutCharNoUpdate(char c)
{
+ if(isProcessingEscSequence)
+ {
+ ProcessEscSequence(c);
+ return;
+ }
InvalidateCursor();
switch(c)
{
+ case '\033': // Begin of an ANSI escape sequence
+ isProcessingEscSequence=true;
+ sequenceStep=0;
+ break;
case '\r':
cursorX = 0;
break;
@@ -197,7 +329,9 @@ void Console::PutCharNoUpdate(char c)
ScrollUp();
break;
default:
- chars[cursorY * cols + cursorX] = c;
+ chars[cursorY * cols + cursorX].c = c;
+ chars[cursorY * cols + cursorX].attrs = currentAttr;
+
if(dirtyRect.right == 0)
{
dirtyRect.right = (dirtyRect.left = cursorX) + 1;
@@ -214,6 +348,8 @@ void Console::PutCharNoUpdate(char c)
cursorX++;
if(cursorX >= cols)
PutCharNoUpdate('\n');
+ // This is to make sure the cursor width is calculated correctly
+ chars[cursorY * cols + cursorX].attrs = currentAttr;
}
}
@@ -228,12 +364,12 @@ void Console::Update()
bool needclear = false;
for(short col = dirtyRect.left; col < dirtyRect.right; ++col)
{
- char old = onscreen[row * cols + col];
+ AttributedChar old = onscreen[row * cols + col];
if(chars[row * cols + col] != old)
{
if(start == -1)
start = col;
- if(old != ' ')
+ if(old.c != ' ')
needclear = true;
onscreen[row * cols + col] = chars[row * cols + col];
}
@@ -259,7 +395,7 @@ void Console::Update()
InvertRect(&r);
cursorDrawn = !cursorDrawn;
}
-
+
#if TARGET_API_MAC_CARBON
QDFlushPortBuffer(consolePort,NULL);
#endif
@@ -331,7 +467,6 @@ void Console::InvalidateCursor()
if(cursorDrawn)
{
PortSetter setport(consolePort);
-
DrawCell(cursorX, cursorY, true);
cursorDrawn = false;
}
@@ -368,11 +503,11 @@ void Console::Reshape(Rect newBounds)
cursorY = newRows - 1;
}
- std::vector newChars(newRows*newCols, ' ');
+ std::vector newChars(newRows*newCols, AttributedChar(' ', currentAttr));
for(short row = 0; row < newRows && row + upshift < rows; row++)
{
- char *src = &chars[(row+upshift) * cols];
- char *dst = &newChars[row * newCols];
+ AttributedChar *src = &chars[(row+upshift) * cols];
+ AttributedChar *dst = &newChars[row * newCols];
std::copy(src, src + std::min(cols, newCols), dst);
}
chars.swap(newChars);
diff --git a/Console/retro/Console.h b/Console/retro/Console.h
index d94417c21b..e1d998eafd 100644
--- a/Console/retro/Console.h
+++ b/Console/retro/Console.h
@@ -1,5 +1,5 @@
/*
- Copyright 2012 Wolfgang Thaller.
+ Copyright 2012-2020 Wolfgang Thaller, Davide Bucci
This file is part of Retro68.
@@ -25,6 +25,39 @@
namespace retro
{
+ class Attributes
+ {
+ public:
+
+ bool isBold(void) const;
+ bool isUnderline(void) const;
+ bool isItalic(void) const;
+
+ void setBold(const bool v);
+ void setUnderline(const bool v);
+ void setItalic(const bool v);
+
+ Attributes(void);
+ void reset(void);
+
+ private:
+
+ bool cBold;
+ bool cUnderline;
+ bool cItalic;
+ };
+
+ class AttributedChar
+ {
+ public:
+ char c;
+ Attributes attrs;
+ AttributedChar(char cc, Attributes aa) {c=cc; attrs=aa;}
+ };
+
+// inline bool operator==(const Attributes& lhs, const Attributes& rhs);
+// inline bool operator!=(const Attributes& lhs, const Attributes& rhs);
+
class Console
{
public:
@@ -52,8 +85,11 @@ namespace retro
private:
GrafPtr consolePort = nullptr;
Rect bounds;
+ Attributes currentAttr;
- std::vector chars, onscreen;
+ std::vector chars, onscreen;
+ bool isProcessingEscSequence;
+ int sequenceStep;
short cellSizeX;
short cellSizeY;
@@ -72,10 +108,13 @@ namespace retro
void PutCharNoUpdate(char c);
void Update();
+ short CalcStartX(short x, short y);
Rect CellRect(short x, short y);
void DrawCell(short x, short y, bool erase = true);
void DrawCells(short x1, short x2, short y, bool erase = true);
void ScrollUp(short n = 1);
+ void ProcessEscSequence(char c);
+ void SetAttributes(Attributes aa);
void InvalidateCursor();
diff --git a/Console/retro/ConsoleWindow.cc b/Console/retro/ConsoleWindow.cc
index 1f4092d313..9b5c9ae5cf 100644
--- a/Console/retro/ConsoleWindow.cc
+++ b/Console/retro/ConsoleWindow.cc
@@ -1,5 +1,5 @@
/*
- Copyright 2012 Wolfgang Thaller.
+ Copyright 2012-2020 Wolfgang Thaller, Davide Bucci
This file is part of Retro68.
@@ -31,8 +31,8 @@ namespace
ConsoleWindow::ConsoleWindow(Rect r, ConstStr255Param title)
{
GrafPtr port;
-
- win = NewWindow(NULL, &r, "\pRetro68 Console", true, 0, (WindowPtr)-1, false, 0);
+ //Retro68 Improved Console
+ win = NewWindow(NULL, &r, "\pThe Queen's Footsteps", true, 0, (WindowPtr)-1, true, 0);
#if !TARGET_API_MAC_CARBON
port = win;
@@ -105,7 +105,6 @@ char ConsoleWindow::WaitNextChar()
}
break;
case mouseDown:
-
switch(FindWindow(event.where, &eventWin))
{
case inDrag:
@@ -118,6 +117,11 @@ char ConsoleWindow::WaitNextChar()
Reshape(Rect {0, 0, (short) (growResult >> 16), (short) (growResult & 0xFFFF) });
}
break;
+ case inGoAway:
+ {
+ if (TrackGoAway(eventWin,event.where))
+ exit(0);
+ }
}
break;
}
diff --git a/Console/retro/ConsoleWindow.h b/Console/retro/ConsoleWindow.h
index 6d491f7b04..9e149b4cc9 100644
--- a/Console/retro/ConsoleWindow.h
+++ b/Console/retro/ConsoleWindow.h
@@ -1,5 +1,5 @@
/*
- Copyright 2012 Wolfgang Thaller.
+ Copyright 2012-2020 Wolfgang Thaller, Davide Bucci
This file is part of Retro68.
diff --git a/Console/retro/Makefile b/Console/retro/Makefile
new file mode 100644
index 0000000000..6e413e98e3
--- /dev/null
+++ b/Console/retro/Makefile
@@ -0,0 +1,20 @@
+# path to RETRO68
+RETRO68=../../../Retro68-build/toolchain
+
+PREFIX=$(RETRO68)/m68k-apple-macos
+CC=$(RETRO68)/bin/m68k-apple-macos-gcc
+CXX=$(RETRO68)/bin/m68k-apple-macos-g++
+REZ=$(RETRO68)/bin/Rez
+AR=$(RETRO68)/bin/m68k-apple-macos-gcc-ar
+
+LDFLAGS=
+RINCLUDES=$(PREFIX)/RIncludes
+REZFLAGS=-I$(RINCLUDES)
+
+
+libConsole.a: Console.o ConsoleWindow.o InitConsole.o
+ $(AR) rcs $@ $?
+
+.PHONY: clean
+clean:
+ rm -f Console.o ConsoleWindow.o InitConsole.o
diff --git a/IConsole/IConsoleTest.cc b/IConsole/IConsoleTest.cc
deleted file mode 100644
index beb9f5ee24..0000000000
--- a/IConsole/IConsoleTest.cc
+++ /dev/null
@@ -1,23 +0,0 @@
-#include "retro/IConsole.h"
-#include
-
-namespace retro
-{
- void InitIConsole();
-}
-
-int main()
-{
- retro::InitIConsole();
- std::string out = "Hello, \033[1mexternal world of \033[0m\033[3mtrue beauty and \033[4mgreatness\033[0m.\nEnter \"exit\" to quit.\n";
- retro::IConsole::currentInstance->write(out.data(), out.size());
-
- std::string in;
- do
- {
- in = retro::IConsole::currentInstance->ReadLine();
- out = "You Entered: " + in;
- retro::IConsole::currentInstance->write(out.data(), out.size());
- } while(in != "exit\n");
- return 0;
-}
diff --git a/IConsole/retro/IConsole.cc b/IConsole/retro/IConsole.cc
deleted file mode 100644
index c9f99df9e0..0000000000
--- a/IConsole/retro/IConsole.cc
+++ /dev/null
@@ -1,538 +0,0 @@
-/*
- Copyright 2012-2019 Wolfgang Thaller, Davide Bucci
-
- 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 .
-*/
-
-#include "IConsole.h"
-#include "MacUtils.h"
-#include "Fonts.h"
-#include "Processes.h"
-
-#include
-
-using namespace retro;
-
-IConsole *IConsole::currentInstance = NULL;
-
-Attributes::Attributes(void)
-{
- reset();
-}
-void Attributes::reset(void)
-{
- cBold=false;
- cUnderline=false;
- cItalic=false;
-}
-
-bool Attributes::isBold(void) const
-{
- return cBold;
-}
-
-
-bool Attributes::isUnderline(void) const
-{
- return cUnderline;
-}
-
-bool Attributes::isItalic(void) const
-{
- return cItalic;
-}
-
-void Attributes::setBold(const bool v)
-{
- cBold=v;
-}
-
-void Attributes::setItalic(const bool v)
-{
- cItalic=v;
-}
-
-void Attributes::setUnderline(const bool v)
-{
- cUnderline=v;
-}
-
-inline bool operator==(const Attributes& lhs, const Attributes& rhs)
-{
- return lhs.isBold()==rhs.isBold() && lhs.isUnderline()==rhs.isUnderline() && lhs.isItalic()==rhs.isItalic();
-}
-
-inline bool operator!=(const Attributes& lhs, const Attributes& rhs)
-{
- return !(lhs == rhs);
-}
-
-inline bool operator==(const AttributedChar& lhs, const AttributedChar& rhs)
-{
- return lhs.c==rhs.c && lhs.attrs==rhs.attrs;
-}
-
-inline bool operator!=(const AttributedChar& lhs, const AttributedChar& rhs)
-{
- return !(lhs == rhs);
-}
-
-namespace
-{
- class FontSetup
- {
- short saveFont, saveSize, saveFace;
- public:
- FontSetup()
- {
-#if TARGET_API_MAC_CARBON
- GrafPtr port;
- GetPort(&port);
- saveFont = GetPortTextFont(port);
- saveSize = GetPortTextSize(port);
-#else
- saveFont = qd.thePort->txFont;
- saveSize = qd.thePort->txSize;
- saveFace = qd.thePort->txFace;
-#endif
- TextFont(kFontIDMonaco);
- TextSize(9);
- TextFace(normal);
- }
-
- ~FontSetup()
- {
- TextFont(saveFont);
- TextSize(saveSize);
- TextFace(saveFace);
- }
- };
-}
-
-IConsole::IConsole()
-{
-}
-
-IConsole::IConsole(GrafPtr port, Rect r)
-{
- Init(port, r);
-}
-
-IConsole::~IConsole()
-{
- if(currentInstance == this)
- currentInstance = NULL;
-}
-
-void IConsole::Init(GrafPtr port, Rect r)
-{
- consolePort = port;
- bounds = r;
-
- PortSetter setport(consolePort);
- FontSetup fontSetup;
-
- InsetRect(&bounds, 2,2);
-
- cellSizeY = 12;
- cellSizeX = CharWidth('M');
-
- rows = (bounds.bottom - bounds.top) / cellSizeY;
- cols = (bounds.right - bounds.left) / cellSizeX;
-
- chars = std::vector(rows*cols, AttributedChar(' ',currentAttr));
-
- onscreen = chars;
-
- cursorX = cursorY = 0;
- isProcessingEscSequence=false;
-}
-
-void IConsole::SetAttributes(Attributes aa)
-{
- TextFace(aa.isBold()?bold+condense:0 + aa.isUnderline()?underline:0 + aa.isItalic()?italic:0);
-}
-
-Rect IConsole::CellRect(short x, short y)
-{
- return { (short) (bounds.top + y * cellSizeY), (short) (bounds.left + x * cellSizeX),
- (short) (bounds.top + (y+1) * cellSizeY), (short) (bounds.left + (x+1) * cellSizeX) };
-}
-void IConsole::DrawCell(short x, short y, bool erase)
-{
- Rect r = CellRect(x,y);
-
- if(cursorDrawn)
- {
- if(y == cursorY && x == cursorX)
- {
- erase = true;
- cursorDrawn = false;
- }
- }
-
- if(erase)
- EraseRect(&r);
- MoveTo(r.left, r.bottom - 2);
- DrawChar(chars[y * cols + x].c);
-}
-
-void IConsole::DrawCells(short x1, short x2, short y, bool erase)
-{
- Rect r = { (short) (bounds.top + y * cellSizeY), (short) (bounds.left + x1 * cellSizeX),
- (short) (bounds.top + (y+1) * cellSizeY), (short) (bounds.left + x2 * cellSizeX) };
- if(cursorDrawn)
- {
- if(y == cursorY && x1 <= cursorX && x2 > cursorX)
- {
- erase = true;
- cursorDrawn = false;
- }
- }
-
- if(erase)
- EraseRect(&r);
- MoveTo(r.left, r.bottom - 2);
-
- Attributes a=chars[y * cols + x1].attrs;
- SetAttributes(a);
- for(int i=x1; i 0 ? dirtyRect.top - 1 : 0;
- dirtyRect.bottom = dirtyRect.bottom > 0 ? dirtyRect.bottom - 1 : 0;
-}
-
-void IConsole::ProcessEscSequence(char c)
-{
- switch(sequenceStep)
- {
- case 0:
- if(c=='[')
- ++sequenceStep;
- else
- isProcessingEscSequence=false;
- break;
- case 1:
- ++sequenceStep;
- switch(c)
- {
- case '0': // Normal character
- currentAttr.reset();
- break;
- case '1': // Bold
- currentAttr.setBold(true);
- break;
- case '3': // Italic
- currentAttr.setItalic(true);
- break;
- case '4': // Underline
- currentAttr.setUnderline(true);
- break;
- default:
- isProcessingEscSequence=false;
- }
- break;
- case 2:
- if(c=='m')
- isProcessingEscSequence=false;
- else if(c==';')
- sequenceStep=1;
- else
- isProcessingEscSequence=false;
- break;
- default:
- sequenceStep=0;
- }
-}
-
-void IConsole::PutCharNoUpdate(char c)
-{
- if(isProcessingEscSequence)
- {
- ProcessEscSequence(c);
- return;
- }
- InvalidateCursor();
- switch(c)
- {
- case '\033': // Begin of an ANSI escape sequence
- isProcessingEscSequence=true;
- sequenceStep=0;
- break;
- case '\r':
- cursorX = 0;
- break;
- case '\n':
- cursorY++;
- cursorX = 0;
- if(cursorY >= rows)
- ScrollUp();
- break;
- default:
- chars[cursorY * cols + cursorX].c = c;
- chars[cursorY * cols + cursorX].attrs = currentAttr;
-
- if(dirtyRect.right == 0)
- {
- dirtyRect.right = (dirtyRect.left = cursorX) + 1;
- dirtyRect.bottom = (dirtyRect.top = cursorY) + 1;
- }
- else
- {
- dirtyRect.left = std::min(dirtyRect.left, cursorX);
- dirtyRect.top = std::min(dirtyRect.top, cursorY);
- dirtyRect.right = std::max(dirtyRect.right, short(cursorX + 1));
- dirtyRect.bottom = std::max(dirtyRect.bottom, short(cursorY + 1));
- }
-
- cursorX++;
- if(cursorX >= cols)
- PutCharNoUpdate('\n');
- // This is to make sure the cursor width is calculated correctly
- chars[cursorY * cols + cursorX].attrs = currentAttr;
- }
-}
-
-void IConsole::Update()
-{
- PortSetter setport(consolePort);
- FontSetup fontSetup;
-
- for(short row = dirtyRect.top; row < dirtyRect.bottom; ++row)
- {
- short start = -1;
- bool needclear = false;
- for(short col = dirtyRect.left; col < dirtyRect.right; ++col)
- {
- AttributedChar old = onscreen[row * cols + col];
- if(chars[row * cols + col] != old)
- {
- if(start == -1)
- start = col;
- if(old.c != ' ')
- needclear = true;
- onscreen[row * cols + col] = chars[row * cols + col];
- }
- else
- {
- if(start != -1)
- DrawCells(start, col, row, needclear);
- start = -1;
- needclear = false;
- }
- }
- if(start != -1)
- DrawCells(start, dirtyRect.right, row, needclear);
- }
- dirtyRect = Rect();
-
- if(cursorVisible != cursorDrawn)
- {
- Rect r = CellRect(cursorX, cursorY);
- if(cursorDrawn)
- DrawCell(cursorX, cursorY, true);
- else
- InvertRect(&r);
- cursorDrawn = !cursorDrawn;
- }
-
-#if TARGET_API_MAC_CARBON
- QDFlushPortBuffer(consolePort,NULL);
-#endif
-}
-
-void IConsole::putch(char c)
-{
- if(!rows)
- return;
- PutCharNoUpdate(c);
- Update();
-}
-
-void IConsole::write(const char *p, int n)
-{
- if(!rows)
- return;
-
- for(int i = 0; i < n; i++)
- IConsole::currentInstance->PutCharNoUpdate(*p++);
- Update();
-}
-
-
-std::string IConsole::ReadLine()
-{
- if(!consolePort)
- return "";
-
- std::string buffer;
- char c;
-
- do
- {
- c = WaitNextChar();
- if(!c)
- {
- eof = true;
- return "";
- }
-
- if(c == '\r')
- c = '\n';
-
- if(c == '\b')
- {
- if(buffer.size())
- {
- InvalidateCursor();
- cursorX--;
- PutCharNoUpdate(' ');
- cursorX--;
- Update();
-
- buffer.resize(buffer.size()-1);
- }
-
- continue;
- }
-
- putch(c);
- buffer.append(1,c);
- } while(c != '\n');
- return buffer;
-}
-
-void IConsole::InvalidateCursor()
-{
- if(cursorDrawn)
- {
- PortSetter setport(consolePort);
- DrawCell(cursorX, cursorY, true);
- cursorDrawn = false;
- }
-}
-
-void IConsole::Idle()
-{
- long ticks = TickCount();
- if(ticks - blinkTicks > 60)
- {
- cursorVisible = !cursorVisible;
- blinkTicks = ticks;
- Update();
- }
-}
-
-void IConsole::Reshape(Rect newBounds)
-{
- if(!consolePort)
- return;
-
- 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 newChars(newRows*newCols, AttributedChar(' ', currentAttr));
- for(short row = 0; row < newRows && row + upshift < rows; row++)
- {
- AttributedChar *src = &chars[(row+upshift) * cols];
- AttributedChar *dst = &newChars[row * newCols];
- std::copy(src, src + std::min(cols, newCols), dst);
- }
- chars.swap(newChars);
- /*newChars = std::vector(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();
- }
-}
-
-char IConsole::WaitNextChar()
-{
- return 0;
-}
diff --git a/IConsole/retro/IConsole.h b/IConsole/retro/IConsole.h
deleted file mode 100644
index 053a7a7357..0000000000
--- a/IConsole/retro/IConsole.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- 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 .
-*/
-#ifndef RETRO68_CONSOLE_H_
-#define RETRO68_CONSOLE_H_
-
-#include
-#include
-#include
-
-namespace retro
-{
- class Attributes
- {
- public:
-
- bool isBold(void) const;
- bool isUnderline(void) const;
- bool isItalic(void) const;
-
- void setBold(const bool v);
- void setUnderline(const bool v);
- void setItalic(const bool v);
-
- Attributes(void);
- void reset(void);
-
- private:
-
- bool cBold;
- bool cUnderline;
- bool cItalic;
- };
-
- class AttributedChar
- {
- public:
- char c;
- Attributes attrs;
- AttributedChar(char cc, Attributes aa) {c=cc; attrs=aa;}
- };
-
-// inline bool operator==(const Attributes& lhs, const Attributes& rhs);
-// inline bool operator!=(const Attributes& lhs, const Attributes& rhs);
-
- class IConsole
- {
- public:
- IConsole();
- IConsole(GrafPtr port, Rect r);
- ~IConsole();
-
- void Reshape(Rect newBounds);
-
- void Draw(Rect r);
- void Draw() { Draw(bounds); }
- void putch(char c);
-
- void write(const char *s, int n);
- std::string ReadLine();
-
- static IConsole *currentInstance;
-
- short GetRows() const { return rows; }
- short GetCols() const { return cols; }
-
- void Idle();
-
- bool IsEOF() const { return eof; }
- private:
- GrafPtr consolePort = nullptr;
- Rect bounds;
- Attributes currentAttr;
-
- std::vector chars, onscreen;
- bool isProcessingEscSequence;
- int sequenceStep;
-
- short cellSizeX;
- short cellSizeY;
-
- short rows = 0, cols = 0;
-
- short cursorX, cursorY;
-
- Rect dirtyRect = {};
-
- long blinkTicks = 0;
- bool cursorDrawn = false;
- bool cursorVisible = true;
- bool eof = false;
-
- void PutCharNoUpdate(char c);
- void Update();
-
- short CalcStartX(short x, short y);
- Rect CellRect(short x, short y);
- void DrawCell(short x, short y, bool erase = true);
- void DrawCells(short x1, short x2, short y, bool erase = true);
- void ScrollUp(short n = 1);
- void ProcessEscSequence(char c);
- void SetAttributes(Attributes aa);
-
- void InvalidateCursor();
-
- virtual char WaitNextChar();
-
- protected:
- void Init(GrafPtr port, Rect r);
-
- };
-
-
-}
-
-#endif /* RETRO68_CONSOLE_H_ */
diff --git a/IConsole/retro/IConsoleWindow.cc b/IConsole/retro/IConsoleWindow.cc
deleted file mode 100644
index 0872fbcc94..0000000000
--- a/IConsole/retro/IConsoleWindow.cc
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- 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 .
-*/
-
-#include "IConsoleWindow.h"
-#include "Events.h"
-#include
-
-using namespace retro;
-
-namespace
-{
- std::unordered_map *windows = NULL;
-}
-
-IConsoleWindow::IConsoleWindow(Rect r, ConstStr255Param title)
-{
- GrafPtr port;
- //Retro68 Improved Console
- win = NewWindow(NULL, &r, "\pThe Queen's Footsteps", true, 0, (WindowPtr)-1, true, 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);
-
- if(!windows)
- windows = new std::unordered_map();
- (*windows)[win] = this;
-
- Init(port, portRect);
-}
-
-IConsoleWindow::~IConsoleWindow()
-{
- windows->erase(win);
- DisposeWindow(win);
-}
-
-char IConsoleWindow::WaitNextChar()
-{
- EventRecord event;
- WindowPtr eventWin;
- IConsoleWindow *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)
- {
- Rect updateRect;
- BeginUpdate(eventWin);
-#if TARGET_API_MAC_CARBON
- RgnHandle rgn = NewRgn();
- GetPortVisibleRegion(GetWindowPort(eventWin), rgn);
- GetRegionBounds(rgn, &updateRect);
- DisposeRgn(rgn);
-#else
- updateRect = (*qd.thePort->visRgn)->rgnBBox; // Life was simple back then.
-#endif
- realConsole->Draw(updateRect);
- 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, false);
- Reshape(Rect {0, 0, (short) (growResult >> 16), (short) (growResult & 0xFFFF) });
- }
- break;
- case inGoAway:
- {
- if (TrackGoAway(eventWin,event.where))
- exit(0);
- }
- }
- break;
- }
- } while(event.what != keyDown && event.what != autoKey);
-
- return event.message & charCodeMask;
-}
diff --git a/IConsole/retro/IConsoleWindow.h b/IConsole/retro/IConsoleWindow.h
deleted file mode 100644
index 62d820f246..0000000000
--- a/IConsole/retro/IConsoleWindow.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- 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 .
-*/
-
-#include
-#include
-#include
-
-#include "IConsole.h"
-
-namespace retro
-{
- class IConsoleWindow : public IConsole
- {
- public:
- IConsoleWindow(Rect r, ConstStr255Param title);
- ~IConsoleWindow();
- private:
- WindowPtr win;
-
- virtual char WaitNextChar();
- };
-}
diff --git a/IConsole/retro/InitIConsole.cc b/IConsole/retro/InitIConsole.cc
deleted file mode 100644
index 01df867552..0000000000
--- a/IConsole/retro/InitIConsole.cc
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- Copyright 2014 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 .
-*/
-
-#include
-
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-
-#include "MacUtils.h"
-#include "IConsole.h"
-#include "IConsoleWindow.h"
-
-namespace retro
-{
- void InitIConsole();
-}
-
-using namespace retro;
-
-void retro::InitIConsole()
-{
- if(IConsole::currentInstance)
- return;
- IConsole::currentInstance = (IConsole*) -1;
-
-#if !TARGET_API_MAC_CARBON
- InitGraf(&qd.thePort);
- InitFonts();
- InitWindows();
- InitMenus();
-
- Rect r = qd.screenBits.bounds;
-#else
- Rect r = (*GetMainDevice())->gdRect;
-#endif
- {
- // give MultiFinder a chance to bring the App to front
- // see Technote TB 35 - MultiFinder Miscellanea
- // "If your application [...] has the canBackground bit set in the
- // size resource, then it should call _EventAvail several times
- // (or _WaitNextEvent or _GetNextEvent) before putting up the splash
- // screen, or the splash screen will come up behind the frontmost
- // layer. If the canBackground bit is set, MultiFinder will not move
- // your layer to the front until you call _GetNextEvent,
- // _WaitNextEvent, or _EventAvail."
-
- EventRecord event;
- for(int i = 0; i < 5; i++)
- EventAvail(everyEvent, &event);
- }
-
- r.top += 40;
- InsetRect(&r, 5,5);
-
- IConsole::currentInstance = new IConsoleWindow(r, "\pRetro68 IConsole");
- InitCursor();
-}
-
-extern "C" ssize_t _consolewrite(int fd, const void *buf, size_t count)
-{
- if(!IConsole::currentInstance)
- InitIConsole();
- if(IConsole::currentInstance == (IConsole*)-1)
- return 0;
-
- IConsole::currentInstance->write((const char*)buf, count);
- return count;
-}
-
-extern "C" ssize_t _consoleread(int fd, void *buf, size_t count)
-{
- if(!IConsole::currentInstance)
- InitIConsole();
- if(IConsole::currentInstance == (IConsole*)-1)
- return 0;
-
- static std::string consoleBuf;
- if(consoleBuf.size() == 0)
- consoleBuf = IConsole::currentInstance->ReadLine();
-
- if(count > consoleBuf.size())
- count = consoleBuf.size();
- memcpy(buf, consoleBuf.data(), count);
- consoleBuf = consoleBuf.substr(count);
- return count;
-}
diff --git a/IConsole/retro/MacUtils.h b/IConsole/retro/MacUtils.h
deleted file mode 100644
index 4bff8f907c..0000000000
--- a/IConsole/retro/MacUtils.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- 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 .
-*/
-
-#include
-#include
-
-namespace retro
-{
- class PortSetter
- {
- GrafPtr save;
- public:
- PortSetter(GrafPtr port)
- {
- ::GetPort(&save);
- ::SetPort(port);
- }
-
- ~PortSetter()
- {
- ::SetPort(save);
- }
- };
-}