mirror of
https://github.com/chrim05/nds-console.git
synced 2025-06-19 06:05:37 -04:00
219 lines
5.8 KiB
C++
219 lines
5.8 KiB
C++
#include "console.h"
|
|
|
|
void NDSConsole::processVirtualKey(int key)
|
|
{
|
|
// remapping some special virtual keyboard keys
|
|
switch (key)
|
|
{
|
|
case DVK_LEFT:
|
|
moveCursorIndex(MovingDirection2D::LeftOrUp);
|
|
break;
|
|
|
|
case DVK_RIGHT:
|
|
moveCursorIndex(MovingDirection2D::RightOrDown);
|
|
break;
|
|
|
|
case DVK_UP:
|
|
moveRecentBuffer(MovingDirection2D::LeftOrUp);
|
|
break;
|
|
|
|
case DVK_DOWN:
|
|
moveRecentBuffer(MovingDirection2D::RightOrDown);
|
|
break;
|
|
|
|
case DVK_BACKSPACE:
|
|
removeChar();
|
|
break;
|
|
|
|
case DVK_ENTER:
|
|
returnPrompt();
|
|
break;
|
|
|
|
case DVK_ALT:
|
|
case DVK_CTRL:
|
|
case DVK_SHIFT:
|
|
case DVK_CAPS:
|
|
case DVK_FOLD:
|
|
case DVK_MENU:
|
|
break;
|
|
|
|
default:
|
|
insertChar(char(key));
|
|
break;
|
|
}
|
|
}
|
|
|
|
void NDSConsole::insertChar(char c)
|
|
{
|
|
// the letter has to be added at the top of the string
|
|
if (promptCursorIndex == promptBuffer->length())
|
|
{
|
|
promptBuffer->push_back(c);
|
|
promptCursorIndex++;
|
|
}
|
|
// the letter has to be inserted inside the string
|
|
else
|
|
promptBuffer->insert(promptBuffer->begin() + promptCursorIndex++, c);
|
|
|
|
// setting the max reached prompt length whether the current prompt length is greater
|
|
if (promptBuffer->length() > maxReachedPromptLength)
|
|
maxReachedPromptLength = promptBuffer->length();
|
|
}
|
|
|
|
void NDSConsole::removeChar()
|
|
{
|
|
// when the prompt buffer is empty there's no need to remove any char
|
|
if (promptCursorIndex == 0)
|
|
return;
|
|
|
|
// the letter to remove is on the top of the string
|
|
if (promptCursorIndex == promptBuffer->length())
|
|
{
|
|
promptBuffer->pop_back();
|
|
promptCursorIndex--;
|
|
return;
|
|
}
|
|
|
|
// the letter to remove is inside the string
|
|
promptBuffer->erase(promptBuffer->begin() + --promptCursorIndex);
|
|
}
|
|
|
|
void NDSConsole::flushPromptBuffer(uint64_t frame, bool printCursor)
|
|
{
|
|
// going back at the end of the prompt prefix
|
|
printableConsole->cursorX = getPromptPrefix().length();
|
|
|
|
// printing the buffer and the cursor
|
|
for (uint64_t i = 0; i < promptBuffer->length(); i++)
|
|
{
|
|
// printing the cursor when it's inside the string
|
|
if (i == promptCursorIndex)
|
|
printBlinkingCursor(frame, printCursor);
|
|
|
|
iprintf("%c", promptBuffer->at(i));
|
|
}
|
|
|
|
// printing the cursor when is on the top of the string
|
|
if (promptCursorIndex == promptBuffer->length())
|
|
printBlinkingCursor(frame, printCursor);
|
|
|
|
// replacing the overflowed letters with spaces
|
|
for (uint64_t i = 0; i < maxReachedPromptLength + 1 - promptBuffer->length(); i++)
|
|
iprintf(" ");
|
|
}
|
|
|
|
void NDSConsole::moveCursorIndex(MovingDirection2D direction)
|
|
{
|
|
// the cursor index is at the left edge (cannot be moved again)
|
|
if (direction == MovingDirection2D::LeftOrUp && promptCursorIndex == 0)
|
|
return;
|
|
|
|
// the cursor index is at the right edge (cannot be moved again)
|
|
if (direction == MovingDirection2D::RightOrDown && promptCursorIndex == promptBuffer->length())
|
|
return;
|
|
|
|
promptCursorIndex += uint64_t(direction);
|
|
}
|
|
|
|
void NDSConsole::moveRecentBuffer(MovingDirection2D direction)
|
|
{
|
|
// the reecent buffer index is at the upper edge (cannot be moved again)
|
|
if (direction == MovingDirection2D::LeftOrUp && recentPromptsIndex == 0)
|
|
return;
|
|
|
|
// the recenet buffer index is at the down edge (cannot be moved again)
|
|
if (direction == MovingDirection2D::RightOrDown && recentPromptsIndex == recentPrompts.size() - 1)
|
|
return;
|
|
|
|
// updating the recent prompts index and setting up the new prompt buffer
|
|
recentPromptsIndex += uint64_t(direction);
|
|
this->promptBuffer = recentPrompts[recentPromptsIndex];
|
|
this->promptCursorIndex = promptBuffer->length();
|
|
}
|
|
|
|
void NDSConsole::scrollScreen(MovingDirection2D direction)
|
|
{
|
|
// unimplemented yet
|
|
}
|
|
|
|
void NDSConsole::returnPrompt()
|
|
{
|
|
// when the prompt buffer is empty there's no need to process the prompted command
|
|
if (promptBuffer->empty())
|
|
return;
|
|
|
|
// removing the old prompt buffer whether it's empty (returnPrompt worked because promptBuffer was set to another recent prompt)
|
|
if (recentPrompts[recentPrompts.size() - 1]->empty())
|
|
{
|
|
delete recentPrompts[recentPrompts.size() - 1];
|
|
recentPrompts.pop_back();
|
|
}
|
|
|
|
// reprinting the current prompt buffer without the cursor
|
|
flushPromptBuffer(1, false);
|
|
|
|
// going to the next line for the prompted command output
|
|
iprintf("\n");
|
|
|
|
try
|
|
{
|
|
// processing the prompted command
|
|
auto result = processCommand(*promptBuffer);
|
|
|
|
// when the expression returns `none` it's not shown up
|
|
if (result.kind != NScript::NodeKind::None)
|
|
iprintf("\n%s\n", result.toString().c_str());
|
|
}
|
|
catch (const NScript::Error& e)
|
|
{
|
|
printPromptParsingError(e);
|
|
}
|
|
|
|
// setting up the new prompt buffer
|
|
// the old one is already saved on the top of recentPrompts
|
|
this->promptBuffer = new std::string();
|
|
this->promptCursorIndex = 0;
|
|
|
|
// saving the new prompt buffer on the top of recentPrompts
|
|
recentPromptsIndex = recentPrompts.size();
|
|
recentPrompts.push_back(promptBuffer);
|
|
|
|
// initializing the new prompt line
|
|
printPromptPrefix();
|
|
}
|
|
|
|
void NDSConsole::printPromptParsingError(NScript::Error e)
|
|
{
|
|
auto promptLength = getPromptPrefix().length();
|
|
|
|
// padding the error underlining
|
|
for (uint64_t i = 0; i < promptLength + e.position.startPos; i++)
|
|
iprintf(" ");
|
|
|
|
|
|
// underlining the wrong part
|
|
for (uint64_t i = 0; i < e.position.length(); i++)
|
|
iprintf("-");
|
|
|
|
// printing the error message
|
|
iprintf("\n\nerror: ");
|
|
for (const auto& m : e.message)
|
|
iprintf("%s", m.c_str());
|
|
|
|
iprintf("\n");
|
|
}
|
|
|
|
NScript::Node NDSConsole::processCommand(std::string command)
|
|
{
|
|
NScript::Parser parser(command);
|
|
|
|
return evaluator.evaluateNode(parser.parse());
|
|
}
|
|
|
|
void NDSConsole::printBlinkingCursor(uint64_t frame, bool printCursor)
|
|
{
|
|
if (!printCursor)
|
|
return;
|
|
|
|
iprintf(frame % 32 <= 16 ? " " : "|");
|
|
} |