generated from rnentjes/kotlin-server-web-undertow
Compare commits
2 Commits
37691dc7fa
...
d7e331728f
| Author | SHA1 | Date | |
|---|---|---|---|
| d7e331728f | |||
| 8457d3a854 |
@@ -18,13 +18,8 @@ class MTMCDisplay(private val computer: MonTanaMiniComputer) {
|
|||||||
LIGHT(87, 124, 68),
|
LIGHT(87, 124, 68),
|
||||||
LIGHTEST(127, 134, 15);
|
LIGHTEST(127, 134, 15);
|
||||||
|
|
||||||
val intVal: Int
|
val intVal: Int = 0xFF shl 24 or (r shl 16) or (g shl 8) or b
|
||||||
val javaColor: Color
|
val javaColor: Color = Color(r, g, b)
|
||||||
|
|
||||||
init {
|
|
||||||
this.intVal = 0xFF shl 24 or (r shl 16) or (g shl 8) or b
|
|
||||||
javaColor = Color(r, g, b)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun distance(r: Int, g: Int, b: Int): Int {
|
fun distance(r: Int, g: Int, b: Int): Int {
|
||||||
val dr = this.r - r
|
val dr = this.r - r
|
||||||
@@ -56,15 +51,20 @@ class MTMCDisplay(private val computer: MonTanaMiniComputer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun loadSplashScreen() {
|
private fun loadSplashScreen() {
|
||||||
/* try {
|
currentColor = DisplayColor.DARK
|
||||||
val bytes: ByteArray = Base64.getDecoder().decode(SPLASH_SCREEN)
|
var currentColorCount = 0
|
||||||
val bais = ByteArrayInputStream(bytes)
|
var currentColor = 0
|
||||||
var img: BufferedImage? = null
|
var colorIndex = 0
|
||||||
img = ImageIO.read(bais)
|
for (col in 0..<COLS) {
|
||||||
loadScaledImage(img)
|
for (row in 0..<ROWS) {
|
||||||
} catch (e: IOException) {
|
if (currentColorCount == 0) {
|
||||||
e.printStackTrace()
|
currentColorCount = SPLASH_SCREEN_COLORS[colorIndex++]
|
||||||
}*/
|
currentColor = SPLASH_SCREEN_COLORS[colorIndex++]
|
||||||
|
}
|
||||||
|
setPixel(col, row, DisplayColor.entries[currentColor])
|
||||||
|
currentColorCount--
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadImage(data: ByteArray): BufferedImage? {
|
private fun loadImage(data: ByteArray): BufferedImage? {
|
||||||
@@ -107,7 +107,11 @@ class MTMCDisplay(private val computer: MonTanaMiniComputer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun setPixel(col: Int, row: Int, color: DisplayColor) {
|
fun setPixel(col: Int, row: Int, color: DisplayColor) {
|
||||||
buffer.setRGB(col, row, color.intVal)
|
try {
|
||||||
|
buffer.setRGB(col, row, color.intVal)
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
throw e
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getPixel(col: Int, row: Int): Short {
|
fun getPixel(col: Int, row: Int): Short {
|
||||||
@@ -173,7 +177,7 @@ class MTMCDisplay(private val computer: MonTanaMiniComputer) {
|
|||||||
//computer.notifyOfDisplayUpdate()
|
//computer.notifyOfDisplayUpdate()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toPng(): ByteArray? {
|
fun toPng(): ByteArray {
|
||||||
return byteArray
|
return byteArray
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ class MonTanaMiniComputer {
|
|||||||
registerFile = ShortArray(Register.entries.size)
|
registerFile = ShortArray(Register.entries.size)
|
||||||
memory = ByteArray(MEMORY_SIZE)
|
memory = ByteArray(MEMORY_SIZE)
|
||||||
breakpoints = ByteArray(MEMORY_SIZE)
|
breakpoints = ByteArray(MEMORY_SIZE)
|
||||||
rewindIndex = -1
|
|
||||||
setRegisterValue(
|
setRegisterValue(
|
||||||
Register.SP,
|
Register.SP,
|
||||||
MEMORY_SIZE.toShort().toInt()
|
MEMORY_SIZE.toShort().toInt()
|
||||||
@@ -792,7 +791,7 @@ class MonTanaMiniComputer {
|
|||||||
val currentValue = memory[address]
|
val currentValue = memory[address]
|
||||||
addRewindStep { memory[address] = currentValue }
|
addRewindStep { memory[address] = currentValue }
|
||||||
memory[address] = value
|
memory[address] = value
|
||||||
observers!!.forEach { o: MTMCObserver? ->
|
observers.forEach { o: MTMCObserver? ->
|
||||||
o!!.memoryUpdated(address, value)
|
o!!.memoryUpdated(address, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -816,7 +815,7 @@ class MonTanaMiniComputer {
|
|||||||
registerFile[register] = currentValue
|
registerFile[register] = currentValue
|
||||||
}
|
}
|
||||||
registerFile[register] = value.toShort()
|
registerFile[register] = value.toShort()
|
||||||
observers!!.forEach { o: MTMCObserver? ->
|
observers.forEach { o: MTMCObserver? ->
|
||||||
o!!.registerUpdated(register, value)
|
o!!.registerUpdated(register, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1727
src/commonMain/kotlin/mtmc/emulator/SplashData.kt
Normal file
1727
src/commonMain/kotlin/mtmc/emulator/SplashData.kt
Normal file
File diff suppressed because it is too large
Load Diff
@@ -11,12 +11,14 @@ val mainView = MTMCView(computer)
|
|||||||
val display = DisplayView(computer)
|
val display = DisplayView(computer)
|
||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
computer.speed = 2000000 // default to 1hz
|
computer.speed = 1000000
|
||||||
computer.load(lifeCode, lifeData)
|
computer.load(lifeCode, lifeData)
|
||||||
|
//computer.load(snakeCode, snakeData)
|
||||||
|
|
||||||
Komponent.create(document.body!!, mainView)
|
Komponent.create(document.body!!, mainView)
|
||||||
|
|
||||||
computer.start()
|
computer.start()
|
||||||
|
|
||||||
mainView.requestUpdate()
|
mainView.requestUpdate()
|
||||||
|
display.requestUpdate()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ actual fun requestAnimationFrame(action: (Double) -> Unit) {
|
|||||||
action(it)
|
action(it)
|
||||||
|
|
||||||
display.requestUpdate()
|
display.requestUpdate()
|
||||||
if (currentTimeMillis() - lastMemoryUpdate > 100) {
|
if (currentTimeMillis() - lastMemoryUpdate > 125) {
|
||||||
mainView.registerView.requestUpdate()
|
mainView.registerView.requestUpdate()
|
||||||
mainView.memoryView.requestUpdate()
|
mainView.memoryView.requestUpdate()
|
||||||
lastMemoryUpdate = currentTimeMillis()
|
lastMemoryUpdate = currentTimeMillis()
|
||||||
|
|||||||
@@ -1,18 +1,136 @@
|
|||||||
package mtmc.view
|
package mtmc.view
|
||||||
|
|
||||||
|
import kotlinx.html.button
|
||||||
import kotlinx.html.div
|
import kotlinx.html.div
|
||||||
|
import kotlinx.html.i
|
||||||
|
import kotlinx.html.js.onChangeFunction
|
||||||
|
import kotlinx.html.js.onClickFunction
|
||||||
|
import kotlinx.html.label
|
||||||
|
import kotlinx.html.option
|
||||||
|
import kotlinx.html.select
|
||||||
|
import kotlinx.html.span
|
||||||
|
import mtmc.display
|
||||||
import mtmc.emulator.MonTanaMiniComputer
|
import mtmc.emulator.MonTanaMiniComputer
|
||||||
|
import mtmc.mainView
|
||||||
import nl.astraeus.komp.HtmlBuilder
|
import nl.astraeus.komp.HtmlBuilder
|
||||||
import nl.astraeus.komp.Komponent
|
import nl.astraeus.komp.Komponent
|
||||||
|
import org.w3c.dom.HTMLSelectElement
|
||||||
|
import kotlin.text.Typography.nbsp
|
||||||
|
|
||||||
class ControlView(
|
class ControlView(
|
||||||
val computer: MonTanaMiniComputer
|
val computer: MonTanaMiniComputer
|
||||||
) : Komponent() {
|
) : Komponent() {
|
||||||
|
|
||||||
override fun HtmlBuilder.render() {
|
override fun HtmlBuilder.render() {
|
||||||
div {
|
div("control-panel") {
|
||||||
+"Controls view"
|
div("control-header") {
|
||||||
|
span {
|
||||||
|
+"m"
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
+"s"
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
+"u"
|
||||||
|
}
|
||||||
|
nbsp
|
||||||
|
i {
|
||||||
|
+"MTMC-16"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div("control-secondary") {
|
||||||
|
+"MonTana Mini-Computer"
|
||||||
|
}
|
||||||
|
div("control-buttons") {
|
||||||
|
label {
|
||||||
|
select {
|
||||||
|
name = "speed"
|
||||||
|
|
||||||
|
option {
|
||||||
|
value = "1"
|
||||||
|
+"1 Hz"
|
||||||
|
}
|
||||||
|
option {
|
||||||
|
value = "10"
|
||||||
|
+"10 Hz"
|
||||||
|
}
|
||||||
|
option {
|
||||||
|
value = "100"
|
||||||
|
+"100 Hz"
|
||||||
|
}
|
||||||
|
option {
|
||||||
|
value = "1000"
|
||||||
|
+"1 Khz"
|
||||||
|
}
|
||||||
|
option {
|
||||||
|
value = "1000000"
|
||||||
|
selected = true
|
||||||
|
+"1 Mhz"
|
||||||
|
}
|
||||||
|
option {
|
||||||
|
value = "2000000"
|
||||||
|
+"2 Mhz"
|
||||||
|
}
|
||||||
|
option {
|
||||||
|
value = "5000000"
|
||||||
|
+"5 Mhz"
|
||||||
|
}
|
||||||
|
|
||||||
|
onChangeFunction = {
|
||||||
|
val target = it.target as? HTMLSelectElement
|
||||||
|
target?.value?.toIntOrNull()?.let { speed ->
|
||||||
|
computer.speed = speed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buttons with fx-* attributes
|
||||||
|
button {
|
||||||
|
if (computer.getStatus() != MonTanaMiniComputer.ComputerStatus.EXECUTING) {
|
||||||
|
+"run"
|
||||||
|
onClickFunction = {
|
||||||
|
computer.run()
|
||||||
|
requestUpdate()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
+"pause"
|
||||||
|
onClickFunction = {
|
||||||
|
computer.pause()
|
||||||
|
requestUpdate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
disabled =
|
||||||
|
computer.getStatus() == MonTanaMiniComputer.ComputerStatus.WAITING && computer.rewindIndex >= 0
|
||||||
|
|
||||||
|
+"back"
|
||||||
|
|
||||||
|
onClickFunction = {
|
||||||
|
computer.back()
|
||||||
|
mainView.requestUpdate()
|
||||||
|
display.requestUpdate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
+"step"
|
||||||
|
|
||||||
|
onClickFunction = {
|
||||||
|
computer.step()
|
||||||
|
mainView.requestUpdate()
|
||||||
|
display.requestUpdate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
disabled = true
|
||||||
|
+"reset"
|
||||||
|
|
||||||
|
onClickFunction = {
|
||||||
|
//computer.reset()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,12 @@
|
|||||||
|
:root {
|
||||||
|
--pdp-blue: #243571;
|
||||||
|
--pdp-light-blue: #3286ce;
|
||||||
|
--pdp-beige: #fdfddc;
|
||||||
|
--pdp-white: #f1f1f6;
|
||||||
|
--pdp-off-white: #F0EBCD;
|
||||||
|
--filetree-gray: #666;
|
||||||
|
}
|
||||||
|
|
||||||
html, body {
|
html, body {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@@ -14,7 +23,7 @@ body {
|
|||||||
grid-template-rows: 1fr;
|
grid-template-rows: 1fr;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
background-color: #ccc;
|
background-color: var(--pdp-white);
|
||||||
}
|
}
|
||||||
|
|
||||||
.left-column {
|
.left-column {
|
||||||
@@ -52,6 +61,53 @@ body {
|
|||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* control */
|
||||||
|
|
||||||
|
.control-panel > * {
|
||||||
|
margin: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-header {
|
||||||
|
background-color: var(--pdp-blue);
|
||||||
|
color: var(--pdp-white);
|
||||||
|
font-family: monospace;
|
||||||
|
font-size: 32px;
|
||||||
|
padding: 4px 24px;
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-header span {
|
||||||
|
display: inline-block;
|
||||||
|
margin-top: -6px;
|
||||||
|
margin-bottom: -6px;
|
||||||
|
padding: 4px 8px;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 38px;
|
||||||
|
border-right: 4px solid white;
|
||||||
|
border-left: 4px solid white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-header span:not(:first-child) {
|
||||||
|
border-left: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-secondary {
|
||||||
|
background-color: var(--pdp-light-blue);
|
||||||
|
color: var(--pdp-white);
|
||||||
|
font-family: monospace;
|
||||||
|
font-size: 18px;
|
||||||
|
font-style: italic;
|
||||||
|
text-align: center;
|
||||||
|
padding: 4px 4px;
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-buttons {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
/* registers */
|
/* registers */
|
||||||
|
|
||||||
table.register-table {
|
table.register-table {
|
||||||
|
|||||||
Reference in New Issue
Block a user