mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-03-17 00:16:04 +09:00
profile.json rw wip
This commit is contained in:
@@ -0,0 +1,91 @@
|
|||||||
|
package net.torvald.terrarum.utils
|
||||||
|
|
||||||
|
import com.badlogic.gdx.utils.JsonReader
|
||||||
|
import com.badlogic.gdx.utils.JsonValue
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by minjaesong on 2016-02-15.
|
||||||
|
*/
|
||||||
|
object JsonFetcher {
|
||||||
|
|
||||||
|
private var jsonString: StringBuffer? = null
|
||||||
|
|
||||||
|
@Throws(java.io.IOException::class)
|
||||||
|
operator fun invoke(jsonFilePath: String): JsonValue {
|
||||||
|
jsonString = StringBuffer() // reset buffer every time it called
|
||||||
|
readJsonFileAsString(jsonFilePath)
|
||||||
|
|
||||||
|
// printdbg(this, "Reading JSON $jsonFilePath")
|
||||||
|
|
||||||
|
if (jsonString == null) {
|
||||||
|
throw Error("[JsonFetcher] jsonString is null!")
|
||||||
|
}
|
||||||
|
|
||||||
|
return JsonReader().parse(jsonString.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(java.io.IOException::class)
|
||||||
|
operator fun invoke(jsonFile: java.io.File): JsonValue {
|
||||||
|
jsonString = StringBuffer() // reset buffer every time it called
|
||||||
|
readJsonFileAsString(jsonFile.canonicalPath)
|
||||||
|
|
||||||
|
// printdbg(this, "Reading JSON ${jsonFile.path}")
|
||||||
|
|
||||||
|
if (jsonString == null) {
|
||||||
|
throw Error("[JsonFetcher] jsonString is null!")
|
||||||
|
}
|
||||||
|
|
||||||
|
return JsonReader().parse(jsonString.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(java.io.IOException::class)
|
||||||
|
private fun readJsonFileAsString(path: String) {
|
||||||
|
java.nio.file.Files.lines(java.nio.file.FileSystems.getDefault().getPath(path)).forEach(
|
||||||
|
{ jsonString!!.append(it) }
|
||||||
|
) // JSON does not require line break
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterates [JsonValue] over its siblings.
|
||||||
|
*
|
||||||
|
* @param map JsonValue to iterate over
|
||||||
|
* @param action A `function(`Name of the sibling or a stringified integer if the `map` is an array`, `JsonValue representation of the sibling`)` -> `Unit`
|
||||||
|
*/
|
||||||
|
fun forEachSiblings(map: JsonValue, action: (String, JsonValue) -> Unit) {
|
||||||
|
var counter = 0
|
||||||
|
var entry = map.child
|
||||||
|
while (entry != null) {
|
||||||
|
action(entry.name ?: "$counter", entry)
|
||||||
|
entry = entry.next
|
||||||
|
counter += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterates [JsonValue] over its siblings.
|
||||||
|
*
|
||||||
|
* @param map JsonValue to iterate over
|
||||||
|
* @param action A `function(index, `Name of the sibling or a stringified integer if the `map` is an array`, `JsonValue representation of the sibling`)` -> `Unit`
|
||||||
|
*/
|
||||||
|
fun forEachSiblingsIndexed(map: JsonValue, action: (Int, String, JsonValue) -> Unit) {
|
||||||
|
var counter = 0
|
||||||
|
var entry = map.child
|
||||||
|
while (entry != null) {
|
||||||
|
action(counter, entry.name ?: "$counter", entry)
|
||||||
|
entry = entry.next
|
||||||
|
counter += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterates [JsonValue] over its siblings.
|
||||||
|
* @param action A function(`Name of the sibling or a stringified integer if the `map` is an array`, `JsonValue representation of the sibling`)` -> `Unit`
|
||||||
|
*/
|
||||||
|
fun JsonValue.forEachSiblings(action: (String, JsonValue) -> Unit) = JsonFetcher.forEachSiblings(this, action)
|
||||||
|
/**
|
||||||
|
* Iterates [JsonValue] over its siblings.
|
||||||
|
* @param action A `function(index, `Name of the sibling or a stringified integer if the `map` is an array`, `JsonValue representation of the sibling`)` -> `Unit`
|
||||||
|
*/
|
||||||
|
fun JsonValue.forEachSiblingsIndexed(action: (Int, String, JsonValue) -> Unit) = JsonFetcher.forEachSiblingsIndexed(this, action)
|
||||||
32
tsvm_executable/src/net/torvald/tsvm/ProfileSerialiser.kt
Normal file
32
tsvm_executable/src/net/torvald/tsvm/ProfileSerialiser.kt
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
package net.torvald.tsvm
|
||||||
|
|
||||||
|
import com.badlogic.gdx.utils.Json
|
||||||
|
import com.badlogic.gdx.utils.JsonValue
|
||||||
|
import com.badlogic.gdx.utils.JsonWriter
|
||||||
|
import java.math.BigInteger
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by minjaesong on 2022-10-27.
|
||||||
|
*/
|
||||||
|
object ProfileSerialiser {
|
||||||
|
|
||||||
|
val jsoner = Json(JsonWriter.OutputType.json)
|
||||||
|
|
||||||
|
init {
|
||||||
|
jsoner.ignoreUnknownFields = true
|
||||||
|
jsoner.setUsePrototypes(false)
|
||||||
|
jsoner.setIgnoreDeprecated(false)
|
||||||
|
|
||||||
|
// BigInteger
|
||||||
|
jsoner.setSerializer(BigInteger::class.java, object : Json.Serializer<BigInteger> {
|
||||||
|
override fun write(json: Json, obj: BigInteger?, knownType: Class<*>?) {
|
||||||
|
json.writeValue(obj?.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun read(json: Json, jsonData: JsonValue, type: Class<*>?): BigInteger? {
|
||||||
|
return if (jsonData.isNull) null else BigInteger(jsonData.asString())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,22 +2,22 @@ package net.torvald.tsvm
|
|||||||
|
|
||||||
import com.badlogic.gdx.ApplicationAdapter
|
import com.badlogic.gdx.ApplicationAdapter
|
||||||
import com.badlogic.gdx.Gdx
|
import com.badlogic.gdx.Gdx
|
||||||
|
import com.badlogic.gdx.files.FileHandle
|
||||||
import com.badlogic.gdx.graphics.*
|
import com.badlogic.gdx.graphics.*
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
import com.badlogic.gdx.utils.Json
|
|
||||||
import com.badlogic.gdx.utils.JsonReader
|
import com.badlogic.gdx.utils.JsonReader
|
||||||
import com.badlogic.gdx.utils.JsonValue
|
import com.badlogic.gdx.utils.JsonValue
|
||||||
|
import com.badlogic.gdx.utils.JsonWriter
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.cancel
|
import kotlinx.coroutines.cancel
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import net.torvald.terrarum.FlippingSpriteBatch
|
import net.torvald.terrarum.FlippingSpriteBatch
|
||||||
import net.torvald.terrarum.imagefont.TinyAlphNum
|
import net.torvald.terrarum.imagefont.TinyAlphNum
|
||||||
|
import net.torvald.terrarum.utils.JsonFetcher
|
||||||
import net.torvald.tsvm.VMEmuExecutableWrapper.Companion.FONT
|
import net.torvald.tsvm.VMEmuExecutableWrapper.Companion.FONT
|
||||||
import net.torvald.tsvm.VMEmuExecutableWrapper.Companion.SQTEX
|
import net.torvald.tsvm.VMEmuExecutableWrapper.Companion.SQTEX
|
||||||
import net.torvald.tsvm.peripheral.*
|
import net.torvald.tsvm.peripheral.*
|
||||||
import java.io.File
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class VMEmuExecutableWrapper(val windowWidth: Int, val windowHeight: Int, var panelsX: Int, var panelsY: Int, val diskPathRoot: String) : ApplicationAdapter() {
|
class VMEmuExecutableWrapper(val windowWidth: Int, val windowHeight: Int, var panelsX: Int, var panelsY: Int, val diskPathRoot: String) : ApplicationAdapter() {
|
||||||
|
|
||||||
@@ -77,6 +77,17 @@ class VMEmuExecutable(val windowWidth: Int, val windowHeight: Int, var panelsX:
|
|||||||
var vmRunners = HashMap<Int, VMRunner>() // <VM's identifier, VMRunner>
|
var vmRunners = HashMap<Int, VMRunner>() // <VM's identifier, VMRunner>
|
||||||
var coroutineJobs = HashMap<Int, Job>() // <VM's identifier, Job>
|
var coroutineJobs = HashMap<Int, Job>() // <VM's identifier, Job>
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val APPDATADIR = System.getProperty("os.name").toUpperCase().let {
|
||||||
|
if (it.contains("WIN")) System.getenv("APPDATA") + "/tsvmdevenv"
|
||||||
|
else if (it.contains("OS X") || it.contains("MACOS")) System.getProperty("user.home") + "/Library/Application Support/tsvmdevenv"
|
||||||
|
else System.getProperty("user.home") + "/.tsvmdevenv"
|
||||||
|
}
|
||||||
|
|
||||||
|
val FILE_CONFIG = Gdx.files.absolute("$APPDATADIR/config.json")
|
||||||
|
val FILE_PROFILES = Gdx.files.absolute("$APPDATADIR/profiles.json")
|
||||||
|
}
|
||||||
|
|
||||||
val fullscreenQuad = Mesh(
|
val fullscreenQuad = Mesh(
|
||||||
true, 4, 6,
|
true, 4, 6,
|
||||||
VertexAttribute.Position(),
|
VertexAttribute.Position(),
|
||||||
@@ -84,6 +95,26 @@ class VMEmuExecutable(val windowWidth: Int, val windowHeight: Int, var panelsX:
|
|||||||
VertexAttribute.TexCoords(0)
|
VertexAttribute.TexCoords(0)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val profiles = HashMap<String, JsonValue>()
|
||||||
|
|
||||||
|
fun writeProfilesToFile(outFile: FileHandle) {
|
||||||
|
val out = StringBuilder()
|
||||||
|
out.append('{')
|
||||||
|
|
||||||
|
profiles.forEach { name, jsonValue ->
|
||||||
|
out.append("\"$name\":{")
|
||||||
|
out.append(jsonValue.toJson(JsonWriter.OutputType.json))
|
||||||
|
out.append("},")
|
||||||
|
}
|
||||||
|
|
||||||
|
out.deleteCharAt(out.lastIndex).append('}')
|
||||||
|
|
||||||
|
val outstr = out.toString()
|
||||||
|
println(outstr)
|
||||||
|
|
||||||
|
outFile.writeString(outstr, false)
|
||||||
|
}
|
||||||
|
|
||||||
override fun create() {
|
override fun create() {
|
||||||
super.create()
|
super.create()
|
||||||
|
|
||||||
@@ -98,6 +129,18 @@ class VMEmuExecutable(val windowWidth: Int, val windowHeight: Int, var panelsX:
|
|||||||
fbatch.projectionMatrix = camera.combined
|
fbatch.projectionMatrix = camera.combined
|
||||||
|
|
||||||
|
|
||||||
|
// create profiles.json if the file is not there
|
||||||
|
if (!FILE_PROFILES.exists()) {
|
||||||
|
FILE_PROFILES.writeString("{${defaultProfile}}", false)
|
||||||
|
}
|
||||||
|
// read profiles
|
||||||
|
JsonFetcher(FILE_PROFILES.file()).let {
|
||||||
|
JsonFetcher.forEachSiblings(it) { profileName, profileJson ->
|
||||||
|
profiles[profileName] = profileJson
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// install the default VM on slot 0
|
// install the default VM on slot 0
|
||||||
/*val vm = VM("./assets", 8192 shl 10, TheRealWorld(), arrayOf(TsvmBios), 8)
|
/*val vm = VM("./assets", 8192 shl 10, TheRealWorld(), arrayOf(TsvmBios), 8)
|
||||||
vm.getIO().blockTransferPorts[0].attachDevice(TestDiskDrive(vm, 0, File("assets/disk0")))
|
vm.getIO().blockTransferPorts[0].attachDevice(TestDiskDrive(vm, 0, File("assets/disk0")))
|
||||||
@@ -326,8 +369,6 @@ class VMEmuExecutable(val windowWidth: Int, val windowHeight: Int, var panelsX:
|
|||||||
private val tabPos = (menuTabs + "").mapIndexed { index, _ -> 1 + menuTabs.subList(0, index).sumBy { it.length } + 2 * index }
|
private val tabPos = (menuTabs + "").mapIndexed { index, _ -> 1 + menuTabs.subList(0, index).sumBy { it.length } + 2 * index }
|
||||||
private val tabs = listOf(ProfilesMenu(menuTabW, menuTabH))
|
private val tabs = listOf(ProfilesMenu(menuTabW, menuTabH))
|
||||||
private var menuTabSel = 0
|
private var menuTabSel = 0
|
||||||
private val profilesPath = "profiles.json"
|
|
||||||
private val configPath = "config.json"
|
|
||||||
|
|
||||||
private fun drawMenu(batch: SpriteBatch, x: Float, y: Float) {
|
private fun drawMenu(batch: SpriteBatch, x: Float, y: Float) {
|
||||||
batch.inUse {
|
batch.inUse {
|
||||||
@@ -388,9 +429,9 @@ class VMEmuExecutable(val windowWidth: Int, val windowHeight: Int, var panelsX:
|
|||||||
"ramsize":8388608,
|
"ramsize":8388608,
|
||||||
"cardslots":8,
|
"cardslots":8,
|
||||||
"roms":["./assets/bios/tsvmbios.js"],
|
"roms":["./assets/bios/tsvmbios.js"],
|
||||||
"com1":{"class":"net.torvald.tsvm.peripheral.TestDiskDrive", "args":[0, "./assets/disk0/"]},
|
"com1":{"cls":"net.torvald.tsvm.peripheral.TestDiskDrive", "args":[0, "./assets/disk0/"]},
|
||||||
"com2":{"class":"net.torvald.tsvm.peripheral.HttpModem", "args":[]},
|
"com2":{"cls":"net.torvald.tsvm.peripheral.HttpModem", "args":[]},
|
||||||
"card4":{"class":"net.torvald.tsvm.peripheral.RamBank", "args":[256]}
|
"card4":{"cls":"net.torvald.tsvm.peripheral.RamBank", "args":[256]}
|
||||||
}
|
}
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
|
|
||||||
@@ -415,7 +456,7 @@ class VMEmuExecutable(val windowWidth: Int, val windowHeight: Int, var panelsX:
|
|||||||
// install peripherals
|
// install peripherals
|
||||||
listOf("com1", "com2", "com3", "com4").map { json.get(it) }.forEachIndexed { index, jsonValue ->
|
listOf("com1", "com2", "com3", "com4").map { json.get(it) }.forEachIndexed { index, jsonValue ->
|
||||||
jsonValue?.let { deviceInfo ->
|
jsonValue?.let { deviceInfo ->
|
||||||
val className = deviceInfo.getString("class")
|
val className = deviceInfo.getString("cls")
|
||||||
|
|
||||||
val loadedClass = Class.forName(className)
|
val loadedClass = Class.forName(className)
|
||||||
|
|
||||||
@@ -454,7 +495,7 @@ class VMEmuExecutable(val windowWidth: Int, val windowHeight: Int, var panelsX:
|
|||||||
}
|
}
|
||||||
(2..cardslots).map { it to json.get("card$it") }.forEach { (index, jsonValue) ->
|
(2..cardslots).map { it to json.get("card$it") }.forEach { (index, jsonValue) ->
|
||||||
jsonValue?.let { deviceInfo ->
|
jsonValue?.let { deviceInfo ->
|
||||||
val className = deviceInfo.getString("class")
|
val className = deviceInfo.getString("cls")
|
||||||
|
|
||||||
val loadedClass = Class.forName(className)
|
val loadedClass = Class.forName(className)
|
||||||
val argTypes = loadedClass.declaredConstructors[0].parameterTypes
|
val argTypes = loadedClass.declaredConstructors[0].parameterTypes
|
||||||
|
|||||||
Reference in New Issue
Block a user