Rich Talbot-Watkins wrote:My gut instinct on this is that the only bit which you can probably truly 'port' is the game/animation logic, basically all the high-level stuff. The graphics routines are going to need to get a total rewrite to conform more with the Beeb hardware.

My take on it would be to bite the bullet and go to MODE 2 (or 1). You could keep the tile size the same, and store the sprites in a more native format; so 10 tiles of 14 (or 28) pixels wide, which fits nicely on a byte boundary still, and allows for a 70 column wide screen. Perhaps I haven't grasped quite how low memory is! Obviously doing that would double the size of the sprite data (and it's already doubled the size of the screen), but I suspect it'd be possible to compress the sprites, even with a RLE type method. I would find a way to avoid having to do double-buffering so you can at least use a shadow screen, and keep main RAM for non-graphics related stuff.

Do you have a basic overview of the memory needs for PoP? In honesty, I'm struggling to imagine how it can be so demanding - unless it's just that there are a lot of frames of animation.

I think you might be right Rich. The graphics routines will need a total rewrite but thankfully is a very small part of the overall codebase. There is a massive amount of gameplay code which should stay completely intact. All of this is in Aux (SHADOW) RAM at the moment, with Main RAM being used for the screen buffers and rendering code.

On the sprite front, this is from my notes for what needs to be permanently resident in SWRAM:

This is sprite data in Apple II pixel format. Pretty sure CHTAB6&7 are only required for cutscenes so these could be loaded on demand.From my brief tests this data gets bloated by minimum 50% in MODE 1 form (2bpp, uncompressed of course.) Not all of the sprites are required, for example some of the larger ones are actually text message boxes!

Yes, there really is 16KB of just gameplay code in Aux and I haven't finished porting it all yet. Basically the entire game is hand-coded for every player action with lots of (for the time) sophisticated and subtle control behaviours - reminds me a lot of my first N64 game actually.

I'm losing a couple of pages to alignment and there are at least 8 pages I can steal from the OS for BSS.

I think I'm going to proceed by trying the approach of converting Apple II into native MODE 4 for now, mostly because I've already written the converter and it keeps all the memory requirements about the same. I can figure out exactly what the expected behaviour of the sprite plotting functions are before worrying about shifting colour format pixels around efficiently.

From my best understanding, the scenery tiles are an awkward size on the Apple (28x63), and are rendered in a complicated way. In particular, what intrigues me is the way the floors are rendered:

