Prince Of Persia FX- is it doable?

Hi all. I’ve gotten the ‘bug’ to make a game. I’d love to make a faithful port of Prince of Persia. I just started playing around yesterday, to get a sense of whether or not it could work at such a small resolution, and I think it’ll look OK, based on a couple of images I quickly resampled and loaded into a basic game shell for a test (I will redraw them based on the original B&W Apple 2 assets if I go forward with this).

The characters will be pretty minimally detailed, but as long as the motion is fluid, I think it would work.

Title
ArduboyCapture

I’ve also played with some 3-color variants, and they look MUCH better, especially the characters at this size. I thought about using the ‘flash between 2 images’ technique to get the mid-tone grey, but I’m going to struggle with space as it is, and that would basically double the space needed for the sprites, if I understand the technique correctly. I could just do the characters, though, since the level tiles will look fine at 1-bit color. The characters sprites are only about 14 pixels tall, so the space needed for each is tiny, but the hallmark of this game is it’s fluid movement animation, so I’d probable favour keeping as many frames in as possible over having better graphics.

The problem is going to be space. There’s a fair bit of game logic to code, on top of there being far more sprites than I was imagining for the dungeons, palace, traps, cutscenes, guards of varying types, etc.

The original creator, Jordan Mechner, breaks down the memory usage on the Apple 2 version like this:

Obviously, the Arduboy has far less everything available to it. My hope is that there’s a way for me to do it via the new FX functionality, but I don’t know if it’s feasible. Is it?

My thoughts are to store as much as possible on the flash memory, and only pull it down as needed:

  • Images would only be pulled as needed. For instance, all cutscene background and character sprites only on the AB while the scene is active. Same for dungeon levels, palace levels. Same for enemy types. I don’t know if any levels have more than 1 type (and if so, this is a concession I’d be willing to make to make this work)
  • Music, if possible, would only be required on the title screen, and perhaps cutscenes, so I’d like to have that live primarily on the flash as well.
  • All level map definitions should be fine to store there and pull down.

I’m assuming all the above is possible. There may be other ways to save space. This is where my questions come in:

Is there a way that I could store certain game logic routines on flash, and only pull them down as needed?

Seeing as Jordan used 48K just for code, this is where my biggest worry lies. My hope is that certain “one-off” sequences can be moved to flash, and only loaded in when you enter the pertinent “room” (this game doesn’t scroll - it’s room by room, and if some rooms take a moment or 2 longer to load, it should be fine).

Some examples of “one-off” sequences would be where you find and pick up a sword, a special mirror that you jump through and it creates a “shadow” version of yourself (who also shows up in a few rooms in that level afterwards). It’s been many years since I played through the entire game, but I think there will be a couple more.

Only some rooms have traps, like falling floor tiles, sliding blades or floor spikes that pop out. Only some have pressure pad tiles that you step on to activate doors.

An even bigger win would be to be able to swap the combat logic in and out depending on the screen. There really aren’t a whole lot of combat scenes. Even if it turns out to be possible on a technical level, I’m not sure that I’d save much space, since I think there are rooms that have an enemy + other elements like traps. I could, though, make some changes to the level designs to help here.

So… is it possible to store expanded game logic on the FX chip, or is that idea dead in the water? My guess is that I’ll need all the game logic loaded into the onboard memory, but thought I’d ask.

Any other ideas of things I could do to make a faithful, full port possible?

To be honest, I’ve never seen an example that has convinced me this ‘technique’ is viable or even actually works. To me it never looks grey, it always just looks like two frames flashing between each other.

Sort of…

You could create and embed a virtual machine into the main game and then load bytecode from the FX chip, but the VM itself will take memory, so it might not be worth it. It depends what sort of logic you’re thinking about offloading.

As for whether you can load actual machine code, machine code can only be written to the on-board flash memory by the bootloader, so if you needed custom logic for each level you could theoretically make each level a separate game and require the user to flash a new game every time there’s a significant level switch (think of it as being like how computers and some consoles used to require you to change discs on certain games), but it’s not particularly practical.

Honestly, trying to compare the size of machine code implementations between architectures can be a bit like comparing apples (if you’ll pardon the pun) to oranges.

The Apple II used a MOS 6502, which only had six registers including the processor flags, program counter and stack pointer. The remaining three registers were the accumulator, the x index and the y index, and most operations used the accumulator as the destination. This means that most M6502 code does a lot of shuffling data around, so a lot of that code is probably data shuffling due to hardware limitations.

