mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-03-07 11:51:49 +09:00
lfs -c impl; tvdos app spec change
This commit is contained in:
@@ -40,9 +40,9 @@ if (targetOS != 1 && targetOS != 0) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function strToInt48(str) {
|
function strToInt32(str) {
|
||||||
let s = [...str].map(it=>it.charCodeAt(0))
|
let s = [...str].map(it=>it.charCodeAt(0))
|
||||||
return ((4294967296 + (s[0] << 40)) + (s[1] << 32) + (s[2] << 24) + (s[3] << 16) + (s[4] << 8) + s[5]) - 4294967296
|
return (s[0] << 24) + (s[1] << 16) + (s[2] << 8) + s[3]
|
||||||
|
|
||||||
}
|
}
|
||||||
function makeHash(length) {
|
function makeHash(length) {
|
||||||
@@ -63,8 +63,8 @@ let sectionTable = []
|
|||||||
let rodata = {}
|
let rodata = {}
|
||||||
|
|
||||||
for (let i = 0; i < sectionCount; i++) {
|
for (let i = 0; i < sectionCount; i++) {
|
||||||
let sectName = filebytes.substring(16 * (i+1), 16 * (i+1) + 10).trimNull()
|
let sectName = filebytes.substring(16 * (i+1), 16 * (i+1) + 12).trimNull()
|
||||||
let sectOffset = strToInt48(filebytes.substring(16 * (i+1) + 10, 16 * (i+1) + 16))
|
let sectOffset = strToInt32(filebytes.substring(16 * (i+1) + 12, 16 * (i+1) + 16))
|
||||||
sectionTable.push([sectName, sectOffset])
|
sectionTable.push([sectName, sectOffset])
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,17 +72,17 @@ for (let i = 0; i < sectionTable.length - 1; i++) {
|
|||||||
let [sectName, sectOffset] = sectionTable[i]
|
let [sectName, sectOffset] = sectionTable[i]
|
||||||
let nextSectOffset = sectionTable[i+1][1]
|
let nextSectOffset = sectionTable[i+1][1]
|
||||||
|
|
||||||
let uncompLen = strToInt48(filebytes.substring(sectOffset, sectOffset + 6))
|
let uncompLen = strToInt32(filebytes.substring(sectOffset, sectOffset + 4))
|
||||||
let compPayload = filebytes.substring(sectOffset + 6, nextSectOffset)
|
let compPayload = filebytes.substring(sectOffset + 4, nextSectOffset)
|
||||||
|
|
||||||
if ("RODATA" == sectName) {
|
if ("RODATA" == sectName) {
|
||||||
let rodataPtr = 0
|
let rodataPtr = 0
|
||||||
while (rodataPtr < nextSectOffset - sectOffset) {
|
while (rodataPtr < nextSectOffset - sectOffset) {
|
||||||
let labelLen = filebytes.charCodeAt(sectOffset + rodataPtr)
|
let labelLen = filebytes.charCodeAt(sectOffset + rodataPtr)
|
||||||
let label = filebytes.substring(sectOffset + rodataPtr + 1, sectOffset + rodataPtr + 1 + labelLen)
|
let label = filebytes.substring(sectOffset + rodataPtr + 1, sectOffset + rodataPtr + 1 + labelLen)
|
||||||
let payloadLen = strToInt48(filebytes.substring(sectOffset + rodataPtr + 1 + labelLen, sectOffset + rodataPtr + 1 + labelLen + 6))
|
let payloadLen = strToInt32(filebytes.substring(sectOffset + rodataPtr + 1 + labelLen, sectOffset + rodataPtr + 1 + labelLen + 4))
|
||||||
let uncompLen = strToInt48(filebytes.substring(sectOffset + rodataPtr + 1 + labelLen + 6, sectOffset + rodataPtr + 1 + labelLen + 12))
|
let uncompLen = strToInt32(filebytes.substring(sectOffset + rodataPtr + 1 + labelLen + 4, sectOffset + rodataPtr + 1 + labelLen + 8))
|
||||||
let sectPayload = filebytes.substring(sectOffset + rodataPtr + 1 + labelLen + 12, sectOffset + rodataPtr + 1 + labelLen + 12 + payloadLen)
|
let sectPayload = filebytes.substring(sectOffset + rodataPtr + 1 + labelLen + 8, sectOffset + rodataPtr + 1 + labelLen + 8 + payloadLen)
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -96,11 +96,11 @@ for (let i = 0; i < sectionTable.length - 1; i++) {
|
|||||||
|
|
||||||
decompFun(payload)
|
decompFun(payload)
|
||||||
|
|
||||||
rodataPtr += 13 + labelLen + payloadLen
|
rodataPtr += 9 + labelLen + payloadLen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ("TEXT" == sectName) {
|
else if ("TEXT" == sectName) {
|
||||||
let program = String.fromCharCode.apply(null, decompFun(compPayload))
|
let program = btostr(decompFun(compPayload))
|
||||||
|
|
||||||
// inject RODATA map
|
// inject RODATA map
|
||||||
let rodataSnippet = `const __RODATA=Object.freeze(${JSON.stringify(rodata)});`
|
let rodataSnippet = `const __RODATA=Object.freeze(${JSON.stringify(rodata)});`
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ To list the collected files:
|
|||||||
lfs -t`)
|
lfs -t`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const option = exec_args[1]
|
let option = exec_args[1]
|
||||||
const lfsPath = exec_args[2]
|
const lfsPath = exec_args[2]
|
||||||
const dirPath = exec_args[3]
|
const dirPath = exec_args[3]
|
||||||
|
|
||||||
@@ -19,3 +19,70 @@ if (option === undefined || lfsPath === undefined || option.toUpperCase() != "-T
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
option = option.toUpperCase()
|
||||||
|
|
||||||
|
|
||||||
|
function recurseDir(file, action) {
|
||||||
|
if (!file.isDirectory) {
|
||||||
|
action(file)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
file.list().forEach(fd => {
|
||||||
|
recurseDir(fd, action)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const lfsFile = files.open(_G.shell.resolvePathInput(lfsPath).full)
|
||||||
|
const rootDir = files.open(_G.shell.resolvePathInput(dirPath).full)
|
||||||
|
|
||||||
|
const rootDirPathLen = rootDir.fullPath.length
|
||||||
|
|
||||||
|
if ("-C" == option) {
|
||||||
|
if (!rootDir.exists) {
|
||||||
|
printerrln(`No such directory: ${rootDir.fullPath}`)
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
let out = "TVDOSLFS\x01\x00\x00\x00\x00\x00\x00\x00"
|
||||||
|
|
||||||
|
recurseDir(rootDir, file=>{
|
||||||
|
let f = files.open(file.fullPath)
|
||||||
|
let flen = f.size
|
||||||
|
let fname = file.fullPath.substring(rootDirPathLen + 1)
|
||||||
|
let plen = fname.length
|
||||||
|
|
||||||
|
out += "\x01" + String.fromCharCode(
|
||||||
|
(plen >>> 8) & 255,
|
||||||
|
plen & 255
|
||||||
|
)
|
||||||
|
|
||||||
|
out += fname
|
||||||
|
|
||||||
|
out += String.fromCharCode(
|
||||||
|
(flen >>> 24) & 255,
|
||||||
|
(flen >>> 16) & 255,
|
||||||
|
(flen >>> 8) & 255,
|
||||||
|
flen & 255
|
||||||
|
)
|
||||||
|
|
||||||
|
out += f.sread()
|
||||||
|
})
|
||||||
|
|
||||||
|
lfsFile.swrite(out)
|
||||||
|
}
|
||||||
|
else if ("T" == option || "-X" == option) {
|
||||||
|
if (!lfsFile.exists) {
|
||||||
|
printerrln(`No such file: ${lfsFile.fullPath}`)
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TODO()
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printerrln("Unknown option: " + option)
|
||||||
|
return 2
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user