start on image converter

This commit is contained in:
John Bintz 2024-06-03 12:46:32 -04:00
parent 2a420f6f4f
commit 9ea3e5f8a6
5 changed files with 147 additions and 6 deletions

2
.rubocop.yml Normal file
View File

@ -0,0 +1,2 @@
AllCops:
TargetRubyVersion: 3.2

90
image_converter.rb Executable file
View File

@ -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

BIN
main

Binary file not shown.

61
main.c
View File

@ -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 custom_sprite_control = (uint16_t)offsetof(Custom, spr);
uint16_t chip spriteData[200]; uint16_t chip spriteData[200];
uint16_t chip spriteData2[20];
uint16_t spritePositionsEachLine[256][2]; uint16_t spritePositionsEachLine[256][2];
@ -75,7 +76,7 @@ int main(void) {
printf("setting up, i haven't crashed...yet.\n"); printf("setting up, i haven't crashed...yet.\n");
x = 150; x = 150;
y = 100; y = 47;
height = y + 98; height = y + 98;
printf("%d, %d, %d\n", x, y, height); printf("%d, %d, %d\n", x, y, height);
@ -85,13 +86,33 @@ int main(void) {
printf("%0x %0x\n", spriteData[0], spriteData[1]); printf("%0x %0x\n", spriteData[0], spriteData[1]);
for (i = 2; i < 198; ++i) { for (i = 2; i < 198; i += 2) {
spriteData[i] = 0xffff; spriteData[i] = 0x0f + i % 16;
spriteData[i + 1] = 0xf0f0;
} }
spriteData[198] = 0x0000; spriteData[198] = 0x0000;
spriteData[199] = 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); setupScreen(&screenSetup, SCREEN_WIDTH, SCREEN_HEIGHT, 3);
setupInitialCurrentScreen(&screenSetup, &currentScreen); setupInitialCurrentScreen(&screenSetup, &currentScreen);
@ -138,19 +159,46 @@ int main(void) {
*(currentCopperlist++) = 0x00F; *(currentCopperlist++) = 0x00F;
*(currentCopperlist++) = custom_sprite; *(currentCopperlist++) = custom_sprite;
*(currentCopperlist++) = ((uint32_t)&spriteData >> 16); *(currentCopperlist++) = ((uint32_t)&spriteData2 >> 16);
*(currentCopperlist++) = custom_sprite + 2; *(currentCopperlist++) = custom_sprite + 2;
*(currentCopperlist++) = ((uint32_t)&spriteData & 0xffff); *(currentCopperlist++) = ((uint32_t)&spriteData2 & 0xffff);
for (y = 0; y < 256; ++y) { for (y = 0; y < 256; ++y) {
if (y > 100) { /*
if (y > 100 && y < 135) {
*(currentCopperlist++) = custom_sprite_control; *(currentCopperlist++) = custom_sprite_control;
*(currentCopperlist++) = SPRPOS(60 + y, y); *(currentCopperlist++) = SPRPOS(60 + y, y);
*(currentCopperlist++) = custom_sprite_control + 2; *(currentCopperlist++) = custom_sprite_control + 2;
*(currentCopperlist++) = SPRCTL(60 + y, y, 0); *(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++) = 1 + (31 << 1) + ((44 + y) << 8);
*(currentCopperlist++) = 0xFFFE; *(currentCopperlist++) = 0xFFFE;
@ -161,6 +209,7 @@ int main(void) {
*(currentCopperlist++) = 0xFFFE; *(currentCopperlist++) = 0xFFFE;
*(currentCopperlist++) = custom_color; *(currentCopperlist++) = custom_color;
*(currentCopperlist++) = 0x000; *(currentCopperlist++) = 0x000;
} }
endCopperlist(currentCopperlist); endCopperlist(currentCopperlist);

BIN
topaz.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB