Cooking Circle

RSS
I haven’t posted in ages! Again!
Then when attempting a decent post, Tumblr handily deleted the whole thing for me. THANKS MATE LOVE YOU. So you get a tiny 150kb GIF instead of a decent 3mb video. Oh well, that’s 2nd services for you.
Anyway, I’m...

I haven’t posted in ages!  Again! 

Then when attempting a decent post, Tumblr handily deleted the whole thing for me.  THANKS MATE LOVE YOU.  So you get a tiny 150kb GIF instead of a decent 3mb video.  Oh well, that’s 2nd services for you.

Anyway, I’m getting back into some things now - expect a few posts when I come across something interesting in my life.  This first thing is a *ahem* quick conversion of music for Bubble Ghost, written by Rob Evans, of Wubsoft and Samtona fame.  It already looks really good, copied from the Gameboy version, which shits all over every other version IMO.

It’s been a really exciting year so far!  Glad I got my effort out first because shortly afterwards, Chris Pile released Battlezone and it’s jaw-droppingly good.  There’s also been pretty great releases from pals across the scene - try Wubsoft’s Samtona, try The Space Adventure Simulator…  Try BlackJet’s Sploids for a little casual gaming fun.  For a curveball, try a conversion of Hibernated-1 by Stefan Vogt.  David Ledbury and Chris Pile helped out on this one for a ProDOS-based text adventure too. 

What’s next for me?  Well, I recently moved house, which sucked up a lot of spare time, and although things are settling down now, my job is way up in the air, so that might put a crimp in my plans for a while too.  But assuming it doesn’t, I’m on a Complete It Mission. 

That’s right, I have simply loads of unfinished projects sitting there, and loads of interest in the SAM at the moment.  So expect some concerted effort to push out stuff quicker.  It doesn’t mean I’m giving up on R-Type, Outrun or Reckless Rufus.  Just that it’s time to get some some momentum going!  Expect that right sidebar to get an awful lot longer.  Happy solstice.

Feb 8

Flappy Bird?  Where did that come from?

Hello!  It’s been way too long again.  For some reason I’ve gotten a bit out of the habit of blogging my progress with things.  That’s basically because I was saying the same things over and over again.  And also, I was incresingly worried I wasn’t making the right choices!  I’d fallen back into the habit of not completing projects, and that was probably as frustrating to read about as to do.

THE ARGUMENT

And then came an argument on Reddit.  On a game programming subreddit, a perfectly normal question of whether it’s possible to make games if you don’t have much maths skills.  I responded with the standard, non-controversial talking point.  Of course, I got a reponse from a third person.  Let’s call him Angry Reddit Guy:

image

It goes on until I tell him he doesn’t know what he’s talking about, and he laughs at me for being a child.  Good times :)

And lo, suddenly I was angry.  A *bit* at ARG, but mostly because hell!  This was good advice.  And I’m still very sure this guy has never developed a game to completion - his Reddit profile doesn’t show any dev at all.

So why can’t I finish a game?

WHAT IS FLAPPY BIRD?

You’ll get a lot of answers to this, but to someone who grew up in the 80s, the real answer is ‘a re-skin’.  Since I can remember, there have been Spectrum demos where you drive a line through a cavern, left to right, and don’t crash into the floor or ceiling.  Flappy Bird is the same, just with gravity in it.  It also sacrifices increasing difficulty and any variety of obstacles.  Looks pretty, though!

From my side I know how to make this game as a jerky mess, so the challenge wasn’t really how to do it, but how to keep the feature list short while keeping the update speed high.  I think I did it.  But what did I learn?

THE MATHS IS INDEED SIMPLE, BUT THE FIDDLING IS NOT

Yep, turns out I was right, the actual maths for movement is so simple I can screenshot it in one page for you.  And it includes other bits too!  Like triggering the sound effects for flapping.  And making sure we’re not in Get Ready mode.  And clamping the bird to the top of screen.

image

Shall I do a full explanation?  The secret is, the momentum is stored as an 8:8 fixed-point number.  This way, I can easily change speeds accurately without doing lots of fiddling with the floating-point calculator.  There’s always 3 times as much work in a game as you expect, so why add some if you don’t need to?  Here’s the first version:

image

Previously I’d got a little stuck with my plans on the sprite manager.  The idea was to run the 'game’ on the interrupts at a steady 50hz, and the display catches up whenever it can.  But to make sure things are updated safely, you would attach a routine to the sprite data, and the manager would run the code when it was safe.  So far so good.

But I really needed another version of the variables used, because I can’t guarantee the sprites will run at a certain rate.  And it’s a little weird when people turn off gravity in a game for a bit.

So here’s the sprite updater.  You can see now it’s mostly copying values from one place to another, and that’s intentional - at that point I was still thinking about the concept of volatility.  Remember that word, it enables me to change the main hero values without worrying, and the sprite updater only makes a copy when it needs to.

image

The bottom bit is taking a sine wave as the input, so you don’t plummet to your death immediately on starting.  So far, so simple.  Next up let’s add in a few obstacles:

OBSTACLES AND COLLISION DETECTION

image

Yep, that’s the obstacles added in.  Pretty easy to get a random height within a range, but in the end I made a few more tweaks to this:  with my pseudo-random number generator I could use a modulus to get a range of a certain size.  Then eventually I also made it a little too big, and clamped the answer to within a smaller range.  This would slightly favour pipes being extremely high or low, because seeing 12 pipes in a row at basically the same height was pretty boring.

I’d chosen a narrower screen width for the game for a couple of reasons:

  • It was an iPhone game, which was bafflingly played in portrait mode.  Part of the benefit is, you can only see a single upcoming pipe, so there’s no question of planning a strategy.
  • It would make a scrolling game a little easier to run :)  Let’s be realistic about the horsepower available here.

