graphics computer -- working sprite system

Former-commit-id: eedad5c99d0d8fa1d74a7a5b4e6250017d55163b
Former-commit-id: 0dc08e778cca3300ffc6f696ba395eb8ca2b154b
This commit is contained in:
Song Minjae
2017-02-24 17:35:32 +09:00
parent 1b079524f4
commit 30b82acb4b
11 changed files with 430 additions and 111 deletions

View File

@@ -39,3 +39,8 @@ Connect two or more tracker head to play the array of trackers play simultaneous
- Include a valid way of obtaining Aimhack (possessed weapon shit?)
- Implement it on ```<item>.primaryUse(gc, delta)```
## Computers ##
Instead of single box with bunch of parts, make computers occupy several blocks -- processor unit, core memory unit, storage unit (RAMAC!), I/O unit, etc., like old PDPs. Powerful computer == more space. Plus portable units like TRS-80 Model 100.

View File

@@ -0,0 +1,73 @@
package net.torvald.terrarum
import net.torvald.random.HQRNG
import net.torvald.terrarum.gameactors.roundInt
import net.torvald.terrarum.virtualcomputer.computer.BaseTerrarumComputer
import net.torvald.terrarum.virtualcomputer.peripheral.PeripheralVideoCard
import net.torvald.terrarum.virtualcomputer.terminal.GraphicsTerminal
import org.lwjgl.opengl.GL11
import org.newdawn.slick.GameContainer
import org.newdawn.slick.Graphics
import org.newdawn.slick.state.BasicGameState
import org.newdawn.slick.state.StateBasedGame
import java.util.*
/**
* Created by SKYHi14 on 2017-02-23.
*/
class StateGraphicComputerTest : BasicGameState() {
val computer = BaseTerrarumComputer(8)
val monitor = GraphicsTerminal(computer)
init {
val videocard = PeripheralVideoCard()
monitor.attachVideoCard(videocard)
computer.attachTerminal(monitor)
computer.attachPeripheral(videocard)
}
override fun init(container: GameContainer?, game: StateBasedGame?) {
val sprite = (computer.getPeripheral("ppu") as PeripheralVideoCard).vram.sprites[0]
sprite.setLine(0, intArrayOf(1,1,0,0,0,0,3,3))
sprite.setLine(1, intArrayOf(1,1,0,0,0,0,3,3))
sprite.setLine(2, intArrayOf(1,1,0,0,0,0,1,1))
sprite.setLine(3, intArrayOf(1,1,1,1,1,1,1,1))
sprite.setLine(4, intArrayOf(1,1,1,1,1,1,1,1))
sprite.setLine(5, intArrayOf(0,0,0,0,0,0,1,1))
sprite.setLine(6, intArrayOf(2,2,0,0,0,0,1,1))
sprite.setLine(7, intArrayOf(2,2,0,0,0,0,1,1))
}
var angle = 0.0
override fun update(container: GameContainer, game: StateBasedGame?, delta: Int) {
Terrarum.appgc.setTitle("VT — F: ${container.fps}" +
" — M: ${Terrarum.memInUse}M / ${Terrarum.memTotal}M / ${Terrarum.memXmx}M")
monitor.update(container, delta)
computer.update(container, delta)
val sprite = (computer.getPeripheral("ppu") as PeripheralVideoCard).vram.sprites[0]
angle += delta / 500.0
sprite.posX = (Math.cos(angle) * 80 + 100).roundInt()
sprite.posY = (Math.sin(angle) * 80 + 100).roundInt()
sprite.pal0 = (sprite.pal0 + 1) % 65
sprite.pal1 = (sprite.pal1 + 1) % 65
sprite.pal2 = (sprite.pal2 + 1) % 65
sprite.pal3 = (sprite.pal3 + 1) % 65
sprite.rotation = (angle * 2 / Math.PI).roundInt() % 4
}
override fun getID() = Terrarum.STATE_ID_TEST_TTY
override fun render(container: GameContainer, game: StateBasedGame?, g: Graphics) {
monitor.render(container, g)
}
}

View File

@@ -131,10 +131,11 @@ constructor(gamename: String) : StateBasedGame(gamename) {
gc.graphics.clear() // clean up any 'dust' in the buffer
//addState(StateVTTest())
addState(StateGraphicComputerTest())
//addState(StateTestingLightning())
//addState(StateSplash())
//addState(StateMonitorCheck())
addState(StateFontTester())
//addState(StateFontTester())
//addState(StateNoiseTexGen())
//addState(StateBlurTest())
//addState(StateShaderTest())
@@ -467,7 +468,14 @@ constructor(gamename: String) : StateBasedGame(gamename) {
}
val currentSaveDir: File
get() = File(defaultSaveDir + "/test") // TODO TEST CODE
get() {
val file = File(defaultSaveDir + "/test")
// failsafe?
if (!file.exists()) file.mkdir()
return file // TODO TEST CODE
}
}
}

View File

@@ -107,10 +107,18 @@ class BaseTerrarumComputer(peripheralSlots: Int) {
computerValue["boot"] = computerValue.getAsString("hda")!!
}
fun getPeripheral(tableName: String): Peripheral? {
peripheralTable.forEach {
if (it.tableName == tableName)
return it
}
return null
}
fun attachPeripheral(peri: Peripheral) {
if (peripheralTable.size < maxPeripherals) {
peripheralTable.add(peri)
peri.loadLib()
peri.loadLib(luaJ_globals)
println("[BaseTerrarumComputer] loading peripheral $peri")
}
else {
@@ -121,7 +129,6 @@ class BaseTerrarumComputer(peripheralSlots: Int) {
fun detachPeripheral(peri: Peripheral) {
if (peripheralTable.contains(peri)) {
peripheralTable.remove(peri)
peri.unloadLib()
println("[BaseTerrarumComputer] unloading peripheral $peri")
}
else {
@@ -153,7 +160,6 @@ class BaseTerrarumComputer(peripheralSlots: Int) {
Filesystem(luaJ_globals, this)
HostAccessProvider(luaJ_globals, this)
Input(luaJ_globals, this)
PeripheralInternet(luaJ_globals, this)
PcSpeakerDriver(luaJ_globals, this)
WorldInformationProvider(luaJ_globals)
@@ -179,8 +185,8 @@ class BaseTerrarumComputer(peripheralSlots: Int) {
// load every peripheral if we're in DEBUG
if (DEBUG) {
maxPeripherals = 32
attachPeripheral(PeripheralInternet(luaJ_globals, this))
attachPeripheral(PeripheralPSG(luaJ_globals, this))
attachPeripheral(PeripheralInternet(this))
attachPeripheral(PeripheralPSG(this))
// ...
}
}
@@ -281,8 +287,8 @@ class BaseTerrarumComputer(peripheralSlots: Int) {
chunk.call()
}
catch (e: LuaError) {
lua.STDERR.println("${SimpleTextTerminal.ASCII_DLE}${e.message}${SimpleTextTerminal.ASCII_DC4}")
e.printStackTrace(System.err)
lua.STDERR.println("${SimpleTextTerminal.ASCII_DLE}${e.message}${SimpleTextTerminal.ASCII_DC4}")
}
}
}

View File

@@ -74,9 +74,12 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
lowerCase.delete()
isCaseInsensitive = insensitive
println("[Filesystem] Case insensitivity: $isCaseInsensitive")
}
catch (e: IOException) {
println("[Filesystem] Couldn't determine if file system is case sensitive, falling back to insensitive.")
System.err.println("[Filesystem] Couldn't determine if the file system is case sensitive, falling back to insensitive.")
e.printStackTrace(System.out)
isCaseInsensitive = true
}
}

View File

@@ -7,14 +7,9 @@ import org.luaj.vm2.LuaValue
/**
* Created by minjaesong on 16-09-29.
*/
open class Peripheral(val luaG: Globals, val tableName: String) {
abstract class Peripheral(val tableName: String) {
open fun loadLib() {
luaG[tableName] = LuaTable()
}
open fun unloadLib() {
luaG[tableName] = LuaValue.NIL
}
abstract fun loadLib(globals: Globals)
override fun toString(): String = tableName
override fun toString(): String = "Peripheral:$tableName"
}

View File

@@ -2,6 +2,7 @@ package net.torvald.terrarum.virtualcomputer.peripheral
import org.luaj.vm2.Globals
import net.torvald.terrarum.virtualcomputer.computer.BaseTerrarumComputer
import org.luaj.vm2.LuaTable
import org.luaj.vm2.LuaValue
import org.luaj.vm2.lib.OneArgFunction
import java.io.BufferedReader
@@ -13,11 +14,11 @@ import java.net.URL
*
* Created by minjaesong on 16-09-24.
*/
internal class PeripheralInternet(val globals: Globals, val host: BaseTerrarumComputer)
: Peripheral(globals, "internet"){
internal class PeripheralInternet(val host: BaseTerrarumComputer)
: Peripheral("internet"){
override fun loadLib() {
super.loadLib()
override fun loadLib(globals: Globals) {
globals["internet"] = LuaTable()
globals["internet"]["fetch"] = FetchWebPage()
}

View File

@@ -11,11 +11,11 @@ import org.luaj.vm2.LuaValue
*
* Created by minjaesong on 16-09-27.
*/
internal class PeripheralPSG(val globals: Globals, val host: BaseTerrarumComputer)
: Peripheral(globals, "psg") {
internal class PeripheralPSG(val host: BaseTerrarumComputer)
: Peripheral("psg") {
override fun loadLib() {
super.loadLib()
override fun loadLib(globals: Globals) {
globals["psg"] = LuaTable()
}
}

View File

@@ -10,13 +10,15 @@ import org.luaj.vm2.lib.OneArgFunction
import org.luaj.vm2.lib.ThreeArgFunction
import org.luaj.vm2.lib.TwoArgFunction
import org.luaj.vm2.lib.ZeroArgFunction
import org.lwjgl.opengl.GL11
import org.newdawn.slick.*
import java.util.*
/**
* Created by SKYHi14 on 2017-02-08.
*/
class PeripheralVideoCard(val globals: Globals, val termW: Int = 40, val termH: Int = 25) : Peripheral(globals, "ppu") {
class PeripheralVideoCard(val termW: Int = 40, val termH: Int = 25) :
Peripheral("ppu") {
companion object {
val blockW = 8
val blockH = 8
@@ -43,53 +45,121 @@ class PeripheralVideoCard(val globals: Globals, val termW: Int = 40, val termH:
val height = termH * blockH
val vram = VRAM(width, height, 64)
val frameBuffer = Image(width, height)
val frameBufferG = frameBuffer.graphics
var fontRom = SpriteSheet("./assets/graphics/fonts/milky.tga", blockW, blockH)
// hard-coded 8x8
var fontRom = Array<IntArray>(256, { Array<Int>(blockH, { 0 }).toIntArray() })
val CLUT = vram.CLUT
init {
// build it for first time
resetTextRom()
}
val CLUT = VRAM.CLUT
val coloursCount = CLUT.size
override fun loadLib() {
super.loadLib()
globals["ppu"]["setColor"] = SetColor(this)
globals["ppu"]["getColor"] = GetColor(this)
globals["ppu"]["emitChar"] = EmitChar(this)
fun buildFontRom(ref: String) {
// load font rom out of TGA
val imageRef = Image(ref)
val image = imageRef.texture.textureData
val imageWidth = imageRef.width
for (i in 0..255) {
for (y in 0..blockH - 1) {
// letter mirrored horizontally!
var scanline = 0
for (x in 0..blockW - 1) {
val subX = i % 16
val subY = i / 16
val bit = image[4 * ((subY * blockH + y) * imageWidth + blockW * subX + x) + 3] != 0.toByte()
if (bit) scanline = scanline or (1 shl x)
}
fontRom[i][y] = scanline
}
}
}
override fun loadLib(globals: Globals) {
globals["ppu"] = LuaTable()
globals["ppu"]["setForeColor"] = SetForeColor(this)
globals["ppu"]["getForeColor"] = GetForeColor(this)
globals["ppu"]["setBackColor"] = SetBackColor(this)
globals["ppu"]["getBackColor"] = GetBackColor(this)
globals["ppu"]["emitChar"] = EmitChar(this)
globals["ppu"]["clearAll"] = ClearAll(this)
globals["ppu"]["clearBack"] = ClearBackground(this)
globals["ppu"]["clearFore"] = ClearForeground(this)
}
private val spriteBuffer = ImageBuffer(VSprite.width, VSprite.height)
fun render(g: Graphics) {
g.drawImage(vram.background.image, 0f, 0f)
fun VSprite.render() {
val h = VSprite.height
val w = VSprite.width
if (rotation and 1 == 0) { // deg 0, 180
(if (rotation == 0 && !vFlip || rotation == 2 && vFlip) 0..h-1 else h-1 downTo 0).forEachIndexed { ordY, y ->
(if (rotation == 0 && !hFlip || rotation == 2 && hFlip) 0..w-1 else w-1 downTo 0).forEachIndexed { ordX, x ->
val pixelData = data[y].ushr(2 * x).and(0b11)
val col = getColourFromPalette(pixelData)
spriteBuffer.setRGBA(ordX, ordY, col.red, col.green, col.blue, col.alpha)
}
}
}
else { // deg 90, 270
(if (rotation == 3 && !hFlip || rotation == 1 && hFlip) 0..w-1 else w-1 downTo 0).forEachIndexed { ordY, y ->
(if (rotation == 3 && !vFlip || rotation == 1 && vFlip) h-1 downTo 0 else 0..h-1).forEachIndexed { ordX, x ->
val pixelData = data[y].ushr(2 * x).and(0b11)
val col = getColourFromPalette(pixelData)
spriteBuffer.setRGBA(ordY, ordX, col.red, col.green, col.blue, col.alpha)
}
}
}
}
frameBuffer.filter = Image.FILTER_NEAREST
frameBufferG.clear()
frameBufferG.drawImage(vram.background.image, 0f, 0f)
vram.sprites.forEach {
if (it.isBackground) {
val spriteImage = it.data.image.getFlippedCopy(it.hFlip, it.vFlip)
spriteImage.rotate(90f * it.rotation)
g.drawImage(spriteImage, it.xpos.toFloat(), it.ypos.toFloat())
it.render()
frameBufferG.drawImage(spriteBuffer.image, it.posX.toFloat(), it.posY.toFloat())
}
}
g.drawImage(vram.foreground.image, 0f, 0f)
frameBufferG.drawImage(vram.foreground.image, 0f, 0f)
vram.sprites.forEach {
if (!it.isBackground) {
val spriteImage = it.data.image.getFlippedCopy(it.hFlip, it.vFlip)
spriteImage.rotate(90f * it.rotation)
g.drawImage(spriteImage, it.xpos.toFloat(), it.ypos.toFloat())
}
it.render()
frameBufferG.drawImage(spriteBuffer.image, it.posX.toFloat(), it.posY.toFloat())
}
}
private var currentColour = 49 // white
fun getColor() = currentColour
fun setColor(value: Int) { currentColour = value }
frameBufferG.flush()
fun drawChar(c: Char, x: Int, y: Int, col: Int = currentColour) {
val glyph = fontRom.getSubImage(c.toInt() % 16, c.toInt() / 16)
val color = CLUT[col]
g.drawImage(frameBuffer.getScaledCopy(2f), 0f, 0f)
}
private var foreColor = 49 // white
private var backColor = 64 // transparent
fun drawChar(c: Char, x: Int, y: Int, colFore: Int = foreColor, colBack: Int = backColor) {
val glyph = fontRom[c.toInt()]
val fore = CLUT[colFore]
val back = CLUT[colBack]
// software render
for (gy in 0..blockH) {
for (gx in 0..blockW) {
val glyAlpha = glyph.getPixel(gx, gy)[3]
for (gy in 0..blockH - 1) {
for (gx in 0..blockW - 1) {
val glyAlpha = glyph[gy].ushr(gx).and(1)
if (glyAlpha > 0) {
vram.foreground.setRGBA(x * blockW + gx, y * blockH + gy, color.red, color.green, color.blue, 255)
if (glyAlpha != 0) {
vram.foreground.setRGBA(x * blockW + gx, y * blockH + gy, fore.red, fore.green, fore.blue, fore.alpha)
}
else {
vram.foreground.setRGBA(x * blockW + gx, y * blockH + gy, back.red, back.green, back.blue, back.alpha)
}
}
}
@@ -104,39 +174,75 @@ class PeripheralVideoCard(val globals: Globals, val termW: Int = 40, val termH:
fun clearForeground() {
for (i in 0..width * height - 1) {
vram.foreground.rgba[i] = if (i % 4 == 3) 0xFF.toByte() else 0x00.toByte()
vram.foreground.rgba[i] = 0x00.toByte()
}
}
fun clearAll() {
for (i in 0..width * height - 1) {
vram.background.rgba[i] = if (i % 4 == 3) 0xFF.toByte() else 0x00.toByte()
vram.foreground.rgba[i] = if (i % 4 == 3) 0xFF.toByte() else 0x00.toByte()
vram.foreground.rgba[i] = 0x00.toByte()
}
}
fun getSprite(index: Int) = vram.sprites[index]
fun setTextRom(data: Array<BitSet>) {
TODO("Not implemented")
/**
* Array be like, in binary; notice that glyphs are flipped horizontally:
* ...
* 00011000
* 00011100
* 00011000
* 00011000
* 00011000
* 00011000
* 01111111
* 00000000
* 00111110
* 01100011
* 01100000
* 00111111
* 00000011
* 00000011
* 01111111
* 00000000
* ...
*/
fun setTextRom(data: Array<Int>) {
for (i in 0..255) {
for (y in 0..blockH - 1) {
// letter mirrored horizontally!
fontRom[i][y] = data[blockH * i + y]
}
}
}
fun resetTextRom() {
fontRom = SpriteSheet("./assets/graphics/fonts/milky.tga", blockW, blockH)
buildFontRom("./assets/graphics/fonts/milky.tga")
}
class SetColor(val videoCard: PeripheralVideoCard) : OneArgFunction() {
class SetForeColor(val videoCard: PeripheralVideoCard) : OneArgFunction() {
override fun call(arg: LuaValue): LuaValue {
videoCard.setColor(arg.checkint())
videoCard.foreColor = arg.checkint()
return LuaValue.NONE
}
}
class GetColor(val videoCard: PeripheralVideoCard) : ZeroArgFunction() {
class GetForeColor(val videoCard: PeripheralVideoCard) : ZeroArgFunction() {
override fun call(): LuaValue {
return videoCard.getColor().toLua()
return videoCard.foreColor.toLua()
}
}
class SetBackColor(val videoCard: PeripheralVideoCard) : OneArgFunction() {
override fun call(arg: LuaValue): LuaValue {
videoCard.backColor = arg.checkint()
return LuaValue.NONE
}
}
class GetBackColor(val videoCard: PeripheralVideoCard) : ZeroArgFunction() {
override fun call(): LuaValue {
return videoCard.backColor.toLua()
}
}
class EmitChar(val videoCard: PeripheralVideoCard) : ThreeArgFunction() {
@@ -146,6 +252,24 @@ class PeripheralVideoCard(val globals: Globals, val termW: Int = 40, val termH:
return LuaValue.NONE
}
}
class ClearAll(val videoCard: PeripheralVideoCard) : ZeroArgFunction() {
override fun call(): LuaValue {
videoCard.clearAll()
return LuaValue.NONE
}
}
class ClearBackground(val videoCard: PeripheralVideoCard) : ZeroArgFunction() {
override fun call(): LuaValue {
videoCard.clearBackground()
return LuaValue.NONE
}
}
class ClearForeground(val videoCard: PeripheralVideoCard) : ZeroArgFunction() {
override fun call(): LuaValue {
videoCard.clearForeground()
return LuaValue.NONE
}
}
/////////////
// Sprites //
@@ -211,9 +335,9 @@ class VRAM(pxlWidth: Int, pxlHeight: Int, nSprites: Int) {
val background = ImageBuffer(pxlWidth, pxlHeight)
val foreground = ImageBuffer(pxlWidth, pxlHeight) // text mode glyphs rendered here
var transparentKey: Int = 15 // black
val CLUT = DecodeTapestry.colourIndices64
companion object {
val CLUT = DecodeTapestry.colourIndices64 + Color(0, 0, 0, 0)
}
fun setBackgroundPixel(x: Int, y: Int, color: Int) {
@@ -223,26 +347,26 @@ class VRAM(pxlWidth: Int, pxlHeight: Int, nSprites: Int) {
fun setForegroundPixel(x: Int, y: Int, color: Int) {
val col = CLUT[color]
background.setRGBA(x, y, col.red, col.green, col.blue, if (color == transparentKey) 0 else 255)
background.setRGBA(x, y, col.red, col.green, col.blue, col.alpha)
}
}
class VSprite {
private val width = 8
private val height = 8
companion object {
val width = 8
val height = 8
}
val CLUT = DecodeTapestry.colourIndices64
val data = ImageBuffer(width, height)
internal val CLUT = VRAM.CLUT
internal val data = IntArray(height)
var pal0 = 15 // black
var pal0 = 64 // transparent
var pal1 = 56 // light cyan
var pal2 = 19 // magenta
var pal3 = 49 // white
var transparentKey = 15 // black
var xpos = 0
var ypos = 0
var posX = 0
var posY = 0
var hFlip = false
var vFlip = false
@@ -270,18 +394,18 @@ class VSprite {
}
fun setPixel(x: Int, y: Int, color: Int) {
val col = getColourFromPalette(color)
data.setRGBA(x, y, col.red, col.green, col.blue, if (color == transparentKey) 0 else 255)
data[y] = data[y] xor data[y].and(3 shl (2 * x)) // mask off desired area to 0b00
data[y] = data[y] or (color shl (2 * x))
}
fun setLine(y: Int, rowData: IntArray) {
for (i in 0..width) {
for (i in 0..width - 1) {
setPixel(i, y, rowData[i])
}
}
fun setAll(data: IntArray) {
for (i in 0..width * height) {
for (i in 0..width * height - 1) {
setPixel(i % width, i / width, data[i])
}
}

View File

@@ -1,6 +1,7 @@
package net.torvald.terrarum.virtualcomputer.terminal
import net.torvald.terrarum.blendMul
import net.torvald.terrarum.gameactors.DecodeTapestry
import net.torvald.terrarum.virtualcomputer.computer.BaseTerrarumComputer
import net.torvald.terrarum.virtualcomputer.peripheral.PeripheralVideoCard
import org.newdawn.slick.Color
@@ -9,32 +10,45 @@ import org.newdawn.slick.Graphics
import org.newdawn.slick.Image
/**
* Printing text using Term API triggers 'compatibility' mode, where you are limited to 16 colours.
* Use PPU API for full 64 colours!
*
* Created by SKYHi14 on 2017-02-08.
*/
class GraphicsTerminal(
private val host: BaseTerrarumComputer, val videoCard: PeripheralVideoCard
) : Terminal {
override val width = videoCard.termW
override val height = videoCard.termH
override val coloursCount = videoCard.coloursCount
class GraphicsTerminal(private val host: BaseTerrarumComputer) : Terminal {
lateinit var videoCard: PeripheralVideoCard
override val width: Int; get() = videoCard.termW
override val height: Int; get() = videoCard.termH
override val coloursCount: Int; get() = videoCard.coloursCount
override var cursorX = 0
override var cursorY = 0
override var cursorBlink = true
override var backColour = 15 // black
override var foreColour = 48 // bright grey
val backDefault = 0 // black
val foreDefault = 1 // white
override var backColour = backDefault
override var foreColour = foreDefault
private val colourKey: Int
get() = backColour.shl(4) or (foreColour).and(0xFF)
override var lastInputByte = -1
override fun getColor(index: Int) = videoCard.CLUT[index]
override val displayW = videoCard.width //+ 2 * borderSize
override val displayH = videoCard.height //+ 2 * borderSize
override val displayW: Int; get() = videoCard.width //+ 2 * borderSize
override val displayH: Int; get() = videoCard.height //+ 2 * borderSize
private val videoScreen = Image(videoCard.width, videoCard.height)
private lateinit var videoScreen: Image
var TABSIZE = 4
val errorColour = 6
override fun printChars(s: String) {
TODO("not implemented")
printString(s, cursorX, cursorY)
}
override fun update(gc: GameContainer, delta: Int) {
@@ -60,16 +74,15 @@ class GraphicsTerminal(
}
override fun render(gc: GameContainer, g: Graphics) {
videoCard.render(videoScreen.graphics)
g.drawImage(videoScreen.getScaledCopy(2f), 0f, 0f)
videoCard.render(g)
}
override fun keyPressed(key: Int, c: Char) {
TODO("not implemented")
//TODO("not implemented")
}
override fun writeChars(s: String) {
TODO("not implemented")
writeString(s, cursorX, cursorY)
}
/** Unlike lua function, this one in Zero-based. */
@@ -79,42 +92,78 @@ class GraphicsTerminal(
}
override fun openInput(echo: Boolean) {
TODO("not implemented")
//TODO("not implemented")
}
override fun emitChar(bufferChar: Int, x: Int, y: Int) {
TODO("not implemented")
videoCard.drawChar(
bufferChar.and(0xFF).toChar(), x, y,
CLUT16_TO_64[bufferChar.ushr(8).and(0xF)],
CLUT16_TO_64[bufferChar.ushr(12).and(0xF)]
)
}
override fun closeInputKey(keyFromUI: Int): Int {
TODO("not implemented")
//TODO("not implemented")
return 0
}
override fun closeInputString(): String {
TODO("not implemented")
//TODO("not implemented")
return " "
}
override var lastStreamInput: String? = null
override var lastKeyPress: Int? = null
override fun emitChar(c: Char, x: Int, y: Int) {
TODO("not implemented")
videoCard.drawChar(c, x, y, CLUT16_TO_64[foreColour])
}
override fun printChar(c: Char) {
TODO("not implemented")
wrap()
if (c >= ' ' && c.toInt() != 127) {
emitChar(c)
cursorX += 1
}
else {
when (c) {
ASCII_BEL -> bell(".")
ASCII_BS -> { cursorX -= 1; wrap() }
ASCII_TAB -> { cursorX = (cursorX).div(TABSIZE).times(TABSIZE) + TABSIZE }
ASCII_LF -> newLine()
ASCII_FF -> clear()
ASCII_CR -> { cursorX = 0 }
ASCII_DEL -> { cursorX -= 1; wrap(); emitChar(colourKey.shl(8)) }
ASCII_DC1, ASCII_DC2, ASCII_DC3, ASCII_DC4 -> { foreColour = c - ASCII_DC1 }
ASCII_DLE -> { foreColour = errorColour }
}
}
}
override fun emitString(s: String, x: Int, y: Int) {
TODO("not implemented")
setCursor(x, y)
for (i in 0..s.length - 1) {
printChar(s[i])
wrap()
}
setCursor(x, y)
}
override fun printString(s: String, x: Int, y: Int) {
TODO("not implemented")
writeString(s, x, y)
newLine()
}
override fun writeString(s: String, x: Int, y: Int) {
TODO("not implemented")
setCursor(x, y)
for (i in 0..s.length - 1) {
printChar(s[i])
wrap()
}
}
override fun clear() {
@@ -122,23 +171,31 @@ class GraphicsTerminal(
}
override fun clearLine() {
TODO("not implemented")
//TODO("not implemented")
}
override fun newLine() {
TODO("not implemented")
//TODO("not implemented")
}
override fun scroll(amount: Int) {
TODO("not implemented")
//TODO("not implemented")
}
/**
* does not changes color setting in PPU
*/
override fun setColour(back: Int, fore: Int) {
TODO("not implemented")
foreColour = fore
backColour = back
}
/**
* does not changes color setting in PPU
*/
override fun resetColour() {
TODO("not implemented")
foreColour = foreDefault
backColour = backDefault
}
/** // copied from SimpleTextTerminal
@@ -174,6 +231,53 @@ class GraphicsTerminal(
}
override fun getKeyPress(): Int? {
TODO("not implemented")
//TODO("not implemented")
return null
}
companion object {
private val WHITE7500 = Color(0xe4eaff)
val ASCII_NUL = 0.toChar()
val ASCII_BEL = 7.toChar() // *BEEP!*
val ASCII_BS = 8.toChar() // x = x - 1
val ASCII_TAB = 9.toChar() // move cursor to next (TABSIZE * yy) pos (5 -> 8, 3- > 4, 4 -> 8)
val ASCII_LF = 10.toChar() // new line
val ASCII_FF = 12.toChar() // new page
val ASCII_CR = 13.toChar() // x <- 0
val ASCII_DEL = 127.toChar() // backspace and delete char
val ASCII_DC1 = 17.toChar() // foreground colour 0
val ASCII_DC2 = 18.toChar() // foreground colour 1
val ASCII_DC3 = 19.toChar() // foreground colour 2
val ASCII_DC4 = 20.toChar() // foreground colour 3
val ASCII_DLE = 16.toChar() // error message colour
val asciiControlInUse = charArrayOf(
ASCII_NUL,
ASCII_BEL,
ASCII_BS,
ASCII_TAB,
ASCII_LF,
ASCII_FF,
ASCII_CR,
ASCII_DEL,
ASCII_DC1,
ASCII_DC2,
ASCII_DC3,
ASCII_DC4,
ASCII_DLE
)
val CLUT = DecodeTapestry.colourIndices64
val CLUT16_TO_64 = intArrayOf(
15, 49, 16, 48, 44, 29, 33, 18,
5, 22, 39, 26, 25, 10, 31, 13
)
}
fun attachVideoCard(videocard: PeripheralVideoCard) {
this.videoCard = videocard
videoScreen = Image(videoCard.width, videoCard.height)
}
}

View File

@@ -47,7 +47,7 @@ open class SimpleTextTerminal(
override var backColour = backDefault
override var foreColour = foreDefault
private val colourKey: Int
get() = backColour.shl(4).plus(foreColour).and(0xFF)
get() = backColour.shl(4) or (foreColour).and(0xFF)
override var cursorX = 0
override var cursorY = 0