Looking at that ‘bill of materials’ (or should that be ‘bill of memory’?) a lot of the data listed there is immutable data (images, level data, music), which on the Arduboy would live either in flash or on the FX chip. And don’t forget that colour images use a lot more bytes than monochrome (1 bit per pixel) images.

In other words, all that list is good for is to remind you what the constituent parts of the game are. For estimating how much memory the game will take it can only provide an upper bound.

But even then, the Arduboy FX chips are (I think) 16MB chips, and 252.5 KB isn’t even 1/4 of an MB.

It’s not the immutable data you have to worry about, it’s the mutable data, because you only get just over 1KB of RAM to work with (or slightly more if you’re willing to attempt some crazy custom screen rendering).


That all said, I don’t (at the moment) know enough about the game itself to give an idea of how much memory it might take, I’d have to do some research and get back to you on that.

However, there’s an Arduboy port of Karateka (Wikipedia’s article about the original is here) and I get the impression they have a similar set up (at the very least in terms of side-scrolling rotoscoped graphics - I’m not sure if Karateka’s graphics were rotoscoped like Prince of Persia’s were, but they look similar enough).

It looks like John Mechner designed both Prince of Persia and Karateka, so I wouldn’t be surprised if they both use similar techniques.

One other thing worth mentioning is that the original source code of Prince of Persia (for Apple II) has been made available online:

(Although it’s in M6502 assembly with hardly any comments, so you might have trouble learning anything useful from it.)

@Pharap Thanks for the reply.

To be honest, I’ve never seen an example that has convinced me this ‘technique’ is viable or even actually works. To me it never looks grey, it always just looks like two frames flashing between each other.

I do find it looks grey to me on ‘Ard Driving’. But, it is a bit distracting. I may still try it for the character sprites if I don’t like the monochrome look once I see it in motion.

Honestly, trying to compare the size of machine code implementations between architectures can be a bit like comparing apples (if you’ll pardon the pun) to oranges

Good point. And pun :slight_smile:

And don’t forget that colour images use a lot more bytes than monochrome (1 bit per pixel) images.

Right. I had initially thought that they were monochrome, but I was looking at monochrome image sprites that someone had used for a Commodore 64 remake. So yes, they will be pretty small.

However, there’s an Arduboy port of Karateka and I get the impression they have a similar set up (at the very least in terms of side-scrolling rotoscoped graphics - I’m not sure if Karateka’s graphics were rotoscoped like Prince of Persia’s were, but they look similar enough).

Indeed, I actually used that port as a rough shell for mine.

It’s not the immutable data you have to worry about, it’s the mutable data, because you only get just over 1KB of RAM to work with (or slightly more if you’re willing to attempt some crazy custom screen rendering).

Yeah, that’s tight. I’ve never worked in such a constrained fashion. I don’t mind digging in - I want to learn this stuff, and I have a development background, but it’ll likely be something I just need to get on with and see how it goes. I just don’t want to hit a wall that I don’t see due to my lack of experience here.

The logic in Karateka is a good bit simpler, but it is in the same vein. I should have a close look at how much breathing room was there.

The VM is an interesting idea, but I’ll have to think about how much I could really offload. Probably not enough to make it worth it, but it’s something for me to consider at least.

If you use code from Karateka in the final version, don’t forget to adhere to the licence.

Bear in mind that it’s actually storing everything in progmem because it predates the FX chip.

Again, it really depends what kind of scripts you’re thinking about offloading.

If you’re going for high quality animations then I can imagine making the VM oriented around animation might pay off. It doesn’t need to be anything too fancy, just enough to do some basic arithmetic, move some data around in a designated scratch space, and alter some struct fields on relevant objects (i.e. a means to interact with the ‘outside world’ of your game engine).


Since Prince of Persia was originally for the Apple II, I can’t not mention the VM that Steve Wozniak created for the Apple II:

A mere 28 functions (31 total with 3 unassigned), and the engine apparently taking up only 300 bytes of memory (which I presume includes the 32 bytes for the ‘registers’). It probably wouldn’t help you, but I mention it just because it’s a small piece of notable (and relatively unknown) history.

Thanks. Appreciate the info. I’ll definitely honour the Karateka port license. I may not end up using the code, but I’ll be mindful of it.

1 Like

The Apple II graphics were monochrome however they used a trick to make colour.

Rendering images directly from the FX chip is not only easy, its really quick too. You do not have to worry about storing them in progmem. POP is not a fast game so you should have no worries.

You could even have the level graphics stored in a single image that you scroll left and right allowing you to have larger graphics.I used a large world graphic here.

You would need to have a ‘map’ of the objects and their coordinates in order to use a graphic of a map like this but it would be doable.