But there’s one other benefit - I didn’t need to worry about pipe clipping immediately.  Good - I just want to concentrate on game mechanics first, and add in display techniques later.

With the obstacles in place, now adding in colliders makes sense.

image

The plan was simple in the end, but it took me a while to get there because, as always, I’m trying to generalise too quickly.  It’s not a good personality trait if you can’t make any simple decisions because you’re thinking about turning them into complicated decisions.

In the end keeping a single collider for each pair of pipes was enough.  When you breach the collider with the bird’s hitbox, you test whether it is entirely between the middle area, and score points if so.  Otherwise, bye bye birdie (sorry).  I also made sure there was a flag to set to make sure you only scored one point for each collider, useful.

In this case, I really gave up on generalising, and just wrote bespoke code for this game.  There’s only one type of collision that can take place, which is far simpler than, say, R-Type.  So I don’t need to categorise the collision type (eg do bullets touch other bullets?  Can the hero get hit by his own bullets?  etc), I just test the bird against everything else.  

The benefits to modified code is, I can make the hitbox for the bird nice and small, which makes the game generous.  After this tweak, I never got the feeling the game was unfair, a BIG no-no to most gameplayers.  The generalised collider will have to wait!

MODIFIED SPRITE PRINTERS

I’ve spent a lot of time over the last few years making fast sprite printing and clearing routines, can’t stress enough how useful it is being comfortable with this process in general.  I plugged in some existing routines from R-Type, which are good at clipping sprites on the side of the screen.  Worked fine for standard sprites - let’s call them pipe heads - but I hadn’t bargained for the stretchiness of the pipe *necks*:

image
image

Took a little time to work out but I got there.  The game saves some extra time by having a static background, which means I don’t have to copy bits of background to each sprite’s buffer when printing.  I did run out of space beneath the screens at this point, but worked a way round it.  The code takes more memory than you’d think, especially when unrolling loops for speed.

Essentially, these printers are painting up-and-down rather than left-and-right.  This makes it easy to do a few things, like print the same pixel byte in multiple places.  You can also find an easy break in the code to stop printing, and get a clip effect on one side.  I needed loads of different versions though!  A pair for each of the pipes printing on even x-coords and odd, times two for clipping to the left or right of the screen, times two for printing top pipes and bottom pipes.

Sometimes it’s all about the grind.

THE MUSIC WENT DOWN REALLY WELL

As this was a quick project I didn’t want to spend several nights relearning how to use a tracker, and I had this one track lying around from years ago that I was proud of.  It helps that I’m a huge Maxo fan, and the track is now ten years old.

I used plenty of little tricks to get this tune written, I might need to make another post about that.  I’ve been searching for chiptune tutorials for more tricks, and you’d be surprised how little useful information is out there, unless you’re struggling to make your first tune.

So I was really happy to see Stefan (with one eff, Stefan) Drissen made an oscilloscope view of the music, it’s mesmerising.

image

One thing I’ve realised is that the best tunes seem to be very flexible with their arrangement - different voicings and things.  This tune pretty much forced me to find new voicings every few bars, and it reminded me I needed to get my tracker working.

…AND THE BUGFIXING

There were a few things I couldn’t get working exactly right, and had to ditch:

  • Icons for music and sound effects toggles
  • A nice transition from the credits screen back to main attract screen

Again, a big learning experience for me.  Where I can sit on a project for weeks because I can’t perfect it, this time I needed to release something quick.  So I deemed these things not essential, and binned them!  

Another big win was working out more of how the SimCoupe disassembler/monitor worked.  I had put the interrupt jump table at &6000, which is exactly one byte after the screen.  Smell the danger.  In more cases than I expected, I would put a monitor on the jump table and find sprite printers and their nasty, nasty off-by-one errors:

image

I consider Interrupt-based bugs one of the hardest types to debug, so this was invaluable.

I felt I had fixed enough issues to publish, and the community gathered around to circle the mistakes.  Thankfully, not too many!  But they definitely found a few extra things:

  • Missing 256K check

Yep, this was an oversight!  I should have a quick check that works out if you have the 512K expanded memory.  I need it for this game.  An easy fix:

image

I hooked it into a nice message, should there be only 256K.  I’ll be putting this in every project from now on - it’s just courtesy isn’t it.

  • Volatility was back, baby!

Okay, remember how smart I thought I was about 3 pages ago?  Well, there were many little niggles that were still unfixed, and they seem to all have the same source - volatile data that cannot be trusted.  So pop-quiz:  which of these routines do you prefer?:

image

Top one, right?  Easy to read, purely functional.  Wrong, you need the bottom version.  This is because if you get an interrupt when only half of the address has been written in, you’ll end up jumping to who-knows-where!  The instruction LD (nnnn),HL will do that in one go, and that needs all the other hassle surrounding it.

I’ll admit, this really isn’t a great solution, but it will do for now.  In future, I’ll need to go through my sprite manager and find all other instances of this.  But I learnt that if you are doing bug-fixes, sometimes a little ugliness and a few bytes lost is tolerable.

So some small pauses people were noticing were down to this!  It meant for one frame I was successfully jumping to random addresses, and the game still wasn’t crashing.  It’s a miracle, right?

END OF THE ARGUMENT

So, after all this, did I get back to Angry Reddit Guy?  Of course not :)  I’m pretty sure I did this for myself, and I don’t care to shame some bored doomscrolling stranger.  Haha, sweet invisible revenge. 

image

Is it over?  Yeah, thanks for sticking it out this far!  Back soon with more games!