That overlapping bit is a true horror! Given that the Apple sprite data is 1bpp, there doesn't seem to be any way you could infer a sprite mask from that. So does it have a separate sprite mask? If so, that's great news as it means that the data size is no different from a 2bpp or 4bpp native format sprite. It would need a mask when plotting B and A; either that or it's a constant triangle mask which is applied when plotting B (so C is not overwritten), and it's an optional mask applied when plotting A (depending on whether it's mostly wall, or just a floor). Any idea how the masking works?

I guess this diagram is just a rough overview though. I'd assume it's more clever than that, and breaks up the tiles even more so that it can avoid storing and rendering large runs of blank.

Here are some thoughts for clawing back some memory (if expanding out the graphics to 2 or 4bpp):

* If using MODE 2, store the graphics 2bpp, thus giving the same memory footprint as the MODE 4 graphics. Then use the 'Exile' type approach of rendering them in any 4 colours (or 3 + transparent) of your choosing - I don't think the graphical style would make this limiting, and you could still get all 8 colours on screen.

* Use the top bit of each pixel as a foreground/background indicator. I think the top bit could be inferred from which section of the scenery tile it is (section A always foreground, the rest background?), so you wouldn't have to store it either. Then you could have the character plotting routines look at the top screen bits as a mask. Just save the screen data prior to plotting the character (there will be shadow RAM spare for that), and erase the character by restoring the screen data - nice and quick, and no need for double buffering.

* Long shot: LZ77 compress the scenery graphics in an entire block, and expand them out to the screen buffer (blanked) between screens, copying out only the tiles used by that particular screen to a cache. This approach could also work for the NPC graphics which are not all needed simultaneously (I think). I don't think RLE would give big gains. Neither might this approach of course, if the LZ compressed data + required cache is bigger than the unexpanded graphics.

* Break up the scenery tiles into smaller units which allow for some reuse.

* If we have mirrored sprites for the characters, ditch them and use a mirroring table instead to reverse the bytes (and obviously a different routine to plot them backwards).

Not sure how feasible any of that is, but just want to do a brain dump in case anything there sparks any thoughts of your own

From my best understanding, the scenery tiles are an awkward size on the Apple (28x63), and are rendered in a complicated way. In particular, what intrigues me is the way the floors are rendered:

That overlapping bit is a true horror! Given that the Apple sprite data is 1bpp, there doesn't seem to be any way you could infer a sprite mask from that. So does it have a separate sprite mask? If so, that's great news as it means that the data size is no different from a 2bpp or 4bpp native format sprite. It would need a mask when plotting B and A; either that or it's a constant triangle mask which is applied when plotting B (so C is not overwritten), and it's an optional mask applied when plotting A (depending on whether it's mostly wall, or just a floor). Any idea how the masking works?

I guess this diagram is just a rough overview though. I'd assume it's more clever than that, and breaks up the tiles even more so that it can avoid storing and rendering large runs of blank.

Everything is drawn with painters algorithm, so back to front and overdrawn where necessary. A screen is made up of 10x3 pieces drawn bottom to top and left to right. Where drawing a piece is: (m versions are for the moveable pieces)

\*-------------------------------\*\* D R A W A L L\*\* Draw everything in image lists\*\* This is the only routine that calls HIRES routines.\*\*-------------------------------.DRAWALL{ jsr DOGEN ;Do general stuff like cls

Each sprite can be plotted at any screen position, with clipping, mirroring and with operand STA, OR, AND (mask) and special (shift & XOR for the "ghost" player character.) As the current plotting is quite slow you can watch it assemble screens in each layer from the SSD's earlier in the thread.

There is no separate sprite mask data. It does infer a mask when required from this table: (note these are Apple II bits so "back to front" with lsb being left-most pixel)

Rich Talbot-Watkins wrote:Here are some thoughts for clawing back some memory (if expanding out the graphics to 2 or 4bpp):

* If using MODE 2, store the graphics 2bpp, thus giving the same memory footprint as the MODE 4 graphics. Then use the 'Exile' type approach of rendering them in any 4 colours (or 3 + transparent) of your choosing - I don't think the graphical style would make this limiting, and you could still get all 8 colours on screen.

I like this idea a lot and will definitely look into it once I've got the B&W version rendering correctly. The input parameters for the sprite plot routines are well documented so just up to me to write the necessary routines (just quite a few variations and fiddly features to consider, including clipping.) Again the code is well structured so it should be possible to just alter the render function that handles conversion of object X coordinates into plot coordinates without affecting the gameplay for different screen widths. NB. Game objects have a different coordinate system from the background tiles.

Rich Talbot-Watkins wrote:* Use the top bit of each pixel as a foreground/background indicator. I think the top bit could be inferred from which section of the scenery tile it is (section A always foreground, the rest background?), so you wouldn't have to store it either. Then you could have the character plotting routines look at the top screen bits as a mask. Just save the screen data prior to plotting the character (there will be shadow RAM spare for that), and erase the character by restoring the screen data - nice and quick, and no need for double buffering.

PoP actually already saves and restores screen data prior to plotting mid-ground objects. The LAYRSAVE and PEEL functions are designed to do this and copy the data out into (double) buffers using the same format as the sprite tables (so can use the same routines to be put back.) I haven't implemented the Beeb equivalents yet but have earmarked the 4K of MOS RAM at &8000 for this purpose.

Rich Talbot-Watkins wrote:* Long shot: LZ77 compress the scenery graphics in an entire block, and expand them out to the screen buffer (blanked) between screens, copying out only the tiles used by that particular screen to a cache. This approach could also work for the NPC graphics which are not all needed simultaneously (I think). I don't think RLE would give big gains. Neither might this approach of course, if the LZ compressed data + required cache is bigger than the unexpanded graphics.

* Break up the scenery tiles into smaller units which allow for some reuse.

Compression and/or caching could be an option. The game already uses two different sprite banks (Dungeon & Palace) for background tiles & selects one per level (there are actually three in the code so note sure if there is technically a third bank made up of a combination of the other two - I need to investigate further later on.) It can also be noted that from any given screen there are only four possible next screens (L/R/U/D) so in theory we can (pre)calculate all possible next tiles/pieces that we haven't already rendered if caching. (Also those that are no longer reachable.)

There is only one NPC (Guard) type permitted per level and again this is selected & loaded on a per-level basis. The Princess & bad guy (Vizer) are only used in cutscenes (apart from the final boss fight.) The nuclear option would be to halve the number of animation frames for the player but that would be a shame.

Rich Talbot-Watkins wrote:* If we have mirrored sprites for the characters, ditch them and use a mirroring table instead to reverse the bytes (and obviously a different routine to plot them backwards).

Not sure how feasible any of that is, but just want to do a brain dump in case anything there sparks any thoughts of your own

Again, PoP already mirrors the sprites in software using a separate set of plot functions in this instance.

There are some great thoughts in here Rich, as ever, thank you! I am continuing to explore just using converted Beeb 1bpp data in MODE4 so I can hopefully get the plotting functionality correct without any additional complications. Once this is working I can explore optimisations and the right approach to colour (MODE1 vs MODE2) and enlist the help of our resident artist if needs be.

Apologies all for being a bit quiet of late. I have been plugging away at PoP but reached various impasses / decision-forks so have been exploring (and still exploring them) and found it harder to post concrete updates.

Essentially I implemented ~most~ of the standard sprite plot routine as PoP requires, including per-pixel placement and masking but not clipping or mirroring, in MODE 4 using sprite data converted to 8 pixels per byte format ahead of time and lots of shift & carry tables. I also implemented the sprite save & restore code using MOS 4K RAM as a buffer. The end result, whilst looking good from a level background POV was disheartening - just too damn slow.

I was starting the implementation of mirrored sprites but the whole thing was getting very complicated and relies on a mountain (about 4k) of tables and requires all sorts of careful masking of bits to get 8 pixels per byte data plotted at 1 pixel alignment but in 7 pixel increments. PoP itself uses lots of masking but now everything needs to be masked twice - once for the sprite data as PoP sees it then again for how the Beeb screen sees it. I also couldn't see how the main sprite plotting loop was going to be optimised using the current approach - saving the odd cycle here & there wasn't going to help.

I stopped for a pause and a rethink and have started to explore Rich's suggestion of using 2bpp sprite data but at half the horizontal resolution, so MODE 5 data effectively, but then expanded out at runtime to plot in MODE 2. Although I liked the hi-res MODE1/4 look there are a number of advantages, not least the possibility of "free" masking using appropriate palette mapping. Given the limitations of the original game, having 3 colours for foreground sprites and 4 colours for backgrounds should be plenty.

I've been trawling through various sprite plot implementations and particularly the Exile code disassembly. I'm essentially now in the process of copying that technique (with ZP optimisation to come later.) I haven't finished the new sprite routine yet but should be soon.

Another important decision has been to try rounding up everything to be in multiples of 8 pixels rather than 7. This just makes everything so much easier to contend with on the Beeb and means that when halving the horizontal resolution I'm not faced with the smallest sprite size being 3 1/2 pixels wide. This implies that the new resolution is 160x192 in MODE 2 which stretches everything horizontally, so will look a bit "fat". Currently I'm just point sampling the original sprites in my simple Apple II image converter but the results don't look too bad in my simple BASIC image checker:

Kid sprite sheet in MODE 5

I figure that if I manage to get this project approaching something like completed from a gameplay POV then I will take up DethMunk's kindly offer of artist support for getting all of the sprites redrawn or at least tidied up by hand.

That's it for now. I will post again when I have the background rendering back up & running in MODE 2 and then onwards to a better sprite plot that is good enough for actual animation at runtime. As always your comments & feedback are appreciated.

jbnbeeb wrote:Seconded. Thanks for continuing to post your detailed updates Kieran; I really enjoy reading them. They're giving me inspiration to resume on my game now that I have some time to pick it up.

Thanks,Jason

Thanks guys, I really appreciate the support & encouragement and to know that people are following what I'm up to - it's a lot of work and can be a real slog sometimes wading through endless reams of code!

This is using the Exile approach to sprite plotting, albeit nowhere near as sophisticated or optimised yet. Sprites are stored as 2bpp in MODE 5 byte format and then unrolled onto the stack at runtime. With a bit of bit-shifting you can look up a MODE 2 pixel (left or right handed depending on the parity) and plot to the screen. Once this was working it was simple to write a mirrored version which PoP requires, so we are getting somewhere. However there are a number of issues to resolve, not least:

- my automatic sprite converter from the Apple II source data needs some work. I'm converting 7 B&W pixels into 4 colour pixels taking up the same space on screen so obviously some detail will be lost. In time I'll ask Dethmunk to hand finish the sprites to be optimal for this resolution & palette considerations.

- the Apple II sprite data is weird in that it pixels come out different colours depending on the plot parity - this is why the player sprite is sometimes red and sometimes blue! Presumably on a real machine the animation frames are arranged such that parity is constant - I've just realised this is why for moving objects the X coordinates only range from 0-139 and get doubled up to 0-279 on plot. Still doesn't explain why the source data has mixed parity though, hmm.

- I haven't implemented masking yet. I was going to use the EOR method and have 4x background colours + 3x foreground colours by mapping the 16 colour palette but I think I'll need something more sophisticate than this. For instance the flickering torches are in the background sprite set but ideally we'd want these to be drawn in red & yellow whilst the dungeon walls remain blue & cyan. Exile uses a 3 colour palette per sprite so I think I'm going to copy this approach and have a simple way of specifying which palette is used for which sprite in all the image tables. This means we can take full advantage of being in MODE 2 but does mean I need to think a bit more about the masking implementation. Will probably use the top-bit-as-background-signifier approach.

- the player sprite is being plotted in the wrong place for some reason - too far to the right. I've got the layer save & peel functions working and saving areas of the screen to the MOS 4K RAM block but this doesn't correspond to where the sprites are being drawn! Not sure why, need to do some more digging.

- it's all still terribly slow. Some of this is going to be down to the size of the sprites - the player can be typically 16 x 30+ pixels which is a lot in MODE 2. The inner loop of the sprite plot can definitely be improved as well though. There is also a lot going on in the main game loop but I haven't tried profiling this yet.

But this all said I think this is likely to be a good approach for PoP on the Beeb as it keeps the size of the sprite data the same in quite a convenient way and it's easier to plot on a single pixel alignment. So one byte of 2bpp Beeb data (4 pixels) is being used as a direct replacement for 7 pixels per byte Apple II data. This does mean the screen is stretched to 160 (wide) pixels vs 280 but this is clearly what was done on other (similar) platforms and can be overcome with some assistance from a good artist.

Well done for persevering, I know how wading through pages of assembler can "get old quick" as I have had to do it with the "emulators" that I have written. Its great that you have kept going and I love to read your updates.

tricky wrote:Well done for persevering, I know how wading through pages of assembler can "get old quick" as I have had to do it with the "emulators" that I have written. Its great that you have kept going and I love to read your updates.

Thanks Tricky! Today I had a big breakthrough on the Tube, of all places. A single digit change now means the game runs at 50Hz...

MODE 2 individual palette per sprite

This turned out to be a couple of bugs, one of which was very subtle, that have taken me the best part of two days to track down.

Firstly, there is a function to return sprite dimensions that is used outside of the plot routines. I'd manage to miss setting up the correct swram bank before accessing the sprite data, so was sometimes returning garbage values. I'd also missed that it needs to preserve the A register on return, so in fact was always returning garbage.

That was the "easy" one. The much harder one was a seeming Heisen-bug - if I made innocuous code changes (NOPs) then I was getting different behaviour - either an actual crash from a corrupted stack or, more weirdly, the code wanted to call a function that I hadn't implemented yet but that I knew shouldn't be called at this point. Anyway, long story short there was a very subtle alignment problem with the collision detection data that is used at runtime, it has to be aligned to &10 (fine - I'd caught that) but all tables have to be contained within a single page. The original Apple code ensure this by using a fixed memory location, I had moved this to a general data block in code space, which of course was moving around depending on the code arrangement.

I also had a nagging concern about the framerate. I had forgotten the first rule of optimisation - never make assumptions, always test what's really going on. I went for a beer with sbadger who commented that the original sprite demo I showed last year was much faster, so why was it so slow now? I realised my answer wasn't sufficiently empirical and after single stepping each frame (a feature I added to the NULA version of b-em BTW) I discovered it was taking approx. 2 frames to draw the sprites and then there were 25 static frames! 25 frames ~= 1 million cycles - even I can't write code that is bad enough to take a million cycles! There was clearly something weird going on.

I'm not sure what the weirdness was but it was clearly associated with the collision detection (seems feasible if it ended up looping thousands of times to resolve) as once I'd fixed the alignment bug - boom! 50Hz.

I now realised that I'd been hasty assuming that my black & white bit twiddling in MODE 4 was impossibly slow (1 million cycles ) so back ported the fix to compare.

I now have another decision to make. I have a MODE 2 sprite routine that allows a separate 3 colour palette per sprite ala Exile (actually ripped directly from Exile) and some badly automatically converted MODE 2 "fat" sprites that need some artist love. Alternatively I could continue down the hi-res path in MODE 4 or even think about automatic conversion to MODE 1 as I was doing before. What do my fellow Stardotters think?

I'd also been wondering just how it could be that slow, but assumed there were reasons. Looks lovely now - and even better if you can hack in some rudimentary keyboard control.

For me, it's a no-brainer - MODE 2 wins over MODE 4 or MODE 1, but I've always preferred colours over resolution anyway. Particularly if a Video NuLA palette can be used if the hardware's there. I guess the main issue that can occur with going to MODE 2 (with the stretching of the sprites) is that the movement code might get broken if it's expecting sprites of a different width. The art tidy-up isn't so much of a big deal I don't think - the automatically converted sprites already look pretty good, particularly when they're in constant motion, and they can be tweaked a long way down the line.

If it turns out that you can't really capitalise on the 16 colours (just due to the general graphics design, and the fact that the Apple original is only 4 colours anyway), MODE 1 would give you nice resolution as well as retaining the original colour scheme. But I don't know how you'd compress those sprites, other than essentially using the original Apple data format and expanding it out to 2bpp in real time. I still think it'd be great to emulate the style of the CPC version and make a more colourful port than the original!

I'd also been wondering just how it could be that slow, but assumed there were reasons. Looks lovely now - and even better if you can hack in some rudimentary keyboard control.

Thanks Rich! It was bizarre to add a single character "ALIGN &100" and suddenly have everything magically appear. Oh well, at least I understand the collision detection code a lot better now.

Rich Talbot-Watkins wrote:For me, it's a no-brainer - MODE 2 wins over MODE 4 or MODE 1, but I've always preferred colours over resolution anyway. Particularly if a Video NuLA palette can be used if the hardware's there. I guess the main issue that can occur with going to MODE 2 (with the stretching of the sprites) is that the movement code might get broken if it's expecting sprites of a different width. The art tidy-up isn't so much of a big deal I don't think - the automatically converted sprites already look pretty good, particularly when they're in constant motion, and they can be tweaked a long way down the line.

Yes, I think I'm leaning towards MODE 2 now. The sprite routine can be optimised plenty from where it is right now and has the flexibility to specify a 3 colour palette per sprite - this means the torches can be red & yellow whilst the background is blue & cyan etc. I know Dethmunk has done some awesome sprites for other Beeb (and Speccy) games so confident he could make these look really good. The other advantage is that as far as the game engine is concerned, all the sprite sizes and motion calculations have stayed the same. 1 byte of Apple II data (7 pixels) becomes 1 byte of MODE 5 data (4 wide pixels) that's unrolled to MODE 2 at runtime. PoP thinks it's plotting everything in Apple II screen coordinates, it's just getting drawn at the last moment aligned to 4 wide pixels.

Rich Talbot-Watkins wrote:If it turns out that you can't really capitalise on the 16 colours (just due to the general graphics design, and the fact that the Apple original is only 4 colours anyway), MODE 1 would give you nice resolution as well as retaining the original colour scheme. But I don't know how you'd compress those sprites, other than essentially using the original Apple data format and expanding it out to 2bpp in real time. I still think it'd be great to emulate the style of the CPC version and make a more colourful port than the original!

All 16 colours are available for sprites from an engine perspective and a native NULA version would be really special - unlike anything ever seen on the Beeb before! I do have the source sprites from the PC CGA version which might make a better starting point down the line. For now I'll persevere with the auto-converted Apple II -> MODE 5. (Oh, I found the reason for the sprite parity issue with the source data - this is corrected by a flag in the animation frame tables, if the sprite has to be on an odd/even pixel number and isn't then it gets bumped right by one at runtime.)

I do love the idea of making a MODE 1 version, if only because it's my favourite MODE (strange that one should have such a thing) and very few games used it. I might put this on the "to do" list after the MODE 2 version, as more of an "authentic" Apple II port.

I think you know my preference where mode 1 is concerned, but maybe check with Dethmunk to see if he would be happy making mode 2 graphics.

Did I imagine a NuLA 4 colour mode 4ish that was 1 palette bit + 7 colour bits, maybe I am confusing it with the mode 1ish 4 palettes, 4 colours, 3 pixels; was this the native NuLA mode you were thinking of?

I ported the keyboard & joystick functions (the keyboard actually "emulates" the joystick) and patched in a call to OSBYTE &81. You can use standard Beeb controls: zx*? to move plus ; and ] for up left and up right. I need to do some work on how the strobing & debounce works because it doesn't seem possible to do a single step or proper running jump etc.

It's also not possible to leave the screen as I haven't implemented the destructible floor plates! The game will (deliberately) crash on a BRK if it calls an unimplemented function (of which there are many) - this will happen eventually if you hit the wrong bit of the screen.

I reckon we're about 50% complete at this point but very happy with the progress so far. Another bonus - our Bitshifters musician friend is a big Apple II fan and has offered to write SN versions of the tunes for the game. With a custom NULA version this could look and sound like no other Beeb game ever made!

Great to see the progress you've made on this Kieran. I was expecting to prefer MODE 4 version, but the MODE 2 graphics really do look good and the potential for using exile-type colour dithering (and/or NULA) would make a really unique conversion.

SteveF wrote:That looks great! Really enjoying this write up, and amazed if you really think you're at 50% completion. Of course, everyone knows the last 10% takes 90% of the time.

Do you have a feel for whether memory is going to be a big problem or not yet?

Haha, yes I think might have been a bit giddy with excitement yesterday. I estimate I have ported approximately 50% of the functions but that certainly doesn't mean it's 50% complete. I've made enough games professionally to know that if you want something to be really polished & high quality then that last 10% absolutely does take a crazy amount of time.

On the topic of memory, I started porting some moveable object code to try and get the loose floors working and immediately hit the AUX memory guard point. Back to earth with a bump. There's still quite a bit of swram left but that's not very helpful. The sprite system has a nice clean interface so it's easy to page in a swram bank for sprite plot. Many other data sections are accessed liberally through the gameplay code so it's not as easy to intercept these. I can get 2K back by moving 8x pages of runtime data down below &E00 but I fear that will still not be enough...

On the to-do list: porting all the remaining functions and gameplay code, so that includes fighting, guards, moveable objects, triggers, doors, spikes etc. Also the cutscenes, intro, attract mode, game timer etc. Plus lower level stuff like save game and on-screen messages.

On the Beeb specific side I've still got to revisit the sprite engine for optimisation and to fix up the plot routines to properly draw everything in MODE 2, remove the flicker (means timing against the raster as there's not enough memory for double buffering), get the sprites all redrawn including palette selection, implement music & sound routines for the SN chip, figure out the memory configuration when loading cutscenes, get the disk system to handle double-sided discs.

Just a little bit left to do then. Oh, and there are bound to be some crazy, head-messing bugs that crop up which will take several days to track down.

Rich Talbot-Watkins wrote:Great work Kieran, and so fast arriving at this point! Looks great... and I was able to navigate a few screens before it finally gave up.

How easy was it to transplant the Exile sprite routine by the way? It has some very specific needs regarding sprite format, screen dimensions, and ZP usage.

Thanks Rich! How did you change screen BTW?!

I actually ended up adapting the Exile sprite routine quite a lot and there is still a ton of optimisation possible. Whilst unrolling the 2bpp data Exile uses X as temporary storage to save cycles and then self-mod code to read out of an array in ZP. I used this method at first but with the array located in main memory (hence the smPIXEL labels.) For various reasons along the way I changed this to store the temp data in ZP and then use X as an index. I will look at putting this back later on when I revisit. Exile also magically precomputes exactly where the stack pointer will be ahead of time. I'm just reading the stack pointer after unrolling then self-modding the loop that reads this back so it gets the data from the right place.

There's a load of stuff in here that can be pre-calculated, made simpler and optimised, counting in reverse for example. I wanted to make sure it was working "correctly" first. (There are still some things I need to sort out with respect to PoP's plotting needs.) I love the cunning use of the stack pointer as a "free" index register and the fact that a stack can easily accommodate the pixel parity.

