From d576382567bbea184b243477e49e99209867087c Mon Sep 17 00:00:00 2001 From: minjaesong Date: Sat, 29 Oct 2022 01:30:42 +0900 Subject: [PATCH] even more emulator gui(2) --- .idea/misc.xml | 2 +- tsvm_core/src/net/torvald/tsvm/VM.kt | 8 ++- .../src/net/torvald/tsvm/EmuMenu.kt | 9 +-- .../src/net/torvald/tsvm/ProfilesMenu.kt | 56 ++++++++++++++++++- .../src/net/torvald/tsvm/VMEmuExecutable.kt | 45 ++++++++++++--- 5 files changed, 103 insertions(+), 17 deletions(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index e0844bc..07115cd 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/tsvm_core/src/net/torvald/tsvm/VM.kt b/tsvm_core/src/net/torvald/tsvm/VM.kt index 82eac7d..a61a5bc 100644 --- a/tsvm_core/src/net/torvald/tsvm/VM.kt +++ b/tsvm_core/src/net/torvald/tsvm/VM.kt @@ -52,7 +52,7 @@ class VM( var getErrorStream: () -> OutputStream = { TODO() } var getInputStream: () -> InputStream = { TODO() } - var startTime: Long = -1 + var startTime: Long = -1; private set var resetDown = false var stopDown = false @@ -117,8 +117,14 @@ class VM( killAllContexts() usermem.destroy() peripheralTable.forEach { it.peripheral?.dispose() } + disposed = true } + /** + * To check if the VM has started, check if startTime >= 0 + */ + var disposed = false; private set + /** * @return system uptime in milliseconds */ diff --git a/tsvm_executable/src/net/torvald/tsvm/EmuMenu.kt b/tsvm_executable/src/net/torvald/tsvm/EmuMenu.kt index 6c0634a..80d38fe 100644 --- a/tsvm_executable/src/net/torvald/tsvm/EmuMenu.kt +++ b/tsvm_executable/src/net/torvald/tsvm/EmuMenu.kt @@ -5,10 +5,11 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch /** * Created by minjaesong on 2022-10-25. */ -interface EmuMenu { +abstract class EmuMenu(val parent: VMEmuExecutable, val x: Int, val y: Int, val w: Int, val h: Int) { - fun update() - - fun render(batch: SpriteBatch) + abstract fun show() + abstract fun hide() + abstract fun update() + abstract fun render(batch: SpriteBatch) } \ No newline at end of file diff --git a/tsvm_executable/src/net/torvald/tsvm/ProfilesMenu.kt b/tsvm_executable/src/net/torvald/tsvm/ProfilesMenu.kt index 8a6b02c..b6d003d 100644 --- a/tsvm_executable/src/net/torvald/tsvm/ProfilesMenu.kt +++ b/tsvm_executable/src/net/torvald/tsvm/ProfilesMenu.kt @@ -2,19 +2,69 @@ package net.torvald.tsvm import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.g2d.SpriteBatch +import net.torvald.tsvm.VMEmuExecutableWrapper.Companion.FONT /** * Created by minjaesong on 2022-10-25. */ -class ProfilesMenu(val w: Int, val h: Int) : EmuMenu { +class ProfilesMenu(parent: VMEmuExecutable, x: Int, y: Int, w: Int, h: Int) : EmuMenu(parent, x, y, w, h) { + + companion object { + const val PROFILES_ROWS = 17 // 1 profile-row takes up 2 text-rows + } + + private val profileNames = ArrayList() + private var profilesScroll = 0 + + private var selectedProfileIndex: Int? = null + + private fun resetState() { + profilesScroll = 0 + } + + override fun show() { + profileNames.clear() + profileNames.addAll(parent.profiles.keys.sorted()) + } + + override fun hide() { + + } override fun update() { } override fun render(batch: SpriteBatch) { batch.inUse { - batch.color = Color.LIME - batch.fillRect(0, 0, w, h) + batch.color = EmulatorGuiToolkit.Theme.COL_WELL + it.fillRect(10, 11, 228, 446) + + for (i in 0 until Math.min(PROFILES_ROWS, profileNames.size)) { + val index = profilesScroll + i + + val colBack = if (index == selectedProfileIndex) EmulatorGuiToolkit.Theme.COL_HIGHLIGHT + else if (i % 2 == 0) EmulatorGuiToolkit.Theme.COL_WELL + else EmulatorGuiToolkit.Theme.COL_WELL2 + val colFore = if (index == selectedProfileIndex) EmulatorGuiToolkit.Theme.COL_ACTIVE + else EmulatorGuiToolkit.Theme.COL_ACTIVE2 + + 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) "Running" else "Idle" + val vmViewportText = if (vmViewport != null) "on viewport #${vmViewport+1}" else "hidden" + + batch.color = colBack + it.fillRect(10, 11 + i*2*FONT.H, 228, 26) + + batch.color = colFore + FONT.draw(batch, profileNames[index], 12f, 11f + i*2*FONT.H) + batch.color = EmulatorGuiToolkit.Theme.COL_ACTIVE3 + FONT.draw(batch, "$vmRunStatusText, $vmViewportText", 12f, 11f+FONT.H + i*2*FONT.H) + + + } } } } \ No newline at end of file diff --git a/tsvm_executable/src/net/torvald/tsvm/VMEmuExecutable.kt b/tsvm_executable/src/net/torvald/tsvm/VMEmuExecutable.kt index c4c5103..bdacf5c 100644 --- a/tsvm_executable/src/net/torvald/tsvm/VMEmuExecutable.kt +++ b/tsvm_executable/src/net/torvald/tsvm/VMEmuExecutable.kt @@ -98,7 +98,18 @@ class VMEmuExecutable(val windowWidth: Int, val windowHeight: Int, var panelsX: val profiles = HashMap() - fun writeProfilesToFile(outFile: FileHandle) { + private val currentlyLoadedProfiles = HashMap() + fun getVMbyProfileName(name: String): VM? { + if (profiles.containsKey(name)) { + return currentlyLoadedProfiles.getOrPut(name) { _makeVMfromJson(profiles[name]!!) } + } + else + 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 } + + private fun writeProfilesToFile(outFile: FileHandle) { val out = StringBuilder() out.append('{') @@ -116,6 +127,7 @@ class VMEmuExecutable(val windowWidth: Int, val windowHeight: Int, var panelsX: outFile.writeString(outstr, false) } + override fun create() { super.create() @@ -151,7 +163,7 @@ class VMEmuExecutable(val windowWidth: Int, val windowHeight: Int, var panelsX: vms[0] = VMRunnerInfo(vm, "Initial VM")*/ val testJson = JsonReader().parse("{$defaultProfile}") - val vm1 = makeVMfromJson(testJson.get("Initial VM")) + val vm1 = getVMbyProfileName("Initial VM")!! initVMenv(vm1) vms[0] = VMRunnerInfo(vm1, "Initial VM") @@ -267,7 +279,7 @@ class VMEmuExecutable(val windowWidth: Int, val windowHeight: Int, var panelsX: updateMenu() } - private val defaultGuiBackgroundColour = Color(0x303039ff) + val defaultGuiBackgroundColour = Color(0x303039ff) private fun renderGame(delta: Float) { vms.forEachIndexed { index, vmInfo -> @@ -369,13 +381,24 @@ class VMEmuExecutable(val windowWidth: Int, val windowHeight: Int, var panelsX: private val menuTabW = windowWidth - 4 private val menuTabH = windowHeight - 4 - FONT.H + private val menuTabX = windowWidth * (panelsX-1) + 2 + private val menuTabY =windowHeight * (panelsY-1) + FONT.H + 2 - private val menuTabs = listOf("Profiles", "Machine", "Peripherals", "Cards") + private val menuTabs = listOf("Profiles", "Machine", "COMs", "Cards", "Setup") 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(this, menuTabX, menuTabY, menuTabW, menuTabH)) private var menuTabSel = 0 + private var tabChangeRequested: Int? = 0 // null: not requested + private fun drawMenu(batch: SpriteBatch, x: Float, y: Float) { + if (tabChangeRequested != null) { + tabs[menuTabSel].hide() + tabs[tabChangeRequested!!].show() + menuTabSel = tabChangeRequested!! + tabChangeRequested = null + } + batch.inUse { // background for the entire area batch.color = defaultGuiBackgroundColour @@ -403,7 +426,7 @@ class VMEmuExecutable(val windowWidth: Int, val windowHeight: Int, var panelsX: } // draw the window frame inside the tab - batch.color = EmulatorGuiToolkit.Theme.COL_INACTIVE + batch.color = EmulatorGuiToolkit.Theme.COL_LAND batch.fillRect(x, y + FONT.H, windowWidth, windowHeight - FONT.H) batch.color = EmulatorGuiToolkit.Theme.COL_HIGHLIGHT batch.fillRect(x, y + FONT.H, windowWidth.toFloat(), 2f) @@ -412,7 +435,7 @@ class VMEmuExecutable(val windowWidth: Int, val windowHeight: Int, var panelsX: batch.fillRect(x + windowWidth - 2f, y + FONT.H, 2f, windowHeight - FONT.H - 2f) } - setCameraPosition(windowWidth * (panelsX-1) + 2f, windowHeight * (panelsY-1) + FONT.H + 2f) + setCameraPosition(menuTabX.toFloat(), menuTabY.toFloat()) tabs[menuTabSel].render(batch) } @@ -440,6 +463,7 @@ class VMEmuExecutable(val windowWidth: Int, val windowHeight: Int, var panelsX: } """.trimIndent() + /** * You'll want to further init the things using the VM this function returns, such as: * @@ -450,7 +474,7 @@ class VMEmuExecutable(val windowWidth: Int, val windowHeight: Int, var panelsX: * } * ``` */ - private fun makeVMfromJson(json: JsonValue): VM { + private fun _makeVMfromJson(json: JsonValue): VM { val assetsDir = json.getString("assetsdir") val ramsize = json.getLong("ramsize") val cardslots = json.getInt("cardslots") @@ -547,10 +571,15 @@ object EmulatorGuiToolkit { val COL_INACTIVE2 = Color(0x5a5a5fff.toInt()) val COL_ACTIVE = Color(0x23ff00ff.toInt()) // neon green val COL_ACTIVE2 = Color(0xfff600ff.toInt()) // yellow + val COL_ACTIVE3 = Color.WHITE val COL_HIGHLIGHT = Color(0xe43380ff.toInt()) // magenta val COL_DISABLED = Color(0xaaaaaaff.toInt()) val COL_TAB_NOT_SELECTED = Color(0x503cd4ff) // dark blue + + val COL_LAND = Color(0x6b8ba2ff.toInt()) + val COL_WELL = Color(0x374854ff.toInt()) + val COL_WELL2 = Color(0x3e5261ff.toInt()) } }