I've been studying Pico-8 only for about a week now and really having a good time. I enjoy thinking within it's constraints. In particular I like fiddling around with the graphics memory directly to do fun video effects.
With the following code snippet I can move every other video line offscreen to the left or right, giving an interesting "tearing apart" video effect. This works great and is very fast, and gets me to a blank screen where "blank" just means the screen is filled with a chosen "clear color."
if (y%2==0) then memcpy(dst,src,63) memset(src,clear,1) else memcpy(src,dst,63) memset(src+63,clear,1) end
So, now that the screen is clear, I want to do the opposite. Bring in a full screen image (perhaps a map or scaled sprite) onto screen in the reverse. i.e. Odd-lumbered video lines scroll in from the left and even-lumbered lines scroll in from the right.
This would assume that some pre-composed block of memory is waiting from which i do a similar memcpy() from off-screen to on-screen... or at least that is conceptually what i think needs to happen. But i do not understand the possibilities of Pico-8 deeply enough to understand how/where to keep such an offscreen buffer, or if that is even possible.
Any pointers on how to tackle this?
Interesting issue. I've not mucked around with memory much but I have a couple ideas of what is possible. You could copy the sprite sheet data to the screen data in a similar way to what you are currently doing, and if you wanted to fade in a particular screen you could draw it to the screen to get it to memory, copy that memory to somewhere else (the sprite sheet, or the map data) clear the screen before the end of draw then start to copy it from that location to the screen. I believe you can draw to the sprite sheet in a couple ways, I know of sset for pixel by pixel an memcpy.
For another approach you could also use some combination of the clip function and drawing to the screen - so have the whole scene organised the have clipping for what parts you draw as you fade in. Don't need to have a screens worth of memory kicking around for that either, but would be more code and more difficult to move things into view.
So to answer your question more directly you could conseptually copy your memory to wherever you want then copy it back to the screen, as long as you don't mind overriding whatever is already there. Here's the wiki page on what's stored where if you've not already seen it.
Draw to the sprite sheet.... OK, that is starting to give me an idea.
- Draw a map.
- On screen draw, use the y coordinate to target a horizontal sprite slice of the map.
- Using that slice, read the sprite number and memcpy() the corresponding horizontal pixel slice to an area of the sprite map which has been left empty specifically for this purpose. (using a starting memory space which allows for easy math :P)
- Once the pixel slice has been composed into the sprite sheet, just do my regular memcpy() from sprite sheet memory to on-screen video memory.
So, long story short:
Ad-hoc compose the exact slice of pixels, using the map as the recipe for composition. (although one could conceptually generate a routine which takes other types of desired output and generates the pixel memory on-the-fly for any given y coordinate)
A scaled sprite at full screen could be copied into the map memory space, but that would take over the entire memory space (0x1000 - 0x2fff) and would need to be read as raw data, not indexes into the sprite sheet. Which would actually be simpler... it all depends on what one wants to animate onto screen. Arbitrary graphics, or pre-composed maps.
Presumably, bringing in pixel data that looks like a sprite, but was not placed on-screen using a spr() draw would strip that sprite of any flags that were set. It would "look" right but would not "act" right, I believe...? Once animation is complete, a "proper" map could be drawn on top of the animated facsimile.
Progress today on this. Trying to accomplish without "caching" in the sprite memory (anticipating a time when lines are scrolled onto screen at random).
So far I can bring in arbitrary lines at various lengths from the map onto arbitrary screen coordinates. Much slower than i expected, considering how fast the screen wipe transition performs using similar memcpy() techniques.
I misspoke with the flag concern. I mean that drawing bytes that look like an existing sprite would not have a relationship to the flags set for the original sprite. If the sprite pixels are drawn using map() and spr(), then the flags would know where they exist. But drawing in bytes that are copied from arbitrary memory locations wouldn't have that connection. The original sprite would still have its flags, but this memory copied "clone" would not. The same as if you did a bunch of pset() on pixels to draw an image that looks like a sprite. It would just be a superficial clone, with no understanding of the flags the true sprite holds.
Log in to post a comment