Feb 6
SAM COUPE FLAPPY BIRD!Presenting Flappy Bird! Finally the Sam Coupe gets its version of this classic, frustrating, casual game. Converted by hand from the original iPhone hit of 2013. Use Space, F0 or even 0 to flap your wings to avoid the Mario...

SAM COUPE FLAPPY BIRD!

Presenting Flappy Bird!  Finally the Sam Coupe gets its version of this classic, frustrating, casual game.  Converted by hand from the original iPhone hit of 2013.  Use Space, F0 or even 0 to flap your wings to avoid the Mario pipes.  You can also press F9 to toggle music and F8 to toggle sound effects.

This version was coded by me (Howard Price) over 2 weeks from late January to February 2021, and is FREEWARE.  All feedback and suggestions greatly appreciated.


The game is written for the SAM Coupé. To play the game, firstly you’ll need to download the SAM image, and either a suitable emulator or the original computer.

Flappy-Bird.dsk (SAM disk image)

The game should run on an emulator, I prefer SimCoupé, available from

http://www.simcoupe.org/

Oct 5

Ahoy.  It’s been a while, so I should have plenty to write about, no?  Finally I’ve stopped beating myself up, ie I’ve started keeping release notes for each release I write.

A PRESENT FROM THE PAST

This all started in 2015 which is a long, long time ago now.  I went back to R-Type as I got stuck on a few major things in Reckless Rufus, and needed to fix them in a game I knew inside and out.  So at the back end of July, this year, my first job was to refactor the old ‘game’ to run with the current sprite manager.  This allows many more sprites to be created without the game slowing down.  And it’s quick to develop.

On the positive side, there were plenty of good decisions made, which were easier to follow.  Downgrading the graphics resolution and scaling for the TV 'fat pixels’ is a great choice as it means everything is the right size and behaves the same as the arcade.  Now I use Aesprite and a cheap graphics tablet for making sprites, it was even easier than before to import the arcade graphics.  Of course, they all get repainted to the SAM palette (more on this later), and tidied up to 'read’ well, but the Excel tools I use for this still make turning it into SAM grab data a doddle.  Nice!

MAP ROUTINE REWRITE

I essentially needed to rewrite the whole map print routine, but this time I was realistic!  I made quick-print routines (ie using the stack to print) for the map scenery pieces, and used traditional printer routines for the edge pieces so they clip correctly to the screen.

Some really hard-to-track bugs started falling out immediately.  One memorable one was realising I was losing the flag register every time there was an interrupt!  This meant *any* decision I was making, should the interrupt occur in the middle of it, the game would crash.

This single error found immediately made both games 200% as stable*, and my shoulders dropped for the first time this year.

EVENTS MANAGER

After some of the early technical revelations (and the grown-up decision to postpone full technical optimisations), I was able to move onto an events system to trigger events.  The enemies are spawned on-rails, so it took a pass going through a long-play video of the arcade to time the start times and positions of most of the enemies.

Some of them were incredibly easy - the butterflies, for example, have virtually no intelligence.  I just specify the display frame and height they are spawned on, and off they go.  I just needed to make sure the game ran at *exactly* the same speed as the arcade for this to work.  And it does.

I suppressed the demo-coder instinct in me for one more thing, which also turned out to be very flexible:  I have two objects linked together, one for the enemy state and AI, and one for the actual sprite object itself.  Some more bugs popped out, how I was trying to manipulate objects that weren’t set properly, which again made it more stable.  Good!  The only downsides are the memory it uses, and the speed of the code, as now I am using both IX and IY registers to point to these data at once.  But it’s a compromise I’m willing to take, as it’s still less than 5% of CPU time spent doing this high-level stuff.  

Then, I also got some more practice setting up pixel-accurate sprites, always a fun bi-annual task.  By mid-August I added the Xenomorphs (Alien-style robots at the ship entrance), and started adding some more complicated update criteria.  These ones home in on your ship height but little else.  But also, there are events listed to quietly turn off the background starfield, and to change the palette for the next bit.  

TURRETS

Adding in the turrets was the first example of a certain type of meanie, that are anchored to the map position.  It’s not perfect yet but overall is working fairly well.  The turret objects are generated via the events manager, so are timed, but the position is controlled by the map scroll routines.

So here’s another area where being able to bolt-on a standard sprite to a tailored AI was useful.  The enemy object chooses the correct angle to point the barrel at based on the ship position, with a simple process.

You can find an angle by using the Inverse Tan function, and plugging the delta X and Y distances into it.  This is no harder than having a big lookup table, but it’s either a very big lookup table, or includes an expensive divide function in it.  However Tan^-1(½) is 26.5%, which is very close to 30%.  What can I do with this?  Well, now I have two angles I can easily check for, which give a good approximation to a diagonal direction.  Other simple checks make sure the turret is pointing in the right direction, and of all things, just the Y-position is enough to tell if it’s upside down or not.  Very neat.

PALETTE CHANGES

So, did you notice the palette changes?  Hopefully it will be so subtle you won’t in the real thing.  But while developing, I needed something obvious to check.  So you can see the bottom of the ship sprite change colour for most of them.  Why?  Because there are lots of iconic colours in the game, and no palette was quite good enough to capture it all.  

So among other things, the deep blue pops up for the initial hyperspace burn animation, some firing, and the rotary guns control unit.  The greens appear for the butterfly ships cockpits and the mechadroid guarding the Bydo ship entrance.

But that wasn’t enough!  I have a line interrupt running on interrupt mode 2 which changes palette for different horizontal bars on the screen.  You have a palette for the HUD at the bottom, but then invisibly, there are colour bands in the game screen area too:  Top and bottom scenery blocks, a main area, a bottom area for ground-based walking meanies.  You can probably see some hovering walkers that have too-bright yellow on them - that’s the beetles yellow.  So some other tweaks still to make here.

