mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-03-07 19:51:51 +09:00
gpu to actually use 8bpp texture format to make memcpying easier
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
package net.torvald.tsvm
|
||||
|
||||
import net.torvald.UnsafeHelper
|
||||
import net.torvald.tsvm.peripheral.GraphicsAdapter
|
||||
import sun.nio.ch.DirectBuffer
|
||||
|
||||
class GraphicsJSR223Delegate(val vm: VM) {
|
||||
|
||||
@@ -25,4 +27,23 @@ class GraphicsJSR223Delegate(val vm: VM) {
|
||||
}
|
||||
}
|
||||
|
||||
fun loadBulk(fromAddr: Int, toAddr: Int, length: Int) {
|
||||
getFirstGPU()?.let {
|
||||
it._loadbulk(fromAddr, toAddr, length)
|
||||
}
|
||||
}
|
||||
|
||||
private fun GraphicsAdapter._loadbulk(fromAddr: Int, toAddr: Int, length: Int) {
|
||||
if (toAddr < 250880) {
|
||||
UnsafeHelper.memcpy(
|
||||
vm.usermem.ptr + fromAddr,
|
||||
(this.framebuffer.pixels as DirectBuffer).address() + toAddr,
|
||||
length.toLong()
|
||||
)
|
||||
}
|
||||
else if (toAddr < 250972) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,6 +7,8 @@ import net.torvald.tsvm.firmware.Firmware.Companion.toLuaValue
|
||||
import net.torvald.tsvm.peripheral.IOSpace
|
||||
import net.torvald.tsvm.peripheral.PeriBase
|
||||
import org.luaj.vm2.LuaValue
|
||||
import java.util.*
|
||||
import kotlin.math.ceil
|
||||
import kotlin.random.Random
|
||||
|
||||
/**
|
||||
@@ -55,6 +57,8 @@ class VM(
|
||||
val id = java.util.Random().nextInt()
|
||||
|
||||
val memsize = minOf(USER_SPACE_SIZE, _memsize.toLong())
|
||||
private val MALLOC_UNIT = 64
|
||||
private val mallocBlockSize = (memsize / MALLOC_UNIT).toInt()
|
||||
|
||||
internal val usermem = UnsafeHelper.allocate(memsize)
|
||||
|
||||
@@ -135,8 +139,55 @@ class VM(
|
||||
(memspace as PeriBase).peek(offset)
|
||||
}
|
||||
|
||||
fun Byte.toLuaValue() = LuaValue.valueOf(this.toInt())
|
||||
private val mallocMap = BitSet(mallocBlockSize)
|
||||
private val mallocSizes = HashMap<Int, Int>() // HashMap<Block Index, Block Count>
|
||||
|
||||
private fun findEmptySpace(blockSize: Int): Int? {
|
||||
var cursorHead = 0
|
||||
var cursorTail: Int
|
||||
val cursorHeadMaxInclusive = mallocBlockSize - blockSize
|
||||
while (cursorHead <= cursorHeadMaxInclusive) {
|
||||
cursorHead = mallocMap.nextClearBit(cursorHead)
|
||||
cursorTail = cursorHead + blockSize - 1
|
||||
if (cursorTail > mallocBlockSize) return null
|
||||
if (mallocMap.get(cursorTail) == false) {
|
||||
var isNotEmpty = false
|
||||
for (k in cursorHead..cursorTail) {
|
||||
isNotEmpty = isNotEmpty or mallocMap[k]
|
||||
}
|
||||
|
||||
if (!isNotEmpty) {
|
||||
mallocMap.set(cursorHead, cursorTail + 1)
|
||||
return cursorHead
|
||||
}
|
||||
}
|
||||
cursorHead = cursorTail + 1
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
internal fun malloc(size: Int): Int {
|
||||
val allocBlocks = ceil(size.toDouble() / MALLOC_UNIT).toInt()
|
||||
val blockStart = findEmptySpace(allocBlocks)
|
||||
if (blockStart == null) throw OutOfMemoryError()
|
||||
|
||||
mallocSizes[blockStart] = allocBlocks
|
||||
return blockStart * MALLOC_UNIT
|
||||
}
|
||||
|
||||
internal fun free(ptr: Int) {
|
||||
val index = ptr / MALLOC_UNIT
|
||||
val count = mallocSizes[index]
|
||||
if (count == null) throw OutOfMemoryError()
|
||||
|
||||
mallocMap.set(index, index + count, false)
|
||||
mallocSizes.remove(index)
|
||||
}
|
||||
|
||||
//fun Byte.toLuaValue() = LuaValue.valueOf(this.toInt())
|
||||
|
||||
|
||||
internal data class VMNativePtr(val address: Int, val size: Int)
|
||||
}
|
||||
|
||||
data class PeripheralEntry(
|
||||
|
||||
@@ -25,7 +25,7 @@ class VMGUI(val appConfig: LwjglApplicationConfiguration) : ApplicationAdapter()
|
||||
override fun create() {
|
||||
super.create()
|
||||
|
||||
gpu = GraphicsAdapter(lcdMode = true)
|
||||
gpu = GraphicsAdapter(lcdMode = false)
|
||||
|
||||
vm.peripheralTable[1] = PeripheralEntry(
|
||||
VM.PERITYPE_GRAPHICS,
|
||||
@@ -43,15 +43,10 @@ class VMGUI(val appConfig: LwjglApplicationConfiguration) : ApplicationAdapter()
|
||||
Gdx.gl20.glViewport(0, 0, appConfig.width, appConfig.height)
|
||||
|
||||
|
||||
// TEST LUA PRG
|
||||
//vmRunner = VMRunnerFactory(vm, "lua")
|
||||
//vmRunner.executeCommand(gpuTestPalette)
|
||||
// TEST KTS PRG
|
||||
vmRunner = VMRunnerFactory(vm, "kts")
|
||||
//vmRunner.executeCommand(gpuTestPaletteKt)
|
||||
//launch { vmRunner.executeCommand(gpuTestPaletteKt) } }
|
||||
// TEST PRG
|
||||
vmRunner = VMRunnerFactory(vm, "js")
|
||||
coroutineJob = GlobalScope.launch {
|
||||
vmRunner.executeCommand(gpuTestPaletteKt)
|
||||
vmRunner.executeCommand(gpuTestPaletteJs)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,6 +161,7 @@ while (true) {
|
||||
}
|
||||
""".trimIndent()
|
||||
|
||||
|
||||
private val gpuTestPalette = """
|
||||
local vm = require("rawmem")
|
||||
local bit = require("bit32")
|
||||
@@ -213,55 +209,54 @@ while true do
|
||||
end
|
||||
""".trimIndent()
|
||||
|
||||
private val gpuTestPaletteJs = """
|
||||
var w = 560
|
||||
var h = 448
|
||||
var hwoff = 1048576
|
||||
|
||||
print(typeof print) //function
|
||||
print(typeof vm.poke) //function
|
||||
private val jscode = """
|
||||
var w = 560;
|
||||
var h = 448;
|
||||
var hwoff = 1048576;
|
||||
|
||||
function inthash(x) {
|
||||
x = ((x >> 16) ^ x) * 0x45d9f3b
|
||||
x = ((x >> 16) ^ x) * 0x45d9f3b
|
||||
x = (x >> 16) ^ x
|
||||
return x
|
||||
x = ((x >> 16) ^ x) * 0x45d9f3b;
|
||||
x = ((x >> 16) ^ x) * 0x45d9f3b;
|
||||
x = (x >> 16) ^ x;
|
||||
return x;
|
||||
}
|
||||
|
||||
var rng = Math.floor(Math.random() * 2147483647) + 1
|
||||
var rng = Math.floor(Math.random() * 2147483647) + 1;
|
||||
|
||||
while (true) {
|
||||
|
||||
var tstart = vm.nanoTime()
|
||||
var tstart = vm.nanoTime();
|
||||
|
||||
for (var y = 0; y < 360; y++) {
|
||||
for (var x = 0; x < w; x++) {
|
||||
var palnum = 20 * Math.floor(y / 30) + Math.floor(x / 28)
|
||||
vm.poke(-(y * w + x + 1) - hwoff, inthash(palnum + rng))
|
||||
var palnum = 20 * Math.floor(y / 30) + Math.floor(x / 28);
|
||||
vm.poke(-(y * w + x + 1) - hwoff, inthash(palnum + rng));
|
||||
}
|
||||
}
|
||||
|
||||
for (var y = 360; y < h; y++) {
|
||||
for (var x = 0; x < w; x++) {
|
||||
var palnum = 240 + Math.floor(x / 35)
|
||||
vm.poke(-(y * w + x + 1) - hwoff, palnum)
|
||||
var palnum = 240 + Math.floor(x / 35);
|
||||
vm.poke(-(y * w + x + 1) - hwoff, palnum);
|
||||
}
|
||||
}
|
||||
|
||||
for (var k = 0; k < 2560; k++) {
|
||||
vm.poke(-(253952 + k + 1) - hwoff, -2) // white
|
||||
vm.poke(-(253952 + 2560 + k + 1) - hwoff, -1) // transparent
|
||||
vm.poke(-(253952 + 2560*2 + k + 1) - hwoff, Math.round(Math.random() * 255))
|
||||
vm.poke(-(253952 + k + 1) - hwoff, -2); // transparent
|
||||
vm.poke(-(253952 + 2560 + k + 1) - hwoff, -1); // white
|
||||
vm.poke(-(253952 + 2560*2 + k + 1) - hwoff, Math.round(Math.random() * 255));
|
||||
}
|
||||
|
||||
rng = inthash(rng)
|
||||
rng = inthash(rng);
|
||||
|
||||
var tend = vm.nanoTime()
|
||||
var tend = vm.nanoTime();
|
||||
|
||||
print("Apparent FPS: " + (1000000000 / (tend - tstart)))
|
||||
print("Apparent FPS: " + (1000000000 / (tend - tstart)));
|
||||
}
|
||||
""".trimIndent()
|
||||
|
||||
private val gpuTestPaletteJs = "eval('${jscode.replace(Regex("//[^\\n]*"), "").replace('\n', ' ')}')"
|
||||
|
||||
""".trimIndent()
|
||||
|
||||
private val gpuTestPaletteJava = """
|
||||
int w = 560;
|
||||
@@ -370,6 +365,7 @@ while True:
|
||||
super.dispose()
|
||||
batch.dispose()
|
||||
coroutineJob.cancel()
|
||||
vm.dispose()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,13 +10,7 @@ class VMJSR223Delegate(val vm: VM) {
|
||||
fun poke(addr: Int, value: Int) = vm.poke(addr.toLong(), value.toByte())
|
||||
fun peek(addr: Int) = vm.peek(addr.toLong())
|
||||
fun nanoTime() = System.nanoTime()
|
||||
fun dmagload(from: Int, to: Int, length: Int) {
|
||||
val periid = vm.findPeribyType("gpu")
|
||||
if (periid == null)
|
||||
throw IllegalStateException("GPU not found")
|
||||
else {
|
||||
(vm.peripheralTable[periid].peripheral as GraphicsAdapter).bulkLoad(vm, from.toLong(), to.toLong(), length.toLong())
|
||||
}
|
||||
}
|
||||
fun malloc(size: Int) = vm.malloc(size)
|
||||
fun free(ptr: Int) = vm.free(ptr)
|
||||
|
||||
}
|
||||
@@ -53,7 +53,7 @@ internal class Firmware(val vm: VM) : TwoArgFunction() {
|
||||
val t = LuaTable()
|
||||
t["poke"] = Poke(vm)
|
||||
t["peek"] = Peek(vm)
|
||||
t["nanotime"] = object : ZeroArgFunction() {
|
||||
t["nanoTime"] = object : ZeroArgFunction() {
|
||||
override fun call(): LuaValue {
|
||||
return LuaValue.valueOf(System.nanoTime().toDouble())
|
||||
}
|
||||
|
||||
137
src/net/torvald/tsvm/peripheral/GlassTty.kt
Normal file
137
src/net/torvald/tsvm/peripheral/GlassTty.kt
Normal file
@@ -0,0 +1,137 @@
|
||||
package net.torvald.tsvm.peripheral
|
||||
|
||||
import com.badlogic.gdx.utils.Queue
|
||||
|
||||
/**
|
||||
* Implements standard TTY that can interpret some of the ANSI escape sequences
|
||||
*/
|
||||
abstract class GlassTty(val TEXT_ROWS: Int, val TEXT_COLS: Int) {
|
||||
|
||||
abstract fun getCursorPos(): Pair<Int, Int>
|
||||
abstract fun setCursorPos(x: Int, y: Int)
|
||||
|
||||
abstract var rawCursorPos: Int
|
||||
abstract var blinkCursor: Boolean
|
||||
|
||||
abstract var ttyFore: Int
|
||||
abstract var ttyBack: Int
|
||||
abstract var ttyRawMode: Boolean
|
||||
|
||||
abstract fun putChar(x: Int, y: Int, text: Byte, foreColour: Byte = ttyFore.toByte(), backColour: Byte = ttyBack.toByte())
|
||||
|
||||
private var ttyMode = Queue<Byte>() // stores escape sequences like: <ESC> [
|
||||
|
||||
/**
|
||||
* ONLY accepts a character to either process the escape sequence, or say the input character is allowed to print.
|
||||
* This function will alter the internal state of the TTY intepreter (aka this very class)
|
||||
*
|
||||
* Any unrecognisable escape sequence will result the internal state to be reset but the character WILL NOT be marked
|
||||
* as printable.
|
||||
*
|
||||
* @return true if character should be printed as-is
|
||||
*/
|
||||
private fun acceptChar(char: Byte): Boolean {
|
||||
TODO()
|
||||
|
||||
if (ESC == char) {
|
||||
// beginning of the escape sequence
|
||||
if (ttyMode.isEmpty) {
|
||||
ttyMode.addLast(char)
|
||||
}
|
||||
else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
// Any escape sequences
|
||||
else if (ttyMode.size >= 1) {
|
||||
// make a state machine; if the machine should move into accepting state: accept a char, and return false;
|
||||
// for a rejecting state (sequence not in the transition table): clear the ttyMode, and return false;
|
||||
// for a terminating state (escape sequence is terminated successfully): run interpretCSI(), and return false.
|
||||
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
private fun interpretEscapeSequence() {
|
||||
TODO()
|
||||
}
|
||||
|
||||
|
||||
|
||||
private val ESC = 0x1B.toByte()
|
||||
private val LBRACKET = 0x5B.toByte()
|
||||
|
||||
private val FORE_DEFAULT = 254
|
||||
private val BACK_DEFAULT = 255
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Note 1. State machine for Escape sequence
|
||||
|
||||
digraph G {
|
||||
|
||||
ESC -> Reset [label="c"]
|
||||
ESC -> CSI [label="["]
|
||||
|
||||
CSI -> numeral [label="0..9"]
|
||||
CSI -> CursorUp [label="A"]
|
||||
CSI -> CursorDown [label="B"]
|
||||
CSI -> CursorFwd [label="C"]
|
||||
CSI -> CursorBack [label="D"]
|
||||
CSI -> CursorNextLine [label="E"]
|
||||
CSI -> CursorPrevLine [label="F"]
|
||||
CSI -> CursorY [label="G"]
|
||||
CSI -> EraseDisp [label="J"]
|
||||
CSI -> EraseLine [label="K"]
|
||||
CSI -> ScrollUp [label="S"]
|
||||
CSI -> ScrollDown [label="T"]
|
||||
|
||||
numeral -> numeral [label="0..9"]
|
||||
numeral -> CursorUp [label="A"]
|
||||
numeral -> CursorDown [label="B"]
|
||||
numeral -> CursorFwd [label="C"]
|
||||
numeral -> CursorBack [label="D"]
|
||||
numeral -> CursorNextLine [label="E"]
|
||||
numeral -> CursorPrevLine [label="F"]
|
||||
numeral -> CursorY [label="G"]
|
||||
numeral -> EraseDisp [label="J"]
|
||||
numeral -> EraseLine [label="K"]
|
||||
numeral -> ScrollUp [label="S"]
|
||||
numeral -> ScrollDown [label="T"]
|
||||
|
||||
numeral -> SGR [label="(any unacceptable char)"]
|
||||
|
||||
numeral -> separator1 [label=";"]
|
||||
separator1 -> numeral2 [label="0..9"]
|
||||
numeral2 -> numeral2 [label="0..9"]
|
||||
numeral2 -> CursorPos [label="H"]
|
||||
|
||||
numeral2 -> separator2 [label=";"]
|
||||
|
||||
separator2 -> numeral3 [label="0..9"]
|
||||
numeral3 -> numeral3 [label="0..9"]
|
||||
|
||||
numeral3 -> "SGR-Colour" [label="(any unacceptable char)"]
|
||||
|
||||
ESC [shape=Mdiamond]
|
||||
Reset -> end
|
||||
CursorUp -> end
|
||||
CursorDown -> end
|
||||
CursorFwd -> end
|
||||
CursorBack -> end
|
||||
CursorNextLine -> end
|
||||
CursorPrevLine -> end
|
||||
CursorY -> end
|
||||
EraseDisp -> end
|
||||
EraseLine -> end
|
||||
ScrollUp -> end
|
||||
ScrollDown -> end
|
||||
CursorPos -> end
|
||||
SGR -> end
|
||||
"SGR-Colour" -> end
|
||||
end [shape=Msquare]
|
||||
}
|
||||
|
||||
*/
|
||||
@@ -11,9 +11,9 @@ import net.torvald.tsvm.kB
|
||||
import sun.nio.ch.DirectBuffer
|
||||
import kotlin.experimental.and
|
||||
|
||||
class GraphicsAdapter(val lcdMode: Boolean = false) : PeriBase {
|
||||
class GraphicsAdapter(val lcdMode: Boolean = false) : GlassTty(Companion.TEXT_ROWS, Companion.TEXT_COLS), PeriBase {
|
||||
|
||||
internal val framebuffer = Pixmap(WIDTH, HEIGHT, Pixmap.Format.RGBA8888)
|
||||
internal val framebuffer = Pixmap(WIDTH, HEIGHT, Pixmap.Format.Alpha)
|
||||
private var rendertex = Texture(1, 1, Pixmap.Format.RGBA8888)
|
||||
internal val paletteOfFloats = FloatArray(1024) {
|
||||
val rgba = DEFAULT_PALETTE[it / 4]
|
||||
@@ -29,15 +29,16 @@ class GraphicsAdapter(val lcdMode: Boolean = false) : PeriBase {
|
||||
private val paletteShader = AppLoader.loadShaderInline(DRAW_SHADER_VERT, if (lcdMode) DRAW_SHADER_FRAG_LCD else DRAW_SHADER_FRAG)
|
||||
private val textShader = AppLoader.loadShaderInline(DRAW_SHADER_VERT, if (lcdMode) TEXT_TILING_SHADER_LCD else TEXT_TILING_SHADER)
|
||||
|
||||
private var textmodeBlinkCursor = true
|
||||
override var blinkCursor = true
|
||||
override var ttyRawMode = false
|
||||
private var graphicsUseSprites = false
|
||||
private var lastUsedColour = (-1).toByte()
|
||||
private var currentChrRom = 0
|
||||
private var chrWidth = 7f
|
||||
private var chrHeight = 14f
|
||||
|
||||
private var ttyFore: Int = 254 // cannot be Byte
|
||||
private var ttyBack: Int = 255 // cannot be Byte
|
||||
override var ttyFore: Int = 254 // cannot be Byte
|
||||
override var ttyBack: Int = 255 // cannot be Byte
|
||||
|
||||
private val textForePixmap = Pixmap(TEXT_COLS, TEXT_ROWS, Pixmap.Format.RGBA8888)
|
||||
private val textBackPixmap = Pixmap(TEXT_COLS, TEXT_ROWS, Pixmap.Format.RGBA8888)
|
||||
@@ -52,7 +53,14 @@ class GraphicsAdapter(val lcdMode: Boolean = false) : PeriBase {
|
||||
private val memTextBackOffset = 2980L + 2560
|
||||
private val memTextOffset = 2980L + 2560 + 2560
|
||||
|
||||
private fun getTtyCursorPos() = spriteAndTextArea.getShort(memTextCursorPosOffset) % TEXT_COLS to spriteAndTextArea.getShort(3938L) / TEXT_COLS
|
||||
override var rawCursorPos: Int
|
||||
get() = spriteAndTextArea.getShort(memTextCursorPosOffset).toInt()
|
||||
set(value) { spriteAndTextArea.setShort(memTextCursorPosOffset, value.toShort()) }
|
||||
|
||||
override fun getCursorPos() = rawCursorPos % TEXT_COLS to rawCursorPos / TEXT_COLS
|
||||
override fun setCursorPos(x: Int, y: Int) {
|
||||
rawCursorPos = toTtyTextOffset(x, y)
|
||||
}
|
||||
private fun toTtyTextOffset(x: Int, y: Int) = y * TEXT_COLS + x
|
||||
|
||||
init {
|
||||
@@ -71,12 +79,15 @@ class GraphicsAdapter(val lcdMode: Boolean = false) : PeriBase {
|
||||
// when in text mode, and that's undesired behaviour
|
||||
// -1 is preferred because it points to the colour CLEAR, and it's constant.
|
||||
spriteAndTextArea.fillWith(-1)
|
||||
|
||||
|
||||
println(framebuffer.pixels.limit())
|
||||
}
|
||||
|
||||
override fun peek(addr: Long): Byte? {
|
||||
val adi = addr.toInt()
|
||||
return when (addr) {
|
||||
in 0 until 250880 -> framebuffer.getPixel(adi % WIDTH, adi / WIDTH).toByte()
|
||||
in 0 until 250880 -> framebuffer.pixels.get(adi)//framebuffer.getPixel(adi % WIDTH, adi / WIDTH).toByte()
|
||||
in 250880 until 250972 -> unusedArea[adi - 250880]
|
||||
in 250972 until 261632 -> spriteAndTextArea[addr - 250972]
|
||||
in 261632 until 262144 -> peekPalette(adi - 261632)
|
||||
@@ -94,7 +105,7 @@ class GraphicsAdapter(val lcdMode: Boolean = false) : PeriBase {
|
||||
when (addr) {
|
||||
in 0 until 250880 -> {
|
||||
lastUsedColour = byte
|
||||
framebuffer.drawPixel(adi % WIDTH, adi / WIDTH, bi.shl(24))
|
||||
framebuffer.pixels.put(adi, byte)
|
||||
}
|
||||
250883L -> {
|
||||
unusedArea[adi - 250880] = byte
|
||||
@@ -110,13 +121,16 @@ class GraphicsAdapter(val lcdMode: Boolean = false) : PeriBase {
|
||||
}
|
||||
}
|
||||
|
||||
private fun getTextmodeAttirbutes(): Byte = (currentChrRom.and(15).shl(4) or textmodeBlinkCursor.toInt()).toByte()
|
||||
private fun getTextmodeAttirbutes(): Byte = (currentChrRom.and(15).shl(4) or
|
||||
ttyRawMode.toInt().shl(1) or
|
||||
blinkCursor.toInt()).toByte()
|
||||
|
||||
private fun getGraphicsAttributes(): Byte = graphicsUseSprites.toInt().toByte()
|
||||
|
||||
private fun setTextmodeAttributes(rawbyte: Byte) {
|
||||
currentChrRom = rawbyte.toInt().and(0b11110000).ushr(4)
|
||||
textmodeBlinkCursor = rawbyte.and(1) == 1.toByte()
|
||||
blinkCursor = rawbyte.and(0b0001) != 0.toByte()
|
||||
ttyRawMode = rawbyte.and(0b0010) != 0.toByte()
|
||||
}
|
||||
|
||||
private fun setGraphicsAttributes(rawbyte: Byte) {
|
||||
@@ -173,35 +187,17 @@ class GraphicsAdapter(val lcdMode: Boolean = false) : PeriBase {
|
||||
* @param to memory "offset" in Graphics Adapter's memory space, starts from zero.
|
||||
* @param length how many bytes should be moved
|
||||
*/
|
||||
fun bulkLoad(vm: VM, from: Long, to: Long, length: Long) {
|
||||
/*fun bulkLoad(vm: VM, from: Long, to: Long, length: Long) {
|
||||
UnsafeHelper.unsafe.copyMemory(null, vm.usermem.ptr + from, (framebuffer.pixels as DirectBuffer).address(), to, length)
|
||||
}
|
||||
}*/
|
||||
|
||||
private fun putChar(x: Int, y: Int, text: Byte, foreColour: Byte = ttyFore.toByte(), backColour: Byte = ttyBack.toByte()) {
|
||||
override fun putChar(x: Int, y: Int, text: Byte, foreColour: Byte, backColour: Byte) {
|
||||
val textOff = toTtyTextOffset(x, y)
|
||||
spriteAndTextArea[memTextForeOffset + textOff] = foreColour
|
||||
spriteAndTextArea[memTextBackOffset + textOff] = backColour
|
||||
spriteAndTextArea[memTextOffset + textOff] = text
|
||||
}
|
||||
|
||||
private fun advanceCursor() {
|
||||
spriteAndTextArea.setShort(
|
||||
memTextCursorPosOffset,
|
||||
((spriteAndTextArea.getShort(memTextCursorPosOffset) + 1) % (TEXT_COLS * TEXT_ROWS)).toShort()
|
||||
)
|
||||
}
|
||||
|
||||
// how TTY should work with all those ASCII control characters
|
||||
fun print(char: Byte) {
|
||||
val (cx, cy) = getTtyCursorPos()
|
||||
when (char) {
|
||||
in 0x20..0x7E, in 0x80..0xFF -> {
|
||||
putChar(cx, cy, char)
|
||||
advanceCursor()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
framebuffer.dispose()
|
||||
rendertex.dispose()
|
||||
@@ -225,7 +221,7 @@ class GraphicsAdapter(val lcdMode: Boolean = false) : PeriBase {
|
||||
|
||||
fun render(delta: Float, batch: SpriteBatch, x: Float, y: Float) {
|
||||
rendertex.dispose()
|
||||
rendertex = Texture(framebuffer)
|
||||
rendertex = Texture(framebuffer, Pixmap.Format.RGBA8888, false)
|
||||
|
||||
|
||||
batch.shader = null
|
||||
@@ -383,7 +379,7 @@ float rand(vec2 co){
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
gl_FragColor = pal[int(texture2D(u_texture, v_texCoords).r * 255.0)];
|
||||
gl_FragColor = pal[int(texture2D(u_texture, v_texCoords).a * 255.0)];
|
||||
}
|
||||
""".trimIndent()
|
||||
|
||||
@@ -403,7 +399,7 @@ float rand(vec2 co){
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
vec4 palCol = pal[int(texture2D(u_texture, v_texCoords).r * 255.0)];
|
||||
vec4 palCol = pal[int(texture2D(u_texture, v_texCoords).a * 255.0)];
|
||||
float lum = floor((3.0 * palCol.r + 4.0 * palCol.g + palCol.b) / 8.0 * intensitySteps) / intensitySteps;
|
||||
vec4 outIntensity = vec4(vec3(1.0 - lum), palCol.a);
|
||||
|
||||
|
||||
7
src/net/torvald/tsvm/peripheral/TermSim.kt
Normal file
7
src/net/torvald/tsvm/peripheral/TermSim.kt
Normal file
@@ -0,0 +1,7 @@
|
||||
package net.torvald.tsvm.peripheral
|
||||
|
||||
internal class TermSim {
|
||||
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user