Level Editor: Mirror/rotate a selection

Got a cool idea that should be in R'n'D? Let's hear it!

Moderators: Flumminator, Zomis

Post Reply
Flumminator
Posts: 184
Joined: Fri Jun 18, 2004 8:08 pm
Location: Germany

Level Editor: Mirror/rotate a selection

Post by Flumminator »

Hi all,

here's an idea I had quite recently: Since I often create levels that are - at least in parts - symmetrical, it would be really cool, if the level editor would help me achieving this.

Given the existing editing tools, I suppose the easiest way to implement this would be an extension to the "brush" tool. The idea is that when some level area is selected as a brush there's some buttons or hotkeys which allow to mirror the selection horizontally/vertically or rotate it by 90 degrees.

I hope you can give this a thought!
Flumminator->PostCounter += 1;
Flumminator
Posts: 184
Joined: Fri Jun 18, 2004 8:08 pm
Location: Germany

Re: Level Editor: Mirror/rotate a selection

Post by Flumminator »

Figuring this can't be too hard, I came up with a prototype implementation and took the liberty of creating a pull request on Github: https://github.com/ArtsoftEntertainment ... nds/pull/8

There's still some graphical glitches, which I also described in the PR. Any hints of how to address these are highly welcome :)
Flumminator->PostCounter += 1;
User avatar
Holger
Site Admin
Posts: 4081
Joined: Fri Jun 18, 2004 4:13 pm
Location: Germany
Contact:

Re: Level Editor: Mirror/rotate a selection

Post by Holger »

This is a really very good and useful idea! And I highly appreciated your pull request, which I could add nearly without changes to the R'n'D code base -- thanks a lot for this great contribution! :D

In your pull request description text, you wondered how to update the brush after flipping or rotating:
I guess it's necessary to re-draw the brush properly after changing it. Any help on how to achieve this is highly welcome ;)
I have attached the final commit that implements flipping and rotating brushes in the level editor; more or less, your really only needed an additional

Code: Select all

CopyBrushExt(last_cursor_x, last_cursor_y, 0, 0, 0, CB_BRUSH_TO_CURSOR);
to update the screen with the flipped or rotated brush. For rotating the brush, which may change its x/y size, you also have to temporarily delete the brush first using

Code: Select all

CopyBrushExt(0, 0, 0, 0, 0, CB_DELETE_OLD_CURSOR);
which can be seen in the patch file, too.

As the key shortcuts of the level editor of R'n'D are highly based on those of good old Deluxe Paint on the Amiga, I also used the "x", "y" and "z" keys for flipping (mirroring) the brush in x and y direction and to rotate the brush clockwise by 90° (which was in fact "x" for x-flipping, "z" for "y-flipping" and "y" for rotating clockwise in Deluxe Paint for strange/unknown reasons, so I used the more logical ones from the DPaint clone "GrafX2", which uses the shortcuts I also use in R'n'D's editor now.)

OK, so we now can flip and rotate brushes. That's very nice indeed! But: What's immediately apparent when using this new feature is that while brushes are flipped/rotated, tiles (game elements) are not! :shock: This is not only true for enemies starting to move in some direction, but especially apparent when using some sophisticated patterns using the DX style connected tubes or the DC style decorated steel walls. Or things like expanding walls. Or conveyor belts. And when editing MM style levels, the new feature really does not work well with all those sub-tile walls, which are just placed at wrong (or at least very unexpected) locations after flipping or rotating.

So I complemented the new feature with tiles/elements of the flipped/rotated brushes also being correctly flipped and rotated, and now the new feature really starts to be fun and be even more useful! :-)

I've added this second patch, too. Have fun!

Update: Forgot to mention that I skipped the shortcut for XY flipping the brush, which I think won't be needed too often, and which can easily be emulated by just pressing "x" and "z" instead (to x-flip and rotate the brush).
Attachments
1-flip_and_rotate_brushes.patch
(3.41 KiB) Downloaded 181 times
2-flip_and_rotate_tiles.patch
(17.3 KiB) Downloaded 168 times
Flumminator
Posts: 184
Joined: Fri Jun 18, 2004 8:08 pm
Location: Germany

Re: Level Editor: Mirror/rotate a selection

Post by Flumminator »

Thank you for taking this over!

Since you took over the code directly, I guess I can close the PR on github?
So I complemented the new feature with tiles/elements of the flipped/rotated brushes also being correctly flipped and rotated, and now the new feature really starts to be fun and be even more useful! :-)
That is really great, I haven't really thought of this since I was only experimenting with pretty plain walls/sand/amoeba patterns. Just, when I looked at your patch I thought "There has to be an easier way of doing this instead of these huge switch-case-statements!"

Well, I didn't exactly come up with an easier way, but by using some lookup-tables and exploiting the fact that there's always pairs of tiles that are transformed into each other, I did at least find a way to write it in less lines of code. 8)

The patch is attached. Use it, if you like it.
Attachments
0001-Flipped-tile-table-lookups-instead-of-switch-case.patch
(18.29 KiB) Downloaded 182 times
Flumminator->PostCounter += 1;
User avatar
Holger
Site Admin
Posts: 4081
Joined: Fri Jun 18, 2004 4:13 pm
Location: Germany
Contact:

Re: Level Editor: Mirror/rotate a selection

Post by Holger »

Since you took over the code directly, I guess I can close the PR on github?
Yes, you can do that. The code isn't maintained on GitHub anyway, just released there as a backup, or secondary repository, and because many people use GitHub. (And because the main repo does not offer any of the functionality of GitHub, so things like forking the code and creating pull requests is much easier if the code is also available on GitHub.)
Just, when I looked at your patch I thought "There has to be an easier way of doing this instead of these huge switch-case-statements!"

Well, I didn't exactly come up with an easier way, but by using some lookup-tables and exploiting the fact that there's always pairs of tiles that are transformed into each other, I did at least find a way to write it in less lines of code. 8)
Yes, I agree that the current "switch/case" solution is less than satisfactory, especially as it contains a lot of redundancy due to the element pairs, just as you mentioned. I also thought about an approach using lists of corresponding elements, but decided to use the "switch/case" solution because it will most likely be optimized by the compiler using jump tables to have O(log n) runtime complexity, while the list approach would result in linear O(n) time complexity, which will (at least theoretically) speed up the element flipping functions by a factor of around 10 (like 6 steps instead of 64 steps for a list of 64 elements).

However, I decided to use your solution anyway. The reason is that even for very large brushes, an execution speed factor of 10 can still be neglected with nowadays CPUs in favor of shorter code with much better readability and maintainability (and with regard to time/space complexity, we at least gain a factor of 2 for the space complexity of the data set involved. ;-) )
Post Reply