keyevent reading moved to the tvdos itself

This commit is contained in:
minjaesong
2021-09-24 11:30:55 +09:00
parent 96e23d9019
commit 012bc44845
10 changed files with 632 additions and 70 deletions

View File

@@ -427,51 +427,6 @@ con.KEY_DELETE = 211;
con.KEY_BACKSPACE = 8;
con.KEY_TAB = 9;
con.KEY_RETURN = 13;
let _79kfQgystrobocounter = 4294967296*0; // 0L
let _pur82anstrobotime = 4294967296*0;
let _acpgrUzstrobodelays = [0,250000000,0,25000000,0]; // 250ms, 25ms
let _sT9mpKGstrobostatus = 0; // 0: first key, 1: waiting for initial delay, 2: repeating key, 3: waiting for repeat delay
let _9gyFcs7oldkeys = [];
let _qtkf932repeatcnt932repeatcnt = 0;
let _x93paQZshiftin = false;
// basically a multi-key version of con.getch() with GDX keycodes
con.scankeys = function(callback) {
// TODO: char as a first argument of callback, which needs KeyboardLayout(QWERTY, Colemak, Dvorak, etc)
function arrayEq(a,b) {
for (var i = 0; i < a.length; ++i) {
if (a[i] !== b[i]) return false;
}
return true;
}
sys.poke(-40, 255);
let keys = [sys.peek(-41),sys.peek(-42),sys.peek(-43),sys.peek(-44),sys.peek(-45),sys.peek(-46),sys.peek(-47),sys.peek(-48)];
if (_sT9mpKGstrobostatus % 2 == 0 && keys[0] != 0) {
_sT9mpKGstrobostatus += 1;
_pur82anstrobotime = sys.nanoTime();
_qtkf932repeatcnt += 1;
_x93paQZshiftin = keys.includes(59) || keys.includes(60);
callback('x', keys, _qtkf932repeatcnt);
}
else if (!arrayEq(keys, _9gyFcs7oldkeys) || keys[0] == 0) {
_sT9mpKGstrobostatus = 0;
_qtkf932repeatcnt = 0;
_x93paQZshiftin = keys.includes(59) || keys.includes(60);
}
else if (_sT9mpKGstrobostatus % 2 == 1 && sys.nanoTime() - _pur82anstrobotime < _acpgrUzstrobodelays[_sT9mpKGstrobostatus]) {
sys.spin();
}
else {
_sT9mpKGstrobostatus += 1;
if (_sT9mpKGstrobostatus >= 4) {
_sT9mpKGstrobostatus = 2;
}
}
_9gyFcs7oldkeys = keys;
// sys.spin();
};
con.getch = function() {
return sys.readKey();
};

View File