Kieran - just ran your latest cut of this. Very well done ! I know there's a lot more work to do but it's a real milestone to see that familiar sprite animation, with the control feeling just like it did when I played on PC back in the day!

I was able to move left in to another room as well.

D'you think you'll be able to keep all the frames of animation without double buffering?

Fantastic progress, super fast at 50fps and can't wait to experience it all when sunc'd to the raster, expecting it to be smooth as butter

I think the game will work for any mode really so will be great if you end up doing multiple releases, saying that I would be super stoked with a mode 2 chunky style beeb classic conversion / port of a childhood favourite, well done for taking on this project

Exile's sprite routine is ingenious isn't it? Using the stack as per-pixel scratch space is an idea I'd never thought of, and the fact that it makes recolouring, offsetting and mirroring the sprite so simple is brilliant in its inventiveness. If you can reserve those zp locations for holding the colours of sprite pixels, it'll definitely help your performance.

It's nice that you don't have to worry about scrolling, and particularly the screen wraparound at &8000, as this makes the Exile code even more complicated.

A very quick Friday night treat for you. I ported some more gameplay functions, including gate, loose floor, spikes and press plates. You can explore a bit more now but the controls are still wonky so it's very easy to die. Also there are various sprite plotting glitches that are very obvious. Oh, and if you die you have to shift-break to start again! It's early days.

I also completely ran out of memory so going to have to think a bit more about how I handle this. I might have to assign a SWRAM bank to gameplay coded and page this in alongside the SHADOW RAM. This means more loading of sprites etc. during cutscenes, but pretty sure that's what the original did anyway.

A separate question to think about - would anyone like to be a "proper" gameplay tester when I get a bit further along? Ideally someone that knows the game really well and has completed it before on a different platform. Be warned that being a tester tends to ruin your enjoyment of a game, certainly in my professional experience - you'll be sick of it after repeating the same handful of screens over & over again.