mirror of
https://github.com/emu-russia/pureikyubu.git
synced 2025-04-02 10:42:15 -04:00
470 lines
14 KiB
C++
470 lines
14 KiB
C++
// keyboard input
|
|
#include "pch.h"
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
static void con_function_key(int vkey, int ctrl)
|
|
{
|
|
switch(vkey)
|
|
{
|
|
case VK_F1:
|
|
con_update_registers();
|
|
con.update |= CON_UPDATE_REGS;
|
|
con_refresh();
|
|
break;
|
|
case VK_F2:
|
|
con_change_focus(WDATA); // Data
|
|
break;
|
|
case VK_F3:
|
|
con_change_focus(WDISA); // Disa
|
|
break;
|
|
case VK_F4:
|
|
con_change_focus(WCONSOLE); // Console (roll)
|
|
break;
|
|
case VK_F5:
|
|
if (Gekko::Gekko)
|
|
{
|
|
if (Gekko::Gekko->IsRunning())
|
|
{
|
|
con_break();
|
|
}
|
|
else
|
|
{
|
|
Gekko::Gekko->Run();
|
|
}
|
|
}
|
|
break;
|
|
case VK_F6:
|
|
// Switch Registers View
|
|
if(ctrl & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
|
|
{
|
|
if(wind.regmode == REGMOD_GPR)
|
|
{
|
|
wind.regmode = (REGWNDMODE)(REGMOD_MAX - 1);
|
|
memset(con.buf, 0, sizeof(CHAR_INFO) * CON_WIDTH * wind.regs_h);
|
|
con.update |= CON_UPDATE_REGS;
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
// back enum
|
|
wind.regmode = (REGWNDMODE) ((int)wind.regmode - 1);
|
|
memset(con.buf, 0, sizeof(CHAR_INFO) * CON_WIDTH * wind.regs_h);
|
|
con.update |= CON_UPDATE_REGS;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(wind.regmode == REGMOD_MAX - 1)
|
|
{
|
|
wind.regmode = (REGWNDMODE)0;
|
|
memset(con.buf, 0, sizeof(CHAR_INFO) * CON_WIDTH * wind.regs_h);
|
|
con.update |= CON_UPDATE_REGS;
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
// forward enum
|
|
wind.regmode = (REGWNDMODE)((int)wind.regmode + 1);
|
|
memset(con.buf, 0, sizeof(CHAR_INFO) * CON_WIDTH * wind.regs_h);
|
|
con.update |= CON_UPDATE_REGS;
|
|
}
|
|
}
|
|
break;
|
|
case VK_F9: // Toggle Breakpoint
|
|
Gekko::Gekko->ToggleBreakpoint(con.disa_cursor);
|
|
con.update |= CON_UPDATE_DISA;
|
|
break;
|
|
case VK_F10: // Step Over
|
|
Gekko::Gekko->AddOneShotBreakpoint(Gekko::Gekko->regs.pc + 4);
|
|
Gekko::Gekko->Run();
|
|
break;
|
|
case VK_F11: // Step Into
|
|
con_step_into();
|
|
break;
|
|
case VK_F12: // Skip
|
|
Gekko::Gekko->regs.pc += 4;
|
|
con.update |= CON_UPDATE_DISA;
|
|
DBReport2(DbgChannel::CPU, "skipped!\n");
|
|
break;
|
|
}
|
|
}
|
|
|
|
// searching for beginning of each word
|
|
static void search_left()
|
|
{
|
|
roll.editlen = (int)strlen(roll.editline);
|
|
|
|
// check editpos!=0 for possibility check [editpos-1]
|
|
if((roll.editlen == 0) || (roll.editpos == 0)) return;
|
|
|
|
// we at beginning of the word? if so, move to the space
|
|
if((roll.editline[roll.editpos] != 0x20) && (roll.editline[roll.editpos - 1] == 0x20)) roll.editpos--;
|
|
|
|
// note: no need check editpos!=0 here
|
|
if(roll.editline[roll.editpos] == 0x20)
|
|
{ // are we at space?
|
|
//search for first non-space
|
|
while((roll.editpos != 0) && (roll.editline[roll.editpos] == 0x20)) roll.editpos--;
|
|
if(!roll.editpos) return;
|
|
}
|
|
|
|
// we at last char, search for first space now
|
|
while(roll.editpos != 0)
|
|
{
|
|
// sure, editpos!=0 here, coz while check it first
|
|
if(roll.editline[roll.editpos - 1] == 0x20) return;
|
|
roll.editpos--;
|
|
}
|
|
}
|
|
|
|
static void search_right()
|
|
{
|
|
roll.editlen = (int)strlen(roll.editline);
|
|
if((roll.editlen == 0) || (roll.editpos == roll.editlen)) return;
|
|
if(roll.editline[roll.editpos] != 0x20)
|
|
{
|
|
while(roll.editline[roll.editpos] != 0x20)
|
|
{
|
|
if(roll.editpos == roll.editlen) return;
|
|
roll.editpos++;
|
|
}
|
|
}
|
|
|
|
while((roll.editpos != roll.editlen) && (roll.editline[roll.editpos] == 0x20)) roll.editpos++;
|
|
}
|
|
|
|
#define endl ( line[p] == 0 )
|
|
#define space ( line[p] == 0x20 )
|
|
#define quot ( line[p] == '\'' )
|
|
#define dquot ( line[p] == '\"' )
|
|
|
|
void con_tokenizing(char *line)
|
|
{
|
|
int p, start, end;
|
|
p = roll.tokencount = start = end = 0;
|
|
memset(roll.tokens, 0, sizeof(roll.tokens));
|
|
|
|
// while not end line
|
|
while(!endl)
|
|
{
|
|
// skip space first, if any
|
|
while(space) p++;
|
|
if(!endl && (quot || dquot))
|
|
{ // quotation, need special case
|
|
p++;
|
|
start = p;
|
|
while(1)
|
|
{
|
|
if(endl)
|
|
{
|
|
con_print(ConColor::BRED, "Open quotation\n");
|
|
return;
|
|
}
|
|
|
|
if(quot || dquot)
|
|
{
|
|
end = p;
|
|
p++;
|
|
break;
|
|
}
|
|
else p++;
|
|
}
|
|
|
|
if(roll.tokencount >= CON_TOKENCNT)
|
|
{
|
|
con_print(ConColor::BRED, "Too many args (>%i) or need quotes\n", CON_TOKENCNT);
|
|
return;
|
|
}
|
|
|
|
strncpy_s (roll.tokens[roll.tokencount], sizeof(roll.tokens[roll.tokencount]), line + start, end - start);
|
|
|
|
// make lower only first token
|
|
if(roll.tokencount == 0) _strlwr_s(roll.tokens[roll.tokencount], sizeof(roll.tokens[roll.tokencount]));
|
|
roll.tokencount++;
|
|
}
|
|
else if(!endl)
|
|
{
|
|
start = p;
|
|
while(1)
|
|
{
|
|
if(endl || space || quot || dquot)
|
|
{
|
|
end = p;
|
|
break;
|
|
}
|
|
|
|
p++;
|
|
}
|
|
|
|
if(roll.tokencount >= CON_TOKENCNT)
|
|
{
|
|
con_print(ConColor::BRED, "Too many args (>%i) or need quotes\n", CON_TOKENCNT);
|
|
return;
|
|
}
|
|
|
|
strncpy_s (roll.tokens[roll.tokencount], sizeof(roll.tokens[roll.tokencount]), line + start, end - start);
|
|
roll.tokencount++;
|
|
}
|
|
}
|
|
}
|
|
|
|
#undef space
|
|
#undef quot
|
|
#undef dquot
|
|
#undef endl
|
|
|
|
static int testempty(char *str)
|
|
{
|
|
int i, len = (int)strlen(str);
|
|
|
|
for(i=0; i<len; i++)
|
|
{
|
|
if(str[i] != 0x20) return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static void con_roll_edit_key(char ascii, int vkey, int ctrl)
|
|
{
|
|
std::vector<std::string> args;
|
|
if(ascii >= 0x20 && ascii < 256)
|
|
{
|
|
roll.editlen = (int)strlen(roll.editline);
|
|
if(roll.editlen >= 77) return;
|
|
else
|
|
{
|
|
if(roll.editpos == roll.editlen)
|
|
{
|
|
roll.editline[roll.editpos++] = ascii;
|
|
roll.editline[roll.editpos] = 0;
|
|
}
|
|
else
|
|
{
|
|
memmove(
|
|
roll.editline + roll.editpos + 1,
|
|
roll.editline + roll.editpos,
|
|
roll.editlen - roll.editpos + 1
|
|
);
|
|
roll.editline[roll.editpos++] = ascii;
|
|
}
|
|
|
|
con_update(CON_UPDATE_EDIT);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch(vkey)
|
|
{
|
|
case VK_RETURN:
|
|
roll.editlen = (int)strlen(roll.editline);
|
|
if(!roll.editlen) return;
|
|
if(testempty(roll.editline)) return;
|
|
strcpy_s (roll.history[roll.historypos], sizeof(roll.history[roll.historypos]), roll.editline);
|
|
roll.historypos++;
|
|
if(roll.historypos > 255) roll.historypos = 0;
|
|
roll.historycur = roll.historypos;
|
|
con_print(ConColor::NORM, ": %s", roll.editline);
|
|
con_tokenizing(roll.editline);
|
|
roll.editpos = roll.editlen = roll.editline[0] = 0;
|
|
con_update(CON_UPDATE_EDIT | CON_UPDATE_MSGS);
|
|
for (int i = 0; i < roll.tokencount; i++)
|
|
{
|
|
args.push_back(roll.tokens[i]);
|
|
}
|
|
con_command(args);
|
|
break;
|
|
case VK_UP:
|
|
if(!roll.autoscroll)
|
|
{
|
|
roll.viewpos --;
|
|
if(roll.viewpos < 0) roll.viewpos = 0;
|
|
con_update(CON_UPDATE_MSGS);
|
|
}
|
|
else
|
|
{
|
|
if(--roll.historycur < 0) roll.historycur = 0;
|
|
else
|
|
{
|
|
strcpy_s (roll.editline, sizeof(roll.editline), roll.history[roll.historycur]);
|
|
roll.editpos = roll.editlen = (int)strlen(roll.editline);
|
|
con_update(CON_UPDATE_EDIT);
|
|
}
|
|
}
|
|
break;
|
|
case VK_DOWN:
|
|
if(!roll.autoscroll)
|
|
{
|
|
roll.viewpos ++;
|
|
if(roll.viewpos >= roll.rollpos)
|
|
{
|
|
roll.viewpos = roll.rollpos;
|
|
con_set_autoscroll(TRUE);
|
|
}
|
|
con_update(CON_UPDATE_MSGS);
|
|
}
|
|
else
|
|
{
|
|
if(++roll.historycur >= roll.historypos)
|
|
{
|
|
roll.historycur = roll.historypos;
|
|
roll.editpos = roll.editlen = roll.editline[0] = 0;
|
|
con_update(CON_UPDATE_EDIT);
|
|
}
|
|
else
|
|
{
|
|
strcpy_s (roll.editline, sizeof(roll.editline), roll.history[roll.historycur]);
|
|
roll.editpos = roll.editlen = (int)strlen(roll.editline);
|
|
con_update(CON_UPDATE_EDIT);
|
|
}
|
|
}
|
|
break;
|
|
case VK_HOME:
|
|
if(!roll.autoscroll)
|
|
{
|
|
roll.viewpos = 0;
|
|
con_update(CON_UPDATE_MSGS);
|
|
}
|
|
else
|
|
{
|
|
roll.editpos = 0;
|
|
con_update(CON_UPDATE_EDIT);
|
|
}
|
|
break;
|
|
case VK_END:
|
|
if(!roll.autoscroll)
|
|
{
|
|
roll.viewpos = roll.rollpos;
|
|
con_update(CON_UPDATE_MSGS);
|
|
}
|
|
else
|
|
{
|
|
roll.editpos = (int)strlen(roll.editline);
|
|
con_update(CON_UPDATE_EDIT);
|
|
}
|
|
break;
|
|
case VK_LEFT:
|
|
if(ctrl & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) search_left();
|
|
else if(roll.editpos) roll.editpos--;
|
|
con_update(CON_UPDATE_EDIT);
|
|
break;
|
|
case VK_RIGHT:
|
|
roll.editlen = (int)strlen(roll.editline);
|
|
if(roll.editlen && (roll.editpos != roll.editlen))
|
|
{
|
|
if(ctrl & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) search_right();
|
|
else if(roll.editpos < roll.editlen) roll.editpos++;
|
|
con_update(CON_UPDATE_EDIT);
|
|
}
|
|
break;
|
|
case VK_BACK:
|
|
if(roll.editpos)
|
|
{
|
|
roll.editlen = (int)strlen(roll.editline);
|
|
if(roll.editlen == roll.editpos) roll.editline[--roll.editpos] = 0;
|
|
else memmove(
|
|
roll.editline + roll.editpos - 1,
|
|
roll.editline + roll.editpos,
|
|
roll.editlen - roll.editpos + 1
|
|
), roll.editpos--;
|
|
con_update(CON_UPDATE_EDIT);
|
|
}
|
|
break;
|
|
case VK_ESCAPE:
|
|
if(!roll.autoscroll)
|
|
{
|
|
con_set_autoscroll(TRUE);
|
|
con_update(CON_UPDATE_MSGS);
|
|
}
|
|
else
|
|
{
|
|
roll.historycur = roll.historypos;
|
|
roll.editpos = roll.editlen = roll.editline[0] = 0;
|
|
con_update(CON_UPDATE_EDIT);
|
|
}
|
|
break;
|
|
case VK_PRIOR:
|
|
if(roll.autoscroll)
|
|
{
|
|
con_set_autoscroll(FALSE);
|
|
roll.viewpos = roll.rollpos;
|
|
}
|
|
|
|
roll.viewpos -= 8;
|
|
if(roll.viewpos < 0) roll.viewpos = 0;
|
|
con_update(CON_UPDATE_MSGS);
|
|
break;
|
|
case VK_NEXT:
|
|
if(roll.autoscroll)
|
|
{
|
|
con_set_autoscroll(FALSE);
|
|
roll.viewpos = roll.rollpos;
|
|
}
|
|
|
|
roll.viewpos += 8;
|
|
if(roll.viewpos >= roll.rollpos)
|
|
{
|
|
roll.viewpos = roll.rollpos;
|
|
con_set_autoscroll(TRUE);
|
|
}
|
|
con_update(CON_UPDATE_MSGS);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void con_virtualkey(char ascii, int vkey, int ctrl)
|
|
{
|
|
// functions F1..F12 and control
|
|
if((vkey >= VK_F1) && (vkey <= VK_F12))
|
|
{
|
|
con_function_key(vkey, ctrl);
|
|
}
|
|
|
|
// switch focus to input line if symbol key
|
|
if(vkey == 0x8 || (ascii >= 0x20 && ascii < 256))
|
|
{
|
|
con_change_focus(WCONSOLE);
|
|
}
|
|
|
|
switch(wind.focus)
|
|
{
|
|
case WREGS:
|
|
break;
|
|
case WDATA:
|
|
con_data_key(ascii, vkey, ctrl);
|
|
break;
|
|
case WDISA:
|
|
con_disa_key(ascii, vkey, ctrl);
|
|
break;
|
|
case WCONSOLE:
|
|
con_roll_edit_key(ascii, vkey, ctrl);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void con_read_input(int peek)
|
|
{
|
|
INPUT_RECORD record;
|
|
DWORD count;
|
|
|
|
if(con.active == FALSE) return;
|
|
|
|
if(peek)
|
|
{
|
|
PeekConsoleInput(con.input, &record, 1, &count);
|
|
if(!count) return;
|
|
}
|
|
|
|
ReadConsoleInput(con.input, &record, 1, &count);
|
|
if(!count) return;
|
|
|
|
if(record.EventType == KEY_EVENT && record.Event.KeyEvent.bKeyDown)
|
|
{
|
|
char ascii = record.Event.KeyEvent.uChar.AsciiChar;
|
|
int vcode = record.Event.KeyEvent.wVirtualKeyCode;
|
|
int ctrl = record.Event.KeyEvent.dwControlKeyState;
|
|
con_virtualkey(ascii, vcode, ctrl);
|
|
}
|
|
}
|