SPACE ISSUES

If all this sounds too smooth to be true, I did hit some problems soon enough.  My original plans were to have compiled graphics being built just before the level played.  And if there were more memory constraints, I was hoping to do it invisibly while you were playing the level!  (In fact, that’s still my goal, as I’ll need something similar to that to work for Outrun if it’s not to be a multi-loader game.)  But so far my compiler and print algorithms aren’t efficient enough, so there’s a howling 10-second delay to start the game.

Instead I managed to find more space for the attract logo animation, so all the compilation can happen at the start of the game, an acceptable delay, especially if you’re forced to watch my little Cooking Circle ident anyway ;)

Overall, though, the space is much more well-managed than I possibly could expect.  The only concern would happen if I decided to turn this into a full game.

DOBKERATOPS

Yes, that’s the official name for the end of level boss!  If I’m totally honest, this wasn’t so much fun to do, because it’s just a graphical demo.  Finding the correct palette was a bit of a pain, but I like the outcome!  Some problems that still remain include figuring out the tail swish, and I’ll need to split this up into several smaller blocks to save space and allow smooth scrolling.  But it will get done.

CIRCULAR GUNS

This part has been a *lot* of fun to do.  Put together all the things I have mentioned before and you have a really nice effect.  There are 25 frames of animation, comprising 16 angles for the guns and the control pod, and a single 'dead pod’ frame.  Then I drew from my experience rotating 2D vectors in Thrust.  I love this stuff!

As you’d expect, the objects are sometimes treated as one.  What I’ve learnt is that the code should *directly* reflect that.  So the event manager creates an invisible object anchored to the centre of the circle, just like the turret are.  Then each actual gun uses that as a pivot, and the angle is used to decide the x- and y-displacement.  

I used a lookup sine table for the displacements, which also allowed me to scale the width to 4/5ths, and tweak to taste.  Technically we’re describing an ellipse now, but the effect looks pretty circular.  And all of a sudden, my experiment to make one single object wobble up and down like a demo scroller has turned into a set of objects all moving perfectly.  One problem - where’s the gap for the ship to enter?

Sometimes you notice things when you copy design elements from another game.  This time, I guessed the size of the gap was maybe 2 guns’ size.  And a bit?  Seeing as the guns are described in terms of 1/256ths rotation around the circle, I changed the offsets from 0,16,32,48 etc to 14ths.  And just like that!  it was the right size immediately.  But what’s better, because the sprites are the right size, they touch each other just right.  I love it when that happens!

NEXT STEPS

So!  Looking good so far.  I’m not quite finished with the display features yet, but will shortly be.  I shared the video on Facebook and got some very supportive comments, which is really encouraging – also highlighting an itch I’ve had for a while, ie printing clipped sprites on the edges of the play area.  If someone else notices, then I’m not mad - I do need to give that some effort :)  

Then I’ll take a bit of a break as I have other projects that need attention.  Hooray!

Honestly I’m still here! Sorry I’ve been quiet over the last year. I’m um… [insert excuse]
Okay - so I’ve discovered Tumblr doesn’t like being looked directly in the eyes. You know what this iconic end-of-level boss is from, and I know what it’s...

Honestly I’m still here!  Sorry I’ve been quiet over the last year.  I’m um… [insert excuse]


Okay - so I’ve discovered Tumblr doesn’t like being looked directly in the eyes.  You know what this iconic end-of-level boss is from, and I know what it’s from, But we can’t call it by its real name.  Presumably, copyright strikes dangle perilously over my head right now, even though these graphics are completely redrawn, using differen palette, different resolution, different aspect ratio.  And the code has been rewritten from scratch without reference to the original.

But still.  Tumblr removed all results from the tag this used to be under, so I’ve made a new tag, just for my website.  Where it remains used.

So! Let’s all assume this 30-year-old homebrew conversion of an arcade game.  That’s no longer available.  Onto a retro machine that numbers possibly 2000 units.  Is actually called something else. Hopefully no one gets sued.

But for the record, this feels similar to someone deleting my drawing of Mulder and Scully because it breaks copyright.  Man, Irem, I thought you were cool.

image

Where the hell did the last year go?!

I’m still here! I’ve actually got a super-pretty project I’m about to share some developer-rants with you about. So sorry for being crap and not posting in a ‘while’.

But here’s the thing: the IP seems to be split between a bunch of different people and entities, and so it’s not 100% secure that it’s legal. No, we (yah, there’s more than just me this time!) haven’t stolen anything or ripped anyone off. It’s an old game that still has loads of charm but has some dust on it.

And it’s not Hungry Horace either, in case you’ve been paying attention :D

If that sounds like a dumb way to work, believe me we’re not deaf to the irony. But sometimes a passion project needs a little of that old-fashioned gumption to get you through. Back when I was an over-enthusiastic 20-something, the bands I was in ended up going way farther than I expected. And that was mostly because people picked up on the passion we had for the music.

I’m pretty sure all we need to do to get this one over the final hump of goodwill is to demonstrate the passion we have for this thing. In the meantime I’m going to keep beavering away at this thing and hope whoever has the power to OK this is feeling nice when s/he sees it.

Can I say more than that? Maybe, let’s see:

* We got the original graphics artist with a /spectacular/ set of sprites and playing tiles

* The original C64 author has been in touch, given the project his blessing and even helped provide map levels and tips

* We just heard the original composer has OK'ed the project.


From our side, I have written a from-the-ground-up engine for the game, which is currently sitting around 60% done. That’s a programmer’s 60%, obviously, so adjust your expectations down accordingly! But I can’t see any reason why this wouldn’t be completed in the next couple of months. Get hyped!

