From d974e2610b85d999896620dfc9979c835501f22a Mon Sep 17 00:00:00 2001 From: Ralph Caraveo Date: Fri, 25 Apr 2014 17:59:44 -0700 Subject: [PATCH] Adding a Go translation (pre-liminary) --- .../cdgmagic_cdgdecoder_lowresource.go | 187 ++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 HTML5-CDGPlayer_files/cdgmagic_cdgdecoder_lowresource.go diff --git a/HTML5-CDGPlayer_files/cdgmagic_cdgdecoder_lowresource.go b/HTML5-CDGPlayer_files/cdgmagic_cdgdecoder_lowresource.go new file mode 100644 index 0000000..6342d1d --- /dev/null +++ b/HTML5-CDGPlayer_files/cdgmagic_cdgdecoder_lowresource.go @@ -0,0 +1,187 @@ +package main + +import "fmt" + +/* + * This file is part of CD+Graphics Magic. + * + * CD+Graphics Magic is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * CD+Graphics Magic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with CD+Graphics Magic. If not, see . + * + */ + +/* + * This class instantiates an HTML5/Canvas CD+Graphics decoder object. + * + * This is the "low resource" version, and should be very close + * to as fast as possible with JavaScript. + * + * The difference between the "low resource" and normal version + * is that this one packs each 6 pixel font line in to one + * array value, unrolling some loops and minimizing array lookups. + * + * The only concession made is lack of H/V "offset" support used + * for smooth scrolling. + * Block based scrolls *are* still supported, however, so the basic + * intent of the graphics is presented, but less than ideally. + * + * It is recommended for CPU constrained (eg. mobile or embedded) devices. + * + */ + +// Useful enums for CD+Graphics... + +const ( + VRAM_SIZE = 300 * 216 // Total linear size of VRAM, in pixels. + VRAM_WIDTH = 300 // Width (or pitch) of VRAM, in pixels. + VRAM_HEIGHT = 216 // Height of VRAM, in pixels. + VISIBLE_SIZE = 288 * 192 // Total linear size of visible screen, in pixels. + VISIBLE_WIDTH = 288 // Width (or pitch) of visible screen, in pixels. + VISIBLE_HEIGHT = 192 // Height of visible screen, in pixels. + FONT_WIDTH = 6 // Width of one "font" (or block). + FONT_HEIGHT = 12 // Height of one "font" (or block). + NUM_X_FONTS = 50 // Number of horizontal fonts contained in VRAM. + NUM_Y_FONTS = 18 // Number of vertical fonts contained in VRAM. + PALETTE_ENTRIES = 16 // Number of CLUT palette entries. + TV_GRAPHICS = 0x09 // 50x18 (48x16) 16 color TV graphics mode. + MEMORY_PRESET = 0x01 // Set all VRAM to palette index. + BORDER_PRESET = 0x02 // Set border to palette index. + LOAD_CLUT_LO = 0x1E // Load Color Look Up Table index 0 through 7. + LOAD_CLUT_HI = 0x1F // Load Color Look Up Table index 8 through 15. + COPY_FONT = 0x06 // Copy 12x6 pixel font to screen. + XOR_FONT = 0x26 // XOR 12x6 pixel font with existing VRAM values. + SCROLL_PRESET = 0x14 // Update scroll offset, copying if 0x20 or 0x10. + SCROLL_COPY = 0x18 // Update scroll offset, setting color if 0x20 or 0x10. +) + +var ( + internal_palette = make([]byte, PALETTE_ENTRIES) + internal_vram = make([]byte, NUM_X_FONTS*VRAM_HEIGHT) + internal_dirty_blocks = make([]byte, 900) + + internal_border_index = 0x00 // The current border palette index. + internal_current_pack = 0x00 // + + internal_border_dirty = false + internal_screen_dirty = false +) + +func main() { + fmt.Println("Compiles baby!") +} + +func resetCDGState() { + internal_current_pack = 0x00 + internal_border_index = 0x00 + clearPalette() + clearVRAM(0x00) + clearDirtyBlocks() +} + +func clearPalette() { + for idx := 0; idx < PALETTE_ENTRIES; idx++ { + internal_palette[idx] = 0x00 + } +} + +func get_current_pack() byte { + //casting: must test!!! + return byte(internal_current_pack) +} + +/* Possibly not needed! +func set_dirtyrect(requested_value) { + internal_usedirtyrect = requested_value +} +*/ + +func redrawCanvas() { + + if internal_border_dirty || internal_screen_dirty { + // render_screen_to_rgb() + // internal_screen_dirty = 0 + // clear_dirty_blocks() + // internal_rgba_context.putImageData(internal_rgba_imagedata, 0, 0) + } else { + var local_context = internal_rgba_context + var local_rgba_imagedata = internal_rgba_imagedata + + update_needed := false + var blk = 0x00 + + //NOTE: test the post-increment (Go does not have pre, so had to change it) + + for y_blk := 1; y_blk <= 16; y_blk++ { + + blk = y_blk*NUM_X_FONTS + 1 + + for x_blk := 1; x_blk <= 48; x_blk++ { + + if internal_dirty_blocks[blk] { + + render_block_to_rgb(x_blk, y_blk) + + if internal_usedirtyrect == 0x01 { + local_context.putImageData(local_rgba_imagedata, 0, 0, + (x_blk-1)*FONT_WIDTH, + (y_blk-1)*FONT_HEIGHT, + FONT_WIDTH, + FONT_HEIGHT) + } else { + update_needed = 0x01 + } + + internal_dirty_blocks[blk] = 0x00 + } + //Note: test the post-increment + blk++ + } + } + // Update the whole screen for browsers where dirty rect isn't supported. + // Since this can't be detected(???) in any way, it has to be User Agent selected, or an actual user option. + // TODO: See if a dirty rect-based partial update of known pixel values combined with a getImageData + // call could be used to determine if it works correctly *without* evil browser sniffing. + if update_needed { + //local_context.putImageData(local_rgba_imagedata, 0, 0); + } + } +} + +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 clearDirtyBlocks() { + for blk := 0; blk < 900; blk++ { + internal_dirty_blocks[blk] = 0x00 + } +} + +func fill_line_with_palette_index(requested_index byte) byte { + + adjusted_value := requested_index // Pixel 0 + adjusted_value |= (requested_index << 004) // Pixel 1 + adjusted_value |= (requested_index << 010) // Pixel 2 + adjusted_value |= (requested_index << 014) // Pixel 3 + adjusted_value |= (requested_index << 020) // Pixel 4 + adjusted_value |= (requested_index << 024) // Pixel 5 + + return adjusted_value +}