New sprite conversion tool: Tilificator

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
New sprite conversion tool: Tilificator
by on (#89609)
Tilificator has now reached a state where it might actually be useful for other people.

Tilificator is a sprite conversion tool I wrote to try to solve an annoying problem I've always had with sprite graphics for the NES: How to create CHR and sprite data that re-uses CHR patterns and tries to minimize the sprites per scanline, without lots of repetitive effort.

To do this for you, it uses some clever heuristics, and a lot of brute-force, trading artist time for computer time. It's a work in progress, and will still produce bad results for some seemingly obvious cases. But it'll probably do the job better for big amounts of sprite data unless you're dedicated to hand-optimizing your sprites. :)

Have a try with it, and give me your feedback!

by on (#89618)
A long time ago, back in the first quarter of 2007, I had written a similar tool that only worked across, turning large (fighting-game-sized) characters into rows of 8x16 pixel sprites.

Andrew Davie wrote a similar tool called Objective

by on (#89671)
Tilificator is open-source and work with multiple targets (and runs on many operating systems, too). So, that is one advantage over using Objective. However, I see no command-line mode for Tilificator; but someone can add that if wanted.

But, good idea! Thank you!

by on (#89773)
Seems pretty nice, gotta try it some time. I wrote something similar myself, it handles layered sprites but it's much slower and doesn't do "global optimization" of the resulting tiles.

On a side note, not sure if you're aware of this, but the .zip contains the .svn directory.

by on (#89780)
Hey this looks pretty cool but unfortunately I have a problem running it.
I compiled/installed it successfully but when I try to run from the terminal I get some error.

by on (#89785)
Quote:
Seems pretty nice, gotta try it some time. I wrote something similar myself, it handles layered sprites but it's much slower and doesn't do "global optimization" of the resulting tiles.


Well, lack of what I would also call "global optimization" is the current limitation of Tilificator as well. While the 'TilingMethodDragQueen' is the most capable (albeit slowest) of the methods to choose from, each of the methods suffer from the limitation that they will process each image separately, and try to match it to the tile table already built. To get better results for the cases where the optimal tilification for one image actually gives a crappy match for a later one, there'd probably be a need for a pre-pass that looks for similarities in all images at once.

I have some ideas for how this could work, but no idea when I'd get the motivation to do so, considering how much time this "side-project" of mine has already eaten up :)

Quote:
On a side note, not sure if you're aware of this, but the .zip contains the .svn directory.


Indeed I am aware of this. I figured there'd be no point in removing it, since it means you can update your version from the trunk just by using tortoiseSVN. The release .zip was just there to provide some convenience for those that don't want to mess with versioning systems just to try it out.



Quote:
Hey this looks pretty cool but unfortunately I have a problem running it.
I compiled/installed it successfully but when I try to run from the terminal I get some error.


Heh, it would be much much easier to help you out if you could tell me what that "some error" actually was... ;)

by on (#89786)
That's what I wanted to do but this stupid terminal doesn't allow to copy/paste what is written in it and I can't dump it as text either !
Looks like I'll have to copy the error message by hand :(

It says :
Code:
Taceback (most recent call last):
  File "C:\[...]\tilificatorgui.py", line 23 in (module)
     import gtk, gobject, cairo, pango
  File "C:\python27\[...]\gtk\__init__.py", line 40, in (module)
     from gtk import _gtk
ImportError : DLL load failed: La procédure spécifiée est introvable.

by on (#89788)
Quote:
Taceback (most recent call last):
File "C:\[...]\tilificatorgui.py", line 23 in (module)
import gtk, gobject, cairo, pango
File "C:\python27\[...]\gtk\__init__.py", line 40, in (module)
from gtk import _gtk
ImportError : DLL load failed: La procédure spécifiée est introvable.


Hmm, that shows that PyGTK (the python interface to GTK+) is being found, but that one cannot find the .DLL files of GTK+. According to Google, this is usually caused by having installed multiple versions of GTK+, missing the GTK+ directory on the %PATH% system variable (which the all-in-one installer should have done for you), and other tricky issues.

Could you maybe give me some more info such as: exactly how you installed it, what your %PATH% variable is, what Windows version you're running, phase of the moon, etc?

by on (#89807)
I installed it by using the 3 installers in the page you linked in your first post, and by following the instructions to run the install scripts from the terminal.

My %path% variable is.... long (agan I can't copy it form the terminal) but I don't find any python related path I think.

I use Windows 7 professional.

The moon was full 2 or 3 nights ago I think.

by on (#89811)
Try Alt+Space E K, drag a box around what you want to copy, and press Enter. Then paste into Notepad. Does that still work in Windows 7?

by on (#89823)
tepples wrote:
Try Alt+Space E K, drag a box around what you want to copy, and press Enter. Then paste into Notepad. Does that still work in Windows 7?

Thanks for this! Sometimes the right-click menu doesn't work on cmd.exe windows, I didn't know you could access the menu from the application menu/title bar as well.

Bananmos wrote:
Quote:
Taceback (most recent call last):
File "C:\[...]\tilificatorgui.py", line 23 in (module)
import gtk, gobject, cairo, pango
File "C:\python27\[...]\gtk\__init__.py", line 40, in (module)
from gtk import _gtk
ImportError : DLL load failed: La procédure spécifiée est introvable.


Hmm, that shows that PyGTK (the python interface to GTK+) is being found, but that one cannot find the .DLL files of GTK+. According to Google, this is usually caused by having installed multiple versions of GTK+, missing the GTK+ directory on the %PATH% system variable (which the all-in-one installer should have done for you), and other tricky issues.

Could you maybe give me some more info such as: exactly how you installed it, what your %PATH% variable is, what Windows version you're running, phase of the moon, etc?

I remember having the same problem with GTK some other time, not with Python though. Pretty sure it was caused by non-compatible version of GTK (libgtk*.dll) in Windows' System32/SysWOW64 directory.

by on (#89831)
Quote:
I remember having the same problem with GTK some other time, not with Python though. Pretty sure it was caused by non-compatible version of GTK (libgtk*.dll) in Windows' System32/SysWOW64 directory.


Yes, that could indeed be the case... I'd suggest doing a global search for libgtk*.dll across the file system and removing those, or at least renaming them temporarily.

Unless you changed this at installation, the proper .dll's should be in c:\gtk\bin, so also double check that your %PATH% environment includes this path.

by on (#89832)
The repertory c:\gtk doesn't even exist.

I have a load of libgtk-win32-2.0-0.dll files all over the place in my system though, namely in :
c:\program files\pigdin\gtk
c:\program files\common files\gtk\2.0
c:\python27\lib\site-packages\gtk2.0\runtime

I also have 2 times libgtkspell.dll in
c:\program files
c:\program files\pigdin

PS : I'm pretty sure none of those paths are in %path%

by on (#89834)
Quote:
The repertory c:\gtk doesn't even exist.


Pardon me for leading you on the wrong path (no pun intended) in this case. I realize now that my c:\gtk\bin directory is from some old installation and is not used by PyGTK.

My installation of PyGTK uses the .dll files under 'C:\Python27\Lib\site-packages\gtk-2.0\runtime\bin'. (did you just forget the '\bin' ending part in your post above?) I was also able to reproduce an error similar to yours by renaming the 'bin' directory to the dummy name 'binn':

Code:
Traceback (most recent call last):
  File "E:\rnb\tilificator\trunk\tilificatorgui.py", line 23, in <module>
    import gtk, gobject, cairo, pango
  File "C:\Python27\lib\site-packages\gtk-2.0\gtk\__init__.py", line 30, in <module>
    import gobject as _gobject
  File "C:\Python27\lib\site-packages\gtk-2.0\gobject\__init__.py", line 26, in <module>
    from glib import spawn_async, idle_add, timeout_add, timeout_add_seconds, \
  File "C:\Python27\lib\site-packages\gtk-2.0\glib\__init__.py", line 22, in <module>
    from glib._glib import *
ImportError: DLL load failed: The specified module could not be found


I could then restore the normal behavior by doing:

Code:
set PATH=C:\Python27\Lib\site-packages\gtk-2.0\runtime\binn;%PATH%


To make the dummy 'binn' directory name still be searched. Maybe you could try this to put the directory on the path explicitly? (even if it seems that is unnecessary on my system)

However, it's possible you must also make sure Windows cannot find any other conflicting .dlls, as specific directories (such as system,system32 etc) have priority over the ones in %PATH% in later Windows versions, IIRC...

by on (#89849)
Don't worry I pardon you.
And yes I forgot the \bin\ in my previous post.

I tried adding the path to path specifically, but unfortunately I still get the same error :(

by on (#89854)
Quote:
I tried adding the path to path specifically, but unfortunately I still get the same error


Seems this sounds more and more like TheFox's hypothesis that other gtk .dlls are getting in the way. Again, I'd recommend you to remove those from the search paths by either renaming them, or moving them to some place you are sure will not be searched by Windows...

by on (#89869)
I renamed all the others from *.dll to *.d__ but I still have the same error.

EDIT : In fact even if I rename even the good dll in d__ I still get the same error.

by on (#89872)
I wasn't gonna say anything, but the kind of problem Bregalad is having is one of the reasons I tend to avoid making tools that need frameworks, plugins and the like... These things are supposed to "just work", but sometimes it's just hell to figure out what's wrong. Good old native compiled code never presents these problems.

by on (#89874)
Quote:
I wasn't gonna say anything, but the kind of problem Bregalad is having is one of the reasons I tend to avoid making tools that need frameworks, plugins and the like... These things are supposed to "just work", but sometimes it's just hell to figure out what's wrong. Good old native compiled code never presents these problems.


This is going a bit offtopic and would benefit from a split, but I feel the need to say that getting stuck in ".dll hell" is commonplace on Windows and is hardly dependant upon using native compiled code or scripts/JIT compilation. Besides that, you are confusing and mixing up a lot of different things here in one sentence.

About native code:
Tilificator is written in Python, as it has been a project where I've experimented a lot with quite complex algorithms, and frankly would never have been able to finish it had I used "native code" instead (meaning C/C++ in these days as thankfully few people write their PC applications in asm)

Besides that, native code gives you the joy of "illegal exceptions" instead, leaving the user without any clues of where to look for answers as to your crashing application. That's more close to having "a hell to figure out what's wrong", if you ask me. :)

About frameworks:
Tilificator also uses GTK+, as it needed a GUI and GTK+ was the one I was most familliar with. Of course there are alternatives to GTK+, such as Qt, wxWidgets etc, each having their pro's and cons.

And no, none of their runtimes will come bundled with a Windows installation, so they all need some sort of thirdparty installation. Besides the fact that the Win32 widget framework is just horrible to use IMHO, I would not want to exclude GNU/Linux users from running my software just to make the experience of Windows users slightly smoother. I hope some non-Windows users will appreciate my choice.

About plugins:
Windows uses .dlls, so naturally it is the most natural way to use above said frameworks on Windows. And frankly I must say that for all the bashing that GNU/Linux usually gets, the package management there is really superior to .dll hell on Windows.

That said, my home computer which Tilificator is currently being developed on uses Windows 7, so I am surprised to see the difficulties people are facing, and am trying to investigate the reaons. But unconstructive picking on my choice of development tools isn't really helping much.

by on (#89876)
Relax, I wasn't "picking" on you. It's just that sometimes people think I'm weird for always wanting the simplest and smallest development environments possible, and I have a bit of trouble explaining why.

This was just a good example of the kind of thing I like to avoid, when making my own personal tools for my personal use. I think it's great that you are thinking about the Linux guys. Personally, I don't have the patience to deal with these kinds of issues, but I'm not saying everyone has to be like me.

Sorry if my post seemed offensive.

by on (#89877)
Bananmos wrote:
About native code:
Tilificator is written in Python
[...]
About frameworks:
Tilificator also uses GTK+, as it needed a GUI and GTK+ was the one I was most familliar with. Of course there are alternatives to GTK+, such as Qt, wxWidgets etc, each having their pro's and cons.

Tkinter, the Python interface to Tcl/Tk, comes bundled with every copy of Python for Windows. IDLE uses it, and 8name II (a nametable editor that I wrote in late 2009) uses it. You could probably get away with just making a tool depend on Python, Tkinter, and PIL, which a Windows user can install with two EXEs and an Ubuntu user can install with sudo apt-get install python-imaging-tk.

by on (#89889)
You could use Dependency Walker to see exactly which imports a Windows executable has.
One way out of this problem would be to add a manifest that specifies which exact version of each library to link against, and then include those libraries with your application (assuming that you're allowed to do so).

by on (#89896)
I also have Linux installed on my PC so maybe I could try running the tool from here if someone would explain me how I'm supposed to achieve this.

And don't worry it's not the first time I have issues with tools running on my PC ! A lot of stuff is problematic, sometimes I even have to use DoxBox or Wine (form linux) to run tools that are supposed to work in Windows.

My Windows 7 has been installed 2 years and a half ago (when it came out) and not it's basically a huge mess and very slow Windows I have, and I should definitely back up and format to get PC for a second youth.
However, I never wants to do it right away because I'm lazy and I have some *ahem* programs I got from *ahem* odd ways and I'm afraid of loosing them completely if I format my drive.

I don't think Baramos is to blame for using libraries, in fact I guess his tools use complex logic (it's not something simple like a hex to .db converter or something in the like like the tools I'm able to develop on my own), so obviously he has to use some libraries.
I remember getting trouble getting other similarly complex tools like the drum to while noise converter, the NES image converter and other things, to run.

by on (#89920)
Quote:
Tkinter, the Python interface to Tcl/Tk, comes bundled with every copy of Python for Windows. IDLE uses it, and 8name II (a nametable editor that I wrote in late 2009) uses it. You could probably get away with just making a tool depend on Python, Tkinter, and PIL, which a Windows user can install with two EXEs and an Ubuntu user can install with sudo apt-get install python-imaging-tk.


Yes, Tkinter does have the appeal of being the only GUI that's included in the standard Python library, which could ease the setup process for people. Like I said, I've been using GTK+ mostly out of tradition, but do change my preferences over time. You probably won't see me porting Tilificator to Tkinter anytime soon, but I might indeed take the opportunity to familliarize myself with Tkinter the next time I need to make a simple GUI program from scratch.

Quote:
I also have Linux installed on my PC so maybe I could try running the tool from here if someone would explain me how I'm supposed to achieve this.


In theory things should be much simpler in GNU/Linux, since the package manager should fix everything for you if you just find the package for PyGTK and PIL. In practice... I haven't tried Tilificator on a Linux system in quite a while, so can't gurantee it'll work well. But hey, that's what beta testers are for, right? ;)

I also had a try with py2exe to produce a win32 native build with all .dlls included which you could also try out, but I don't know if it'll be any more successful at solving the .dll hell...

(btw, are you using 32-bit or 64-bit Windows?...)

by on (#89921)
I use 32-bit Windows.

And the .exe version actually works ! This definitely looks like a very advanced tool, it's amazing ! I'll have to play with it a lot.

Edit : OK the next problem is already here. When I load the demo megaman sheet, it works perfect, but when I load my own sprite sheet, it seems like it works at first, I press the "Ok" button and then nothing happens (the metasprites does not show up on the right panel).

by on (#89925)
Nice to hear you got it working! I would recommend trying to get the source version working eventually though, as it's more fun to play with when you can experiment.

Quote:
Edit : OK the next problem is already here. When I load the demo megaman sheet, it works perfect, but when I load my own sprite sheet, it seems like it works at first, I press the "Ok" button and then nothing happens (the metasprites does not show up on the right panel).


In order for the automatic locating of sprites in the sprite sheet to work, the background should be color#0 (the image needs to be 8-bit indexed color format), and it must be possible to find a blank line between each row of sprites in the sheet.

If it's possible for you to share the sprite sheet in question, I can look into it.

by on (#89941)
Nice to see that py2exe fixed the problem. I've used it in the past to release stand-alone win32 versions of some programs I wrote.

by on (#90080)
Bananmos wrote:
Tilificator is written in Python, as it has been a project where I've experimented a lot with quite complex algorithms, and frankly would never have been able to finish it had I used "native code" instead (meaning C/C++ in these days as thankfully few people write their PC applications in asm)

It's the same way for me, I've only recently discovered the joys of Python, but now it's pretty much all I use for tools like this, unless I absolutely need the performance gains of C++.

Quote:
And no, none of their runtimes will come bundled with a Windows installation, so they all need some sort of thirdparty installation. Besides the fact that the Win32 widget framework is just horrible to use IMHO, I would not want to exclude GNU/Linux users from running my software just to make the experience of Windows users slightly smoother. I hope some non-Windows users will appreciate my choice.

Yeah the native Win32 GUI API has a ton of baggage. It can do everything, but not in a programmer friendly way. Personally I've used wxWidgets with Python, I like it a lot. Qt also seems great, but wxWidgets is a little bit more lightweight. Then again, Qt (probably) has better support tools. Pros and cons, like you said. :)

Quote:
About plugins:
Windows uses .dlls, so naturally it is the most natural way to use above said frameworks on Windows. And frankly I must say that for all the bashing that GNU/Linux usually gets, the package management there is really superior to .dll hell on Windows.

That said, my home computer which Tilificator is currently being developed on uses Windows 7, so I am surprised to see the difficulties people are facing, and am trying to investigate the reaons. But unconstructive picking on my choice of development tools isn't really helping much.

Personally I don't think the DLL hell is all that bad. Or it wouldn't be if authors always distributed their applications with all the necessary DLLs. There's really no excuse to not be doing that nowadays (unless the application is being distributed as source code, like in your case). The actual issues behind errors like seen by Bregalad are always very simple, I'm still willing to be that older copies of the same DLLs were "somewhere". Unfortunately Windows doesn't make it easy by default to diagnose these problems...

The package management systems of *nix distros are fine until you need to install something more specialized, and then the dependency hell often becomes even worse than on Windows.

That's my 5 cents on derailing the thread. :)

by on (#90135)
Quote:
If it's possible for you to share the sprite sheet in question, I can look into it.

I just wanted to point out I've sent you a PM with the sprite sheet linked in it (apparently you didn't notice ?).
I'm sorry but I don't want my sprites to be too much revealed to the public yet, as I want people to have some surprise when the game comes out (if it ever comes out).

by on (#90139)
Sorry for not noticing your PM until now, I usually only login if I need to write in a thread.

Like I suspected, your spritesheet does not use color#0 for the background, and this triggered a bug in the cut spritesheet dialog where it would use the color of the upper-left pixel of the sheet as the background color in some of its code, but still assume color#0 to be the background code in another routine.

I've fixed that bug in the SVN source repository, so your sprite sheet now loads. But I kind of doubt the result is what you wanted: the composite sprite window on the write will end up showing gray rectangles around the characters, while the black contours will end up as transparent.

Instead, I think what you want to do is remap the colors and switch color#0 with color#3, so that the gray bg will be color#0 and the black contours will be color#3. I easily did this with the "Rearrange Colormap" menu in GIMP. If this is not what you want, please try to explain what you would expect Tilificator to do here.

With the 'ShiftedRows' method, your spritesheet ends up using 90 tiles. I could also reduce this to 89 tiles by noticing some suboptimal tiling (a result of the order of images and the lack of global optimization mentioned earlier) and deleting some tiles manually and running a second pass, forcing it to use another, similar instead. I also noticed at least two tiles which differed only in the color of one pixel.

With the 'DragQueen' method, I got 90 tiles at well, although the results look very different since that method squezees the tiles together as much as possible (which may be considered an advantage when doing OAM cycling, since less total pixels will flicker).

However, it also seemed to produce a worthless completely blank sprite/tile! I need to look into this.
EDIT: This bug in now fixed in the SVN source repository.


Anyways, that mans 89 tiles for that spritesheet should really be the result without manual tweaking. Does that satisfy your tile budget? :)

by on (#90142)
OK, so the problem was about the color map. Which I get no control on when I do "PNG export" in Tile Molester...

That's weird the current sprite sheet I have for this is 70 tiles (which I already made) but I wanted to see if this could be improved further.

by on (#90144)
Quote:
That's weird the current sprite sheet I have for this is 70 tiles (which I already made) but I wanted to see if this could be improved further.


Ouch, that does sound like a major disappointment then...

I'd love to get access to your .chr tiles if I could, so I could see what sort of handcraft Tilificator is not able to match here. There is a third tiling method called 'FullMatch', which does not add any tiles to the tile table but instead tries to match the sprite images to an existing tile table. This should (at least in theory) produce something very similar to your manual sprite arrangement.

by on (#90151)
Sure, I'll send you a link to the .chr file I use in my game by PM.

by on (#92503)
I tried using the DragQueen method (with color size 4) on this image:

Image

The progress bar fills up (slowly) and then it just gets stuck here:

Image

by on (#92526)
Sorry for yet another silly bug... I've fixed this now on the trunk. If you're using that, do an SVN update. Otherwise, I might be able to compile a new binary tomorrow night unless it gets too late... gonna watch Iron Sky at the movies tomorrow after work. Funny how one nazi-themed scifi story can delay me in helping out with another ;)

After running about 15 minutes on my netbook, it seems to result in 36 tiles:
Image

(ShiftedRows method runs much faster, but gives 2 tiles more..)

Here are the two palette layers shown individually:
Image

Image

One thing to note though, is that the tilification will be split into a separate phase for each palette, and only the first phase will be shown in the progress bar - the other will seem to have stopped until it completes. (but this time you should not get the out-of-bounds exception that cause it to never finish). Should fix this issue in the progress box sometime soon I guess, since it can be quite confusing...

by on (#92542)
Bananmos wrote:
Otherwise, I might be able to compile a new binary tomorrow night unless it gets too late...

That would be nice, I don't have a SVN client installed here right now.

by on (#92547)
Wow, Iron Sky is probably the best scifi movie in decades!

Here's a new win32 build produced by py2exe which fixes the bug you ran into (and a few earlier ones):

https://sourceforge.net/projects/tilificator/files/releases/tilificator_v0.2C07-win32.zip/download

I take a wild guess that you are trying to fit all the faces in a single spritepage of 256 tiles that you can switch to during the dialogues? Having a look at the image sheet of faces, it looks like it could be a tight fit... but it might be doable.

Good news is that professor Tary doesn't seem to need more than 3 colors+bg. And you could take some liberties with the guy with glasses and change the very few pink pixels he has into brown ones.

Besides that, a lot of the faces requiring more than 1 palette have just one extra color, such as the one you tried converting. In this case, rather than waste bits on an empty bitplane you could do the old trick of encoding two 1-bit tiles in a 2-bit one, and use the sprite palette to select which one to use. But of course, there's no easy way to do that automatically with Tilificator.

by on (#92548)
Bananmos wrote:
Besides that, a lot of the faces requiring more than 1 palette have just one extra color, such as the one you tried converting. In this case, rather than waste bits on an empty bitplane you could do the old trick of encoding two 1-bit tiles in a 2-bit one

That or use any of various forms of RLE on the CHR data.

by on (#92549)
Actually, having a closer thought about this: by using all three sprite palettes (besides the main 4-color one) as 1-color palettes selecting diplaying either the low or high bits at a specific color, you could convert lots of the tiles that happen to get tilified into a single color (+bg) so they use these single color palettes. In that case, you would probably have no difficulties fitting this into a 256 tile bank!

Requires some extra tooling though, so I guess it's only worth it if you really have trouble squeezing it in.

by on (#92550)
Quote:
That or use any of various forms of RLE on the CHR data.


There are indeed lots of ways this could be compressed more efficiently (the codemasters scheme Tokumaru reverse-engineered comes to mind). But I was specifically thinking about how all tiles could be fit in a single 256 tile bank here for more simple coding, and chr compression schemes won't help with that.

by on (#92554)
Bananmos wrote:
Wow, Iron Sky is probably the best scifi movie in decades!

I've been meaning to see it for a while now as well...

Quote:
Here's a new win32 build produced by py2exe which fixes the bug you ran into (and a few earlier ones):

Thanks!

Quote:
I take a wild guess that you are trying to fit all the faces in a single spritepage of 256 tiles that you can switch to during the dialogues? Having a look at the image sheet of faces, it looks like it could be a tight fit... but it might be doable.

It's not strictly required to fit them all in 256 tiles, I can upload each face when the speaker changes. So I don't think I'm going to bother with attempting that for now.

Quote:
Besides that, a lot of the faces requiring more than 1 palette have just one extra color, such as the one you tried converting. In this case, rather than waste bits on an empty bitplane you could do the old trick of encoding two 1-bit tiles in a 2-bit one, and use the sprite palette to select which one to use. But of course, there's no easy way to do that automatically with Tilificator.

Yeah that's a good idea.

--

EDIT: Found a minor bug, when the open/save file dialog is open and I switch to another window (like this browser window) and then back to Tilificator, the main window pops up on front of the file dialog. File dialog is still the one with the focus but the main window obscures it. GTK problem?

by on (#92580)
Quote:
It's not strictly required to fit them all in 256 tiles, I can upload each face when the speaker changes. So I don't think I'm going to bother with attempting that for now.


Well, in that case, I indeed think you would be better off just employing some compression scheme to the raw images and converting the decompressed pixels to tiles on-the-fly during decoding, rather than using Tilificator. The "hardware compression scheme" inferred by the NES's 2-bit tiles really doesn't score that high as far as compression ratio is concerned.

There's plenty of time to run a decoders like this since the original game opens up the text box so slowly by design. And since only the mouth is changing between the images, the face could be animated by just enabling/disabling a sprite or two. :)


The Codemasters codec could be a good starting point, but you'll most likely need to modify it to support more than 4 colors to make it really useful.

by on (#92636)
Bananmos wrote:
Well, in that case, I indeed think you would be better off just employing some compression scheme to the raw images and converting the decompressed pixels to tiles on-the-fly during decoding, rather than using Tilificator. The "hardware compression scheme" inferred by the NES's 2-bit tiles really doesn't score that high as far as compression ratio is concerned.

Yeah possibly, I'll probably explore these options when I have a better idea of what PRG size I'm going to target. :) For now, I'm just looking for a quick way to get them to show up.

This reminds me of another thing why prematurely optimizing for size is bad especially on the NES: the PRG size is pretty much forced to be a power of two. So let's say at some point in development we make an optimization that saves us 2KB of ROM. Now if the final game still ends up being e.g. 60KB big, that optimization was for nothing. Just something to keep in mind. :)

by on (#92642)
thefox wrote:
This reminds me of another thing why prematurely optimizing for size is bad especially on the NES: the PRG size is pretty much forced to be a power of two. So let's say at some point in development we make an optimization that saves us 2KB of ROM. Now if the final game still ends up being e.g. 60KB big, that optimization was for nothing. Just something to keep in mind. :)

Unless the game is in a multicart with something else. That's what Wisdom Tree did when its Christian hack of Menace Beach into Sunday Funday: fix up Free Fall into Fish Fall and shove it into the remaining space. And it's possibly how we got the Balloon Trip mode of Balloon Fight. If your game ends up 80 KiB, but you can squeeze clones of two other A52 games into the rest of a 128 KiB cart, that's even better.

by on (#92734)
Quote:
This reminds me of another thing why prematurely optimizing for size is bad especially on the NES: the PRG size is pretty much forced to be a power of two. So let's say at some point in development we make an optimization that saves us 2KB of ROM. Now if the final game still ends up being e.g. 60KB big, that optimization was for nothing. Just something to keep in mind.


Very good point. I'd say just get it working in whatever shape is playable on the NES, then see if you have motivation left for size tweaks.

Anyways, let me know if there's bugfixes/improvements to Tilificator I can do to help your effort. I'm really excited about your porting project, so I'd love to help out a bit if I can. :)

by on (#93007)
Bananmos wrote:
Anyways, let me know if there's bugfixes/improvements to Tilificator I can do to help your effort. I'm really excited about your porting project, so I'd love to help out a bit if I can. :)

Well, here's a feature request: Would it be possible to add an option to not crop the images when using "Import sprite images"?

I'm converting this image (differences of the 2nd frame of Joe's face when compared to the 1st one), and when Tilificator crops it, it loses its positional information relative to the original image.

Image

EDIT: Also opening a project doesn't seem to work?
Code:
Traceback (most recent call last):
  File "tilificatorgui.py", line 486, in openWorkspace
  File "tilificatorgui.py", line 494, in openWorkspaceAs
  File "TilificatorProject.pyo", line 161, in readXML
  File "plistlib.pyo", line 78, in readPlist
  File "plistlib.pyo", line 406, in parse
xml.parsers.expat.ExpatError: not well-formed (invalid token): line 1, column 0

by on (#93731)
Sorry for the very late response - my recent move to the UK kept me away from this board more than I had thought. :)

I have removed the cropping as requested, you can find a new Windows build here

About opening the project: you accidentally made Tilificator select the codepath for loading the old deprecated XML-based format that I was using before, probably because your project file did not use '.tpr' naming.

I switched to a JSON-based format before the first public release, and kept this support there just to be able to load my old files, and that codepath will probably be removed completely at some later point...

The choice of it trying to call the deprecated XML loading whenever the suffix is not .tpr wasn't the best one though, as your example shows. So I've also changed it to always use the JSON-codepath unless the filename matches the previous very long suffix that no one should be stumbling across accidentally...

by on (#93734)
Bananmos wrote:
The choice of it trying to call the deprecated XML loading whenever the suffix is not .tpr wasn't the best one though, as your example shows.

Yeah, I mean, I had no idea that .tpr was the recommended suffix, because the save dialog didn't automatically append it. So I've been using ".tilifactor". :) But thanks for the changes again!

by on (#95592)
I was interested in trying this but it doesn't seem to work.

Code:
Traceback (most recent call last):
  File "tilificatorgui.py", line 23, in <module>
  File "gtk\__init__.pyo", line 40, in <module>
  File "gtk\_gtk.pyo", line 12, in <module>
  File "gtk\_gtk.pyo", line 10, in __load
ImportError: DLL load failed: The specified procedure could not be found.


Do I need to install additional python stuff with the .exe version? Pop up windows claims it can't find an except(ion?) handler entry point in msvcrt.dll, but I don't think that is so important.
Re: New sprite conversion tool: Tilificator
by on (#98611)
DragQueen method crashes with this image (ShiftedRows works):

Image

Color size was set to 4.

Here's the log:
Code:
Traceback (most recent call last):
  File "tilificatorgui.py", line 316, in tilifyAll
  File "tilificator.pyo", line 76, in tilifySpriteImage
  File "tilingmethoddragqueen.pyo", line 213, in tilify
  File "tilingmethoddragqueen.pyo", line 109, in getOptimizedTilificationFromColumns
  File "tilingmethoddragqueen.pyo", line 600, in optimizeRows
  File "tilingmethoddragqueen.pyo", line 499, in reductionImpossible
  File "tilingmethoddragqueen.pyo", line 488, in minimumSpriteTilesNeededForRow
  File "tilingmethoddragqueen.pyo", line 337, in findLastNonBlankColumn
IndexError: list index out of range
Re:
by on (#98614)
Movax12 wrote:
Do I need to install additional python stuff with the .exe version?

You might need to install GTK. Do you have GIMP (GNU Image Manipulation Program) or Pidgin (multiprotocol chat client) installed?
Re:
by on (#98617)
Movax12 wrote:
Do I need to install additional python stuff with the .exe version? Pop up windows claims it can't find an except(ion?) handler entry point in msvcrt.dll, but I don't think that is so important.

You shouldn't have to install anything extra. What's the version of msvcrt.dll in your System32 or SysWOW64 directory?
Re: New sprite conversion tool: Tilificator
by on (#98796)
thefox wrote:
DragQueen method crashes with this image (ShiftedRows works):

Image

Color size was set to 4.

Here's the log:
Code:
Traceback (most recent call last):
  File "tilificatorgui.py", line 316, in tilifyAll
  File "tilificator.pyo", line 76, in tilifySpriteImage
  File "tilingmethoddragqueen.pyo", line 213, in tilify
  File "tilingmethoddragqueen.pyo", line 109, in getOptimizedTilificationFromColumns
  File "tilingmethoddragqueen.pyo", line 600, in optimizeRows
  File "tilingmethoddragqueen.pyo", line 499, in reductionImpossible
  File "tilingmethoddragqueen.pyo", line 488, in minimumSpriteTilesNeededForRow
  File "tilingmethoddragqueen.pyo", line 337, in findLastNonBlankColumn
IndexError: list index out of range


Drat! Now fixed on the trunk in the latest commit.
Re: New sprite conversion tool: Tilificator
by on (#99333)
Bananmos wrote:
Drat! Now fixed on the trunk in the latest commit.

Thanks! Got another crash with this image. Dunno if it's because of the big size?

Code:
Traceback (most recent call last):
  File "tilificatorgui.py", line 316, in tilifyAll
    for progress in tilifySpriteImage(siw.spriteImage, self.tileTable):
  File "C:\Users\f\Desktop\tilificator-svn\trunk\tilificator.py", line 76, in tilifySpriteImage
    for progress in tilingMethod.tilify():
  File "C:\Users\f\Desktop\tilificator-svn\trunk\tilingmethoddragqueen.py", line 200, in tilify
    ycoordCombinationsMinimal[r] = self.getSpriteColumns(self.si, x)
  File "C:\Users\f\Desktop\tilificator-svn\trunk\tilingmethoddragqueen.py", line 362, in getSpriteColumns
    ycoordCombinations = self.genYCoords(buf, bufNext1, bufNext1[0]-self.settings.tileHeight+1)
  File "C:\Users\f\Desktop\tilificator-svn\trunk\tilingmethoddragqueen.py", line 354, in genYCoords
    tail = self.genYCoords(buf, bufNext1, y+self.settings.tileHeight)
  File "C:\Users\f\Desktop\tilificator-svn\trunk\tilingmethoddragqueen.py", line 354, in genYCoords
    tail = self.genYCoords(buf, bufNext1, y+self.settings.tileHeight)
  File "C:\Users\f\Desktop\tilificator-svn\trunk\tilingmethoddragqueen.py", line 355, in genYCoords
    nextRange = expandedProduct([y], tail)
  File "C:\Users\f\Desktop\tilificator-svn\trunk\common.py", line 115, in expandedProduct
    return [list(itertools.chain([sublist[0]], sublist[1])) if(type(sublist[1])==list or type(sublist[1])==tuple) else [subli
st[0],sublist[1]] for sublist in p]
MemoryError
Re: New sprite conversion tool: Tilificator
by on (#99365)
Quote:
Thanks! Got another crash with this image. Dunno if it's because of the big size?


Most likely yes... the DragQueen method basically starts out by trying to test pretty much every combination of "columns variants", where the "column variants" are every way you can cover all pixels in an 8xScreenHeight column with 8x8 sprites without them overlapping. To avoid doing unreasonable amounts of combinations, the columns are reduced by selecting the "probably best ones" (basically a local optimization step, risking to miss out on the final global optimum) so that the final product of all of them doesn't go beyond a certain reasonable size. But the size of your image manages to make the column creation itself go out of memory. :)

I'll have a look at what can be done... probably a lot by just changing list comprehensions to iterators where possible. But even so, the processing time required to tilify that image will probably be enormous due to the large amount of combinations DragQueen tests. So I'd suggest just going with the ShiftedRows method for this particular one...
Re: New sprite conversion tool: Tilificator
by on (#99370)
Bananmos wrote:
I'll have a look at what can be done... probably a lot by just changing list comprehensions to iterators where possible. But even so, the processing time required to tilify that image will probably be enormous due to the large amount of combinations DragQueen tests. So I'd suggest just going with the ShiftedRows method for this particular one...

Yeah and it turns out that I can't probably use that big of an image anyways, as it'll result in more than 64 sprite tiles. I guess I could try 8x16 sprites...
Re: New sprite conversion tool: Tilificator
by on (#99389)
Haven't done anything to Tilificator yet, but I tried to have a go myself at converting that title picture of Superb Joe...

I choose a slightly different set of colors for the conversion. Also, there were two colors only used in a few pixels that were so close to other colors that I assume they were accidentally put there, and you wouldn't be able to use different ones when using the NES palette anyway, so I remapped those.

I started by making the reddish colors of the armor use the BG palette. Also, to not bump into the 8 sprites/scanline limit I had to use an extra BG palette for Joe's right hand, and figured I might as well use that palette for some other BG tiles to have a few sprites less. Got this result using NESST:
Image

Then, I used two separate sprite palettes for the skin and blue details:
Image

To avoid the memory constraints of DragQueen, I manually separated the skin/blue sprite overlays and split them vertically. I guess this is what Tilificator should be improved to do transparently when possible...

Result with Tilificator:

63 tiles and 65 sprites with ShiftedRows method.
58 tiles/sprites with DragQueen method, so no need for 8x16 sprites.

BG uses 118 tiles.

If you want some assistance, I could help you further with optimizing this to fit your title screen requirements, but I'll need to know which constraints you're working with. How does the rest of your title screen look? Do you want to implement some of the scrolling effects from the original game? (logo going in one direction, Suer Joe image and text in other directions) If so you probably need to use sprites exclusively for the top of Joe's head to be able to scroll Joe independently.
Re: New sprite conversion tool: Tilificator
by on (#99394)
Bananmos wrote:
Haven't done anything to Tilificator yet, but I tried to have a go myself at converting that title picture of Superb Joe...

If you want some assistance, I could help you further with optimizing this to fit your title screen requirements, but I'll need to know which constraints you're working with. How does the rest of your title screen look? Do you want to implement some of the scrolling effects from the original game? (logo going in one direction, Suer Joe image and text in other directions) If so you probably need to use sprites exclusively for the top of Joe's head to be able to scroll Joe independently.

Nice results! The only real difference to the original I can see is the missing shading on the right (Joe's left) arm, but that's not a big deal.

As for constraints, there's nothing too special in the title screen, like in the original. I used two background palettes for the logo (just because of the light red line in it). I also need one color for the selection bullet point, but that can use a color from Joe's outfit, or wherever (color doesn't really matter). The font needs the white color, that can come from the logo palettes.

I'm up for implementing the scrolling effect. It looks like your version of big Joe already has the top 11 pixels of his head (re-)defined with sprites, so that could be enough for some overlap with the logo. Of course there also the option of not having overlap at all.
Re: New sprite conversion tool: Tilificator
by on (#99422)
Quote:
The only real difference to the original I can see is the missing shading on the right


Doh! I must have mistakenly erased that while optimizing the image. Just got a bit carried away I suppose... :)

Took some time to optimize BG as well:
Image
Resulting in 98 tiles, that should give plenty of room for the logo and font.

Besides fixing the missing shading you mentioned, I also added a third sprite palette to have almost the entire of Joe's face available for overlap: (Incidentally, the pink color here is also the same as the one used for the selection bullet point you mentioned)
Image

Tile/sprite count went slightly up due to the additions, to 62 tiles/sprites. (no re-use of tiles) That leaves you with a very fine margin of 2 sprites for the bullet point and a sprite#0 hit. Again, I had to split the images vertically to avoid the memory error...

As for the scrolling effect, I can't imagine how you would manage to get all three independently moving objects from the original, so you'll probably need to compromise a bit. Maybe just remove the bottom text when the user presses start and the screen flashes, so that only the logo and Joe have to scroll?
Re: New sprite conversion tool: Tilificator
by on (#99424)
Bananmos wrote:
...

Tile/sprite count went slightly up due to the additions, to 62 tiles/sprites. (no re-use of tiles) That leaves you with a very fine margin of 2 sprites for the bullet point and a sprite#0 hit. Again, I had to split the images vertically to avoid the memory error...

As for the scrolling effect, I can't imagine how you would manage to get all three independently moving objects from the original, so you'll probably need to compromise a bit. Maybe just remove the bottom text when the user presses start and the screen flashes, so that only the logo and Joe have to scroll?

Thanks man, that looks absolutely perfect! Can you send me the .tpr file of the sprite overlay?

For scrolling yeah it was my plan to scroll just Joe and the logo.
Re: New sprite conversion tool: Tilificator
by on (#99489)
thefox wrote:
Thanks man, that looks absolutely perfect! Can you send me the .tpr file of the sprite overlay?

For scrolling yeah it was my plan to scroll just Joe and the logo.


Got stuck trying to make tilificator split things up, so here's a manually merged .tpr of the image I had to split up. (good to have a text-based data format for once :)

Hope it'll be useful, looking really forward to seeing the final game!
Re: New sprite conversion tool: Tilificator
by on (#99515)
Bananmos wrote:
Got stuck trying to make tilificator split things up, so here's a manually merged .tpr of the image I had to split up. (good to have a text-based data format for once :)

Hope it'll be useful, looking really forward to seeing the final game!

Thanks, I've added that in to the game. Now to code that transition...
Re:
by on (#132874)
Movax12 wrote:
I was interested in trying this but it doesn't seem to work.
Code:
Traceback (most recent call last):
  File "tilificatorgui.py", line 23, in <module>
  File "gtk\__init__.pyo", line 40, in <module>
  File "gtk\_gtk.pyo", line 12, in <module>
  File "gtk\_gtk.pyo", line 10, in __load
ImportError: DLL load failed: The specified procedure could not be found.


tilificator_v0.2C07-win32
windows xp

Same error for me.
installing PyGTK doesn't help.

tried on other pc, without python doesn't launch. with python 2.7 same error.

on first pc also have gimp.
Re: New sprite conversion tool: Tilificator
by on (#132875)
Almost sounds like py2exe might be a better overall choice. Yes, larger binary and result, but should guarantee compatibility across the board. (And plus I hate installing Python on Windows machines -- I'm perfectly fine with a big fat standalone executable)