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"?>
<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" />
</component>
</project>

View File

@@ -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
*/

View File

@@ -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)
}

View File

@@ -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<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 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)
}
}
}
}

View File

@@ -98,7 +98,18 @@ class VMEmuExecutable(val windowWidth: Int, val windowHeight: Int, var panelsX:
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()
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())
}
}