Found by Gavin Smith! Cheers dude. It seems programming this beast can be pretty stressful. Glad I’m way older and doing it over several years.

May 7

SAM MOD player 2 30 - eon

Stefan Drissen’s Mod Player keeps getting better!  Now able to deal with pretty long songs as well, which means the ability to read from larger media became a necessity too.

Only thing I wish is that Mods don’t have to religiously adhere to the Amiga’s only dumbass design decision - the panned mono channels split left and right.  Wouldn’t it be sweeet if you could pull the stereo fields in a bit?

OUTRUN SAMPLES!

Hiya. Over the last few weeks I got sidetracked with a version of 3D for the vapourware demo. It was going to be great! But after a while I slowed right down until I almost got stuck, and needed a break.

Right about that time Keith Sear from Chibi Akumas fame was doing sampled sound on Your-Tubes with a million different machines, and it intrigued me.  I need to have a few samples in Outrun, and I figure it’ll be such a low-key release Sega just will not care if I use them.  After all, they sold the Sonic coin ping to use in every EFTPOS in Mexico or something.

Keith actually didn’t have much joy negotiating the screen contention that the SAM and the Camputer Lynx (never heard of it up til then) both exhibited. But I know about that.  Maybe I can do better.

Turns out I could to better. It took only a few different swings at it before it started working well.

SOMETIMES MISERY DOESN’T NEED COMPANY

Okay, full disclosure here, I’ve been having a rough time of it recently and was very frustrated, self-pitying and SMELLY over the few days I worked on this.  Why smelly?  Because on the Saturday I was only going to hack for an hour or so when I got up, then move on.  But I was so annoyed I couldn’t get it sounding good, I worked on it in my horrible pyjamas until 8:30pm.  The life of a single bloke into programming.  Glamorous.

DATA PREPARATION

The hardest part was actually getting the data in the right order, stripped of the header data.  I needed to convert the samples by hand because I couldn’t find a DAW that would export 4-bit samples.  I got out trusty Excel VBA and wrote a converter.  Annoyingly, this took a long time, even though here [] was a really clear wave format document I followed.  But eventually I found a route with ADODB streams that worked and went with it.

I’ve packed the samples into top and bottom nibbles because I was worried about the size of the samples.  However after eventually settling on a samplerate that worked, and throwing them through the deflate algorithm, I may process them as stereo samples for more clarity, as the file sizes compressed are THIS:

  • Get ready:   1555 bytes
  • Checkpoint!: 1907
  • Congratulations: 3498

TOTAL: 696 bytes.

It’s ridiculous.  At less than 7kb I was literally laughing.

PLAYBACK TIME

Next step was to write the playback routine, and here’s where it gets interesting for us.  There is effectively two separate playback routines running interlaced.  One for in ‘screen time’, which can use the line interrupt for timing.  The other for playing in the top and bottom borders, which must use cycle-counting to keep its timing steady.

Some demos managed to avoid this hassle by turning off the screen entirely, which leaves the screen contention completely absent.  But I want these samples to play over the game.  So.

I’m quite comfortable with the line interrupt now I’ve been futzing with palette changes on Outrun’s road markings, so that was an easy thing to get working.  However the timing really has to be very exact or you will get warbling from slight differences in timing.  

The border routine was interesting, as for some reason I’ve been using all the wrong data for timings.  It seems there are 60 screen lines in the top and bottom borders each, and they each use 312ts per line.  I decided to output the sample changes to palette 0 as well, in the hope I could 'see’ the timings better.  This was actually useful and showed the published timings still don’t apply to the SAM because the ASIC chip needs to synchronise other things too.

EXTRA VOLUME AND QUALITY

Now.  The samples played are technically 4-bit, 15.6khz stereo samples, which is very impressive.  But they sounded very brittle indeed, probably because the amplitude jumps up in a very ungraceful square wave.  I thought maybe I could use a trianglar wave, more on this later.  For now, I found a good trick to increase the resolution:

  • You have two envelope registers on the SAM, both can be used to play the same sample.  With any waveform-matched output, it increases the volume as the amplitude is combined.  
  • But the SAA1099 is well-documented to *claim* 4-bit resolution on these registers, but it’s actually 3-bit.  If you try to play a sound with volume 1 (of a scale from 0 to 15), you get silence.  Other people have tested the outputs of the other volume settings, it’s essentially 3-bit.  Ugh.
  • So let’s first combine the two envelope registers, giving us a louder sample.  It needs it anyway.  Then let’s increase the second envelope register by 1, so it will be slightly louder when the original sample ends with a binary 1.  That way we get back the 4-bit resolution.


And bam, it works! 

This also improves the signal-to-noise ratio, so the whole thing sounds less harsh.  And louder.  Noticeably, it’s still pretty noisy.  why?

GET FULL QUALITY WITH THIS ONE WEIRD TRICK*

(* No clicks, all clickbait.)

The second experiment I thought may work, I haven’t tried yet but might do later.  A little background:  You might have seen some extremely amazing sample demos on the C64 recently.  They use this strange 'lock’ trick on the SID which essentially bypasses the input volumes on a triangle wave, and manages the timing on a volume increase until it hits the desired volume.  Then the lock is activated, and you end up with a curiously high amount of accuracy - 8-bits.  I’m paraphrasing, it’s explained better here:

image

https://brokenbytes.blogspot.com/2018/03/a-48khz-digital-music-player-for.html

Spicy!

So, in the SAA there’s something called External Envelope Clock on the envelope register settings.  Instead of taking the pitch from oscillator 1 or 4, you can push the timing through the address register as a pulse.  However, I failed to get this working, I think because the upper frequency limit is set much lower.

