| |
TWW
Registered: Jul 2009 Posts: 545 |
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.... |
| |
TWW
Registered: Jul 2009 Posts: 545 |
I got an idea.
#1 - progressivly scan each 4x8 block and find the first one with 4 collors and add those collors to a list
#2 - continue scanning untill next block with 4 collors
#3 - find common collors between the two and discard the rest
#4 - repeat untill 1 collor remains in the list, BG collor set.
(I guess this is what you said^^)
I have 2 specific questions:
#1 - Can this:
.for (var Id = 0 ; Id < 64 ; Id++) {
.var PixelCollor = gfx.getPixel([Id>>1]&3, [Id>>3])
.eval BlockCollors.put(Id,PixelCollor)
}
be written like:
.for (var Id = 0 ; Id < 64 ; Id++) {
.eval BlockCollors.put(Id,gfx.getPixel([Id>>1]&3, [Id>>3]))
}
somehow? (not very importain but just curios).
#2: - I have the collors from a 4x8 block in a hashtable, what is a good way to figgure out how many variants are stored in the table. Are we talking a long line of .if's here or is there a more smooth method? |
| |
algorithm
Registered: May 2002 Posts: 705 |
Even more easier
$d021 col=0
check each 4x8 block, if colors in bitmap exceed limitations, then inc d021 and start over. until you get no clash
|
| |
TWW
Registered: Jul 2009 Posts: 545 |
Interesting. Assume the BG collor and verify...
How about compilation time if the BG = #$0f vs. method stipulated above? |
| |
enthusi
Registered: May 2004 Posts: 677 |
The approach to brute force BG has the advantage that you can as well convert pictures that do not match MCbitmap restrictions that way (weighting via least_clashes, etc...).
In general I personally dislike the idea to integrate such things into kickassembler (or any assembler).
I dont like the simplified interface to implement SID files already. I see hordes of beginners to not get what's working why and how.
But then again, that might just be me thinking that way.
PS:
You can aswell use vice-dumps directly if your method relies on vice bitmaps anyway. There you can simply read out all colors. Check here i.e.:
Vice Snapshot Grabber 4.2 |
| |
Cruzer
Registered: Dec 2001 Posts: 1048 |
I personally think it's a better idea to have as much import, convert and precalc functionality as an assembler script, since it's much easier to customize for the situation than external tools, which also have a tendency to be windows-only, unlike KickAssembler. The only drawback is that it slows down the assembly time if it's too complex. In these cases I usually save the generated data when it has reached a usable state, and have an option to turn on/off whether to load or regenerate it. |
| |
TWW
Registered: Jul 2009 Posts: 545 |
I'm with Cruiser on this one. I've been coding assembler on the 64 since the late eigthies so if I can't figgure that part out then screw it :-) Perhaps for a beginner it would be more prudent to do it the hard way but I'm past that stage and I want it as easy and fast as possible.
There are too many small tools and stuff anyway so why not implement some of the trivial ones yourself. This way I get a chance to learn more about script language in the process^^
I don't know about the sid stuff though. |
| |
enthusi
Registered: May 2004 Posts: 677 |
Sorry, dont get me wrong: Coding something like Kickassembler is extremely cool ;-) But that differs from my opinion about its existance :) |
| |
TWW
Registered: Jul 2009 Posts: 545 |
Alright, this is what I got so far. It seems to be working but I have feeling it is extreemly bloated. Could some script guru take a look ang give me some pointers is something is done bad/wrong/unoptimized?
(Assuming collor palette is pre-defined)
.macro PNGtoKOALA(PNGpicture,BMPdata,Chardata,D800data) {
// Hastable for storing 4x8 collordata
.var BlockCollors = Hashtable()
// Hash table for holding potential BackGround Collors from a block
.var BG = Hashtable()
// Hashtable for keeping track of candidates
.var BGCandidate = Hashtable()
// Declare some variables
.var Id = 0
.var CurrentBlock = 0
.var BGRemaining = 4
.var CollCounter = 0
.var FirstMatch = true
.var i = 0
// Load the picture into gfx
.var gfx = LoadPicture(PNGpicture,List())
// Block Pointer Variable
.for (CurrentBlock=0 ; CurrentBlock<1000&&BGRemaining > 1 ; CurrentBlock++) {
// Fetch 4x8 pixel block collors
.for (var Id = 0 ; Id < 32 ; Id++) {
.var PixelCollor = gfx.getPixel([8*CurrentBlock+[[Id<<1]&7]]-[320*[floor(CurrentBlock/40)]], [8*floor(CurrentBlock/40)]+[Id>>2])
.eval BlockCollors.put(PixelCollor,Id)
}
// First check for 4 collors in a block
.if (BlockCollors.containsKey(Black) ==true) { .eval BG.put(CollCounter,Black) .eval CollCounter=CollCounter+1 }
.if (BlockCollors.containsKey(White) ==true) { .eval BG.put(CollCounter,White) .eval CollCounter=CollCounter+1 }
.if (BlockCollors.containsKey(Red) ==true) { .eval BG.put(CollCounter,Red) .eval CollCounter=CollCounter+1 }
.if (BlockCollors.containsKey(Cyan) ==true) { .eval BG.put(CollCounter,Cyan) .eval CollCounter=CollCounter+1 }
.if (BlockCollors.containsKey(Purple) ==true) { .eval BG.put(CollCounter,Purple) .eval CollCounter=CollCounter+1 }
.if (BlockCollors.containsKey(Green) ==true) { .eval BG.put(CollCounter,Green) .eval CollCounter=CollCounter+1 }
.if (BlockCollors.containsKey(Blue) ==true) { .eval BG.put(CollCounter,Blue) .eval CollCounter=CollCounter+1 }
.if (BlockCollors.containsKey(Yellow) ==true) { .eval BG.put(CollCounter,Yellow) .eval CollCounter=CollCounter+1 }
.if (BlockCollors.containsKey(L_brown)==true) { .eval BG.put(CollCounter,L_brown) .eval CollCounter=CollCounter+1 }
.if (BlockCollors.containsKey(D_brown)==true) { .eval BG.put(CollCounter,D_brown) .eval CollCounter=CollCounter+1 }
.if (BlockCollors.containsKey(L_red) ==true) { .eval BG.put(CollCounter,L_red) .eval CollCounter=CollCounter+1 }
.if (BlockCollors.containsKey(D_grey) ==true) { .eval BG.put(CollCounter,D_grey) .eval CollCounter=CollCounter+1 }
.if (BlockCollors.containsKey(Grey) ==true) { .eval BG.put(CollCounter,Grey) .eval CollCounter=CollCounter+1 }
.if (BlockCollors.containsKey(L_green)==true) { .eval BG.put(CollCounter,L_green) .eval CollCounter=CollCounter+1 }
.if (BlockCollors.containsKey(L_blue) ==true) { .eval BG.put(CollCounter,L_blue) .eval CollCounter=CollCounter+1 }
.if (BlockCollors.containsKey(L_grey) ==true) { .eval BG.put(CollCounter,L_grey) .eval CollCounter=CollCounter+1 }
.if (CollCounter == 4) {
// Check if it is the first block with 4 collors
.if (FirstMatch) {
// Copy the 4 collors as possible candidates
.eval BGCandidate.put(0,BG.get(0))
.eval BGCandidate.put(1,BG.get(1))
.eval BGCandidate.put(2,BG.get(2))
.eval BGCandidate.put(3,BG.get(3))
.eval FirstMatch = false
} else {
// Check BG candidate #0 = BG #0->3 => Next if some match OR Remove value / Decrease BGReamining
.for (var i = 0 ; i < BGRemaining ; 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)
.eval BGRemaining = BGRemaining-1
}
}
}
}
}
}
}
// Clear out the Block Collors
.eval BlockCollors = Hashtable()
// Reset the Block Collor Counter
.eval CollCounter = 0
}
// Verification of BG Coll:
.print "BG Collor is: " + BGCandidate.get(0)
}
|
| |
Slammer
Registered: Feb 2004 Posts: 416 |
Try the following:
When you have a time-consuming program, with pure script commands - then place them in a .define block or in a function and it will be faster.
The technical reason for this (which you don't need to know but some might find interesting):
When Kick Assembler evaluates a function or dircetive it saves the result, so it doesn't have to evaluate it in the next pass. The directive will only be reevaluated if the result is invalid (That happens if the result depends on a label that is defined later in the sourcecode). However if you have too many saved intermediate results, it damages the performace and the memory usage. Placing your script inside a function or .define block will save only one result and not all the intermediate results.
So this will be more effective:
.var bgColor = findBgColor(params)
.function findBgColor(params) {
...
}
|
| |
Slammer
Registered: Feb 2004 Posts: 416 |
Btw. if you dont want to restructure your code then just place a define directive inside your code that takes care of those for-loops. |
Previous - 1 | 2 | 3 | 4 | 5 - Next |