Hi everybody,
I'm looking into converting lots of maps for a personal project, taking them from the level.ini files that Lemmini creates. I've managed to get the levels to display the graphics in the correct positions, but I'm at a loss as to figure out the layering of the individual tiles.
Does anybody know how Lemmini determines which tile overlaps which other?
For example. The level "Here's one I prepared earlier" has a lot of tiles that overlap to create the shape of a boat. However, my program can read the level file either top to bottom or bottom to top, yet no matter which way I make it read, the level doesn't look the same as the official one.
Another example is "The Art Gallery". This one is a complete mess with my code. The 3D style effect is totally lost.
Examples of what I'm talking about can be found here... https://imgur.com/gallery/BHZ3Lgp (https://imgur.com/gallery/BHZ3Lgp)
Any ideas what else I can try to get the correct layering order?
Guess: You aren't interpreting the no-overwrite flags.
In DOS Lemmings 1, tiles have 3 flags:
erase (instead of drawing the tile, erase pixels where the tile would be),
upside-down (flip vertically), and
no-overwrite (draw behind existing tiles).
Naively, it looks like you don't need special code to handle no-overwrite, you would simply draw all no-overwrite tiles first, then the rest on top. Here's a counterexample to this strategy:
(http://www.lixgame.com/etc/noow-reason.png)
The order of these tiles in the file is A, B, C. Tile A is normal, tile B is an eraser, and tile C is no-overwrite. You cannot draw C-A-B because that would erase the part of C that appears in the hole. Neither you can draw C-B-A because A would appear as a complete square, which it should not. And you can't draw A-B-C because C shall not overwrite A.
You must really draw A, then erase with B, then draw with C exactly in the hole where there are no pixels, even though this is slow with hardware rendering.
Any other correct solution would be more complicated, e.g., you can analyze the tiles and observe that B really cuts something from A, creating a tile A' with the corner gnawed away, and then paint C, then A'.
I have no idea how Lemmini encodes no-overwrite in the text files.
-- Simon
Ah, thank you again! I was interpreting the "no overwrite" as in things wouldn't overwrite that tile, and so was bringing it to the front!
I've got the flags sorted for inverted, mask etc. Just had that one the wrong way round. I'll have a fiddle in a mo once I'm back at my computer :)
Hopefully I'll be able to do some advanced masking with newer CSS tricks to get the cut away working. (My program is an HTML and JavaScript file)
Edit:
Alas, it looks like the kind of masking required is beyond simple HTML/CSS and Javascript's capabilities.
At least I can use these codes to get a general feel to how the levels should look, and can also discover where all the hidden traps etc. are for those levels that have them :)
Cool, thanks for the feedback.
Right, there is no simple solution. No-overwrite is a nasty flag if you want to render the terrain properly.
Many L1 levels could have been designed with background tiles instead of no-overwrite, but the L1 designers still put many no-overwrite tiles. At least you'll have many test cases to check your algorithm. :devil:
Quote from: doogleHopefully I'll be able to do some advanced masking with newer CSS tricks to get the cut away working. (My program is an HTML and JavaScript file)
How do you draw eraser tiles? If that's cheap with your libraries, then idea:
Have two level-sized canvases, canvas 1 and canvas 2. Draw the level on canvas 1 as you're already doing. Canvas 2 is fully transparent. When a no-overwrite tile appears in the list, draw it on the canvas 2. Draw the canvas 1 onto canvas 2 as if canvas 1 were a single gigantic eraser tile. Draw canvas 2 onto canvas 1. Clear canvas 2.
The downside is that this allocates a second level-sized canvas. But every known solution either looks at the already-drawn terrain pixel-by-pixel (the straightforward implementation of no-overwrite straight from its specification), or allocates at least a small extra bitmap (to create tile A' in my reply #1).
Modern CSS is powerful, maybe you'll find something much better. I'll let myself get surprised with what it can do.
-- Simon
I never even thought about canvas! Funny how people can get stuck in the past when writing code.
Having the two (or three) level sized canvas objects is no issue, as this is purely for my own curiosity.
This whole thing started as I wanted to grab the skill sets from the .ini files for each level without having to manually go through each file. Then I noticed the terrain and object codes in the files corresponded to the image names, and so, curiosity got me writing this little level preview thing :)
Having a quick play around, it seems I might be able to do it properly using the canvas object,
I've got a simple "copy image 1 over image 2 while cutting out the black pixels" thing working, now I just need to get the objects to write to the correct locations. For some reason they're ignoring the x/y positioning and everything writes to the same location :(
I'll figure it out though.
I've already found a lot more hidden traps in the levels I've looked at than I thought there would be, such as in Oh No! More Lemmings level "Where Lemmings Dare", there are six of those vine traps surrounding the exit!
A much easier way to find those might be to fire up those levels in NeoLemmix and activate Clear Physics Mode, which marks the location of all object trigger areas no matter how hidden they are.