5 ms·
Quick explanation of compiled sprites: Most commonly a sprite is represented as a 2d array of pixels that you for X, for Y over and use math or branching to bl
by corysama 12y ago
Quick explanation of compiled sprites:
Most commonly a sprite is represented as a 2d array of pixels that you for X, for Y over and use math or branching to blend on to the screen. But, that's a lot of reading and writing, and a lot of the math ends up doing nothing because a lot of the pixels are intentionally invisible.
So, you could do some sort of visible/invisible RLE to skip over the invisible pixels. That's better, but it's still a complicated loop and still a lot of reading pixels.
So, many crazy democoders have decided to write "sprite compilers" that read the 2D color array of a sprite and spits out the assembly for the exact instructions needed to write each visible pixel one at a time as a linear instruction sequence with no branching. The sprites are then assembled and linked into the program code as individual functions. I believe they can even exclusively use immediate values encoded inside the instructions rather than reading the colors from a separate memory address. So, rather than read instruction, read data, write data; it becomes a read instruction, write data in two straight lines in memory.
- ekianjo 12y ago> it becomes a read instruction, write data in two straight lines in memory. So basically this kind of hack could not be used for a game, then, where interaction is needed?
- masswerk 12y agoEven the very first digital video game (Spacewar!) used something very much alike (Dan Edwards' outline compiler). Movable and rotatable – think of advancing by unit vectors –, compiled just in time from directional encodings. Read more at: http://www.masswerk.at/spacewar/inside/insidespacewar-pt4-oc.html http://www.masswerk.at/spacewar/inside/insidespacewar-pt4-oc...
- geocar 12y agoYour game could dynamically modify the instructions.
- ekianjo 12y agoSure, but wouldn't that incur a loss of performance ?
- geocar 12y agoSome, but maybe not very much: The screen is redrawn much more frequently than a key is pressed.
- skrebbel 12y agoYou might get noticeable latency though.
- userbinator 12y agoOn a modern pipelined CPU with separate instruction/data caches self-modifying code does have a rather large penalty since it has to flush the pipeline and the caches, but on the original 8088 PC which has no cache and no pipeline (there's only a 4-byte prefetch queue), the penalty is much smaller.
- ajenner 12y agoIt certainly can be (and has been) used for games where a limited set of sprites are drawn - each frame of animation is just a separate compiled sprite routine. Compiled sprite routines write at video memory addresses relative to a specified position, so they can be moved around at will.
- corysama 12y agoIIRC, because of relative-address store instructions, the destination address does not have to be hard-coded. So, the sprites can still move around dynamically. What's harder is clipping against the sides of the screen. With no branching, there's no way to prevent the sprite from writing past the end of a line/screen (wrapping/mem-stomping). So, there does need to be a test per sprite to detect that case and fall back on a more complicated blitter. The Allegro game framework had a compiled sprite jitter as a feature early on. So, that would be existence proof of them being used in games :) http://alleg.sourceforge.net/stabledocs/en/alleg016.html http://alleg.sourceforge.net/stabledocs/en/alleg016.html
- nitrogen 12y agoWhat's harder is clipping against the sides of the screen. With no branching, there's no way to prevent the sprite from writing past the end of a line/screen (wrapping/mem-stomping). So, there does need to be a test per sprite to detect that case and fall back on a more complicated blitter. In fullscreen modes, you could also just make your screen buffer bigger than the actual screen by the width and height of your largest sprite.
- lscharen 12y agoIn my game engine I wrote for the Apple IIgs a long time ago, I used compiled sprites and maintained a 1-scanline-wide mask that I used to clip the compiled sprite to the screen edge. This only cost one extra AND instruction and allowed the sprites to be clipped to any size rectangular playfield while still maintaining almost all of the speed benefits.
- Drakim 12y agoIt could probably be used for games as long as you keep within the bounds of your pixel data. However, modern games use GPU acceleration instead of plotting the pixels with the CPU, and most higher languages don't expose the sort of functionality you need to use this trick in the first place.
- enqk 12y agoIf you create code for each sprite and only change the base address to write to, you can use it for games alright. Jazz Jackrabbit is one that I've seen mentioned using compiled sprites. Lots of DOS games basically had to.
- boomlinde 12y agoI think Wolfenstein 3D compiles column scaling for each texture to speed up column rendering.
- JoshuaR 12y agoThe comments in the Wolf3D source implied that the self-compiling raycasting wasn't faster on an 80286 than a conventional BSP tree would have been, and was in fact slower on an 80486 thanks to invalidating the code cache over and over.