From 86af873bdf1d94ad5179a649e20afeb3c7aed344 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Wed, 14 Dec 2022 03:51:46 +0900 Subject: [PATCH] assigning vms on the viewport --- tsvm_core/src/net/torvald/tsvm/VM.kt | 2 + .../src/net/torvald/tsvm/ProfilesMenu.kt | 52 +++++++-- .../src/net/torvald/tsvm/VMEmuExecutable.kt | 106 ++++++++++++------ 3 files changed, 115 insertions(+), 45 deletions(-) diff --git a/tsvm_core/src/net/torvald/tsvm/VM.kt b/tsvm_core/src/net/torvald/tsvm/VM.kt index 5b9abd8..0fb4025 100644 --- a/tsvm_core/src/net/torvald/tsvm/VM.kt +++ b/tsvm_core/src/net/torvald/tsvm/VM.kt @@ -65,6 +65,8 @@ class VM( private val mallocSizes = HashMap() // HashMap var allocatedBlockCount = 0; private set + val isRunning: Boolean + get() = !disposed &&startTime >= 0 init { println("[VM] Creating new VM with ID of $id, memsize $memsize") diff --git a/tsvm_executable/src/net/torvald/tsvm/ProfilesMenu.kt b/tsvm_executable/src/net/torvald/tsvm/ProfilesMenu.kt index 713c137..0fbe04c 100644 --- a/tsvm_executable/src/net/torvald/tsvm/ProfilesMenu.kt +++ b/tsvm_executable/src/net/torvald/tsvm/ProfilesMenu.kt @@ -42,6 +42,7 @@ class ProfilesMenu(parent: VMEmuExecutable, x: Int, y: Int, w: Int, h: Int) : Em val mx = Gdx.input.x - x val my = Gdx.input.y - y + // make profile list work if (mx in 10 until 10+228) { if (my in 11 until 11+446) { val li = (my - 11) / (2*FONT.H) @@ -52,6 +53,42 @@ class ProfilesMenu(parent: VMEmuExecutable, x: Int, y: Int, w: Int, h: Int) : Em selectedProfileIndex = null } } + + // make controls for the selected profile work + if (selectedProfileIndex != null) profileNames[selectedProfileIndex!!].let { profileName -> + val theVM = parent.getVMbyProfileName(profileName) + if (theVM != null) { + // viewport selector + if (my in 427..453) { + if (mx in 253..640) { + val oldIndex = parent.getViewportForTheVM(theVM) + val newIndex = ((mx - 253) / 14).let { if (it == 0) null else it - 1 } + + if (newIndex == null || newIndex in 0 until viewportColumns * viewportRows - 1) { + if (oldIndex == null && newIndex != null) { + parent.addVMtoView(theVM, profileName, newIndex) + } + else if (oldIndex != null) { + parent.moveView(oldIndex, newIndex) + } + } + } + } + // stop and play buttons + else if (my in 375..401) { + + println("vm: $profileName; isRunning = ${theVM.isRunning}; mx = $mx") + + if (mx in 377..390 && theVM.isRunning) { + parent.killVMenv(theVM) + } + else if (mx in 398..412 && !theVM.isRunning) { + parent.initVMenv(theVM) + } + } + } + + } } } @@ -79,10 +116,9 @@ class ProfilesMenu(parent: VMEmuExecutable, x: Int, y: Int, w: Int, h: Int) : Em else EmulatorGuiToolkit.Theme.COL_INACTIVE3 val theVM = parent.getVMbyProfileName(profileNames[index]) - val isVMrunning = if (theVM != null) !theVM.disposed && theVM.startTime >= 0 else false val vmViewport = parent.getViewportForTheVM(theVM) - val vmRunStatusText = if (isVMrunning) STR_PLAY else STR_STOP + val vmRunStatusText = if (theVM?.isRunning == true) STR_PLAY else STR_STOP val vmViewportText = if (vmViewport != null) "on viewport #${vmViewport+1}" else "and hidden" batch.color = colBack @@ -103,7 +139,6 @@ class ProfilesMenu(parent: VMEmuExecutable, x: Int, y: Int, w: Int, h: Int) : Em val profile = parent.profiles[profileName]!! val theVM = parent.getVMbyProfileName(profileName) - val isVMrunning = if (theVM != null) !theVM.disposed && theVM.startTime >= 0 else false val vmViewport = parent.getViewportForTheVM(theVM) @@ -137,22 +172,23 @@ class ProfilesMenu(parent: VMEmuExecutable, x: Int, y: Int, w: Int, h: Int) : Em FONT.draw(batch, "Show on Viewport:", 253f, 414f) batch.setColourBy { vmViewport == null } - FONT.draw(batch, "Hi", 254f, 429f) - FONT.draw(batch, "de", 254f, 439f) + FONT.draw(batch, "Hi", 253f, 429f) + FONT.draw(batch, "de", 253f, 439f) for (i in 1 until viewportRows * viewportColumns) { batch.setColourBy { (vmViewport != null && i == vmViewport + 1) } - FONT.draw(batch, "$i", 254f + (i * 14f) + (if (i < 10) 7f else 0f), 434f) + FONT.draw(batch, "$i", 253f + (i * 14f) + (if (i < 10) 7f else 0f), 434f) } // draw machine control + batch.color = Color.WHITE FONT.draw(batch, "Machine Control:", 253f, 381f) - batch.setColourBy { !isVMrunning } + batch.setColourBy { theVM?.isRunning != true } FONT.draw(batch, STR_STOP, 377f, 382f) - batch.setColourBy { isVMrunning } + batch.setColourBy { theVM?.isRunning == true } FONT.draw(batch, STR_PLAY, 398f, 382f) } diff --git a/tsvm_executable/src/net/torvald/tsvm/VMEmuExecutable.kt b/tsvm_executable/src/net/torvald/tsvm/VMEmuExecutable.kt index 95099bf..d868462 100644 --- a/tsvm_executable/src/net/torvald/tsvm/VMEmuExecutable.kt +++ b/tsvm_executable/src/net/torvald/tsvm/VMEmuExecutable.kt @@ -94,7 +94,7 @@ class VMEmuExecutable(val windowWidth: Int, val windowHeight: Int, var panelsX: val profiles = HashMap() private val currentlyLoadedProfiles = HashMap() - fun getVMbyProfileName(name: String): VM? { + internal fun getVMbyProfileName(name: String): VM? { if (profiles.containsKey(name)) { return currentlyLoadedProfiles.getOrPut(name) { _makeVMfromJson(profiles[name]!!, name) } } @@ -102,7 +102,20 @@ class VMEmuExecutable(val windowWidth: Int, val windowHeight: Int, var panelsX: return null } - fun getViewportForTheVM(vm: VM?): Int? = if (vm == null) null else vms.indexOfFirst { vm.id == it?.vm?.id }.let { if (it < 0) null else it } + internal fun getViewportForTheVM(vm: VM?): Int? = if (vm == null) null else vms.indexOfFirst { vm.id == it?.vm?.id }.let { if (it < 0) null else it } + + internal fun moveView(oldIndex: Int, newIndex: Int?) { + if (oldIndex != newIndex) { + if (newIndex != null) { + vms[newIndex] = vms[oldIndex] + } + vms[oldIndex] = null + } + } + + internal fun addVMtoView(vm: VM, profileName: String, index: Int) { + vms[index] = VMRunnerInfo(vm, profileName) + } private fun writeProfilesToFile(outFile: FileHandle) { val out = StringBuilder() @@ -176,7 +189,7 @@ class VMEmuExecutable(val windowWidth: Int, val windowHeight: Int, var panelsX: Gdx.input.inputProcessor = if (currentVMselection != null) vms[currentVMselection!!]?.vm?.getIO() else vmEmuInputProcessor } - private fun initVMenv(vm: VM) { + internal fun initVMenv(vm: VM) { vm.init() vm.peripheralTable.getOrNull(1)?.peripheral?.dispose() @@ -192,6 +205,17 @@ class VMEmuExecutable(val windowWidth: Int, val windowHeight: Int, var panelsX: coroutineJobs[vm.id] = GlobalScope.launch { vmRunners[vm.id]?.executeCommand(vm.roms[0]!!.readAll()) } } + internal fun killVMenv(vm: VM) { + vm.dispose() + vm.peripheralTable.fill(PeripheralEntry()) + vm.getPrintStream = { TODO() } + vm.getErrorStream = { TODO() } + vm.getInputStream = { TODO() } + + vmRunners[vm.id]?.close() + coroutineJobs[vm.id]?.cancel() + } + private fun setCameraPosition(newX: Float, newY: Float) { camera.position.set((-newX + TsvmEmulator.WIDTH / 2), (-newY + TsvmEmulator.HEIGHT / 2), 0f) // deliberate integer division camera.update() @@ -263,7 +287,7 @@ class VMEmuExecutable(val windowWidth: Int, val windowHeight: Int, var panelsX: vms.forEachIndexed { index, it -> if (it?.vm?.resetDown == true && index == currentVMselection) { reboot(it.vm) } - it?.vm?.update(delta) + if (it?.vm?.isRunning == true) it?.vm?.update(delta) } updateMenu() @@ -297,44 +321,52 @@ class VMEmuExecutable(val windowWidth: Int, val windowHeight: Int, var panelsX: } private fun drawVMtoCanvas(delta: Float, vm: VM?, pposX: Int, pposY: Int) { - vm.let { vm -> - // assuming the reference adapter of 560x448 - val xoff = pposX * windowWidth.toFloat() - val yoff = pposY * windowHeight.toFloat() + // assuming the reference adapter of 560x448 + val xoff = pposX * windowWidth.toFloat() + val yoff = pposY * windowHeight.toFloat() - if (vm != null) { - (vm.peripheralTable.getOrNull(1)?.peripheral as? GraphicsAdapter).let { gpu -> - if (gpu != null) { - val clearCol = gpu.getBackgroundColour() - // clear the viewport by drawing coloured rectangle becausewhynot - fbatch.color = clearCol - fbatch.inUse { - fbatch.fillRect(pposX * windowWidth, pposY * windowHeight, windowWidth, windowHeight) - } - - gpu.render(delta, fbatch, xoff + 40f, yoff + 16f, false, null) + if (vm != null) { + (vm.peripheralTable.getOrNull(1)?.peripheral as? GraphicsAdapter).let { gpu -> + if (gpu != null && !vm.isRunning) { + // vm has stopped + fbatch.inUse { + fbatch.color = defaultGuiBackgroundColour + fbatch.fillRect(pposX * windowWidth, pposY * windowHeight, windowWidth, windowHeight) + // draw text + fbatch.color = EmulatorGuiToolkit.Theme.COL_INACTIVE + FONT.draw(fbatch, "vm is not running", xoff + (windowWidth - 119) / 2, yoff + (windowHeight - 12) / 2) } - else { - // no graphics device available - fbatch.inUse { - fbatch.color = defaultGuiBackgroundColour - fbatch.fillRect(pposX * windowWidth, pposY * windowHeight, windowWidth, windowHeight) - // draw text - fbatch.color = EmulatorGuiToolkit.Theme.COL_INACTIVE - FONT.draw(fbatch, "no graphics device available", xoff + (windowWidth - 196) / 2, yoff + (windowHeight - 12) / 2) - } + } + else if (gpu != null) { + val clearCol = gpu.getBackgroundColour() + // clear the viewport by drawing coloured rectangle becausewhynot + fbatch.color = clearCol + fbatch.inUse { + fbatch.fillRect(pposX * windowWidth, pposY * windowHeight, windowWidth, windowHeight) + } + + gpu.render(delta, fbatch, xoff + 40f, yoff + 16f, false, null) + } + else { + // no graphics device available + fbatch.inUse { + fbatch.color = defaultGuiBackgroundColour + fbatch.fillRect(pposX * windowWidth, pposY * windowHeight, windowWidth, windowHeight) + // draw text + fbatch.color = EmulatorGuiToolkit.Theme.COL_INACTIVE + FONT.draw(fbatch, "no graphics device available", xoff + (windowWidth - 196) / 2, yoff + (windowHeight - 12) / 2) } } } - else { - // no vm on the viewport - fbatch.inUse { - fbatch.color = defaultGuiBackgroundColour - fbatch.fillRect(pposX * windowWidth, pposY * windowHeight, windowWidth, windowHeight) - // draw text - fbatch.color = EmulatorGuiToolkit.Theme.COL_INACTIVE - FONT.draw(fbatch, "no vm on this viewport", xoff + (windowWidth - 154) / 2, yoff + (windowHeight - 12) / 2) - } + } + else { + // no vm on the viewport + fbatch.inUse { + fbatch.color = defaultGuiBackgroundColour + fbatch.fillRect(pposX * windowWidth, pposY * windowHeight, windowWidth, windowHeight) + // draw text + fbatch.color = EmulatorGuiToolkit.Theme.COL_INACTIVE + FONT.draw(fbatch, "no vm on this viewport", xoff + (windowWidth - 154) / 2, yoff + (windowHeight - 12) / 2) } } }