I am hoping someone will use my ArduboyTonesFX or ArduboyPlaytuneFX libraries for something good.

When I was creating Karateka I obviously had no FX. The performance of the game suffered as I had to resort to compressed graphics to get it to fit. I also sliced the people up into heads, torsos and legs so that I could construct a person out of parts to save memory. All this rendering of masked images also takes its toll as the old drawCompressed() functions resulted in two calls - black out the mask and then draw on top. The FX has more features for masking and you have space to keep complete images of people therefore avoiding the multiple rendering passes.

If I did it again, I would simply create the cut scenes as a flipboard of images (shown one after the other). It is inefficient storage-wise but who cares when you have an FX?

2 Likes

Thanks for chiming in.

This is great to know. I assumed I’d have to be swapping them in and out of progmem. Very nice :slight_smile:

I’ll do my best. Can the music be run without loading into progmem too? I’ve read a little about the difference between these 2 libs. Is this a fair high-level breakdown:

ArduboyTonesFX is more performant/smaller size, and doesn’t have a negative effect on LED
ArduboyPlaytune allows 2 channels simultateously?

I noticed you’d sliced all the components up. Good to know I won’t have to :relieved: Looks like a LOT of work.

Interesting idea on the cutscenes as well. So simple - like a short movie!

Re: a full level map image – that could really simplify things as well! I’ve though about showing less at a time and using larger character sprites. It could certainly work, but there’s something about seeing each “room” in it’s entirety at once. Though… you never really need to change rows (i.e top, middle, bottom sections in a single room) quickly, so perhaps I could show the full active row, and half a row above and below.

Appreciate the ideas. I’m thinking I’ll likely go ahead with this project.

It’s one of my favourite all-time games. I played it as a kid on a Tandy and fell in love with it immediately. It’s a very satisfying game to play right through.

And if this goes well, maybe I could tackle Blackthorne next, as it’s kind of similar :slight_smile:

Yep … they read directly from the FX chip. I must warn you though, I haven’t done any performance testing with them and a full graphics payload :slight_smile: As I said though, access to the FX chip seems to be really quick so I do not anticipate problems.

Correct. Even with the little piezo-electric speaker it can make a huge difference. Load up Trials of Astarok and you can hear the better sounds ArduboyPlaytune can make.

Nice and simple!

I wonder if you could have a map in the corner that shows a 1:4 scale that you can toggle using the ‘C’ button. Oh wait, that’s the problem with the Arduboy, not enough buttons!

But you do need to know if you can jump down. Is that a safe landing or a pit?

I grew up on Karateka and POP. I love them!

Just thought of something … maybe you could have 4 or so images of the level or room you are about to enter at different scales. As you enter the room it zooms from a small image to full size so that you can see the room in its entirety before you play it.

I’m thinking I could just have the camera pan up or down if I hold the A button (the careful step button) while pressing up or down. The only action it would coincide with would be when you’re lowering down a ledge, in which case you’d want it to pan down anyways.

I looked at the NES controls, since it only uses 2 buttons, and it looks like this would work.

Also, I found a video of a widescreen mod (with scroll) someone made of the MS-DOS version, and it’s a pretty nice effect - really looks like it improves the ‘flow’ of the game:

1 Like

Oh that’s nice.

I remember that level completely!

1 Like

I just did. Sounds great :). Now, does it only affect the LED while music is playing?
On a side note, that game is great. I had it loaded onto the flash, hadn’t tried it yet. Very addictive.

1 Like

A very interesting article. The explicit mention of NTSC makes me wonder if the trick only works for NTSC and not for PAL or SECAM.

I was investigating Cabi last week (for hopefully obvious reasons) and wondered why it was producing a mask since the drawing function didn’t have a ‘mask’ parameter. This explains that.

This is a good idea and I’m slightly annoyed that I didn’t think of it.
Evidently I’ve spent too much time working with tile-based games.

Just to point it out, this isn’t possible for the same reason swapping code out isn’t possible. As I mentioned briefly before, progmem can only be written to when the CPU is in bootloader mode. Outside of that it’s all write protected.

The FX chip itself, on the other hand, is not write protected, so you can write to it from within a game. However, it’s flash memory so there are some limitations on how you can write.

During writing you can only set 1 bits to 0, if you need a bit to go back to being 1 you have to erase a whole ‘page’ of data, which in turn means you need to store anything you’d want to keep in RAM. (Fortunately you can use the Arduboy2 framebuffer for that, assuming you haven’t begun drawing yet.)

1 Like

