Log inRegister an accountBrowse CSDbHelp & documentationFacts & StatisticsThe forumsAvailable RSS-feeds on CSDbSupport CSDb Commodore 64 Scene Database
You are not logged in - nap
CSDb User Forums


Forums > C64 Coding > Kickassembler - Converting .PNG to Koala
2012-02-21 15:04
TWW

Registered: Jul 2009
Posts: 541
Kickassembler - Converting .PNG to Koala

Hey fellow hackers.

I wanted to write a converter in Kickassembler which can take any .PNG MC Bitmap screenshot from VICE (Then I don't need to worry about the RGB values since they are known) and convert into raw data you can use in your productions.

This is the way I imagine doing it:

#1 - Determin the background collor based on the most used collor in the picture
#2 - Verify there is no 4x8 block containing more than 3 collors+BG
#3 - Convert each 4x8 block afterwards and write the data into 3 lists (1 for BMP data, 1 for Charcollors and 1 for collmem).
#4 - Add BG collor at the end :-)

I'm looking for improvement comments on this or maybee I need to revise the way I think about this?
 
... 37 posts hidden. Click here to view all posts....
 
2012-02-25 20:35
TWW

Registered: Jul 2009
Posts: 541
Ok. Slammer, thanx.

I will try out your suggestions and come back with the result whne it's done. (not today coz I got a party to go to 8-D)
2012-02-26 12:38
TWW

Registered: Jul 2009
Posts: 541
EDIT: EDIT: I am a idiot!

Figgured it out...
2012-02-26 19:40
TWW

Registered: Jul 2009
Posts: 541
Alright. Got the background sorted. I decieded to do a full scan of all blocks to simultaniously extract the collors used which I now have neatly stored into a indexed collor hashtable.

The only thing remaining is to capture the actual bmp-data and make sure the Background collor is mapped with #%00 bitmpair (transparent).

I tried this:

        // Load the picture into the data list Graphics
        .var Graphics = LoadPicture(PNGpicture,List().add(BackgroundColor))

        // Fill in the Bitmap data
        .pc = BMPdata
        .fill 8000,[Graphics.getMulticolorByte(floor(i/8)-40*floor(i/320),i-[floor(i/8)-40*flo or(i/320)]*8-312*floor(i/320))]


Which works perfectly for the BG collor. However I thought if I left out the three last bitpair definitions in the getMulticolorByte function, that any other collor then BG would be treated as if no bitpair collor was defined (I.e. get mapped progressivly by the function using the three last bitpair combinations #%01 #%10 & #%11)

So before I go ahead and make a bigger job out of this and check every pixel on the picture to determine which bitpair should be used, I want to check if I am missing something or doing this in the wrong way.
2012-02-27 13:10
Slammer

Registered: Feb 2004
Posts: 416
getMulticolorByte is for 4 color pictures so you can't use that.

Btw. Have you seen this converter. It might offer some inspiration. http://codebase64.org/doku.php?id=base:double_screen_horizontal..
2012-02-27 21:57
TWW

Registered: Jul 2009
Posts: 541
Ok.

Improvement suggestion: Wouldn't it be cool if you could use the getMCByte on only a part (say a 4x8 pixel block) when you have the BG and the block collors defined 8-D


But then ofcourse Cruizer had done this before. Anyway I like playing around with this to think a little more "scripted".

Now that I know you need to aproach this pixel by pixel it shouldn't be too tough. If it is, atleast there is some inspiration to be found.
2012-02-29 00:13
TWW

Registered: Jul 2009
Posts: 541
Ok, Done. There is definately a lot of improvement potential here but it works.

Thanx for the pointers.


    .macro PNGtoKOALA(PNGpicture,BMPData,Chardata,D800data,BGC) {

        // Create RGB to C64 color index
        .var RGBtoC64 = Hashtable()
        .eval RGBtoC64.put(Black,0)
        .eval RGBtoC64.put(White,1)
        .eval RGBtoC64.put(Red,2)
        .eval RGBtoC64.put(Cyan,3)
        .eval RGBtoC64.put(Purple,4)
        .eval RGBtoC64.put(Green,5)
        .eval RGBtoC64.put(Blue,6)
        .eval RGBtoC64.put(Yellow,7)
        .eval RGBtoC64.put(L_brown,8)
        .eval RGBtoC64.put(D_brown,9)
        .eval RGBtoC64.put(L_red,10)
        .eval RGBtoC64.put(D_grey,11)
        .eval RGBtoC64.put(Grey,12)
        .eval RGBtoC64.put(L_green,13)
        .eval RGBtoC64.put(L_blue,14)
        .eval RGBtoC64.put(L_grey,15)

        // Hashtable for Storing all the colors.
        .var RGBColorTable  = Hashtable()

        // Create a list to hold all the Bitmap and collor data
        .var AllData = List(10000)

        // Load the picture into the data list Graphics
        .var Graphics = LoadPicture(PNGpicture,List())

        // Convert and return the Background Color
        .var BackgroundColor = FindBackgroundColor()

        .pc = BMPData "KOALA - Bitmap Graphics"
        .fill 8000,AllData.get(i)
        .pc = Chardata "KOALA - Character Color Data"
        .fill 1000,AllData.get(i+8000)
        .pc = D800data "KOALA - D800 Color Data"
        .fill 1000,AllData.get(i+9000)
        .pc = BGC "KOALA - Background Collor"
        .fill 1,BackgroundColor

    }

//=============================================================================
    // ColorTable-Hashtable has to be defined outside the function.
    .function FindBackgroundColor() {

        // Hastable for storing 4x8 block colordata
        .var BlockColors = Hashtable()

        // Hashtable for potential background Colors from inside one block
        .var BG = Hashtable()

        // Hashtable for keeping track of background color candidates from all blocks
        .var BGCandidate  = List(4)

        // Declare some variables
        .var CurrentBlock = 0     // Keeps track of which block is being checked
        .var BGRemaining  = 4     // Remaining backgound color candidates (begins with 4 since the first block get's it's 4 colors copied into the BGCandidate Hastable)
        .var ColorCounter = 0     // Counter for keeping track of how many colors are found inside each block
        .var FirstMatch   = true  // Used to diferensiate between the first 4 color block (It has to contain the backgound color) and the rest of the blocks

        // Loop for checking all 1000 blocks
        .for (CurrentBlock=0 ; CurrentBlock<1000 ; CurrentBlock++) {

            // Clear out any block colors from the hashtable
            .eval BlockColors = Hashtable()

            // Fetch 4x8 pixel block colors (32 total)
            .for (var Pixel = 0 ; Pixel < 32 ; Pixel++) {
                .var PixelColor = Graphics.getPixel([8*CurrentBlock+[[Pixel<<1]&7]]-[320*[floor(CurrentBlock/40)]] , [8*floor(CurrentBlock/40)]+[Pixel>>2])
                .eval BlockColors.put(PixelColor,Pixel)
            }

            // Reset the block color counter
            .eval ColorCounter = 0

            // Store the block colors in BG
            .if (BlockColors.containsKey(Black)  ==true) { .eval BG.put(ColorCounter,Black)   .eval RGBColorTable.put([ColorCounter+[4*CurrentBlock]],Black)   .eval ColorCounter=ColorCounter+1 }
            .if (BlockColors.containsKey(White)  ==true) { .eval BG.put(ColorCounter,White)   .eval RGBColorTable.put([ColorCounter+[4*CurrentBlock]],White)   .eval ColorCounter=ColorCounter+1 }
            .if (BlockColors.containsKey(Red)    ==true) { .eval BG.put(ColorCounter,Red)     .eval RGBColorTable.put([ColorCounter+[4*CurrentBlock]],Red)     .eval ColorCounter=ColorCounter+1 }
            .if (BlockColors.containsKey(Cyan)   ==true) { .eval BG.put(ColorCounter,Cyan)    .eval RGBColorTable.put([ColorCounter+[4*CurrentBlock]],Cyan)    .eval ColorCounter=ColorCounter+1 }
            .if (BlockColors.containsKey(Purple) ==true) { .eval BG.put(ColorCounter,Purple)  .eval RGBColorTable.put([ColorCounter+[4*CurrentBlock]],Purple)  .eval ColorCounter=ColorCounter+1 }
            .if (BlockColors.containsKey(Green)  ==true) { .eval BG.put(ColorCounter,Green)   .eval RGBColorTable.put([ColorCounter+[4*CurrentBlock]],Green)   .eval ColorCounter=ColorCounter+1 }
            .if (BlockColors.containsKey(Blue)   ==true) { .eval BG.put(ColorCounter,Blue)    .eval RGBColorTable.put([ColorCounter+[4*CurrentBlock]],Blue)    .eval ColorCounter=ColorCounter+1 }
            .if (BlockColors.containsKey(Yellow) ==true) { .eval BG.put(ColorCounter,Yellow)  .eval RGBColorTable.put([ColorCounter+[4*CurrentBlock]],Yellow)  .eval ColorCounter=ColorCounter+1 }
            .if (BlockColors.containsKey(L_brown)==true) { .eval BG.put(ColorCounter,L_brown) .eval RGBColorTable.put([ColorCounter+[4*CurrentBlock]],L_brown) .eval ColorCounter=ColorCounter+1 }
            .if (BlockColors.containsKey(D_brown)==true) { .eval BG.put(ColorCounter,D_brown) .eval RGBColorTable.put([ColorCounter+[4*CurrentBlock]],D_brown) .eval ColorCounter=ColorCounter+1 }
            .if (BlockColors.containsKey(L_red)  ==true) { .eval BG.put(ColorCounter,L_red)   .eval RGBColorTable.put([ColorCounter+[4*CurrentBlock]],L_red)   .eval ColorCounter=ColorCounter+1 }
            .if (BlockColors.containsKey(D_grey) ==true) { .eval BG.put(ColorCounter,D_grey)  .eval RGBColorTable.put([ColorCounter+[4*CurrentBlock]],D_grey)  .eval ColorCounter=ColorCounter+1 }
            .if (BlockColors.containsKey(Grey)   ==true) { .eval BG.put(ColorCounter,Grey)    .eval RGBColorTable.put([ColorCounter+[4*CurrentBlock]],Grey)    .eval ColorCounter=ColorCounter+1 }
            .if (BlockColors.containsKey(L_green)==true) { .eval BG.put(ColorCounter,L_green) .eval RGBColorTable.put([ColorCounter+[4*CurrentBlock]],L_green) .eval ColorCounter=ColorCounter+1 }
            .if (BlockColors.containsKey(L_blue) ==true) { .eval BG.put(ColorCounter,L_blue)  .eval RGBColorTable.put([ColorCounter+[4*CurrentBlock]],L_blue)  .eval ColorCounter=ColorCounter+1 }
            .if (BlockColors.containsKey(L_grey) ==true) { .eval BG.put(ColorCounter,L_grey)  .eval RGBColorTable.put([ColorCounter+[4*CurrentBlock]],L_grey)  .eval ColorCounter=ColorCounter+1 }

            // Carry out a background color check when there are 4 colors in a block
            .if (ColorCounter == 4 && BGCandidate.size()>1) {

                // Check if it is the first block with 4 collors
                .if (FirstMatch) {

                    // Copy the 4 collors as possible candidates
                    .eval BGCandidate.add(BG.get(0))
                    .eval BGCandidate.add(BG.get(1))
                    .eval BGCandidate.add(BG.get(2))
                    .eval BGCandidate.add(BG.get(3))
                    .eval FirstMatch = false
                } else {
                    .for (var i = 0 ; i < BGCandidate.size() ; i++) {
                        .if (BGCandidate.get(i) != BG.get(0)) {
                            .if (BGCandidate.get(i) != BG.get(1)) {
                                .if (BGCandidate.get(i) != BG.get(2)) {
                                    .if (BGCandidate.get(i) != BG.get(3)) {
                                        .eval BGCandidate.remove(i)
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }


    .var BackgroundColor = BGCandidate.get(0)


    // Test BG Color
    .print BackgroundColor

        // Variable for keeping track of which byte is in use
        .var ByteNumber = 0

        // Create hashtable and ascociate bitmap patterns to RGB Colors (one for bit patterns and one for collor referance)
        .var ColorIndex = Hashtable()
        .var ColorIndex2 = Hashtable()

        // Define the BG Color into the Color Indexes
        .eval ColorIndex.put(BackgroundColor,0)
        .eval ColorIndex2.put(0,BackgroundColor)

        .for (var BlockNumber = 0 ; BlockNumber < 1000 ; BlockNumber++) {

            // Variable for keeping track of which collor is to be used inside the block
            .var colpos = 1

            // Place the RGB color data into the color indexes (Multicolor Bit-combinations 01, 10 & 11 assigned the 3 colors)
            .for (var i = 0 ; i < 4 ; i++) {
                .if (RGBColorTable.get(i+[BlockNumber*4]) != BackgroundColor) {
                    .if (RGBColorTable.get(i+[BlockNumber*4]) != null) {
                        .eval ColorIndex.put(RGBColorTable.get(i+[BlockNumber*4]),colpos)
                        .eval ColorIndex2.put(colpos,RGBColorTable.get(i+[BlockNumber*4]))
                        .eval colpos = colpos+1
                    }
                }
            }

            // Read Pixel Collors in current block and fill in BMPData accordingly
            .for (var Byte = 0 ; Byte < 8 ; Byte++) {

                // Temp Storage for bitmap byte, bitmap pattern and the pixelcolor
                .var BMPByte = 0
                .var BMPPattern = 0
                .var PixelColor = 0

                // Find the pixel collors and cross ref. with the bit patterns to create the BMP data
                .for (var Pixel = 0 ; Pixel < 4 ; Pixel++) {
                        .eval PixelColor = Graphics.getPixel([[8*BlockNumber]+[[Pixel<<1]&7]]-[320*[floor(BlockNumber/40)]] , [8*floor(BlockNumber/40)]+Byte)
                        .eval BMPPattern = ColorIndex.get(PixelColor)
                        .eval BMPByte = BMPByte|[BMPPattern << [6 - Pixel*2]]
                }

                // Set the done BMP data into final data storage
                .eval AllData.set(ByteNumber,BMPByte)
                .eval ByteNumber = ByteNumber+1
            }

            // Create the color data
            .var CharacterColor = 0
            .var D800Color = 0

            .if (RGBtoC64.get(ColorIndex2.get(1)) != null) { .eval CharacterColor = [RGBtoC64.get(ColorIndex2.get(1))<<4] }
            .if (RGBtoC64.get(ColorIndex2.get(2)) != null) { .eval CharacterColor = CharacterColor|RGBtoC64.get(ColorIndex2.get(2)) }
            .if (RGBtoC64.get(ColorIndex2.get(3)) != null) { .eval D800Color = RGBtoC64.get(ColorIndex2.get(3)) }

            // Store the colors into final data storage
            .eval AllData.set(8000+BlockNumber,CharacterColor)
            .eval AllData.set(9000+BlockNumber,D800Color)
        }

    // Return background color:
    .return BackgroundColor

    }


EDIT: Fixed some bugs and small optimalizations.
2012-04-13 16:09
Total Chaos

Registered: Mar 2006
Posts: 74
Since I'm stupid I don't get where do I put filename and addresses into that one?

Also, could it be modified to handle other size bitmaps (like 348 pixels wide)?

Please talk to me like I'm a 5-year old...

//TC
2012-04-13 18:38
andym00

Registered: Jun 2009
Posts: 44
The very first line of the macro contains the parameters you need to pass in..
.macro PNGtoKOALA(PNGpicture,BMPData,Chardata,D800data,BGC)

So filename and 4 sets of addresses for the respective components of the bitmap..
2012-04-13 19:22
Total Chaos

Registered: Mar 2006
Posts: 74
.macro PNGtoKOALA(PNGpicture,BMPData,Chardata,D800data,BGC)

PNGpicture=name
or just replace it?
2012-04-14 07:25
Total Chaos

Registered: Mar 2006
Posts: 74
PNGtoKOALA(PNGpicture=320x200.png,BMPData=$2000,Chardata=$4000,D800data=$5000,BG C=$6000)
PNGtoKOALA(PNGpicture=320x200.png,BMPData=2000,Chardata=4000,D800data=5000,BGC=6 000)
PNGtoKOALA(320x200.png,$2000,$4000,$5000,$6000)

none of these worked



Previous - 1 | 2 | 3 | 4 | 5 - Next
RefreshSubscribe to this thread:

You need to be logged in to post in the forum.

Search the forum:
Search   for   in  
All times are CET.
Search CSDb
Advanced
Users Online
Oswald/Resource
Erol
Menace/Spaceballs
Acidchild/Padua
icon/The Silents, Sp..
kbs/Pht/Lxt
Krill/Plush
daimansion
LuXuS
sebalozlepsi
Guests online: 154
Top Demos
1 Next Level  (9.8)
2 Mojo  (9.7)
3 Coma Light 13  (9.7)
4 Edge of Disgrace  (9.6)
5 Comaland 100%  (9.6)
6 No Bounds  (9.6)
7 Uncensored  (9.6)
8 Wonderland XIV  (9.6)
9 Memento Mori  (9.6)
10 Bromance  (9.5)
Top onefile Demos
1 It's More Fun to Com..  (9.7)
2 Party Elk 2  (9.7)
3 Cubic Dream  (9.6)
4 Copper Booze  (9.5)
5 TRSAC, Gabber & Pebe..  (9.5)
6 Rainbow Connection  (9.5)
7 Wafer Demo  (9.5)
8 Dawnfall V1.1  (9.5)
9 Quadrants  (9.5)
10 Daah, Those Acid Pil..  (9.5)
Top Groups
1 Oxyron  (9.3)
2 Nostalgia  (9.3)
3 Booze Design  (9.3)
4 Censor Design  (9.3)
5 Crest  (9.3)
Top NTSC-Fixers
1 Pudwerx  (10)
2 Booze  (9.7)
3 Stormbringer  (9.7)
4 Fungus  (9.6)
5 Grim Reaper  (9.3)

Home - Disclaimer
Copyright © No Name 2001-2024
Page generated in: 0.045 sec.