diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..c5214bb --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,2 @@ +AllCops: + TargetRubyVersion: 3.2 diff --git a/image_converter.rb b/image_converter.rb new file mode 100755 index 0000000..669e113 --- /dev/null +++ b/image_converter.rb @@ -0,0 +1,90 @@ +#!/usr/bin/env ruby + +require 'rmagick' + +# [ ] load the image +# [ ] map each pixel to a 12 bit color, with pixels less than 25% transparent as mask +# [ ] sort the color counts +# [ ] transparent pixels become the mask +# [ ] turn the big color counts into three bitplames worth of data +# [ ] turn the little color counts into up to 8 sprites worth of data strips & color changes + +image = Magick::Image.read('topaz.png').first + +rows = [] + +class MaskPixel + def initialize; end + + def color? = false +end + +class Color + attr_reader :red, :green, :blue + + def initialize(red:, green:, blue:) + @red = red + @green = green + @blue = blue + end + + def ==(other) + red == other.red && green == other.green && blue == other.blue + end + + alias eql? == + + def hash + red * 256 + green * 16 + blue + end +end + +class BitplanePixel + attr_reader :color + + def initialize(color:) + @color = color + end + + def color? = true +end + +MAX_ALPHA = Magick::QuantumRange * 0.25 +BIT_SHIFT = Math.log2(Magick::QuantumRange + 1) - 4 + +class PixelRow + def initialize + @row = [] + end + + def add(pixel:, x:) + @row[x] = pixel + end + + def colors_with_usage + @row.find_all(&:color?).each_with_object({}) do |pixel, obj| + obj[pixel.color] ||= 0 + obj[pixel.color] += 1 + end + end +end + +image.each_pixel do |px, x, y| + rows[y] ||= PixelRow.new + + pixel = if px.alpha < MAX_ALPHA + MaskPixel.new + else + BitplanePixel.new( + color: Color.new( + red: px.red >> BIT_SHIFT, + green: px.green >> BIT_SHIFT, + blue: px.blue >> BIT_SHIFT + ) + ) + end + + rows[y].add(pixel:, x:) +end + +pp rows[50].colors_with_usage diff --git a/main b/main index b4cfa8d..19363d4 100755 Binary files a/main and b/main differ diff --git a/main.c b/main.c index 195790a..ba22e1b 100644 --- a/main.c +++ b/main.c @@ -39,6 +39,7 @@ uint16_t custom_sprite = (uint16_t)offsetof(Custom, sprpt); uint16_t custom_sprite_control = (uint16_t)offsetof(Custom, spr); uint16_t chip spriteData[200]; +uint16_t chip spriteData2[20]; uint16_t spritePositionsEachLine[256][2]; @@ -75,7 +76,7 @@ int main(void) { printf("setting up, i haven't crashed...yet.\n"); x = 150; - y = 100; + y = 47; height = y + 98; printf("%d, %d, %d\n", x, y, height); @@ -85,13 +86,33 @@ int main(void) { printf("%0x %0x\n", spriteData[0], spriteData[1]); - for (i = 2; i < 198; ++i) { - spriteData[i] = 0xffff; + for (i = 2; i < 198; i += 2) { + spriteData[i] = 0x0f + i % 16; + spriteData[i + 1] = 0xf0f0; } spriteData[198] = 0x0000; spriteData[199] = 0x0000; + spriteData2[0] = SPRPOS(220, 70); + spriteData2[1] = SPRCTL(220, 70, 72); + /* + spriteData2[2] = 0x0345; + spriteData2[3] = 0x5678; + spriteData2[4] = 0x9abc; + spriteData2[5] = 0xdef0; + */ + spriteData2[2] = 0xffff; + spriteData2[3] = 0xffff; + spriteData2[4] = 0xffff; + spriteData2[5] = 0xffff; + spriteData2[6] = SPRPOS(230, 150); + spriteData2[7] = SPRCTL(230, 150, 151); + spriteData2[8] = 0xffff; + spriteData2[9] = 0xffff; + spriteData2[10] = 0; + spriteData2[11] = 0; + setupScreen(&screenSetup, SCREEN_WIDTH, SCREEN_HEIGHT, 3); setupInitialCurrentScreen(&screenSetup, ¤tScreen); @@ -138,19 +159,46 @@ int main(void) { *(currentCopperlist++) = 0x00F; *(currentCopperlist++) = custom_sprite; - *(currentCopperlist++) = ((uint32_t)&spriteData >> 16); + *(currentCopperlist++) = ((uint32_t)&spriteData2 >> 16); *(currentCopperlist++) = custom_sprite + 2; - *(currentCopperlist++) = ((uint32_t)&spriteData & 0xffff); + *(currentCopperlist++) = ((uint32_t)&spriteData2 & 0xffff); for (y = 0; y < 256; ++y) { - if (y > 100) { + /* + if (y > 100 && y < 135) { *(currentCopperlist++) = custom_sprite_control; *(currentCopperlist++) = SPRPOS(60 + y, y); *(currentCopperlist++) = custom_sprite_control + 2; *(currentCopperlist++) = SPRCTL(60 + y, y, 0); } + */ + + *(currentCopperlist++) = 1 + (1 << 1) + ((44 + y) << 8); + *(currentCopperlist++) = 0xFFFE; + + if (y == 27) { + /* + *(currentCopperlist++) = custom_sprite_control; + *(currentCopperlist++) = 0; + + *(currentCopperlist++) = custom_sprite_control + 2; + *(currentCopperlist++) = 0; + */ + + *(currentCopperlist++) = custom_sprite; + *(currentCopperlist++) = ((uint32_t)&spriteData >> 16); + + *(currentCopperlist++) = custom_sprite + 2; + *(currentCopperlist++) = ((uint32_t)&spriteData & 0xffff); + + *(currentCopperlist++) = custom_sprite_control; + *(currentCopperlist++) = SPRPOS(60, 100); + + *(currentCopperlist++) = custom_sprite_control + 2; + *(currentCopperlist++) = SPRCTL(60, 100, 198); + } *(currentCopperlist++) = 1 + (31 << 1) + ((44 + y) << 8); *(currentCopperlist++) = 0xFFFE; @@ -161,6 +209,7 @@ int main(void) { *(currentCopperlist++) = 0xFFFE; *(currentCopperlist++) = custom_color; *(currentCopperlist++) = 0x000; + } endCopperlist(currentCopperlist); diff --git a/topaz.png b/topaz.png new file mode 100644 index 0000000..da0b192 Binary files /dev/null and b/topaz.png differ