mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-06-06 05:28:31 +09:00
TVDOS: userconfigpath and zfmrc
This commit is contained in:
@@ -3,6 +3,7 @@ echo "Starting TVDOS..."
|
|||||||
rem put set-xxx commands here:
|
rem put set-xxx commands here:
|
||||||
set PATH=\tvdos\installer;\tvdos\tuidev;\tbas;\hopper\bin;$PATH
|
set PATH=\tvdos\installer;\tvdos\tuidev;\tbas;\hopper\bin;$PATH
|
||||||
set INCLPATH=\hopper\include;$INCLPATH
|
set INCLPATH=\hopper\include;$INCLPATH
|
||||||
|
set HELPPATH=\hopper\help;$HELPPATH
|
||||||
set KEYBOARD=us_colemak
|
set KEYBOARD=us_colemak
|
||||||
|
|
||||||
rem this line specifies which shell to be presented after the boot precess:
|
rem this line specifies which shell to be presented after the boot precess:
|
||||||
|
|||||||
@@ -151,7 +151,8 @@ _TVDOS.variables = {
|
|||||||
PATHEXT: ".com;.bat;.app;.js;.alias",
|
PATHEXT: ".com;.bat;.app;.js;.alias",
|
||||||
HELPPATH: "\\tvdos\\help",
|
HELPPATH: "\\tvdos\\help",
|
||||||
OS_NAME: "TSVM Disk Operating System",
|
OS_NAME: "TSVM Disk Operating System",
|
||||||
OS_VERSION: _TVDOS.VERSION
|
OS_VERSION: _TVDOS.VERSION,
|
||||||
|
USERCONFIGPATH: "\\home\\config",
|
||||||
};
|
};
|
||||||
Object.freeze(_TVDOS);
|
Object.freeze(_TVDOS);
|
||||||
|
|
||||||
|
|||||||
@@ -823,17 +823,26 @@ shell.execute = function(line, nameOverride) {
|
|||||||
// parse alias
|
// parse alias
|
||||||
// $0: all arguments
|
// $0: all arguments
|
||||||
// $1..9: specific arguments
|
// $1..9: specific arguments
|
||||||
|
// Tokens that contain whitespace or shell metacharacters must be re-quoted
|
||||||
|
// before re-execution, otherwise the re-parse splits them on spaces.
|
||||||
|
var quoteAliasArg = function(s) {
|
||||||
|
if (s === undefined || s === null) return ""
|
||||||
|
s = ''+s
|
||||||
|
if (s.length === 0) return ""
|
||||||
|
if (/[\s"|><&]/.test(s)) return '"' + s.replaceAll('"', '^"') + '"'
|
||||||
|
return s
|
||||||
|
}
|
||||||
var lines = programCode.split('\n').filter(function(it) { return it.length > 0 }) // this return is not shell's return!
|
var lines = programCode.split('\n').filter(function(it) { return it.length > 0 }) // this return is not shell's return!
|
||||||
lines.forEach(function(line) {
|
lines.forEach(function(line) {
|
||||||
var newLine = line
|
var newLine = line
|
||||||
|
|
||||||
// replace $1..$9
|
// replace $1..$9
|
||||||
for (let j = 1; j < 9; j++) {
|
for (let j = 1; j <= 9; j++) {
|
||||||
newLine = newLine.replaceAll('$'+j, tokens[j])
|
newLine = newLine.replaceAll('$'+j, quoteAliasArg(tokens[j]))
|
||||||
}
|
}
|
||||||
|
|
||||||
// replace $0
|
// replace $0
|
||||||
newLine = newLine.replaceAll('$0', tokens.slice(1).join(' '))
|
newLine = newLine.replaceAll('$0', tokens.slice(1).map(quoteAliasArg).join(' '))
|
||||||
|
|
||||||
shell.execute(newLine, cmd)
|
shell.execute(newLine, cmd)
|
||||||
})
|
})
|
||||||
@@ -955,6 +964,18 @@ _G.shell = shell
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// ensure USERCONFIGPATH directory exists
|
||||||
|
try {
|
||||||
|
let userConfigPath = `${CURRENT_DRIVE}:${_TVDOS.variables.USERCONFIGPATH}`
|
||||||
|
let userConfigDir = files.open(userConfigPath)
|
||||||
|
if (!userConfigDir.exists) {
|
||||||
|
debugprintln(`command.js > creating USERCONFIGPATH at ${userConfigPath}`)
|
||||||
|
userConfigDir.mkDir()
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
debugprintln("command.js > USERCONFIGPATH creation failed: " + e.message)
|
||||||
|
}
|
||||||
|
|
||||||
if (exec_args[1] !== undefined) {
|
if (exec_args[1] !== undefined) {
|
||||||
// only meaningful switches would be either -c or -k anyway
|
// only meaningful switches would be either -c or -k anyway
|
||||||
var firstSwitch = exec_args[1].toLowerCase()
|
var firstSwitch = exec_args[1].toLowerCase()
|
||||||
|
|||||||
@@ -307,7 +307,7 @@ for (let i = 0; i < cueElements.length; i++) {
|
|||||||
// Execute the player with modified environment
|
// Execute the player with modified environment
|
||||||
exec_args[1] = targetPath
|
exec_args[1] = targetPath
|
||||||
if (playerFile) {
|
if (playerFile) {
|
||||||
let playerPath = `A:\\tvdos\\bin\\${playerFile}.js`
|
let playerPath = `A:${_TVDOS.variables.DOSDIR}/bin/${playerFile}.js`
|
||||||
if (files.open(playerPath).exists) {
|
if (files.open(playerPath).exists) {
|
||||||
eval(files.readText(playerPath))
|
eval(files.readText(playerPath))
|
||||||
} else {
|
} else {
|
||||||
@@ -334,7 +334,7 @@ for (let i = 0; i < cueElements.length; i++) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Execute the appropriate player
|
// Execute the appropriate player
|
||||||
let playerPath = `A:\\tvdos\\bin\\${playerFile}.js`
|
let playerPath = `A:${_TVDOS.variables.DOSDIR}/bin/${playerFile}.js`
|
||||||
if (!files.open(playerPath).exists) {
|
if (!files.open(playerPath).exists) {
|
||||||
serial.println(`Warning: Player script not found: ${playerPath}`)
|
serial.println(`Warning: Player script not found: ${playerPath}`)
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -1745,18 +1745,18 @@ if (fullPathObj === undefined) {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
const logofile = files.open("A:/tvdos/bin/tauthdr.r8")
|
const logofile = files.open("A:"+_TVDOS.variables.DOSDIR+"/bin/tauthdr.r8")
|
||||||
const logoBytes = logofile.bread(); logofile.close()
|
const logoBytes = logofile.bread(); logofile.close()
|
||||||
const logoTexture = new gl.Texture(92, 14, logoBytes)
|
const logoTexture = new gl.Texture(92, 14, logoBytes)
|
||||||
const buttonfile = files.open("A:/tvdos/bin/tautbtn.r8")
|
const buttonfile = files.open("A:"+_TVDOS.variables.DOSDIR+"/bin/tautbtn.r8")
|
||||||
const buttonBytes = buttonfile.bread(); buttonfile.close()
|
const buttonBytes = buttonfile.bread(); buttonfile.close()
|
||||||
const buttonTexture = new gl.Texture(2, 28, buttonBytes)
|
const buttonTexture = new gl.Texture(2, 28, buttonBytes)
|
||||||
//const buttonNullfile = files.open("A:/tvdos/bin/tautbtn0.r8")
|
//const buttonNullfile = files.open("A:"+_TVDOS.variables.DOSDIR+"/bin/tautbtn0.r8")
|
||||||
//const buttonNullBytes = buttonNullfile.bread(); buttonNullfile.close()
|
//const buttonNullBytes = buttonNullfile.bread(); buttonNullfile.close()
|
||||||
//const buttonNullTexture = new gl.Texture(35, 28, buttonNullBytes)
|
//const buttonNullTexture = new gl.Texture(35, 28, buttonNullBytes)
|
||||||
|
|
||||||
font.setLowRom("A:/tvdos/bin/tautfont_low.chr")
|
font.setLowRom("A:"+_TVDOS.variables.DOSDIR+"/bin/tautfont_low.chr")
|
||||||
font.setHighRom("A:/tvdos/bin/tautfont_high.chr")
|
font.setHighRom("A:"+_TVDOS.variables.DOSDIR+"/bin/tautfont_high.chr")
|
||||||
const songsMeta = loadTaudSongList(fullPathObj.full)
|
const songsMeta = loadTaudSongList(fullPathObj.full)
|
||||||
let currentSongIndex = 0
|
let currentSongIndex = 0
|
||||||
let projectSongCursor = 0
|
let projectSongCursor = 0
|
||||||
|
|||||||
@@ -69,6 +69,55 @@ const EXEC_FUNS = {
|
|||||||
"taud": (f) => _G.shell.execute(`microtone "${f}"`),
|
"taud": (f) => _G.shell.execute(`microtone "${f}"`),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function makeExecFun(template) {
|
||||||
|
return (f) => _G.shell.execute(template.replaceAll("{0}", `"${f}"`))
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadZfmrc() {
|
||||||
|
try {
|
||||||
|
let zfmrcPath = `A:${_TVDOS.variables.USERCONFIGPATH}\\zfmrc`
|
||||||
|
let zfmrcFile = files.open(zfmrcPath)
|
||||||
|
if (!zfmrcFile.exists) return
|
||||||
|
|
||||||
|
let content = zfmrcFile.sread()
|
||||||
|
let lines = content.split(/\r?\n/)
|
||||||
|
let currentSection = null
|
||||||
|
|
||||||
|
for (let i = 0; i < lines.length; i++) {
|
||||||
|
let line = lines[i].trim()
|
||||||
|
if (line.length === 0 || line.startsWith("#") || line.startsWith(";")) continue
|
||||||
|
|
||||||
|
if (line.startsWith("[") && line.endsWith("]")) {
|
||||||
|
currentSection = line.substring(1, line.length - 1).toUpperCase()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentSection === "EXEC_FUNS") {
|
||||||
|
let commaIdx = line.indexOf(",")
|
||||||
|
if (commaIdx < 0) continue
|
||||||
|
let ext = line.substring(0, commaIdx).trim().toLowerCase()
|
||||||
|
let template = line.substring(commaIdx + 1).trim()
|
||||||
|
if (ext.length === 0 || template.length === 0) continue
|
||||||
|
EXEC_FUNS[ext] = makeExecFun(template)
|
||||||
|
}
|
||||||
|
else if (currentSection === "COL_HL_EXT") {
|
||||||
|
let commaIdx = line.indexOf(",")
|
||||||
|
if (commaIdx < 0) continue
|
||||||
|
let ext = line.substring(0, commaIdx).trim().toLowerCase()
|
||||||
|
let colStr = line.substring(commaIdx + 1).trim()
|
||||||
|
if (ext.length === 0 || colStr.length === 0) continue
|
||||||
|
let col = parseInt(colStr, 10)
|
||||||
|
if (isNaN(col)) continue
|
||||||
|
COL_HL_EXT[ext] = col
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
serial.println("zfm: failed to load zfmrc: " + e.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loadZfmrc()
|
||||||
|
|
||||||
let windowMode = 0 // 0 == left, 1 == right
|
let windowMode = 0 // 0 == left, 1 == right
|
||||||
let windowFocus = [0] // is a stack; 0: files window, 1: palette window, 2: popup window
|
let windowFocus = [0] // is a stack; 0: files window, 1: palette window, 2: popup window
|
||||||
|
|
||||||
@@ -82,6 +131,7 @@ let cursor = [0, 0] // absolute position!
|
|||||||
|
|
||||||
function bytesToReadable(i) {
|
function bytesToReadable(i) {
|
||||||
return ''+ (
|
return ''+ (
|
||||||
|
(i > 999999999999) ? (((i / 10000000000)|0)/100 + "T") :
|
||||||
(i > 999999999) ? (((i / 10000000)|0)/100 + "G") :
|
(i > 999999999) ? (((i / 10000000)|0)/100 + "G") :
|
||||||
(i > 999999) ? (((i / 10000)|0)/100 + "M") :
|
(i > 999999) ? (((i / 10000)|0)/100 + "M") :
|
||||||
(i > 9999) ? (((i / 100)|0)/10 + "K") :
|
(i > 9999) ? (((i / 100)|0)/10 + "K") :
|
||||||
@@ -677,11 +727,11 @@ while (!exit) {
|
|||||||
let keysym = event[1]
|
let keysym = event[1]
|
||||||
let keyJustHit = (1 == event[2])
|
let keyJustHit = (1 == event[2])
|
||||||
|
|
||||||
if (keyJustHit && event[3] != keys.ENTER) { // release the latch right away if the key is not Return
|
if (keyJustHit && event[3] != keys.ENTER && keysym != "q") { // release the latch right away if the key is neither Return nor 'q'
|
||||||
firstRunLatch = false
|
firstRunLatch = false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keyJustHit && firstRunLatch) { // filter out the initial ENTER key as they would cause unwanted behaviours
|
if (keyJustHit && firstRunLatch) { // filter out the initial ENTER/'q' key as they would cause unwanted behaviours
|
||||||
firstRunLatch = false
|
firstRunLatch = false
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
Reference in New Issue
Block a user