Work in progress of conversion...code currently doesn't compile....DO NOT USE YET
This commit is contained in:
1 parent
d974e2610b
commit
4c5b55ea8e
1 file changed
+345
-18
@@ -1,6 +1,9 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import "fmt"
|
import (
|
||||||
|
"fmt"
|
||||||
|
"image"
|
||||||
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file is part of CD+Graphics Magic.
|
* This file is part of CD+Graphics Magic.
|
||||||
@@ -65,9 +68,12 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
internal_palette = make([]byte, PALETTE_ENTRIES)
|
internal_palette = make([]byte, PALETTE_ENTRIES)
|
||||||
internal_vram = make([]byte, NUM_X_FONTS*VRAM_HEIGHT)
|
internal_vram = make([]byte, NUM_X_FONTS*VRAM_HEIGHT)
|
||||||
internal_dirty_blocks = make([]byte, 900)
|
internal_dirty_blocks = make([]byte, 900)
|
||||||
|
internal_rgba_context = image.NewRGBA(image.Rect(0, 0, VISIBLE_WIDTH, VISIBLE_HEIGHT))
|
||||||
|
internal_rgba_imagedata = internal_rgba_imagedata.Pix
|
||||||
|
internal_usedirtyrect = true
|
||||||
|
|
||||||
internal_border_index = 0x00 // The current border palette index.
|
internal_border_index = 0x00 // The current border palette index.
|
||||||
internal_current_pack = 0x00 //
|
internal_current_pack = 0x00 //
|
||||||
@@ -109,8 +115,8 @@ func redrawCanvas() {
|
|||||||
|
|
||||||
if internal_border_dirty || internal_screen_dirty {
|
if internal_border_dirty || internal_screen_dirty {
|
||||||
// render_screen_to_rgb()
|
// render_screen_to_rgb()
|
||||||
// internal_screen_dirty = 0
|
internal_screen_dirty = false
|
||||||
// clear_dirty_blocks()
|
clearDirtyBlocks()
|
||||||
// internal_rgba_context.putImageData(internal_rgba_imagedata, 0, 0)
|
// internal_rgba_context.putImageData(internal_rgba_imagedata, 0, 0)
|
||||||
} else {
|
} else {
|
||||||
var local_context = internal_rgba_context
|
var local_context = internal_rgba_context
|
||||||
@@ -131,14 +137,14 @@ func redrawCanvas() {
|
|||||||
|
|
||||||
render_block_to_rgb(x_blk, y_blk)
|
render_block_to_rgb(x_blk, y_blk)
|
||||||
|
|
||||||
if internal_usedirtyrect == 0x01 {
|
if internal_usedirtyrect {
|
||||||
local_context.putImageData(local_rgba_imagedata, 0, 0,
|
local_context.putImageData(local_rgba_imagedata, 0, 0,
|
||||||
(x_blk-1)*FONT_WIDTH,
|
(x_blk-1)*FONT_WIDTH,
|
||||||
(y_blk-1)*FONT_HEIGHT,
|
(y_blk-1)*FONT_HEIGHT,
|
||||||
FONT_WIDTH,
|
FONT_WIDTH,
|
||||||
FONT_HEIGHT)
|
FONT_HEIGHT)
|
||||||
} else {
|
} else {
|
||||||
update_needed = 0x01
|
update_needed = true
|
||||||
}
|
}
|
||||||
|
|
||||||
internal_dirty_blocks[blk] = 0x00
|
internal_dirty_blocks[blk] = 0x00
|
||||||
@@ -157,21 +163,43 @@ func redrawCanvas() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func clearVRAM(colorIndex byte) {
|
// Decode to pack playback_position, using cdg_file_data.
|
||||||
|
func decode_packs(cdg_file_data []byte, playback_position int) {
|
||||||
|
|
||||||
packed_line_value := fill_line_with_palette_index(colorIndex)
|
for curr_pack := internal_current_pack; curr_pack < playback_position; curr_pack++ {
|
||||||
|
|
||||||
for pxl := 0; pxl < len(internal_vram); pxl++ {
|
start_offset := curr_pack * 24
|
||||||
internal_vram[pxl] = packed_line_value
|
curr_command := cdg_file_data[start_offset] & 0x3F
|
||||||
}
|
|
||||||
|
|
||||||
internal_screen_dirty = true
|
if curr_command == TV_GRAPHICS {
|
||||||
}
|
// Slice the file array down to a single pack array.
|
||||||
|
this_pack := cdg_file_data[start_offset : start_offset+24]
|
||||||
|
// Pluck out the graphics instruction.
|
||||||
|
curr_instruction := this_pack[1] & 0x3F
|
||||||
|
// Perform the instruction action.
|
||||||
|
switch curr_instruction {
|
||||||
|
case MEMORY_PRESET:
|
||||||
|
proc_MEMORY_PRESET(this_pack)
|
||||||
|
|
||||||
func clearDirtyBlocks() {
|
case BORDER_PRESET:
|
||||||
for blk := 0; blk < 900; blk++ {
|
proc_BORDER_PRESET(this_pack)
|
||||||
internal_dirty_blocks[blk] = 0x00
|
|
||||||
|
case LOAD_CLUT_LO:
|
||||||
|
case LOAD_CLUT_HI:
|
||||||
|
proc_LOAD_CLUT(this_pack)
|
||||||
|
|
||||||
|
case COPY_FONT:
|
||||||
|
case XOR_FONT:
|
||||||
|
proc_WRITE_FONT(this_pack)
|
||||||
|
|
||||||
|
case SCROLL_PRESET:
|
||||||
|
case SCROLL_COPY:
|
||||||
|
proc_DO_SCROLL(this_pack)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
internal_current_pack = playback_position
|
||||||
}
|
}
|
||||||
|
|
||||||
func fill_line_with_palette_index(requested_index byte) byte {
|
func fill_line_with_palette_index(requested_index byte) byte {
|
||||||
@@ -185,3 +213,302 @@ func fill_line_with_palette_index(requested_index byte) byte {
|
|||||||
|
|
||||||
return adjusted_value
|
return adjusted_value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func clearDirtyBlocks() {
|
||||||
|
for blk := 0; blk < 900; blk++ {
|
||||||
|
internal_dirty_blocks[blk] = 0x00
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func clearVRAM(colorIndex byte) {
|
||||||
|
|
||||||
|
packed_line_value := fill_line_with_palette_index(colorIndex)
|
||||||
|
|
||||||
|
for pxl := 0; pxl < len(internal_vram); pxl++ {
|
||||||
|
internal_vram[pxl] = packed_line_value
|
||||||
|
}
|
||||||
|
|
||||||
|
internal_screen_dirty = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func render_screen_to_rgb() {
|
||||||
|
|
||||||
|
vis_width := 48
|
||||||
|
vis_height := VISIBLE_HEIGHT
|
||||||
|
|
||||||
|
vram_loc := 601 // Offset into VRAM array.
|
||||||
|
rgb_loc := 0x00 // Offset into RGBA array.
|
||||||
|
curr_rgb := 0x00 // RGBA value of current pixel.
|
||||||
|
curr_line_indices := 0x00 // Packed font row index values.
|
||||||
|
|
||||||
|
for y_pxl := 0; y_pxl < vis_height; y_pxl++ {
|
||||||
|
for x_pxl := 0; x_pxl < vis_width; x_pxl++ {
|
||||||
|
|
||||||
|
//for the Go version, maybe don't have to unroll the loop cause it's getting ugly.
|
||||||
|
//NOTE: these values are shifted by Octal numbers looks like ie: 010
|
||||||
|
//NOTE: In Go, ++ is a statement not expression, so had to post-increment after-the-fact
|
||||||
|
|
||||||
|
curr_line_indices = internal_vram[vram_loc] // Get the current line segment indices.
|
||||||
|
vram_loc++
|
||||||
|
curr_rgb = internal_palette[(curr_line_indices>>000)&0x0F] // Get the RGB value for pixel 0.
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 020) & 0xFF // Set red value for pixel 0.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 010) & 0xFF // Set green value for pixel 0.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 000) & 0xFF // Set blue value for pixel 0.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = 0xFF
|
||||||
|
rgb_loc++ // Set alpha value (fully opaque) for pixel 0.
|
||||||
|
|
||||||
|
curr_rgb = internal_palette[(curr_line_indices>>004)&0x0F] // Get the RGB value for pixel 1.
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 020) & 0xFF // Set red value for pixel 1.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 010) & 0xFF // Set green value for pixel 1.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 000) & 0xFF // Set blue value for pixel 1.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = 0xFF // Set alpha value (fully opaque) for pixel 1.
|
||||||
|
rgb_loc++
|
||||||
|
curr_rgb = internal_palette[(curr_line_indices>>010)&0x0F] // Get the RGB value for pixel 2.
|
||||||
|
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 020) & 0xFF // Set red value for pixel 2.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 010) & 0xFF // Set green value for pixel 2.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 000) & 0xFF // Set blue value for pixel 2.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = 0xFF
|
||||||
|
rgb_loc++ // Set alpha value (fully opaque) for pixel 2.
|
||||||
|
|
||||||
|
curr_rgb = internal_palette[(curr_line_indices>>014)&0x0F] // Get the RGB value for pixel 3.
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 020) & 0xFF // Set red value for pixel 3.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 010) & 0xFF // Set green value for pixel 3.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 000) & 0xFF // Set blue value for pixel 3.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = 0xFF // Set alpha value (fully opaque) for pixel 3.
|
||||||
|
rgb_loc++
|
||||||
|
|
||||||
|
curr_rgb = internal_palette[(curr_line_indices>>020)&0x0F] // Get the RGB value for pixel 4.
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 020) & 0xFF // Set red value for pixel 4.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 010) & 0xFF // Set green value for pixel 4.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 000) & 0xFF // Set blue value for pixel 4.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = 0xFF
|
||||||
|
rgb_loc++ // Set alpha value (fully opaque) for pixel 4.
|
||||||
|
|
||||||
|
curr_rgb = internal_palette[(curr_line_indices>>024)&0x0F] // Get the RGB value for pixel 5.
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 020) & 0xFF // Set red value for pixel 5.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 010) & 0xFF // Set green value for pixel 5.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 000) & 0xFF // Set blue value for pixel 5.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = 0xFF // Set alpha value (fully opaque) for pixel 5.
|
||||||
|
rgb_loc++
|
||||||
|
// Or, instead, index 0 could be set transparent to show background image/video.
|
||||||
|
// Alternately, SET_TRANSPARENT instruction could be implemented to set 6bit transparency.
|
||||||
|
// Unfortunately, I don't think many (any?) discs bother to set it :-/...
|
||||||
|
}
|
||||||
|
vram_loc += 2 // Skip the offscreen font blocks.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func render_block_to_rgb(x_start, y_start int) {
|
||||||
|
vram_loc := (y_start * NUM_X_FONTS * FONT_HEIGHT) + x_start // Offset into VRAM array.
|
||||||
|
vram_inc := NUM_X_FONTS
|
||||||
|
vram_end := vram_loc + (NUM_X_FONTS * FONT_HEIGHT) // VRAM location to end.
|
||||||
|
rgb_loc := (y_start - 1) * FONT_HEIGHT * VISIBLE_WIDTH // Row start.
|
||||||
|
rgb_loc += (x_start - 1) * FONT_WIDTH // Column start
|
||||||
|
rgb_loc *= 4 // RGBA, 1 pxl = 4 bytes.
|
||||||
|
|
||||||
|
rgb_inc := (VISIBLE_WIDTH - FONT_WIDTH) * 4
|
||||||
|
curr_rgb := 0x00 // RGBA value of current pixel.
|
||||||
|
curr_line_indices := 0x00 // Packed font row index values.
|
||||||
|
|
||||||
|
for vram_loc < vram_end {
|
||||||
|
curr_line_indices = internal_vram[vram_loc] // Get the current line segment indices.
|
||||||
|
curr_rgb = internal_palette[(curr_line_indices>>000)&0x0F] // Get the RGB value for pixel 0.
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 020) & 0xFF // Set red value for pixel 0.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 010) & 0xFF // Set green value for pixel 0.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 000) & 0xFF // Set blue value for pixel 0.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = 0xFF
|
||||||
|
rgb_loc++ // Set alpha value (fully opaque) for pixel 0.
|
||||||
|
curr_rgb = internal_palette[(curr_line_indices>>004)&0x0F] // Get the RGB value for pixel 1.
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 020) & 0xFF // Set red value for pixel 1.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 010) & 0xFF // Set green value for pixel 1.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 000) & 0xFF // Set blue value for pixel 1.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = 0xFF
|
||||||
|
rgb_loc++ // Set alpha value (fully opaque) for pixel 1.
|
||||||
|
curr_rgb = internal_palette[(curr_line_indices>>010)&0x0F] // Get the RGB value for pixel 2.
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 020) & 0xFF // Set red value for pixel 2.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 010) & 0xFF // Set green value for pixel 2.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 000) & 0xFF // Set blue value for pixel 2.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = 0xFF
|
||||||
|
rgb_loc++ // Set alpha value (fully opaque) for pixel 2.
|
||||||
|
curr_rgb = internal_palette[(curr_line_indices>>014)&0x0F] // Get the RGB value for pixel 3.
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 020) & 0xFF // Set red value for pixel 3.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 010) & 0xFF // Set green value for pixel 3.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 000) & 0xFF // Set blue value for pixel 3.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = 0xFF
|
||||||
|
rgb_loc++ // Set alpha value (fully opaque) for pixel 3.
|
||||||
|
curr_rgb = internal_palette[(curr_line_indices>>020)&0x0F] // Get the RGB value for pixel 4.
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 020) & 0xFF // Set red value for pixel 4.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 010) & 0xFF // Set green value for pixel 4.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 000) & 0xFF // Set blue value for pixel 4.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = 0xFF
|
||||||
|
rgb_loc++ // Set alpha value (fully opaque) for pixel 4.
|
||||||
|
curr_rgb = internal_palette[(curr_line_indices>>024)&0x0F] // Get the RGB value for pixel 5.
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 020) & 0xFF // Set red value for pixel 5.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 010) & 0xFF // Set green value for pixel 5.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = (curr_rgb >> 000) & 0xFF // Set blue value for pixel 5.
|
||||||
|
rgb_loc++
|
||||||
|
internal_rgba_imagedata[rgb_loc] = 0xFF // Set alpha value (fully opaque) for pixel 5.
|
||||||
|
rgb_loc++
|
||||||
|
// Or, instead, index 0 could be set transparent to show background image/video.
|
||||||
|
// Alternately, SET_TRANSPARENT instruction could be implemented to set 6bit transparency.
|
||||||
|
// Unfortunately, I don't think many (any?) discs bother to set it :-/...
|
||||||
|
vram_loc += vram_inc // Move to the first column of the next row of this font block in VRAM.
|
||||||
|
rgb_loc += rgb_inc // Move to the first column of the next row of this font block in RGB pixels.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//########## PRIVATE GRAPHICS DECODE FUNCTIONS ##########//
|
||||||
|
|
||||||
|
func proc_BORDER_PRESET(cdg_pack []byte) {
|
||||||
|
// NOTE: The "border" is actually a DIV element, which can be very expensive to change in some browsers.
|
||||||
|
// This somewhat bizarre check ensures that the DIV is only touched if the actual RGB color is different,
|
||||||
|
// but the border index variable is always set... A similar check is also performed during palette update.
|
||||||
|
new_border_index := cdg_pack[4] & 0x3F // Get the border index from subcode.
|
||||||
|
// Check if the new border **RGB** color is different from the old one.
|
||||||
|
if internal_palette[new_border_index] != internal_palette[internal_border_index] {
|
||||||
|
internal_border_dirty = true // Border needs updating.
|
||||||
|
}
|
||||||
|
|
||||||
|
internal_border_index = new_border_index // Set the new index.
|
||||||
|
}
|
||||||
|
|
||||||
|
func proc_MEMORY_PRESET(cdg_pack []byte) {
|
||||||
|
clearVRAM(cdg_pack[4] & 0x3F)
|
||||||
|
}
|
||||||
|
|
||||||
|
func proc_LOAD_CLUT(cdg_pack []byte) {
|
||||||
|
|
||||||
|
// If instruction is 0x1E then 8*0=0, if 0x1F then 8*1=8 for offset.
|
||||||
|
pal_offset := (cdg_pack[1] & 0x01) * 8
|
||||||
|
// Step through the eight color indices, setting the RGB values.
|
||||||
|
for pal_inc := 0; pal_inc < 8; pal_inc++ {
|
||||||
|
temp_idx := pal_inc + pal_offset
|
||||||
|
temp_rgb := 0x00000000
|
||||||
|
temp_entry := 0x00000000
|
||||||
|
// Set red.
|
||||||
|
temp_entry = (cdg_pack[pal_inc*2+4] & 0x3C) >> 2
|
||||||
|
temp_rgb |= (temp_entry * 17) << 020
|
||||||
|
// Set green.
|
||||||
|
temp_entry = ((cdg_pack[pal_inc*2+4] & 0x03) << 2) | ((cdg_pack[pal_inc*2+5] & 0x30) >> 4)
|
||||||
|
temp_rgb |= (temp_entry * 17) << 010
|
||||||
|
// Set blue.
|
||||||
|
temp_entry = cdg_pack[pal_inc*2+5] & 0x0F
|
||||||
|
temp_rgb |= (temp_entry * 17) << 000
|
||||||
|
|
||||||
|
// Put the full RGB value into the index position, but only if it's different.
|
||||||
|
if temp_rgb != innternal_palette[temp_idx] {
|
||||||
|
innternal_palette[temp_idx] = temp_rgb
|
||||||
|
internal_screen_dirty = true // The colors are now different, so we need to update the whole screen.
|
||||||
|
|
||||||
|
if temp_idx == internal_border_index {
|
||||||
|
internal_border_dirty = true
|
||||||
|
} // The border color has changed.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func proc_WRITE_FONT(cdg_pack []byte) {
|
||||||
|
var local_vram = internal_vram
|
||||||
|
var local_dirty = internal_dirty_blocks
|
||||||
|
// Hacky hack to play channels 0 and 1 only... Ideally, there should be a function and user option to get/set.
|
||||||
|
active_channels := 0x03
|
||||||
|
// First, get the channel...
|
||||||
|
subcode_channel := ((cdg_pack[4] & 0x30) >> 2) | ((cdg_pack[5] & 0x30) >> 4)
|
||||||
|
xor_var := cdg_pack[1] & 0x20
|
||||||
|
// Then see if we should display it.
|
||||||
|
if (active_channels >> subcode_channel) & 0x01 {
|
||||||
|
x_location := cdg_pack[7] & 0x3F // Get horizontal font location.
|
||||||
|
y_location := cdg_pack[6] & 0x1F // Get vertical font location.
|
||||||
|
|
||||||
|
// Verify we're not going to overrun the boundaries (i.e. bad data from a scratched disc).
|
||||||
|
if (x_location <= 49) && (y_location <= 17) {
|
||||||
|
start_pixel := y_location*600 + x_location // Location of first pixel of this font in linear VRAM.
|
||||||
|
// NOTE: Profiling indicates charCodeAt() uses ~80% of the CPU consumed for this function.
|
||||||
|
// Caching these values reduces that to a negligible amount.
|
||||||
|
|
||||||
|
current_indexes = make([]byte, 2)
|
||||||
|
current_indexes[0] = (cdg_pack[4] & 0x0F)
|
||||||
|
current_indexes[1] = (cdg_pack[5] & 0x0F)
|
||||||
|
|
||||||
|
current_row := 0x00 // Subcode byte for current pixel row.
|
||||||
|
temp_pxl := 0x00 // Decoded and packed 4bit pixel index values of current row.
|
||||||
|
for y_inc := 0; y_inc < 12; y_inc++ {
|
||||||
|
var pix_pos = y_inc*50 + start_pixel // Location of the first pixel of this row in linear VRAM.
|
||||||
|
current_row = cdg_pack[y_inc+8] // Get the subcode byte for the current row.
|
||||||
|
temp_pxl = (current_indexes[(current_row>>5)&0x01] << 000)
|
||||||
|
temp_pxl |= (current_indexes[(current_row>>4)&0x01] << 004)
|
||||||
|
temp_pxl |= (current_indexes[(current_row>>3)&0x01] << 010)
|
||||||
|
temp_pxl |= (current_indexes[(current_row>>2)&0x01] << 014)
|
||||||
|
temp_pxl |= (current_indexes[(current_row>>1)&0x01] << 020)
|
||||||
|
temp_pxl |= (current_indexes[(current_row>>0)&0x01] << 024)
|
||||||
|
|
||||||
|
//NOTE: figure out truthy-ness of xor_var
|
||||||
|
if xor_var != 0 {
|
||||||
|
local_vram[pix_pos] ^= temp_pxl
|
||||||
|
} else {
|
||||||
|
local_vram[pix_pos] = temp_pxl
|
||||||
|
}
|
||||||
|
} // End of Y loop.
|
||||||
|
// Mark this block as needing an update.
|
||||||
|
local_dirty[y_location*50+x_location] = 0x01
|
||||||
|
} // End of location check.
|
||||||
|
} // End of channel check.
|
||||||
|
}
|
||||||
|
|
||||||
|
func proc_DO_SCROLL(cdg_pack []byte) {
|
||||||
|
direction := 0 // H/V direction flag.
|
||||||
|
copy_flag = (cdg_pack[1] & 0x08) >> 3 // Type of copy (memory preset or copy).
|
||||||
|
color = cdg_pack[4] & 0x0F // Color index to use for preset type.
|
||||||
|
|
||||||
|
//TODOD: check what value of direction is
|
||||||
|
// Process horizontal commands.
|
||||||
|
if direction = (cdg_pack[5] & 0x30) >> 4; direction != 0 {
|
||||||
|
proc_VRAM_HSCROLL(direction, copy_flag, color)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process vertical commands.
|
||||||
|
if direction = (cdg_pack[6] & 0x30) >> 4; direction != 0 {
|
||||||
|
proc_VRAM_VSCROLL(direction, copy_flag, color)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal_screen_dirty = true // Entire screen needs to be redrawn.
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: proc_VRAM_HSCROLL
|
||||||
|
//TODO: proc_VRAM_VSCROLL
|
||||||
Reference in new issue
Block a user