I probably won’t be able to start programming this for a while. I have a couple of projects ahead of it (main one being preparing an Arduboy-themed STEM program at my son’s school). I have a 1 month work sabbatical I’m entitled to take at any time, which I’ll probably use for this project. But it’ll probably be in the summer that I end up taking it.

To clarify, I meant drawing to the frame buffer during the game loop, not “assuming you haven’t begun drawing images for your game yet”, but good to know anyway.

Even if you haven’t started your project yet, you’re free to ask as many questions as you like and/or ask for whatever help you need.

Thanks for the clarification.

I’ll likely work in little spurts until I have time to fully dive in. I’ll focus on generating the level maps to start with.

I’m sure I’ll be asking plenty along the way, and appreciate the advice. :+1:

1 Like

Would you please share these materials (Arduboy-themed STEM program) here?
Many of us will be very interested

Absolutely, that’s my plan. I have a bit more prep work to do, but I plan to share everything I have - parts lists, lesson outlines (probably pretty lean), brochure, CAD models for the cases, fritzing diagrams, etc. I’ve also taken a lot of time putting together a flash cart, putting the little fixes in as I go to get the games all working correctly with the SH1106 displays I’m using, so I’ll share that as well once it’s done.

It’ll be a mini-breadboard build, similar to Mr. Blinky’s breadboy project, but half the size, using only 2 mini breadboards per unit. Here’s a quick preview from some early CAD renders (it’s changed a bit, but this is the idea)


I’ll start up a new thread once I have it all together and ready to go.

4 Likes

Nice design. Curious about the breadboards connections. Do the display pins connect to the proper Pro Micro pins on that row or are you gonna cut the breadboard contacts on the top row?

Love the case looks almost like it was designed by Nintendo.

As for PoP I think it’s doable. All graphics and data can be stored on the FX chip and a small VM can do animations/cutscenes (I’ve been thinking on addin something like a simple VM to FX library that renders animations from a data stream).

What makes PoP so cool is it’s animations (and we need a pixel artist for them). To make it look good on Arduboy the character needs to be relatively large to make it work. Belows’s a mockup I made a while ago with 16 pixel high sprite. 20 pixels would be better but then some vertical scrolling must be introduced to keep the right ratio.

The extra black area at the right (or left) can be easily filled with part of the adjacent screen when a level is stored as a tilemap.

afbeelding

If you’re wondering about the speed of drawing graphics from FX chip. Check out my balls demo which draws 55 masked ball sprites on a tiled background made up of 16x16 pixel tiles all drawn from FX chip.

Thanks. I thought initially about cutting the breadboard contacts, but it seems like too big of a hassle. Have you done it? Is it not bad. I’m planning on soldering up some basic connectors with some wire leads ahead of time to the displays instead, so the students can still just plug ‘n’ play. It’ll just be quicker for me, plus, the screen will be held in place by the case design, floating above everything else.

I intentionally copied the Game Boy Color style for this. The buttons are GBC replacement buttons from Aliexpress, too. Thought about 3d printing them, but these are really nice. Glad I ordered them instead.

I’ll probably need this. You’ll be my hero if you make it for me (like you have for so many other things) :laughing:

Re: the aspect ratios, yeah it’s a challenge, and a balance. I like the idea of having all 3 levels at once, but I also really like the extra details afforded by going full-width, and only 2 courses high, which fits the AB display almost perfectly. Note that you only have an 8-tile width on your mock - the original is 10 tiles wide, but it’s been done with 8 for a number of systems due to varying screen ratios. I’ll go with the 10.

I was actually considering doing both – by default, having it 2 courses high, always showing the full level below where applicable, which is more important for a gameplay perspective, but also having a less detailed, scaled down full view like you’re showing, as a pause menu (likely by pressing slow step and up at the same time. I would use the side space for menu options like exit, load, save, and show the level info and time left.

I could have the game playable in both ratios, or just use the full-room display for quick reference.

Regarding animations, it’s possible to get the a number of different sprite sheets from different versions. I’ve been playing around with dithering settings while scaling down, and some of them are working pretty well, likely only needing minor clean up. I’ll try that route first, likely with Imagemagick, and see how far I can get.

For the level tiles, I’ve tried it a little, with less success (especially for the 3-level display, where you just can’t make out the spike holes and pressure pads), and have had better luck with drawing them by hand, similar to what you’ve done there. My hope was initially to leverage one of the many ‘PoP level editors’ out there, and leverage their already-perfectly-created maps, but that would involve adopting the original versions tile layout, which is a little confusing (though I get it) and would probably end up being more work than just working in 3 rows of floor-to-ceiling rectangular blocks.