start on image converter
This commit is contained in:
parent
2a420f6f4f
commit
9ea3e5f8a6
|
@ -0,0 +1,2 @@
|
|||
AllCops:
|
||||
TargetRubyVersion: 3.2
|
|
@ -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
|
61
main.c
61
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);
|
||||
|
|
Loading…
Reference in New Issue