1
0
mirror of https://github.com/irmen/ksim65.git synced 2024-06-06 22:29:33 +00:00

tweak charset logic

This commit is contained in:
Irmen de Jong 2019-10-14 20:48:48 +02:00
parent 009b0c5c15
commit e40456d7e4
2 changed files with 17 additions and 21 deletions

View File

@ -12,7 +12,7 @@ import javax.swing.JPanel
* The rendering logic of the screen of the C64.
* It supports: Character mode,
* High res bitmap mode (320*200), Multicolor bitmap mode (160*200).
* TODO: Multicolor character mode. Extended background color mode. Custom charsets.
* TODO: Custom charsets from RAM. Multicolor character mode. Extended background color mode.
*/
internal class Screen(private val chargenData: ByteArray, val ram: MemoryComponent) : JPanel() {
@ -26,7 +26,6 @@ internal class Screen(private val chargenData: ByteArray, val ram: MemoryCompone
val gd = ge.defaultScreenDevice.defaultConfiguration
fullscreenImage = gd.createCompatibleImage(ScreenDefs.SCREEN_WIDTH+2*ScreenDefs.BORDER_SIZE,
ScreenDefs.SCREEN_HEIGHT+2*ScreenDefs.BORDER_SIZE, Transparency.OPAQUE)
fullscreenImage.accelerationPriority = 1.0f
fullscreenG2d = fullscreenImage.graphics as Graphics2D
val size = Dimension(fullscreenImage.width*ScreenDefs.DISPLAY_PIXEL_SCALING.toInt(),
@ -40,9 +39,7 @@ internal class Screen(private val chargenData: ByteArray, val ram: MemoryCompone
}
private fun loadCharacters(shifted: Boolean): Array<BufferedImage> {
val chars = Array(256) {
BufferedImage(8, 8, BufferedImage.TYPE_BYTE_BINARY).also { it.accelerationPriority = 1.0f }
}
val chars = Array(256) { BufferedImage(8, 8, BufferedImage.TYPE_BYTE_BINARY) }
val offset = if (shifted) 256*8 else 0
for (char in 0..255) {
for (line in 0..7) {
@ -164,19 +161,13 @@ internal class Screen(private val chargenData: ByteArray, val ram: MemoryCompone
// normal character mode
val screenAddress = vicBank+(vicVMCSB ushr 4) shl 10
val charsetAddress = (vicVMCSB and 0b00001110) shl 10
if (charsetAddress == 0x1000 || charsetAddress == 0x1800) {
// use built-in character ROM
for (y in 0 until ScreenDefs.SCREEN_HEIGHT_CHARS) {
for (x in 0 until ScreenDefs.SCREEN_WIDTH_CHARS) {
val char = ram[screenAddress+x+y*ScreenDefs.SCREEN_WIDTH_CHARS].toInt()
val color = ram[0xd800+x+y*ScreenDefs.SCREEN_WIDTH_CHARS].toInt() // colors always at $d800
drawColoredChar(x, y, char, color, charsetAddress == 0x1800)
}
for (y in 0 until ScreenDefs.SCREEN_HEIGHT_CHARS) {
for (x in 0 until ScreenDefs.SCREEN_WIDTH_CHARS) {
val char = ram[screenAddress+x+y*ScreenDefs.SCREEN_WIDTH_CHARS].toInt()
val color = ram[0xd800+x+y*ScreenDefs.SCREEN_WIDTH_CHARS].toInt() // colors always at $d800
drawColoredChar(x, y, char, color, vicBank + charsetAddress)
}
}
/* else {
// TODO: custom charsets from RAM. Currently the charset ROM is just loaded externally.
} */
}
}
@ -239,10 +230,15 @@ internal class Screen(private val chargenData: ByteArray, val ram: MemoryCompone
pixels[offset+7] = fourColors[colors[3]]
}
private val coloredCharacters = mutableMapOf<Triple<Int, Int, Boolean>, BufferedImage>()
private val coloredCharacterImageCache = mutableMapOf<Triple<Int, Int, Boolean>, BufferedImage>()
private fun drawColoredChar(x: Int, y: Int, char: Int, color: Int, shifted: Boolean) {
var cached = coloredCharacters[Triple(char, color, shifted)]
private fun drawColoredChar(x: Int, y: Int, char: Int, color: Int, charsetAddr: Address) {
// The vic 'sees' the charset rom at these addresses: $1000 + $1800, $9000 + $9800
// so we can use pre-loaded images to efficiently draw the characters.
// If the address is different, the vic takes charset data from RAM instead.
// TODO: currently custom charsets taken from RAM are not yet supported
val shifted = charsetAddr and 0x0800 != 0
var cached = coloredCharacterImageCache[Triple(char, color, shifted)]
if (cached == null) {
cached = if (shifted) shiftedCharacters[char] else normalCharacters[char]
val colored = fullscreenG2d.deviceConfiguration.createCompatibleImage(8, 8, BufferedImage.BITMASK)
@ -259,7 +255,7 @@ internal class Screen(private val chargenData: ByteArray, val ram: MemoryCompone
}
}
}
coloredCharacters[Triple(char, color, shifted)] = colored
coloredCharacterImageCache[Triple(char, color, shifted)] = colored
cached = colored
}
fullscreenG2d.drawImage(cached, x*8+ScreenDefs.BORDER_SIZE, y*8+ScreenDefs.BORDER_SIZE, null)

View File

@ -31,7 +31,7 @@ object ScreenDefs {
private fun loadCharacters(): Array<BufferedImage> {
val img = ImageIO.read(javaClass.getResourceAsStream("/charset/unscii8x16.png"))
val charactersImage = BufferedImage(img.width, img.height, BufferedImage.TYPE_INT_ARGB).also { it.accelerationPriority = 1.0f }
val charactersImage = BufferedImage(img.width, img.height, BufferedImage.TYPE_INT_ARGB)
charactersImage.createGraphics().drawImage(img, 0, 0, null)
val black = Color(0, 0, 0).rgb