mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-03-07 19:51:51 +09:00
even more emulator gui(2)
This commit is contained in:
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@@ -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>
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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)
|
||||
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user