even more emulator gui(2)

This commit is contained in:
minjaesong
2022-10-29 01:30:42 +09:00
parent 3413b0d053
commit d576382567
5 changed files with 103 additions and 17 deletions

2
.idea/misc.xml generated
View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" /> <output url="file://$PROJECT_DIR$/out" />
</component> </component>
</project> </project>

View File

@@ -52,7 +52,7 @@ class VM(
var getErrorStream: () -> OutputStream = { TODO() } var getErrorStream: () -> OutputStream = { TODO() }
var getInputStream: () -> InputStream = { TODO() } var getInputStream: () -> InputStream = { TODO() }
var startTime: Long = -1 var startTime: Long = -1; private set
var resetDown = false var resetDown = false
var stopDown = false var stopDown = false
@@ -117,8 +117,14 @@ class VM(
killAllContexts() killAllContexts()
usermem.destroy() usermem.destroy()
peripheralTable.forEach { it.peripheral?.dispose() } 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 * @return system uptime in milliseconds
*/ */

View File

@@ -5,10 +5,11 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch
/** /**
* Created by minjaesong on 2022-10-25. * 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() abstract fun show()
abstract fun hide()
fun render(batch: SpriteBatch) abstract fun update()
abstract fun render(batch: SpriteBatch)
} }

View File

@@ -2,19 +2,69 @@ package net.torvald.tsvm
import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.tsvm.VMEmuExecutableWrapper.Companion.FONT
/** /**
* Created by minjaesong on 2022-10-25. * 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<String>()
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 update() {
} }
override fun render(batch: SpriteBatch) { override fun render(batch: SpriteBatch) {
batch.inUse { batch.inUse {
batch.color = Color.LIME batch.color = EmulatorGuiToolkit.Theme.COL_WELL
batch.fillRect(0, 0, w, h) 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)
}
} }
} }
} }

View File

@@ -98,7 +98,18 @@ class VMEmuExecutable(val windowWidth: Int, val windowHeight: Int, var panelsX:
val profiles = HashMap<String, JsonValue>() val profiles = HashMap<String, JsonValue>()
fun writeProfilesToFile(outFile: FileHandle) { private val currentlyLoadedProfiles = HashMap<String, VM>()
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() val out = StringBuilder()
out.append('{') out.append('{')
@@ -116,6 +127,7 @@ class VMEmuExecutable(val windowWidth: Int, val windowHeight: Int, var panelsX:
outFile.writeString(outstr, false) outFile.writeString(outstr, false)
} }
override fun create() { override fun create() {
super.create() super.create()
@@ -151,7 +163,7 @@ class VMEmuExecutable(val windowWidth: Int, val windowHeight: Int, var panelsX:
vms[0] = VMRunnerInfo(vm, "Initial VM")*/ vms[0] = VMRunnerInfo(vm, "Initial VM")*/
val testJson = JsonReader().parse("{$defaultProfile}") val testJson = JsonReader().parse("{$defaultProfile}")
val vm1 = makeVMfromJson(testJson.get("Initial VM")) val vm1 = getVMbyProfileName("Initial VM")!!
initVMenv(vm1) initVMenv(vm1)
vms[0] = VMRunnerInfo(vm1, "Initial VM") vms[0] = VMRunnerInfo(vm1, "Initial VM")
@@ -267,7 +279,7 @@ class VMEmuExecutable(val windowWidth: Int, val windowHeight: Int, var panelsX:
updateMenu() updateMenu()
} }
private val defaultGuiBackgroundColour = Color(0x303039ff) val defaultGuiBackgroundColour = Color(0x303039ff)
private fun renderGame(delta: Float) { private fun renderGame(delta: Float) {
vms.forEachIndexed { index, vmInfo -> 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 menuTabW = windowWidth - 4
private val menuTabH = windowHeight - 4 - FONT.H 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 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 menuTabSel = 0
private var tabChangeRequested: Int? = 0 // null: not requested
private fun drawMenu(batch: SpriteBatch, x: Float, y: Float) { private fun drawMenu(batch: SpriteBatch, x: Float, y: Float) {
if (tabChangeRequested != null) {
tabs[menuTabSel].hide()
tabs[tabChangeRequested!!].show()
menuTabSel = tabChangeRequested!!
tabChangeRequested = null
}
batch.inUse { batch.inUse {
// background for the entire area // background for the entire area
batch.color = defaultGuiBackgroundColour batch.color = defaultGuiBackgroundColour
@@ -403,7 +426,7 @@ class VMEmuExecutable(val windowWidth: Int, val windowHeight: Int, var panelsX:
} }
// draw the window frame inside the tab // 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.fillRect(x, y + FONT.H, windowWidth, windowHeight - FONT.H)
batch.color = EmulatorGuiToolkit.Theme.COL_HIGHLIGHT batch.color = EmulatorGuiToolkit.Theme.COL_HIGHLIGHT
batch.fillRect(x, y + FONT.H, windowWidth.toFloat(), 2f) 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) 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) tabs[menuTabSel].render(batch)
} }
@@ -440,6 +463,7 @@ class VMEmuExecutable(val windowWidth: Int, val windowHeight: Int, var panelsX:
} }
""".trimIndent() """.trimIndent()
/** /**
* You'll want to further init the things using the VM this function returns, such as: * 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 assetsDir = json.getString("assetsdir")
val ramsize = json.getLong("ramsize") val ramsize = json.getLong("ramsize")
val cardslots = json.getInt("cardslots") val cardslots = json.getInt("cardslots")
@@ -547,10 +571,15 @@ object EmulatorGuiToolkit {
val COL_INACTIVE2 = Color(0x5a5a5fff.toInt()) val COL_INACTIVE2 = Color(0x5a5a5fff.toInt())
val COL_ACTIVE = Color(0x23ff00ff.toInt()) // neon green val COL_ACTIVE = Color(0x23ff00ff.toInt()) // neon green
val COL_ACTIVE2 = Color(0xfff600ff.toInt()) // yellow val COL_ACTIVE2 = Color(0xfff600ff.toInt()) // yellow
val COL_ACTIVE3 = Color.WHITE
val COL_HIGHLIGHT = Color(0xe43380ff.toInt()) // magenta val COL_HIGHLIGHT = Color(0xe43380ff.toInt()) // magenta
val COL_DISABLED = Color(0xaaaaaaff.toInt()) val COL_DISABLED = Color(0xaaaaaaff.toInt())
val COL_TAB_NOT_SELECTED = Color(0x503cd4ff) // dark blue 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())
} }
} }