684 lines
22 KiB
C++
684 lines
22 KiB
C++
#include <stdio.h>
|
|
#include <climits>
|
|
#include <vector>
|
|
#include <algorithm>
|
|
#include <sys/stat.h>
|
|
|
|
#include <SDL.h>
|
|
#include "memory.h"
|
|
#include "cpu.h"
|
|
#include "audio.h"
|
|
#include "editor.h"
|
|
#include "loader.h"
|
|
#include "timing.h"
|
|
#include "image.h"
|
|
#include "graphics.h"
|
|
#include "menu.h"
|
|
|
|
|
|
#define MAX_TERM_COLS 80
|
|
#define MAX_TERM_ROWS 47
|
|
#define CMD_LINE_ROW 48
|
|
#define MAX_HISTORY_CMD 50
|
|
#define MAX_COMMAND_CHARS 79
|
|
|
|
|
|
namespace Terminal
|
|
{
|
|
const int _screenMaxIndex = (SCREEN_HEIGHT - (FONT_HEIGHT+2)*1)/(FONT_HEIGHT+2);
|
|
const std::string _eraseLine = std::string(MAX_COMMAND_CHARS+1, 32);
|
|
|
|
enum MenuItem {MenuCopy=0, MenuAll, MenuCut, MenuDel};
|
|
|
|
bool _terminalModeGiga = false;
|
|
bool _waitForPromptGiga = false;
|
|
|
|
int _scrollOffset = 0;
|
|
int _scrollDelta = 0;
|
|
int _scrollIndex = 0;
|
|
int _commandHistoryIndex = 0;
|
|
int _commandCharIndex = 0;
|
|
|
|
std::string _commandLine;
|
|
std::vector<std::string> _commandLineHistory;
|
|
|
|
std::vector<int> _selectedText;
|
|
std::vector<std::string> _terminalText;
|
|
|
|
|
|
void initialise(void)
|
|
{
|
|
std::vector<std::string> items = {"TERM ", "Copy ", "All ", "Cut ", "Delete"};
|
|
Menu::createMenu("Terminal", items, 6, 5);
|
|
}
|
|
|
|
void sendCommandToGiga(const std::string& cmd)
|
|
{
|
|
if(_waitForPromptGiga) return;
|
|
|
|
for(int i=0; i<int(cmd.size()); i++)
|
|
{
|
|
if(!Loader::sendCharGiga(cmd.c_str()[i])) return;
|
|
}
|
|
|
|
_waitForPromptGiga = true;
|
|
}
|
|
|
|
void scrollToEnd(void)
|
|
{
|
|
_scrollOffset = _scrollIndex;
|
|
}
|
|
|
|
void clearCommandLine(void)
|
|
{
|
|
_commandCharIndex = 0;
|
|
_commandLine.clear();
|
|
}
|
|
|
|
void clearHistoryCommandLine(void)
|
|
{
|
|
_commandHistoryIndex = 0;
|
|
_commandLineHistory.clear();
|
|
}
|
|
|
|
void exitTerminalModeGiga(void)
|
|
{
|
|
clearCommandLine();
|
|
clearHistoryCommandLine();
|
|
|
|
if(_terminalModeGiga)
|
|
{
|
|
Loader::sendCharGiga(4);
|
|
_terminalModeGiga = false;
|
|
}
|
|
}
|
|
|
|
void switchToTerminal(void)
|
|
{
|
|
Editor::setEditorMode(Editor::Term);
|
|
scrollToEnd();
|
|
}
|
|
|
|
void prevCommandLineHistory(void)
|
|
{
|
|
if(_commandLineHistory.size() == 0) return;
|
|
if(--_commandHistoryIndex < 0) _commandHistoryIndex = 0;
|
|
_commandLine = _commandLineHistory[_commandHistoryIndex];
|
|
_commandCharIndex = int(_commandLine.size());
|
|
}
|
|
|
|
void nextCommandLineHistory(void)
|
|
{
|
|
if(_commandLineHistory.size() == 0) return;
|
|
if(++_commandHistoryIndex >= int(_commandLineHistory.size())) _commandHistoryIndex = int(_commandLineHistory.size()) - 1;
|
|
_commandLine = _commandLineHistory[_commandHistoryIndex];
|
|
_commandCharIndex = int(_commandLine.size());
|
|
}
|
|
|
|
void prevCommandLineChar(void)
|
|
{
|
|
if(--_commandCharIndex < 0) _commandCharIndex = 0;
|
|
}
|
|
|
|
void nextCommandLineChar(void)
|
|
{
|
|
if(++_commandCharIndex > int(_commandLine.size())) _commandCharIndex = int(_commandLine.size());
|
|
}
|
|
|
|
void backspaceCommandLineChar(void)
|
|
{
|
|
if(_commandLine.size() && _commandCharIndex > 0 && _commandCharIndex <= int(_commandLine.size()))
|
|
{
|
|
_commandLine.erase(--_commandCharIndex, 1);
|
|
}
|
|
}
|
|
|
|
void deleteCommandLineChar(void)
|
|
{
|
|
if(_commandLine.size() && _commandCharIndex >= 0 && _commandCharIndex < int(_commandLine.size()))
|
|
{
|
|
_commandLine.erase(_commandCharIndex, 1);
|
|
if(_commandCharIndex > int(_commandLine.size())) _commandCharIndex = int(_commandLine.size());
|
|
}
|
|
}
|
|
|
|
void copyCommandLineToHistory(void)
|
|
{
|
|
if(_commandLineHistory.size() < MAX_HISTORY_CMD)
|
|
{
|
|
_commandLineHistory.push_back(_commandLine);
|
|
_commandHistoryIndex = int(_commandLineHistory.size());
|
|
}
|
|
else
|
|
{
|
|
_commandLineHistory.push_back(_commandLine);
|
|
_commandLineHistory.erase(_commandLineHistory.begin());
|
|
_commandHistoryIndex = int(_commandLineHistory.size()) - 1;
|
|
}
|
|
|
|
clearCommandLine();
|
|
}
|
|
|
|
void copyTextToClipboard(void)
|
|
{
|
|
int clipboardTextSize = 0;
|
|
for(int i=0; i<int(_terminalText.size()); i++) clipboardTextSize += int(_terminalText[i].size());
|
|
if(clipboardTextSize == 0) return;
|
|
char* clipboardText = new (std::nothrow) char[clipboardTextSize];
|
|
if(!clipboardText) return;
|
|
|
|
// Copy text line by line, char by char, replace trailing zero's with newlines
|
|
int clipboardTextIndex = 0;
|
|
for(int i=0; i<int(_selectedText.size()); i++)
|
|
{
|
|
int index = _selectedText[i];
|
|
for(int j=0; j<int(_terminalText[index].size())-1; j++)
|
|
{
|
|
clipboardText[clipboardTextIndex++] = _terminalText[index][j];
|
|
}
|
|
|
|
// trailing zero's get replaced with newlines, except for last one
|
|
clipboardText[clipboardTextIndex++] = (i < int(_selectedText.size()) - 1) ? '\n' : 0;
|
|
}
|
|
|
|
// Save to system clipboard
|
|
SDL_SetClipboardText(clipboardText);
|
|
|
|
delete [] clipboardText;
|
|
}
|
|
|
|
void printTerminal(void)
|
|
{
|
|
_scrollIndex = std::max(0, int(_terminalText.size()) - _screenMaxIndex);
|
|
if(_scrollOffset >= _scrollIndex) _scrollOffset = _scrollIndex;
|
|
if(_scrollOffset < 0) _scrollOffset = 0;
|
|
|
|
Graphics::clearScreen(0x22222222);
|
|
Graphics::drawText(_eraseLine, 0, _screenMaxIndex*(FONT_HEIGHT+2)+1, 0x55555555, true, MAX_COMMAND_CHARS+1);
|
|
|
|
// Terminal text
|
|
for(int i=_scrollOffset; i<int(_terminalText.size()); i++)
|
|
{
|
|
if(i - _scrollOffset >= _screenMaxIndex) break;
|
|
|
|
bool invert = false;
|
|
for(int j=0; j<int(_selectedText.size()); j++)
|
|
{
|
|
if(i == _selectedText[j])
|
|
{
|
|
invert = true;
|
|
break;
|
|
}
|
|
}
|
|
Graphics::drawText(_terminalText[i], FONT_WIDTH, (i-_scrollOffset)*(FONT_HEIGHT+2), 0xAAAAAAAA, invert, MAX_TERM_COLS);
|
|
}
|
|
|
|
// Command line
|
|
std::string commandLine = _commandLine;
|
|
if(_commandCharIndex >= int(commandLine.size()))
|
|
{
|
|
_commandCharIndex = int(commandLine.size());
|
|
commandLine += char(32);
|
|
}
|
|
|
|
// Flash cursor
|
|
static uint8_t toggle = 0;
|
|
bool invert = ((toggle++) >>4) & 1;
|
|
Graphics::drawText(commandLine, FONT_WIDTH, _screenMaxIndex*(FONT_HEIGHT+2)+1, 0xFFFFFFFF, invert, 1, _commandCharIndex);
|
|
}
|
|
|
|
|
|
void handleGuiEvents(SDL_Event& event)
|
|
{
|
|
switch(event.type)
|
|
{
|
|
case SDL_WINDOWEVENT:
|
|
{
|
|
switch(event.window.event)
|
|
{
|
|
case SDL_WINDOWEVENT_RESIZED:
|
|
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
|
{
|
|
Graphics::setWidthHeight(event.window.data1, event.window.data2);
|
|
}
|
|
break;
|
|
|
|
default: break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SDL_QUIT:
|
|
{
|
|
exitTerminalModeGiga();
|
|
|
|
Cpu::shutdown();
|
|
exit(0);
|
|
}
|
|
|
|
default: break;
|
|
}
|
|
}
|
|
|
|
void handleMouseLeftButtonDown(int mouseX, int mouseY)
|
|
{
|
|
// Normalised mouse position
|
|
float mx = float(mouseX) / float(Graphics::getWidth());
|
|
float my = float(mouseY) / float(Graphics::getHeight());
|
|
mouseX = int(mx * float(SCREEN_WIDTH));
|
|
mouseY = int(my * float(SCREEN_HEIGHT));
|
|
//fprintf(stderr, "%d %d %f %f\n", mouseX, mouseY, mx, my);
|
|
|
|
int terminalTextSelected = (mouseY + 2) / (FONT_HEIGHT+2) + _scrollOffset;
|
|
|
|
// Save selected text line as long as it doesn't already exist
|
|
bool saveText = true;
|
|
for(int i=0; i<int(_selectedText.size()); i++)
|
|
{
|
|
if(_selectedText[i] == terminalTextSelected)
|
|
{
|
|
saveText = false;
|
|
break;
|
|
}
|
|
}
|
|
if(saveText && terminalTextSelected < int(_terminalText.size())) _selectedText.push_back(terminalTextSelected);
|
|
|
|
// Select everything between min and max as long as it doesn't already exist
|
|
int selectedMin = INT_MAX;
|
|
int selectedMax = INT_MIN;
|
|
for(int i=0; i<int(_selectedText.size()); i++)
|
|
{
|
|
if(_selectedText[i] > selectedMax) selectedMax = _selectedText[i];
|
|
if(_selectedText[i] < selectedMin) selectedMin = _selectedText[i];
|
|
}
|
|
for(int i=selectedMin+1; i<selectedMax; i++)
|
|
{
|
|
saveText = true;
|
|
for(int j=0; j<int(_selectedText.size()); j++)
|
|
{
|
|
if(_selectedText[j] == i)
|
|
{
|
|
saveText = false;
|
|
break;
|
|
}
|
|
}
|
|
if(saveText && i < int(_terminalText.size())) _selectedText.push_back(i);
|
|
}
|
|
|
|
if(mouseY == 0) _scrollOffset--;
|
|
}
|
|
|
|
void handleMouseRightButtonDown(int mouseX, int mouseY)
|
|
{
|
|
Menu::captureItem("Terminal", mouseX, mouseY);
|
|
Menu::renderMenu("Terminal");
|
|
}
|
|
|
|
void handleMouseButtonDown(const SDL_Event& event, const Editor::MouseState& mouseState)
|
|
{
|
|
UNREFERENCED_PARAM(event);
|
|
|
|
if(mouseState._state == SDL_BUTTON_LEFT) _selectedText.clear();
|
|
|
|
if(mouseState._state == SDL_BUTTON_X1)
|
|
{
|
|
Menu::captureMenu("Terminal", mouseState._x, mouseState._y);
|
|
}
|
|
}
|
|
|
|
void handleMouseButtonUp(const SDL_Event& event, const Editor::MouseState& mouseState)
|
|
{
|
|
UNREFERENCED_PARAM(event);
|
|
UNREFERENCED_PARAM(mouseState);
|
|
|
|
int menuItemIndex;
|
|
Menu::getMenuItemIndex("Terminal", menuItemIndex);
|
|
|
|
switch(menuItemIndex)
|
|
{
|
|
// Copy selected text
|
|
case MenuCopy:
|
|
{
|
|
if(_terminalText.size() && _selectedText.size())
|
|
{
|
|
// Sort selected text
|
|
std::sort(_selectedText.begin(), _selectedText.end());
|
|
|
|
copyTextToClipboard();
|
|
}
|
|
}
|
|
break;
|
|
|
|
// Toggle between select all and select none
|
|
case MenuAll:
|
|
{
|
|
if(_selectedText.size() == _terminalText.size())
|
|
{
|
|
_selectedText.clear();
|
|
}
|
|
else
|
|
{
|
|
_selectedText.clear();
|
|
for(int i=0; i<int(_terminalText.size()); i++)
|
|
{
|
|
_selectedText.push_back(i);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case MenuCut:
|
|
{
|
|
if(_terminalText.size() && _selectedText.size())
|
|
{
|
|
// Sort selected text
|
|
std::sort(_selectedText.begin(), _selectedText.end());
|
|
|
|
copyTextToClipboard();
|
|
|
|
// Delete selected
|
|
int selectedMin = _selectedText[0];
|
|
int selectedMax = _selectedText.back();
|
|
if(int(_terminalText.size()) > selectedMax)
|
|
{
|
|
_terminalText.erase(_terminalText.begin() + selectedMin, _terminalText.begin() + selectedMax + 1);
|
|
}
|
|
}
|
|
|
|
_selectedText.clear();
|
|
}
|
|
break;
|
|
|
|
case MenuDel:
|
|
{
|
|
if(_terminalText.size() && _selectedText.size())
|
|
{
|
|
// Sort selected text
|
|
std::sort(_selectedText.begin(), _selectedText.end());
|
|
|
|
// Delete selected
|
|
int selectedMin = _selectedText[0];
|
|
int selectedMax = _selectedText.back();
|
|
if(int(_terminalText.size()) > selectedMax)
|
|
{
|
|
_terminalText.erase(_terminalText.begin() + selectedMin, _terminalText.begin() + selectedMax + 1);
|
|
}
|
|
}
|
|
|
|
_selectedText.clear();
|
|
}
|
|
break;
|
|
|
|
default: break;
|
|
}
|
|
}
|
|
|
|
void handleMouseWheel(const SDL_Event& event)
|
|
{
|
|
if(event.wheel.y > 0) _scrollOffset -= 1;
|
|
if(event.wheel.y < 0) _scrollOffset += 1;
|
|
}
|
|
|
|
void handleKey(const SDL_Event& event)
|
|
{
|
|
char keyCode = event.text.text[0];
|
|
|
|
if(_terminalModeGiga) Loader::sendCharGiga(keyCode);
|
|
if(keyCode >= 32 && keyCode <= 126)
|
|
{
|
|
_commandLine.insert(_commandLine.begin() + _commandCharIndex, char(keyCode));
|
|
_commandCharIndex++;
|
|
if(_commandLine.size() >= MAX_COMMAND_CHARS) copyCommandLineToHistory();
|
|
}
|
|
}
|
|
|
|
void handleKeyDown(SDL_Keycode keyCode, Uint16 keyMod)
|
|
{
|
|
// Leave terminal mode
|
|
if(keyCode == Editor::getEmulatorScanCode("Terminal") && keyMod == Editor::getEmulatorKeyMod("Terminal"))
|
|
{
|
|
exitTerminalModeGiga();
|
|
Editor::setEditorToPrevMode();
|
|
}
|
|
// Quit
|
|
else if(keyCode == Editor::getEmulatorScanCode("Quit") && keyMod == Editor::getEmulatorKeyMod("Quit"))
|
|
{
|
|
exitTerminalModeGiga();
|
|
|
|
Cpu::shutdown();
|
|
exit(0);
|
|
}
|
|
// Image editor
|
|
else if(keyCode == Editor::getEmulatorScanCode("ImageEditor") && keyMod == Editor::getEmulatorKeyMod("ImageEditor"))
|
|
{
|
|
Editor::setEditorMode(Editor::Image);
|
|
}
|
|
// Audio editor
|
|
else if(keyCode == Editor::getEmulatorScanCode("AudioEditor") && keyMod == Editor::getEmulatorKeyMod("AudioEditor"))
|
|
{
|
|
Editor::setEditorMode(Editor::Audio);
|
|
}
|
|
|
|
// No modifier keys
|
|
static bool useTerminalHistory = false;
|
|
if(keyMod == 0x0000)
|
|
{
|
|
// Both modes
|
|
switch(keyCode)
|
|
{
|
|
case SDLK_PAGEUP: _scrollOffset -= _screenMaxIndex; break;
|
|
case SDLK_PAGEDOWN: _scrollOffset += _screenMaxIndex; break;
|
|
case SDLK_HOME: _scrollOffset = 0; break;
|
|
case SDLK_END: _scrollOffset = _scrollIndex; break;
|
|
|
|
default: break;
|
|
}
|
|
|
|
// Normal mode
|
|
if(!_terminalModeGiga)
|
|
{
|
|
switch(keyCode)
|
|
{
|
|
case SDLK_UP: prevCommandLineHistory(); break;
|
|
case SDLK_DOWN: nextCommandLineHistory(); break;
|
|
case SDLK_LEFT: prevCommandLineChar(); break;
|
|
case SDLK_RIGHT: nextCommandLineChar(); break;
|
|
case SDLK_DELETE: deleteCommandLineChar(); break;
|
|
case SDLK_BACKSPACE: backspaceCommandLineChar(); break;
|
|
|
|
case '\r':
|
|
case '\n':
|
|
{
|
|
if(!_terminalModeGiga && _commandLine.size() == 1 && (_commandLine[0] == 't' || _commandLine[0] == 'T'))
|
|
{
|
|
_terminalModeGiga = true;
|
|
sendCommandToGiga(_commandLine + "\n");
|
|
clearCommandLine();
|
|
clearHistoryCommandLine();
|
|
}
|
|
else
|
|
{
|
|
sendCommandToGiga(_commandLine + "\n");
|
|
copyCommandLineToHistory();
|
|
}
|
|
}
|
|
break;
|
|
|
|
default: break;
|
|
}
|
|
}
|
|
// Terminal mode
|
|
else
|
|
{
|
|
switch(keyCode)
|
|
{
|
|
case SDLK_UP: Loader::sendCharGiga(27); Loader::sendCharGiga('['); Loader::sendCharGiga('A'); break;
|
|
case SDLK_DOWN: Loader::sendCharGiga(27); Loader::sendCharGiga('['); Loader::sendCharGiga('B'); break;
|
|
case SDLK_RIGHT: Loader::sendCharGiga(27); Loader::sendCharGiga('['); Loader::sendCharGiga('C'); break;
|
|
case SDLK_LEFT: Loader::sendCharGiga(27); Loader::sendCharGiga('['); Loader::sendCharGiga('D'); break;
|
|
case SDLK_TAB: Loader::sendCharGiga(char(keyCode)); break;
|
|
case SDLK_DELETE: Loader::sendCharGiga(char(keyCode)); backspaceCommandLineChar(); break;
|
|
|
|
case '\r':
|
|
case '\n':
|
|
{
|
|
if(useTerminalHistory)
|
|
{
|
|
useTerminalHistory = false;
|
|
for(int i=0; i<int(_commandLine.size()); i++) Loader::sendCharGiga(_commandLine[i]);
|
|
Loader::sendCharGiga('\n');
|
|
clearCommandLine();
|
|
}
|
|
else
|
|
{
|
|
Loader::sendCharGiga(char(keyCode));
|
|
copyCommandLineToHistory();
|
|
clearCommandLine();
|
|
}
|
|
}
|
|
break;
|
|
|
|
default: break;
|
|
}
|
|
}
|
|
}
|
|
// Terminal mode modifier keys
|
|
else if(_terminalModeGiga)
|
|
{
|
|
if(keyMod & KMOD_LCTRL)
|
|
{
|
|
switch(keyCode)
|
|
{
|
|
case SDLK_UP: prevCommandLineHistory(); useTerminalHistory = true; break;
|
|
case SDLK_DOWN: nextCommandLineHistory(); useTerminalHistory = true; break;
|
|
case SDLK_c: Loader::sendCharGiga(3); break; // CTRL C to break BASIC
|
|
case SDLK_d: exitTerminalModeGiga(); break; // CTRL D to exit terminal mode
|
|
|
|
default: break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void handleKeyUp(SDL_Keycode keyCode, Uint16 keyMod)
|
|
{
|
|
// Help screen
|
|
if(keyCode == Editor::getEmulatorScanCode("Help") && keyMod == Editor::getEmulatorKeyMod("Help"))
|
|
{
|
|
static bool helpScreen = false;
|
|
helpScreen = !helpScreen;
|
|
Graphics::setDisplayHelpScreen(helpScreen);
|
|
}
|
|
// TODO: conflicts with CTRL-D in pluggy terminal mode, Disassembler
|
|
//else if(keyCode == Editor::getEmulatorScanCode("Disassembler") && keyMod == Editor::getEmulatorKeyMod("Disassembler"))
|
|
//{
|
|
// Editor::setEditorMode(Editor::Dasm);
|
|
//}
|
|
// Browser
|
|
else if(keyCode == Editor::getEmulatorScanCode("Browse") && keyMod == Editor::getEmulatorKeyMod("Browse"))
|
|
{
|
|
Editor::browseDirectory();
|
|
Editor::setEditorMode(Editor::Load);
|
|
}
|
|
// Hex monitor
|
|
else if(keyCode == Editor::getEmulatorScanCode("HexMonitor") && keyMod == Editor::getEmulatorKeyMod("HexMonitor"))
|
|
{
|
|
Editor::setEditorMode(Editor::Hex);
|
|
}
|
|
}
|
|
|
|
void handleInput(void)
|
|
{
|
|
// Mouse button state
|
|
Editor::MouseState mouseState;
|
|
mouseState._state = SDL_GetMouseState(&mouseState._x, &mouseState._y);
|
|
|
|
SDL_Event event;
|
|
while(SDL_PollEvent(&event))
|
|
{
|
|
SDL_Keycode keyCode = event.key.keysym.sym;
|
|
Uint16 keyMod = event.key.keysym.mod & (KMOD_LCTRL | KMOD_LALT | KMOD_LSHIFT);
|
|
|
|
mouseState._state = SDL_GetMouseState(&mouseState._x, &mouseState._y);
|
|
|
|
handleGuiEvents(event);
|
|
|
|
switch(event.type)
|
|
{
|
|
case SDL_MOUSEBUTTONDOWN: handleMouseButtonDown(event, mouseState); break;
|
|
case SDL_MOUSEBUTTONUP: handleMouseButtonUp(event, mouseState); break;
|
|
case SDL_MOUSEWHEEL: handleMouseWheel(event); break;
|
|
case SDL_TEXTINPUT: handleKey(event); break;
|
|
case SDL_KEYDOWN: handleKeyDown(keyCode, keyMod); break;
|
|
case SDL_KEYUP: handleKeyUp(keyCode, keyMod); break;
|
|
|
|
default: break;
|
|
}
|
|
}
|
|
|
|
if(_waitForPromptGiga)
|
|
{
|
|
std::string line;
|
|
if(!Loader::readLineGiga(line))
|
|
{
|
|
_waitForPromptGiga = false;
|
|
fprintf(stderr, "Terminal::handleInput() : timed out on COM port '%s'\n", Loader::getConfigComPort().c_str());
|
|
}
|
|
else
|
|
{
|
|
_terminalText.push_back(line);
|
|
_scrollDelta = 1;
|
|
|
|
if(line.find("?") != std::string::npos || line.find("Ctrl-D") != std::string::npos)
|
|
{
|
|
_waitForPromptGiga = false;
|
|
_scrollDelta = 2;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Read chars back from Gigatron in terminal mode
|
|
if(_terminalModeGiga)
|
|
{
|
|
char chr = 0;
|
|
static std::string line;
|
|
if(Loader::readCharGiga(&chr))
|
|
{
|
|
if(chr >= 32 && chr <= 126) line.push_back(chr);
|
|
if(chr == '\r' || chr == '\n')
|
|
{
|
|
if(line.size())
|
|
{
|
|
_terminalText.push_back(line);
|
|
_scrollDelta = 1;
|
|
}
|
|
line.clear();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Scroll text one line at a time until end is reached, (jump to end - delta if scroll index is not at end)
|
|
if(_scrollDelta)
|
|
{
|
|
_scrollOffset = _scrollIndex - _scrollDelta + 2;
|
|
_scrollDelta--;
|
|
}
|
|
|
|
printTerminal();
|
|
|
|
switch(mouseState._state)
|
|
{
|
|
case SDL_BUTTON_LEFT: handleMouseLeftButtonDown(mouseState._x, mouseState._y); break;
|
|
case SDL_BUTTON_X1: handleMouseRightButtonDown(mouseState._x, mouseState._y); break;
|
|
|
|
default: break;
|
|
}
|
|
}
|
|
|
|
void process(void)
|
|
{
|
|
handleInput();
|
|
Graphics::render(true);
|
|
}
|
|
}
|