@@ -5,7 +5,7 @@ function hitCtrlQ(keys) {
println("Hit Ctrl+Shift+T+R to exit")
while (true) {
con.scankeys((char, keys, counter) => {
println(`${keys}\t'${char}' (${counter})`)
input.withEvent(event => {
println(event)
})
}

View File

@@ -32,7 +32,7 @@ function generateRandomHashStr(len) {
}
// define TVDOS
var _TVDOS = {};
const _TVDOS = {};
_TVDOS.VERSION = "1.0";
_TVDOS.DRIVES = {}; // Object where key-value pair is <drive-letter> : [serial-port, drive-number]
// actually figure out the drive letter association
@@ -48,6 +48,7 @@ _TVDOS.getPath = function() {
_TVDOS.variables = {
DOSDIR: "\\tvdos",
LANG: "EN",
KEYBOARD: "us_qwerty",
PATH: "\\tvdos\\bin;\\tbas;\\home",
PATHEXT: ".com;.bat;.js",
HELPPATH: "\\tvdos\\help",
@@ -58,7 +59,7 @@ Object.freeze(_TVDOS);
///////////////////////////////////////////////////////////////////////////////
var filesystem = {};
const filesystem = {};
filesystem._toPorts = (driveLetter) => {
if (driveLetter.toUpperCase === undefined) {
throw Error("'"+driveLetter+"' (type: "+typeof driveLetter+") is not a valid drive letter");
@@ -91,8 +92,7 @@ filesystem.open = (driveLetter, path, operationMode) => {
}
com.sendMessage(port[0], "OPEN"+mode+'"'+path+'",'+port[1]);
var response = com.getStatusCode(port[0]);
return (response == 0);
return com.getStatusCode(port[0]);
};
// @return the entire contents of the file in String
filesystem.readAll = (driveLetter) => {
@@ -153,9 +153,104 @@ Object.freeze(filesystem);
///////////////////////////////////////////////////////////////////////////////
const input = {};
const inputwork = {};
inputwork.keymap = [];
input.changeKeyLayout = function(name) {
let res0 = filesystem.open("A",`tvdos/${name.toLowerCase()}.key`,"R");
if (res0 != 0 && inputwork.keymap.length == 0) throw new Error(`I/O Error ${res0} - A:\\tvdos\\${name.toLowerCase()}.key`);
try {
inputwork.keymap = eval(filesystem.readAll("A"));
}
catch (e) {
printerrln(e);
return -1;
}
}
// load initial key layout
input.changeKeyLayout(_TVDOS.variables.KEYBOARD || "us_qwerty");
// states to run the keyboard input
inputwork.stroboTime = 4294967296*0;
inputwork.stroboDelays = [0,250000000,0,25000000,0]; // 250ms, 25ms
inputwork.stroboStatus = 0; // 0: first key, 1: waiting for initial delay, 2: repeating key, 3: waiting for repeat delay
inputwork.oldKeys = [];
inputwork.oldMouse = [];
inputwork.repeatCount = 0;
/**
* callback: takes one argument of object which
* [ <eventname>, args ]
* where:
* "key_down", <key symbol string>, <repeat count>, keycode0, keycode1 .. keycode7
* "key_change", <key symbol string (what went up)>, 0, keycode0, keycode1 .. keycode7 (remaining keys that are held down)
* "mouse_down", pos-x, pos-y, 1 // yes there's only one mouse button :p
* "mouse_up", pos-x, pos-y, 0
* "mouse_move", pos-x, pos-y, <button down?>, oldpos-x, oldpos-y
*/
input.withEvent = function(callback) {
// TODO mouse event
function arrayEq(a,b) {
for (let i = 0; i < a.length; ++i) {
if (a[i] !== b[i]) return false;
}
return true;
}
function arrayDiff(a,b) {
return a.filter(x => !b.includes(x));
}
function keysToStr(keys) {
let shiftin = keys.includes(59) || keys.includes(60);
let headkey = keys.head();
return (inputwork.keymap[headkey] == undefined) ? undefined : (shiftin) ? (inputwork.keymap[headkey][1] || inputwork.keymap[headkey][0]) : inputwork.keymap[headkey][0];
}
sys.poke(-40, 255);
let keys = [sys.peek(-41),sys.peek(-42),sys.peek(-43),sys.peek(-44),sys.peek(-45),sys.peek(-46),sys.peek(-47),sys.peek(-48)];
let mouse = [sys.peek(-33) | (sys.peek(-34) << 8), sys.peek(-35) | (sys.peek(-36) << 8), sys.peek(-37)];
if (inputwork.stroboStatus % 2 == 0 && keys[0] != 0) {
inputwork.stroboStatus += 1;
inputwork.stroboTime = sys.nanoTime();
inputwork.repeatCount += 1;
callback(["key_down", keysToStr(keys), inputwork.repeatCount].concat(keys));
}
else if (!arrayEq(keys, inputwork.oldKeys) || keys[0] == 0) {
inputwork.stroboStatus = 0;
inputwork.repeatCount = 0;
if (inputwork.oldKeys[0] != 0)
callback(["key_change", keysToStr(arrayDiff(inputwork.oldKeys, keys)), inputwork.repeatCount].concat(keys));
}
else if (inputwork.stroboStatus % 2 == 1 && sys.nanoTime() - inputwork.stroboTime < inputwork.stroboDelays[inputwork.stroboStatus]) {
sys.spin();
}
else {
inputwork.stroboStatus += 1;
if (inputwork.stroboStatus >= 4) {
inputwork.stroboStatus = 2;
}
}
inputwork.oldKeys = keys;
inputwork.oldMouse = mouse;
};
Object.freeze(input);
///////////////////////////////////////////////////////////////////////////////
// install other stuffs
filesystem.open("A", "tvdos/gl.js", "R");
var GL = eval(filesystem.readAll("A"));
const GL = eval(filesystem.readAll("A"));
let checkTerm = `if (sys.peek(-49)&1) throw new InterruptedException();`;
let injectIntChk = (s, n) => {

View File

@@ -253,9 +253,9 @@ shell.coreutils = {
if (DEBUG_PRINT) serial.println("command.js > cd > pathstr = "+path.string);
// check if path is valid
filesystem.open(CURRENT_DRIVE, path.string, 'R');
var dirOpened = filesystem.isDirectory(CURRENT_DRIVE); // open a dir; if path is nonexistent, file won't actually be opened
if (!dirOpened) { printerrln("CHDIR failed for '"+path.string+"'"); return; } // if file is not opened, FALSE will be returned
var dirOpenedStatus = filesystem.open(CURRENT_DRIVE, path.string, 'R');
var isDir = filesystem.isDirectory(CURRENT_DRIVE); // open a dir; if path is nonexistent, file won't actually be opened
if (!isDir) { printerrln("CHDIR failed for '"+path.string+"'"); return dirOpenedStatus; } // if file is not opened, IO error code will be returned
shell_pwd = path.pwd;
},
@@ -268,9 +268,9 @@ shell.coreutils = {
if (DEBUG_PRINT) serial.println("command.js > mkdir > pathstr = "+path.string);
// check if path is valid
var dirOpened = filesystem.open(CURRENT_DRIVE, path.string, 'W');
var dirOpenedStatus = filesystem.open(CURRENT_DRIVE, path.string, 'W');
var mkdird = filesystem.mkDir(CURRENT_DRIVE);
if (!mkdird) { printerrln("MKDIR failed for '"+path.string+"'"); return; }
if (!mkdird) { printerrln("MKDIR failed for '"+path.string+"'"); return dirOpenedStatus; }
},
cls: function(args) {
con.clear();
@@ -326,8 +326,8 @@ shell.coreutils = {
var pathstr = (args[1] !== undefined) ? args[1] : shell.getPwdString();
// check if path is valid
var pathOpened = filesystem.open(CURRENT_DRIVE, pathstr, 'R');
if (!pathOpened) { printerrln("File not found"); return; }
var pathOpenedStatus = filesystem.open(CURRENT_DRIVE, pathstr, 'R');
if (pathOpenedStatus != 0) { printerrln("File not found"); return pathOpenedStatus; }
var port = filesystem._toPorts(CURRENT_DRIVE)[0]
com.sendMessage(port, "LIST");
@@ -336,8 +336,8 @@ shell.coreutils = {
cat: function(args) {
var pathstr = (args[1] !== undefined) ? args[1] : shell.getPwdString();
var pathOpened = filesystem.open(CURRENT_DRIVE, pathstr, 'R');
if (!pathOpened) { printerrln("File not found"); return; }
var pathOpenedStatus = filesystem.open(CURRENT_DRIVE, pathstr, 'R');
if (pathOpenedStatus != 0) { printerrln("File not found"); return pathOpenedStatus; }
let contents = filesystem.readAll(CURRENT_DRIVE);
// TODO just print out what's there
print(contents);
@@ -381,7 +381,7 @@ shell.execute = function(line) {
serial.println("[command.js > shell.execute] file search path: "+path);
}
if (filesystem.open(CURRENT_DRIVE, path, "R")) {
if (0 == filesystem.open(CURRENT_DRIVE, path, "R")) {
fileExists = true;
break searchLoop;
}

View File

@@ -39,7 +39,7 @@ let bulletinShown = false;
let cursoringCol = 0;
// load existing file if it's there
let editingExistingFile = filesystem.open(driveLetter, filePath, "R");
let editingExistingFile = (0 == filesystem.open(driveLetter, filePath, "R"));
if (editingExistingFile) {
textbuffer = filesystem.readAll(driveLetter).split("\n");
}

View File

@@ -3,10 +3,10 @@ if (exec_args[1] === undefined) {
return 1;
}
let fileOpened = filesystem.open(_G.shell.getCurrentDrive(), _G.shell.resolvePathInput(exec_args[1]).string, "R");
if (!fileOpened) {
let fileOpenedStatus = filesystem.open(_G.shell.getCurrentDrive(), _G.shell.resolvePathInput(exec_args[1]).string, "R");
if (fileOpenedStatus != 0) {
printerrln(_G.shell.resolvePathInput(exec_args[1]).string+": cannot open");
return 1;
return fileOpenedStatus;
}
let fileContent = filesystem.readAll(_G.shell.getCurrentDrive());
let visible = "";

View File

@@ -11,10 +11,10 @@ if (exec_args[1] === undefined) {
let path = _G.shell.resolvePathInput(exec_args[2] || exec_args[1]).string;
let driveLetter = _G.shell.getCurrentDrive();
let noNewFile = (exec_args[1] == "/c" || exec_args[1] == "/C");
let fileOpened = filesystem.open(driveLetter, path, "W");
if (!fileOpened) {
let fileOpenedStatus = filesystem.open(driveLetter, path, "W");
if (fileOpenedStatus != 0) {
printerrln("TOUCH: Can't open "+driveLetter+":\\"+path+" due to IO error");
return 1;
return fileOpenedStatus;
}
if (!noNewFile) {

View File

@@ -4,7 +4,7 @@ TVDOS Graphics Library
Has no affiliation with OpenGL by Khronos Group
*/
var GL = {};
const GL = {};
// bytes should be able to handle both JSArray and Java ByteArray (toString = "[B")?
GL.Texture = function(w, h, bytes) {

View File

@@ -0,0 +1,256 @@
[[""],[undefined],
[undefined],
["<HOME>"],
[undefined],
["<CALL>"],
["<ENDCALL>"],
["0",")"],
["1","!"],
["2","@"],
["3","#"],
["4","$)"],
["5","%"],
["6","^"],
["7","&"],
["8","*"],
["9","("],
["*"],
["#"],
["<UP>"],
["<DOWN>"],
["<LEFT>"],
["<RIGHT>"],
["<CENTER>"],
["<VOL_UP>"],
["<VOL_DOWN>"],
["<POWER>"],
["<CAMERA>"],
["<CLEAR>"],
["a","A"],
["b","B"],
["c","C"],
["s","S"],
["f","F"],
["t","T"],
["d","D"],
["h","H"],
["u","U"],
["n","N"],
["e","E"],
["i","I"],
["m","M"],
["k","K"],
["y","Y"],
[";",":"],
["q","Q"],
["p","P"],
["r","R"],
["g","G"],
["l","L"],
["v","V"],
["w","W"],
["x","X"],
["j","J"],
["z","Z"],
[",","<"],
[".",">"],
["<ALT_L>"],
["<ALT_R>"],
["<SHIFT_L>"],
["<SHIFT_R>"],
["<TAB>"],
[" "],
["<SYM>"],
["<EXPLORER>"],
["<ENVELOPE>"],
["\n"],
["\x08"],
["`","~"],
["-","_"],
["=","+"],
["[","{"],
["]","}"],
["\\","|"],
["o","O"],
["'",'"'],
["/","?"],
["<AT>"],
["<NUM>"],
["<HEADSETHOOK>"],
["<FOCUS>"],
["+"],
["<MENU>"],
["<NOTIFICATION>"],
["<SEARCH>"],
["<PLAY_PAUSE>"],
["<STOP>"],
["<NEXT>"],
["<PREV>"],
["<REW>"],
["<FFWD>"],
["<MUTE>"],
["<PAGE_UP>"],
["<PAGE_DOWN>"],
["<PICTSYMBOLS>"],
["<SW:>TCH_CHARSET>"],
["<:A:>"],
["<:B:>"],
["<:C:>"],
["<:X:>"],
["<:Y:>"],
["<:Z:>"],
["<:L1:>"],
["<:R1:>"],
["<:L2:>"],
["<:R2:>"],
["<:TL:>"],
["<:TR:>"],
["<:START:>"],
["<:SELECT:>"],
["<:MODE:>"],
["<ESC>"],
["<DEL>"],
[undefined],
[undefined],
["<CAPS_LOCK>"],
["<SCROLL_LOCK>"],
[undefined],
[undefined],
[undefined],
["<PRINT_SCREEN_SYS_RQ>"],
["<PAUSE_BREAK>"],
[undefined],
["<END>"],
["<INSERT>"],
[undefined],
[undefined],
[undefined],
[undefined],
["<CTRL_L>"],
["<CTRL_R>"],
["<F1>"],
["<F2>"],
["<F3>"],
["<F4>"],
["<F5>"],
["<F6>"],
["<F7>"],
["<F8>"],
["<F9>"],
["<F10>"],
["<F11>"],
["<F12>"],
["<NUM_LOCK>"],
["0"],
["1"],
["2"],
["3"],
["4"],
["5"],
["6"],
["7"],
["8"],
["9"],
["/"],
["*"],
["-"],
["+"],
["."],
["."],
["\n"],
["="],
["("],
[")"],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
["<:CIRCLE:>"]
]

View File

@@ -0,0 +1,256 @@
[[""],[undefined],
[undefined],
["<HOME>"],
[undefined],
["<CALL>"],
["<ENDCALL>"],
["0",")"],
["1","!"],
["2","@"],
["3","#"],
["4","$)"],
["5","%"],
["6","^"],
["7","&"],
["8","*"],
["9","("],
["*"],
["#"],
["<UP>"],
["<DOWN>"],
["<LEFT>"],
["<RIGHT>"],
["<CENTER>"],
["<VOL_UP>"],
["<VOL_DOWN>"],
["<POWER>"],
["<CAMERA>"],
["<CLEAR>"],
["a","A"],
["b","B"],
["c","C"],
["d","D"],
["e","E"],
["f","F"],
["g","G"],
["h","H"],
["i","I"],
["j","J"],
["k","K"],
["l","L"],
["m","M"],
["n","N"],
["o","O"],
["p","P"],
["q","Q"],
["r","R"],
["s","S"],
["t","T"],
["u","U"],
["v","V"],
["w","W"],
["x","X"],
["y","Y"],
["z","Z"],
[",","<"],
[".",">"],
["<ALT_L>"],
["<ALT_R>"],
["<SHIFT_L>"],
["<SHIFT_R>"],
["<TAB>"],
[" "],
["<SYM>"],
["<EXPLORER>"],
["<ENVELOPE>"],
["\n"],
["\x08"],
["`","~"],
["-","_"],
["=","+"],
["[","{"],
["]","}"],
["\\","|"],
[";",":"],
["'",'"'],
["/","?"],
["<AT>"],
["<NUM>"],
["<HEADSETHOOK>"],
["<FOCUS>"],
["+"],
["<MENU>"],
["<NOTIFICATION>"],
["<SEARCH>"],
["<PLAY_PAUSE>"],
["<STOP>"],
["<NEXT>"],
["<PREV>"],
["<REW>"],
["<FFWD>"],
["<MUTE>"],
["<PAGE_UP>"],
["<PAGE_DOWN>"],
["<PICTSYMBOLS>"],
["<SW:>TCH_CHARSET>"],
["<:A:>"],
["<:B:>"],
["<:C:>"],
["<:X:>"],
["<:Y:>"],
["<:Z:>"],
["<:L1:>"],
["<:R1:>"],
["<:L2:>"],
["<:R2:>"],
["<:TL:>"],
["<:TR:>"],
["<:START:>"],
["<:SELECT:>"],
["<:MODE:>"],
["<ESC>"],
["<DEL>"],
[undefined],
[undefined],
["<CAPS_LOCK>"],
["<SCROLL_LOCK>"],
[undefined],
[undefined],
[undefined],
["<PRINT_SCREEN_SYS_RQ>"],
["<PAUSE_BREAK>"],
[undefined],
["<END>"],
["<INSERT>"],
[undefined],
[undefined],
[undefined],
[undefined],
["<CTRL_L>"],
["<CTRL_R>"],
["<F1>"],
["<F2>"],
["<F3>"],
["<F4>"],
["<F5>"],
["<F6>"],
["<F7>"],
["<F8>"],
["<F9>"],
["<F10>"],
["<F11>"],
["<F12>"],
["<NUM_LOCK>"],
["0"],
["1"],
["2"],
["3"],
["4"],
["5"],
["6"],
["7"],
["8"],
["9"],
["/"],
["*"],
["-"],
["+"],
["."],
["."],
["\n"],
["="],
["("],
[")"],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
[undefined],
["<:CIRCLE:>"]
]