I also had a bit of fun with testing some effects processing. Panning the mono signal to a centred stereo signal was fine, and definitely worth doing on the fly, as these samples will be compressed and just wheeled out when necessary.  You’ll notice in the arcade original, the 'Get ready’ and 'Congratulations!’ samples play when nothing else has to move.  Admittedly, I’m not sure what I feel about the 'checkpoint’ sample, as I don’t really like when the movement freezes even for a second.  Maybe I’ll put in a beep on hitting the checkpoint, and you can select to put the sample back in.

Other processing I tried did work but the signal degraded pretty drastically.  Because these are actual waveforms I am dealing with, I should be able to apply echoes to the waveform without losing quality.  You just take the output, move forward x samples and add it to that.  Of course, attenuating the waveform helps, and you need to pay attention to any clipping or overflows.  So when I tried it it came out very gritty and degraded.  Not for me.

What’s next?  Well, I’ve got one other experiment, but then I went onto other things, so it’ll have to wait.  Here’s the idea anyway… What if I use some software volume tables to fake a smoother interpolation between sample volumes?  

Hey!  What happened to the sprite lighting experiments?

Oops, I forgot to upload any work in progress shots of this… Well, here’s one I found while working on something else:

image

This was an experiment in moving the lightsource, but the sprite could move as well, which makes sense for games too.  It doesn’t take the overall normal vector of each pixel (or 2 pixels) into consideration yet, but that’s a-coming.

You’re seeing the overall brightness working well, but I hadn’t finished ensuring only colours with an overall brightest RBG shade matching the original colour’s profile would be chosen.  Wow that sounds vague and slow.  Let me explain in two sentences, wonder if I can make sense:

This is only using 16 colours, so colours would be listed in a bunch of tables alongside their darker equivalents.  It wouldn’t be exact, but I could make sure, say mostly blues are in the same table.  Hey, I did it!

Anyway, this was an experiment that would look great for Atic Atac but might entirely change the look and feel of the game, and might be a time-sink I don’t want to fall into yet.  So don’t hold your breath :)

Trackmos and memory management

Hmm it’s been a long time since I pulled apart a new strategy for building my projects.  I’m pretty glad I managed to get this far with my project workflow, but it’s time to expand a little bit.  Standard disclaimer, this is just what’s working for me right now.  You may know better.

image


*DULL*.  WHY BOTHER?

So.  One of the sections of Outrun is a groovy single-screen where you’re fiddling with the radio to get the tune you want.  It’s lovely, very atmospheric, and certainly technically possible to do on pretty much any computer you wanted to make this game on.

However, it’s pretty much just in the way for the rest of the game, and I need that memory for graphics!  Wouldn’t it be good if I could compress the whole section, and just decompress it for the 15 seconds needed at the beginning of each game? Actually why not also compress the samples too?  And maybe the high-score table?  And the animation on the Outrun logo?  Basically, any stand-alone pieces of code that do not need to stay resident.

There are a lot of useful moments where a technique like this can be used, But the big problem is that it’s fiddly.  Making this manually each time is bound to mess up, because I need to compile code very quickly, over and over again, to check all the bugs  have been squashed.  So my list of wants include:

  • Must be able to compile and zip to the right place via a single command/batch file
  • Include a build version that can test it on its own
  • Include a simple interface to the decompression tool for the objectcode to run
  • Allow decompression to happen seamlessly in the background

That seems enough for now.  That last point might be difficult to achieve, I haven’t completed it yet.  But I need it so things like music can continue to play while decompression is happening, so it’s not hugely obvious when it’s happening.

image

The games will have to wait for a little bit, because remember years ago when I just wanted to work out how to do some demo effects?  First Ghost - remember that?  Good name for vapourware!  Well done Howard.  All that stuff I never released I really wanted to cobble together.  It’s a simple version to start with, so let’s start there and build on it later.


7-ZIP COMMAND LINE INTERFACE

The first thing was using a decent compressor via CLI.  I already run my builds through little batch files, and wanted to see if it was possible to extend that paradigm,  Glad to say, it is.  7-Zip is free and open source, and comes with a nice helpfile for using it from the command line.  I just needed to add in a few switches to ensure the compression was using the right method, and outputting to the correct place:

7z a -aoa -tgzip “F:\Dropbox\Wombles\Trackmo\! Linker\gzip\starfield.raw.gz” “F:\Program Files (x86)\pyz80\test\starfield.raw”

So this translates as:  Run 7-zip, add to archive, overwrite all files, use gzip format, output to …starfield.raw.gx, source is …starfield.raw.  Easy.  The default method uses ultra compression, with the Deflate algorithm.  Which is exactly what we need.

I’ve been using 7-zip already, but only for graphics.  And to my shame I’ve mostly been processing these either by hand or through an Excel VBA routine, as I’ve been converting my sprites with my horrible bodge-job Excel files.

image

Honestly!  Save into an old .XPM format, then import to Excel as a string and convert with hand-made palette replacement tables.  It’s been a fun old ride but I don’t want to do this for code, no thank you.  But this will do for now.


OUTPUTTING OBJECT CODE

My major stumbling-block was when I had a bit of trouble getting my compiler of choice (PYZ80) to compile a normal source code, and then output objectcode that can be compressed.  After fiddling around for a while I asked the community, and got a very concise answer!  I’d been using an old version of PYZ80 which has a bug in it.  Stefan Drissen (thanks Stefan!) pointed me to the most up-to-date version of the compiler and away I went.

So instead of outputting a self-running disk image, I now output raw object code as a PC file, and save to a temporary spot.

pyz80.py -D LEAN –obj=test\starfield.raw test\lean.asm

