generated from rnentjes/kotlin-server-web-undertow
Add MemoryView component for memory rendering, refactor BufferedImage for RGB manipulation, and cleanup unused methods and comments in several classes.
This commit is contained in:
@@ -1,28 +1,26 @@
|
||||
package mtmc.emulator
|
||||
|
||||
class BufferedImage(width: Int, height: Int, type: Int) {
|
||||
fun getWidth(): Int {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
fun getHeight(): Int {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
class BufferedImage(
|
||||
val width: Int,
|
||||
val height: Int,
|
||||
val type: Int
|
||||
) {
|
||||
val display = ByteArray(width * height * 4)
|
||||
|
||||
fun getRGB(x: Int, y: Int): Int {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
fun getType(): Int {
|
||||
TODO("Not yet implemented")
|
||||
return display[x * 4 + y * width * 4 + 0].toInt() +
|
||||
display[x * 4 + y * width * 4 + 1].toInt() shl 8 +
|
||||
display[x * 4 + y * width * 4 + 2].toInt() shl 16
|
||||
}
|
||||
|
||||
fun setRGB(x: Int, y: Int, intVal: Int) {
|
||||
TODO("Not yet implemented")
|
||||
display[x * 4 + y * width * 4 + 0] = intVal.toByte()
|
||||
display[x * 4 + y * width * 4 + 1] = (intVal shr 8).toByte()
|
||||
display[x * 4 + y * width * 4 + 2] = (intVal shr 16).toByte()
|
||||
}
|
||||
}
|
||||
|
||||
class Dimension(
|
||||
val width: Int,
|
||||
val height: Int
|
||||
)
|
||||
)
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -67,7 +67,6 @@ class MonTanaMiniComputer {
|
||||
// reset memory
|
||||
initMemory()
|
||||
|
||||
|
||||
val codeBoundary = code.size
|
||||
code.copyInto(memory, 0, 0, codeBoundary)
|
||||
setRegisterValue(Register.CB, codeBoundary - 1)
|
||||
@@ -843,7 +842,7 @@ class MonTanaMiniComputer {
|
||||
breakpoints[address] = (if (active) 1.toByte() else 0.toByte())
|
||||
}
|
||||
|
||||
private fun start() {
|
||||
fun start() {
|
||||
console.start() // start the interactive console
|
||||
}
|
||||
|
||||
@@ -1011,16 +1010,8 @@ class MonTanaMiniComputer {
|
||||
return true
|
||||
}
|
||||
val isMcp = getBits(16, 8, instruction) == 5.toShort()
|
||||
if (isMcp) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val computer = MonTanaMiniComputer()
|
||||
computer.speed = 1 // default to 1hz
|
||||
computer.start()
|
||||
return isMcp
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,17 +2,28 @@ package mtmc
|
||||
|
||||
import kotlinx.browser.document
|
||||
import kotlinx.html.div
|
||||
import kotlinx.html.style
|
||||
import mtmc.emulator.MonTanaMiniComputer
|
||||
import mtmc.view.MTMCView
|
||||
import nl.astraeus.komp.HtmlBuilder
|
||||
import nl.astraeus.komp.Komponent
|
||||
|
||||
class HelloKomponent : Komponent() {
|
||||
override fun HtmlBuilder.render() {
|
||||
div {
|
||||
style = "color: red;"
|
||||
+ "Hello, world!"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun main() {
|
||||
Komponent.create(document.body!!, HelloKomponent())
|
||||
val computer = MonTanaMiniComputer()
|
||||
computer.speed = 1 // default to 1hz
|
||||
|
||||
val view = MTMCView(computer)
|
||||
Komponent.create(document.body!!, view)
|
||||
|
||||
computer.start()
|
||||
|
||||
}
|
||||
|
||||
19
src/jsMain/kotlin/mtmc/view/ControlView.kt
Normal file
19
src/jsMain/kotlin/mtmc/view/ControlView.kt
Normal file
@@ -0,0 +1,19 @@
|
||||
package mtmc.view
|
||||
|
||||
import kotlinx.html.div
|
||||
import mtmc.emulator.MonTanaMiniComputer
|
||||
import nl.astraeus.komp.HtmlBuilder
|
||||
import nl.astraeus.komp.Komponent
|
||||
|
||||
class ControlView(
|
||||
val computer: MonTanaMiniComputer
|
||||
) : Komponent() {
|
||||
|
||||
override fun HtmlBuilder.render() {
|
||||
div {
|
||||
+"Controls view"
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
36
src/jsMain/kotlin/mtmc/view/MTMCView.kt
Normal file
36
src/jsMain/kotlin/mtmc/view/MTMCView.kt
Normal file
@@ -0,0 +1,36 @@
|
||||
package mtmc.view
|
||||
|
||||
import kotlinx.html.div
|
||||
import mtmc.emulator.MonTanaMiniComputer
|
||||
import nl.astraeus.komp.HtmlBuilder
|
||||
import nl.astraeus.komp.Komponent
|
||||
|
||||
class MTMCView(
|
||||
val computer: MonTanaMiniComputer
|
||||
) : Komponent() {
|
||||
val controlView = ControlView(computer)
|
||||
val registerView = RegisterView(computer)
|
||||
val memoryView = MemoryView(computer)
|
||||
|
||||
override fun HtmlBuilder.render() {
|
||||
div("container") {
|
||||
div("left-column") {
|
||||
include(controlView)
|
||||
include(registerView)
|
||||
include(memoryView)
|
||||
}
|
||||
div("middle-column") {
|
||||
div {
|
||||
+"Console"
|
||||
}
|
||||
div {
|
||||
+"Shell"
|
||||
}
|
||||
}
|
||||
div("right-column") {
|
||||
+"Files"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
40
src/jsMain/kotlin/mtmc/view/MemoryView.kt
Normal file
40
src/jsMain/kotlin/mtmc/view/MemoryView.kt
Normal file
@@ -0,0 +1,40 @@
|
||||
package mtmc.view
|
||||
|
||||
import kotlinx.html.div
|
||||
import kotlinx.html.table
|
||||
import kotlinx.html.td
|
||||
import kotlinx.html.tr
|
||||
import mtmc.emulator.MonTanaMiniComputer
|
||||
import nl.astraeus.komp.HtmlBuilder
|
||||
import nl.astraeus.komp.Komponent
|
||||
|
||||
fun ByteArray.asHex(address: Int): String {
|
||||
val value = this[address].toInt() + this[address + 1].toInt() * 256
|
||||
return value.toShort().toHexString()
|
||||
}
|
||||
|
||||
class MemoryView(
|
||||
val computer: MonTanaMiniComputer
|
||||
) : Komponent() {
|
||||
|
||||
override fun HtmlBuilder.render() {
|
||||
div("memory-panel") {
|
||||
div("memory-header") {
|
||||
+"Memory"
|
||||
}
|
||||
div("memory") {
|
||||
table {
|
||||
for (address in 0..<computer.memory.size step 16) {
|
||||
tr {
|
||||
for (offset in 0..<8) {
|
||||
td {
|
||||
+computer.memory.asHex(address + offset)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
70
src/jsMain/kotlin/mtmc/view/RegisterView.kt
Normal file
70
src/jsMain/kotlin/mtmc/view/RegisterView.kt
Normal file
@@ -0,0 +1,70 @@
|
||||
package mtmc.view
|
||||
|
||||
import kotlinx.html.TABLE
|
||||
import kotlinx.html.classes
|
||||
import kotlinx.html.div
|
||||
import kotlinx.html.hr
|
||||
import kotlinx.html.table
|
||||
import kotlinx.html.td
|
||||
import kotlinx.html.tr
|
||||
import mtmc.emulator.MonTanaMiniComputer
|
||||
import mtmc.emulator.Register
|
||||
import nl.astraeus.komp.HtmlBuilder
|
||||
import nl.astraeus.komp.Komponent
|
||||
|
||||
class RegisterView(
|
||||
val computer: MonTanaMiniComputer
|
||||
) : Komponent() {
|
||||
|
||||
override fun HtmlBuilder.render() {
|
||||
div {
|
||||
+"Register view"
|
||||
|
||||
table("register-table") {
|
||||
for (index in 0..<16) {
|
||||
showRegister(index)
|
||||
}
|
||||
tr {
|
||||
td {
|
||||
colSpan = "3"
|
||||
hr {}
|
||||
}
|
||||
}
|
||||
showRegister(16)
|
||||
showRegister(17)
|
||||
tr {
|
||||
td {
|
||||
colSpan = "3"
|
||||
+"Flags"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun TABLE.showRegister(register: Int) {
|
||||
val name = Register.fromInteger(register)
|
||||
val value = computer.registerFile[register]
|
||||
tr {
|
||||
td {
|
||||
+name
|
||||
}
|
||||
td("register-lights") {
|
||||
for (bit in 15 downTo 0) {
|
||||
div("blinken") {
|
||||
if (value.toInt() and (1 shl bit) == 0) {
|
||||
classes += "off"
|
||||
}
|
||||
if (bit % 4 == 0) {
|
||||
classes += "space"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
td("align-right") {
|
||||
+"$value"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
124
src/jsMain/resources/mtmc.css
Normal file
124
src/jsMain/resources/mtmc.css
Normal file
@@ -0,0 +1,124 @@
|
||||
html, body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
overscroll-behavior: none;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: grid;
|
||||
grid-template-columns: 450px 450px 1fr;
|
||||
grid-template-rows: 1fr;
|
||||
overflow-y: auto;
|
||||
gap: 5px;
|
||||
background-color: #ccc;
|
||||
}
|
||||
|
||||
.left-column {
|
||||
grid-template-rows: auto auto minmax(0, 1fr);
|
||||
display: grid;
|
||||
grid-gap: 4px;
|
||||
height: 100dvh;
|
||||
max-height: 100dvh;
|
||||
min-width: 450px;
|
||||
max-width: 450px;
|
||||
}
|
||||
|
||||
.middle-column {
|
||||
background-color: #eee;
|
||||
grid-template-rows: auto minmax(0, 1fr);
|
||||
display: grid;
|
||||
grid-gap: 4px;
|
||||
height: 100dvh;
|
||||
max-height: 100dvh;
|
||||
min-width: 450px;
|
||||
max-width: 450px;
|
||||
}
|
||||
|
||||
.right-column {
|
||||
background-color: #eee;
|
||||
grid-template-rows: auto;
|
||||
display: grid;
|
||||
grid-gap: 4px;
|
||||
height: 100dvh;
|
||||
max-height: 100dvh;
|
||||
min-width: 450px;
|
||||
}
|
||||
|
||||
.align-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/* registers */
|
||||
|
||||
table.register-table {
|
||||
font-family: monospace;
|
||||
width: 100%;
|
||||
padding: 5px;
|
||||
background-color: black;
|
||||
color: white;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
table.register-table tr td .align-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
table.register-table tr td.register-lights {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.blinken {
|
||||
display: inline-block;
|
||||
margin-right: 2px;
|
||||
height: 6px;
|
||||
width: 6px;
|
||||
border-radius: 6px;
|
||||
padding: 3px;
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
.blinken.off {
|
||||
background-color: #5c0119;
|
||||
}
|
||||
|
||||
.blinken.space {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
/* memory */
|
||||
|
||||
.memory-panel {
|
||||
background-color: #eee;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.memory-header {
|
||||
font-family: monospace;
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
/* overflow: auto; */
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.memory {
|
||||
font-family: monospace;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/* console */
|
||||
|
||||
.small-button {
|
||||
transform: rotate(-25deg) translateY(20px) translateX(-20px);
|
||||
margin: 2px;
|
||||
width: 50px;
|
||||
background-color: #7e777b;
|
||||
border: 1px solid dimgray;
|
||||
border-radius: 8px;
|
||||
color: whitesmoke;
|
||||
box-shadow: rgb(0, 0, 0, .2) 2px 2px 1px 1px;
|
||||
}
|
||||
@@ -7,9 +7,9 @@ import io.undertow.predicate.Predicates
|
||||
import io.undertow.server.handlers.encoding.ContentEncodingRepository
|
||||
import io.undertow.server.handlers.encoding.EncodingHandler
|
||||
import io.undertow.server.handlers.encoding.GzipEncodingProvider
|
||||
import nl.astraeus.logger.Logger
|
||||
import mtmc.db.Database
|
||||
import mtmc.web.RequestHandler
|
||||
import nl.astraeus.logger.Logger
|
||||
|
||||
val log = Logger()
|
||||
|
||||
@@ -58,7 +58,6 @@ fun main() {
|
||||
.setServerOption(UndertowOptions.SHUTDOWN_TIMEOUT, 1000)
|
||||
.build()
|
||||
|
||||
println("Starting undertow server at port 6007...")
|
||||
println("Starting undertow server at port $SERVER_PORT...")
|
||||
server?.start()
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package mtmc.web
|
||||
import kotlinx.html.body
|
||||
import kotlinx.html.head
|
||||
import kotlinx.html.html
|
||||
import kotlinx.html.link
|
||||
import kotlinx.html.meta
|
||||
import kotlinx.html.script
|
||||
import kotlinx.html.stream.appendHTML
|
||||
@@ -18,7 +19,7 @@ fun generateIndex(patch: String?): String {
|
||||
result.appendHTML(true).html {
|
||||
head {
|
||||
title(pageTitle)
|
||||
//link("/css/all.min.css", "stylesheet")
|
||||
link("/mtmc.css", "stylesheet")
|
||||
}
|
||||
body {
|
||||
script(src = "/$repoName.js") {}
|
||||
|
||||
Reference in New Issue
Block a user