This is important to visualise.  At this point I have essentially broken the build, because the zipped code uses tokens (symbols, equates and labels) that are obscured in the main program.  This means that it’s pretty difficult to pass data between these parts.

image

Far from being a hindrance, this makes it easier to isolate bugs as you are much more likely to send data between routines in registers.  This is the Z80 equivalent of writing functional code and really useful.  I actually broke this convention and used a single byte for a status flag, but as I was writing demo code to be strung together in a series, it didn’t matter.

But wait!  What’s that -D LEAN bit in the middle?  Ahh, let’s get more complex.


REPURPOSING STANDALONE CODE

Okay, so the First Ghost code has been sitting around for ages gathering dust.  Everything I was trying to do was split into lots of self-contained modules, with nearly identical boiler-plate code round it.  Virtually all the effects were done in 50hz on a single screen, and resided in a single 32K page.  I needed a way to strip the meat of the effects out and leave the builerplate coe to a single management routine.

So I started experimenting with separate builds of the code, and it worked out fairly well.  Firstly, the boilerplate code was stripped out and put in a file (usually called “auto.asm”), and I put the core of the effect into a separate file, which I INCLUDEd back in, called “core.asm”.

Then I created another wrapper module called “lean.asm”, whose sole purpose was to have one line at the top of the effect to jump into the main loop of the effect.  This meant I didn’t need to calculate the start of the main effects by hand for each effect.  I could have juggled things round and put the data beneath the mainloop, but I’ve had a ‘data at the top’ convention for a while now.  Seems to make more sense this way.

image

Okay, any issues?  Well, one, yes.  The standalone (“auto”) versions of the effect worked fine but I needed to include an extra piece of code for the “lean” versions to flip the status flag in the main routine, when the effect ended.  So I used a variable in the batch file to define LEAN for this build.  Then include something like this for when the effect was finished and needed to signal to the main handler it was done:

   if defined (LEAN)
       ld a,-1
       ld (36000 - 1),a
   endif
       ret

Not the prettiest thing in the world, but it works.  The 36000-1 address was where I hardcoded the status register.

In order to recognise this switch, you have to include a “-D LEAN” switch in the pyz80 instruction in the batch file, which is essentially the same technique I use to include debug code in my games.  If I finish another one (I’m hoping I will, soon), then you just compile without the DEBUG switch, and your handy debugging code is left out of the final build.

I did an experiment into batch files running other batch files, but it seems they can’t run nested within one another.  So for now I’ll have to at least compile the lean versions by hand, and then run the final build on another pass.

Okay!  So where are we now?  I have two batch files, one which I can use regularly to actually code the effect on its own, and another which will build a 'lean’ version without the boilerplate code, zip up the code, and put it in my final folder.


LINKING BUSINESS

We’re at the final stages now!  I’d been using Andrew Collier’s SamFlate code to decompress graphics for a while now.  So I installed it somewhere away from other code.  It likes to be called residing at 49152 + 258 bytes, and takes up around 2K.  It also prefers the stack to be above it (I point it to 0, so the first PUSH goes into 65534 and 65535, and moves down), and needs some space in the page before it as a scratch pad.

As I am (apparently) odd in that I put the screen in 0-24575, I have another jumper routine that sits beneath the screen and pages in the main inflate routine.  I also cribbed the 'piano roll’ routine I’ve been rewriting for all the rolling attract sequence effects I’ve been using in my games. It’s remarkably simple for the trackmo - decompress everything to the same address and run it - but I’m sure it will be more complicated for games.


AND THERE YOU HAVE IT

What I was most surprised at was how seamless it looks, and how small the zipped data is.  I suppose it’s because writing fast code often has lots of unrolled loops, ie repeating code with small changes, but I’m getting effects and data typically compressed into less than 4K.  And they decompress in a fraction of a second.  As mentioned before, it’s not quite perfect yet because I need the decompression to happen seamlessly, and currently any music playing (for example) would stop while the decompresion happened.  But it is looking good.

I’m mostly concentrating on pulling together most of the bits of my vapourware demo, but really I will be using this technique on most games I have in development.  I have a a nasty habit of not planning memory usage beforehand in detail, so there is almost always a crunch point where I suddenly have a broken game that needs restructuring.  This may not fix that problem entirely, but it could easily get me out of a tight jam or two.

image

Man, I really should start putting better infographics in these blog posts.  If you followed all that, you’re a pretty good imagineer.

BalorPrice/Snake-in-a-day

Prompted my a mate, published the source to my coding practice, making Snake in a day (weeell, two half-day sessions really).  I pretty much copied it when I saw the Chris Deleon Youtube clip here, where he can make snake in the browser in plain javascript in about 5 minutes.  Well, less than 5 minutes to be honest.  Of course, programming in 8-bit assembly language is slower than that but I was happy with my effort.

And that there is my profile pic on Github, drawn huge because *that* won’t look dumb and self-important.  Cheers, The Tumblr.

The code is entirely basic, so you won’t learn any good hacks to programming, but it might be useful to see how all-assembly code on the SAM is pretty easy to set up and work on.  Beginners are welcome. Have at it.

However, if you really want some mind-blowing code to digest, I humbly suggest you check out Denis Grachev’s two lastest game sources, for Old Tower and Gluf.

Why are these worthy of note?  Well, feast your eyes:

image

All those not-very-Speccy-like color changes in the logo are real.  And they carry on throughout the entire game.  And the best part, the game only scrolls too doesn’t it?  Smoothly! 

You should head to http://www.retrosouls.net/ and test it yourself - you can even play directly in the browser if you can’t be bothered to dig out an emulator.

image

And the best part of the best part?  The source isn’t an easy read at 5400 lines for Gluf, but still wow.  At least my code is split into a million modules so it’s a bit more easily digestible. *Yeah, keep telling yourself that.*

oWo Found some footage of real strangers playing my version of Tetris on the Youtubes. They’re way better than me, green levels are beyond me!

Jan 3

Dynamically-lit sprites?

What just happened? Had a brain-exploding moment talking about dynamically lighting sprites without losing too much speed. For something like Atic Atac, I was thinking. It might actually be possible, watch this space

image

Originally posted by mimipunk

I’m thinking making a compiled sprite that looks up the colour based on an overall brightness and hue value? Can’t be that hard but how to do it without sacrificing a lot of speed? Time for a demo maybe

Time for a catch-up

I’ve left it a really long time to blog.  That was a mistake.  And the reason is, it’s probably easier to make a road map of where I’ve gone wrong to explain what went well.

The TL;DR is:  I got sick of making no progress on Atic Atac, wondered how my plans got turned into that instead, tried to get sound effects and music working, failed, ended up trying to put it into Split Personalities, took forever.  Now I’m trying to finish Split Personalities.  Ta-da.

image

Oh, you’re still here?  Okay, you get the longer version too then.

The Atic Atac thing started in good faith.  After releasing Tetris I had a lot of enthusiasm for polishing off a lot of my projects.  I was going to do a game every 3 months or so.  If that sounds wildly over-enthusiastic it was because these are all games that are nearly finished.  Celeste.  Thrust.  But not the big ones, Outrun etc.

And then there was a huge thread on the Sam Coupé users thread for classic games, and Ultimate Play the Game games specifically.  Before I knew it I’d thrown in my hat to help make Atic Atac, ideally with a few collaborators.  Many hands.  It’s always worried me that I never do programming with other people, and so there’s never any support when I get stuck.  I wanted to do a little of something social so it wouldn’t be too hard.  Teamwork!  Makes the dream work.

However none of us are used to collaborative working with 8-bit.  We ended up with a few people saying they didn’t have time, and me wanting to collaborate.  There was also a guy I’ve respected for decades called Andy wanting to take a stab by himself.  I wound up making a Slack group and Trello board basically for myself.  David Ledbury (who worked with me a lot for Tetris) joined and we bounced around an empty chatroom for a while wondering why we were so unpopular.  Haha!!

Still, progress went okay for a few months.  I tried to develop the game in a way that wouldn’t tread on anyone’s toes should someone want to help.  I built modules that were very loosely bound, and left many areas which could be improved with more time and effort.

To be honest I’m proud of how some of it was working out, especially the framework for the gameplay and sprite updates.  The game runs in IM2 regardless of how long the screen update takes.

And me and David talked a lot about how we could reuse modules of this project for other games.  Maybe take the general framework for some elements and recreate Pssst from it.  Remember kids:  Always recycle.  TO THE EXTREME!

image

But ultimately I got so far before it was all slog.  I took a week off and manually entered the whole castle’s map details.  It took forever.  I was so bored.  And lost all the momentum from my other projects.  Andy’s version wasn’t progressing much faster, he seems to have a lot of real life commitments.  I took a few steps back and wondered when I’d get any better at this.

A different Andy got in touch and I promised him I would be able to move back to sound effects work, which I had singularly failed to do.  I wanted to keep it simple but really wanted to expand it for just a couple of features.  Tetris worked fine, but (a) there was virtually no need to manage more than one sound effect at once, and (b) it couldn’t support the envelope registers.  And I felt that was important to do both of those things.  Andy agreed.  Didn’t seem too much of an ask, right?

[Hey you know what?  Those events weren’t strictly in that order.  I was *definitely* trying to juggle these things at the same time.  And failing.]

Trouble with the sound effects routine is, the SAA does not have a single channel which can support all of the following:

  • Pulse waves
  • Variable-pitch noise
  • Envelope registers for triangle and saw-tooth waves

If you want to support all these in any combination for even a single sound effect channel, you need to rewrite the output support completely to poll for the quietest sound register that provides the feature you need.

Well, I fucked up.  I couldn’t get it working.  In the Tetris Postmortem post, I confessed the sound effects module was a huge pile of rubbish.  Then I couldn’t even get the previous version from Tetris to work either, leaving me with nothing at all.  I buried my head in the sand and decided I just needed a bit of a break, I ended up going back to Splitting Images from years and years ago.  

I let down Andy badly and at this point I’m ready to accept defeat.  I don’t think I’ll ever get proficient enough to make all these sound things I hope for.  So I’m putting BitJockey and other sound projects to bed.  Life’s too short.  I am indeed shit.

I may carry on working on it, but at this point I’m prepared to admit I’m not good enough to make progress at any rate whatsoever.  I can do other things on the Sam, but mostly because it’s a deserted city, and I’m wondering around with virtually no one else here.  If anyone wants to work with me, I’m only going to offer stuff I’ve already completed so I don’t piss off any more people.

ONWARDS, I GUESS

After that little depressing epiphany, I totally simplified and reminded myself I’m not a decent coder, I haven’t rubbed up against people who are able to teach me where I’m going wrong.  I’m not against working with other people but to be honest I don’t trust myself to hit any sort of deadline at this point.  I’m so unreliable that even hitting problems with days of work isn’t enough to guarantee I can be relied on for stuff.  I also failed to finish Thrust and Celeste, both of which are projects that I estimated were only a few weeks off completion.  This is not looking like the CV of a good coder.

So.  I went back to Splitting Images because it’s a single-screen puzzle game.  It should be the simplest thing possible.

I’ve made a lot of progress on this game, but you’d be surprised at how much content still needs to be done.  I wish there was a nice list of highlights I could show you at this point, but really just getting the thing working is all I really want.

So - there it is.  Let’s see what happens next.  Happy Christmas.

image