Friday 30 April 2021

The 80:20 rule of Scramble; you can only get 20% of the way through the game with 80% of the code written.

I've completed the game lifecycle mechanics and fixed a few bugs in the process. Somewhat interestingly, in two completely different routines I had omitted the instructions that reset the column scroll values in the C code. Strange coincidence.

But you can now coin up and play 1P or 2P games through to completion and back to attract mode.


2P game in action

There are a few odd bits of code in there, such as specifically copying two one-byte data values from memory (a level value and a flag) over the storage for a pointer; they're never read back and that same copy is done in two places. However it's benign because the pointer is re-initialised before it is used again. I'm scratching my head wondering how that could have gone unnoticed in the assembler source.

I've only got two reasonbly trivial routines that I can't test to go besides all the the routines related to player bullets & bombs and their collisions and explosions. Those routines simply check if an extra life should be awarded (based on score) and also display the 'mission complete' flags.

Looking at the source code after yet another cleanup I'd estimate it to be around 80% complete. There's nothing new in those routines that hasn't been transcoded already, and a lot of it will be cut and paste. Whilst the code is nicely structured and lends itself very readily to a C transcode, there is a reasonable amount of very similar and in some cases outright duplicate code.

From here there's a couple of days of work in the bullets and bombs and then it'll be play testing.

I'm yet to transcode any audio-related routines. The audio control simply involves writing sound ordinal values to the sound CPU (another Z80) which controls a pair of AY8910 sound chips. I'm not intending on porting any audio at this point, but will probably add stubs for the audio routines so that sound may be added at some point in the future, even if not by me.


Thursday 29 April 2021

2P or not 2P, that is the question.

 Today was mostly working through all the game lifecycle mechanics and adding some support for scoring during the game.

In previous transcodes I've just used (long) binary values for scores etc. In Scramble however, at some point early on I chose to preserve the use of BCD, and although I can't recall the exact reason I do remember thinking it was the right choice at the time. I'm regretting it a bit now, because the code for adding to your score is a bit messy in C, and the high score table code was just tedious.

You can now play through a game and get back to attract mode and start another - if you have sufficient credits of course.

1P gameplay mechanics seems to be complete

With no firing/bombing implemented it's difficult to get too far through the game, even with infinite fuel. On the 1st stage it's fairly easy to dodge the rockets, but the UFOs on the 2nd stage are another matter. A simple algorithm but effective.

High score table update is coded but not tested. Interestingly, the way I read it is if your score equals that of any previous entry in the high score table, the game will not insert your new score. That's a bit weird and it's going to be tough to confirm on MAME because playing the game you get 10 pts every second or so just for staying alive.

Although it's boring I'll probably work through the 2P mechanics just to get it ticked off. Given the architecture of the code though, that'll be an effort not considerably less than the 1P mechanics.

I'm wishing now that I had preserved all the ASM code in the completed C functions. It's kind of cool seeing the original code and makes it easier to debug; just blows out the file size considerably.

Given the relative ease of this transcode, and the fact that Galaxian uses the same hardware, I'm pretty keen to start on that as soon as Scramble is finished and ported to at least one if not a few other platforms. I'm a little concerned that older C compilers may not like my anonymous structures and unions, but I'll cross that bridge when I come to it. With Galaxian though, I'll preserve the original ASM code in the C source and see how that works out for me.

Wednesday 28 April 2021

Running on the smell of an oily rag

Working through the game start up and it's a bit of a grind to be honest. A fair bit of code had to be transcribed before anything interesting happened. But I now have the game starting and the player ship moving around. If you don't die from being hit or colliding with something, you'll run out of fuel.

Coin up, start a game and move around.

No shooting or bombing, but you can play through the 3 lives and it displays "GAME OVER" although I suspect the scroll offsets of the display area haven't been reset as they should be as it appears at a random offset from centre, and in the wrong colour. A quick search didn't reveal where that was but I'll find it.

As I work through the code I mark each routine as being one of UNIMPLEMENTED, WIP, LOOKS_OK, UNTESTED or COMPLETE via a printf that can be selectively enabled or disabled by category. Today added a whole swag of UNTESTED routines.

Unlike my earlier efforts, in this transcode I've started with the original disassembly, with every line denoted a C comment. Makes it much easier to keep functions in the same order as the ASM code, and keep track of addresses etc. Until a few days ago I was writing the new C function under the corresponding ASM function, but more recently I've moved the commented ASM inside the functions with the C code following each block of ASM code.

I've been removing the ASM code from the file whenever I deem a function to be COMPLETE (tested, debugged) but now I'm thinking that in my next transcode, I should actually keep the ASM code in there. It'll blow out the source file size of course, but does that really matter?

An example of what I mean...

// $10BA
void game_init (void)
{
  DEBUG_OPT_UNTESTED;
  
  //10BA: 21 09 40    ld   hl,$4009              ; load HL with address of TEMP_COUNTER_4009  
  //10BD: 35          dec  (hl)
  //10BE: C0          ret  nz                    ; wait until counter reaches zero
  //10BF: 36 0A       ld   (hl),$0A              ; set TEMP_COUNTER_4009 to 10

  if (--wram.temp_counter_4009 != 0)
    return;
  wram.temp_counter_4009 = 10;

  //10C1: 2C          inc  l                     ; bump HL to point to SCRIPT_STAGE
  //10C2: 34          inc  (hl)                  ; advance to next stage of script (PLAY_GAME @ $22F4)
  
  wram.script_stage++;
  
  //10C3: 3E 01       ld   a,$01
  //10C5: 32 19 40    ld   ($4019),a             ; set DRAW_LANDSCAPE_FLAG
  
  wram.draw_landscape_flag = 1;
  
  //10C8: 21 01 00    ld   hl,$0001
  //10CB: 22 80 43    ld   ($4380),hl            ; set PLAYERS[0].IsActive and reset PLAYERS[0].IsExploding flags
  //10CE: 22 A0 43    ld   ($43A0),hl            ; set PLAYERS[1].IsActive and reset PLAYERS[1].IsExploding flags
  
  wram.players[0].is_active = 1;
  wram.players[0].is_exploding = 0;
  wram.players[1].is_active = 1;
  wram.players[1].is_exploding = 0;
  
  //10D1: AF          xor  a
  //10D2: 32 82 43    ld   ($4382),a             ; reset PLAYERS[0].StageOfLife (see PLAYER_INIT @ $16FE)
  
  wram.players[0].stage_of_life = 0;
  
  //; player starting level, update lives remaining 
  //10D5: 21 08 41    ld   hl,$4108              ; load HL with address of CURRENT_PLAYER_LIVES
  //10D8: 35          dec  (hl)                  ; reduce number of lives
  //10D9: 11 03 07    ld   de,$0703              ; Command ID: 7 = HEAD_UP_DISPLAY_COMMAND, Param:3 = DISPLAY_CURRENT_PLAYER_LIVES
  //10DC: FF          rst  $38                   ; call QUEUE_COMMAND
  
  wram.current_player_lives--;
  rst38_queue_command (7, 3);           // HEAD_UP_DISPLAY_COMMAND, CURRENT_PLAYER_LIVES


There is one bug that I haven't even looked for that revealed itself after I got the full demo lifecycle coded; when the player is killed and the next life starts, random strips of the landscape are missing. Given the nature of the bug and the data structures in the game, I suspect it's an area of memory being corrupted... hopefully it won't elude me for too long when I finally go looking for it.

There's probably another day or two (at least) working through the game lifecycle mechanics before I get onto the shooting and bombing.

Tuesday 27 April 2021

Oh flip!!!

 Some good progress today even though there's not a lot to show for it.

I fixed a couple of bugs (including the stubborn explosion sprite one) that weren't directly related to transcoding the actual Z80 instructions to C. And speaking of the sprite bug; I stared at it a while longer before it struck me that the sprite codes for half the ship explosion were out of range! What that meant was that they had flip X/Y bits set - which I hadn't yet implemented!

The other bug was the 'graphical glitch' on the text way back from Day 1. Today I noticed that it only seemed to occur on the attract screens, and then I noticed it was only on the 'space' character, and always the same glitch. Didn't take long to realise that my text strings were using the wrong character code for space! All fixed now.

I worked through the collision routines for the ship and different objects, such as rockets, ufos, fireballs, and ground-based objects, and finally the landscape. I had to patch the code temporarily to trigger different collisions in demo mode, but everything I can test in the demo seems to work now. I also did a big clean-up of all the C code, removing the ASM code (comments) from routines that are considered complete.

So on to starting a game; implementing coin-up, reading from hardware (dipswitches, coin mechanisms and buttons), more scripts and initialisation code to transcode. I also had to hack a fix for a race condition between my two threads - since I don't actually have a proper, pre-emptive vertical blank interrupt (NMI) routine - but works better now.

Current state of progress is that you can coin up and start a game, but you don't get to see any evidence of the latter as of yet.

Coining up

Next I'll continue on with getting a game to start, and either moving the ship or finishing off the higher level mechanics of the 1 and 2 player game lifecycle. That'll leave bullets, bombs and their interactions.

Sunday 25 April 2021

And then I went and spoiled it all by doing something stupid like explode you...

 I've added the player, player explosion and rocket explosion. And in the process I've encountered my first stubbon bug since I began the transcode.

The player explosion is obviously wrong

You can see that the player explosion is using the same sprite for both halves of the ship. Trouble is, I've checked and double-checked the code, printed debug messages, and I still can't explain it. It's driving me nuts. Here's hoping a new day will shed some light.

That aside, there is a *LOT* of code for the collision detection and explosions. The top level collision routine calls no less than 13 subroutines, each checking collisions between a player/bullet/bomb and object/landscape. And there'll be a lot of cut-and-paste in those routines. I'd even estimate that once I've completed both, I'll be 75-80% through the transcode. The remainder will be for coining up, player controls and mechanics of one and two player games and scoring.

Stay tuned.

Saturday 24 April 2021

All your base are belong to us!

 I now have all the objects that aren't related to the player rendering and animating - including the end of game 'base' which is an otherwise unremarkable so-called ground object.


UFO stage

There's a fair bit of near-identical code in the object handlers, so today was more cut and paste and creating tables rather than implementing new behaviours.

Fireball stage

I've added a few build options to the C code, such as the ability to jump straight to the demo in attract mode and also select the starting stage in the demo. No doubt I'll also add options such as infinite fuel, player invincibility and/or infinite lives to facilitate play testing.

The base at the end the final stage

This really has been a staightforward transcode and now, roughly 50% through the code, I don't see any surprises to come. The code structure accomodates a C translation very nicely indeed.

In fact I took another quick look at Scott's Galaxian disassembly today and Scramble is undoubtedly derived from the Galaxian code base, despite the fact that Galaxian was released in 1979 by Namco and Scramble in 1981 by Konami. Galaxian would also be another straightforward transcode, and I'm tempted to work on it sooner rather than later whilst the project is fresh in my mind.

Next up is animating the player and fuel gauge, scores, mission flags etc. Since the player is inevitably destroyed by a rocket early in the demo, I'll have to also implement at least some of the explosion routines sooner rather than later.

I'm starting to consider which platform(s) I'll target for this transcode. I think Neo Geo will (still) be my preferred target, even if in rotated (vertical) mode initially. I'm trying to work out how difficult it will be to convert to horizontal - likely a lot easier than Space Invaders has proved to be - but I probably won't really know until I try.


Friday 23 April 2021

Rocket to me, baby!

Some eye candy today. I've now got the rockets launching and following their pre-described path. Every 64 interrupts the code scans the ground-based objects to see if there are any rockets likely to hit the player (within a hard-coded window towards the left side of the screen) and if so, launches the first one it finds.

There are a maximum of 4 in-flight objects at any one time, and that includes rockets, ufos and even fireballs. Yes, hard to believe that there are only ever 4 fireballs on the screen in stage 3, and that they cause so much trouble!

Rockets launching

Each so-called 'in-flight' object has a table that describes their flight path, which is used to apply a delta to its position every interrupt. Not surprisingly, the path table for the rocket consists of a single entry that moves it up the screen.

Rendering the ceiling and the floor

It's interesting that you don't notice the imperfections in the game until you're debugging a transcode. The rocket sprites actually overwrite the progress bar before disappearing - confirmed on MAME.

You tend not to notice the gaudy palette when you're playing...

Next up is to add the routines to handle ufos and fireballs, and also to render the base (a ground-based object). Aside from the fuel gauge, which is currently not updated, that'll be about all I can do before adding the player ship and handling collision detection & explosion to round out the demo.

All that will leave handling of player controls, bullets and bombs, things exploding and game mechanics suchs as coin-up, scoring, high score updating etc. If I had to take a guess, I think I'm approaching the halfway point in the transcode. It's hard to estimate at this stage because the ASM-to-C code line ratio varies considerably with the code itself.



Thursday 22 April 2021

Completely floored!

No eye candy today but some progress; rockets, fuel tanks and so-called 'mystery' objects are rendered as they appear and then deleted as they scroll off the screen. Interesting to note that they simply disappear as soon as they hit the edge of the visible area of the display, as confirmed in MAME. There is also a maximum of 8 ground-based objects on the screen at any one time.

I've also implemented the routine that switches landscape meta-data as you reach the end of the level. As a result, the demo now scrolls through the entire game, looping endlessly on the BASE level. I've currently only implemented the routine to decode (and render) the floor, so next task is to implement the routine to decode the ceiling.

I was thinking once that's done, I should put together some code that renders all 6 levels into a bitmap.

Wednesday 21 April 2021

Scrollin' scrolling' scrollin'...

 A couple of days ago I implemented the landscape scrolling and, much to my amazement, it actually worked first time - at least until the end of the first stage.

In the last few days I've been working on getting the so-called ground-based objects rendering. There was a bit of infrastructure to implement and also a minor re-architecture on some of the structures in RAM (simplfying them) but after fixing a bug this morning I've got the rockets rendering.

Too bad I can't upload a video of the scrolling landscape

Getting the rest of the ground-based objects rendering should now be straightforward, as they're all handled using a common object structure.

In fact looking at the disassembly it looks like most of the variables have been defined in the C code, so hopefully that'll be the last tweak of the structures.

The next few days will likely involve just working through the routines to create the rest of the ground-based objects and then 'animating' them which I am assuming is how the rockets are launched. Since the code simply operates on the existing structures, it should be a matter of cranking the handle.

Saturday 17 April 2021

Land(scape) ahoy!

Now up to the demo proper. The initial landscape is drawn (hard-coded routine, not part of the landscape data), the stage indicator on the head-up display is rendered, and things are about to start moving! As I suspected, the demo will comprise much of the remainder of the code, which is a good thing.

The demo is about to start...

At this stage there's still lots of variables being added as I go and a little re-architecting as I learn how the variables are accessed, keeping in mind that in some cases the type of variable is optimised for the C code if it does not appreciably affect the code. Scott has defined structures in his disassembly and I'm staying true to his design as far as possible. It helps self-document the code and also helps the transcode which, I must say, has been going particularly smoothly.

A note on the structure of the Scramble code as a whole:

The main routine is a busy loop that waits for tasks to be written onto a circular queue by the NMI routine. If there is nothing on the queue, it will periodically call a few non-time-critical routines, such as blinking text, drawing the fuel gauge, drawing a column of landscape that is just about to be scrolled onto the screen etc.

The NMI, 60Hz driven off the vertical blanking interrupt, does all the heaving lifting. It's one big state machine that Scott refers to as 'scripts' that control high level program flow and subsequently the low level mechanics of the game logic, controller inputs, and video hardware updates.

Quite a neat design, and one that could be applied to any number of early arcade games. Scott has mentioned that Galaxian is very similar, and I'm hoping that's the case as it would make a transcode similarly straightforward, especially as it's running on the same hardware.

Things should really start to get interesting now. Without <F10> I'm going to have to patch the code to run the demo immediately after start-up so I don't have to sit through the attract mode every time...


Friday 16 April 2021

Waiting for the demo...

 Transcoding is progressing nicely. The three attract mode screens (challenge, high scores and score table) are now complete, and the game cycles through to start the demo. The sequence and timing of events and colours and graphics all match what's happening in MAME (graphics corruption aside).


I've been tweaking the architecture as I go, improving a few things that I really should have done from the start. All hardware accesses are now done via 'osd_XXX' functions so the core Scramble code should be highly portable.

Starting to get to the fun bit now; the demo, which I'd think would comprise most of the functionality of the game itself. It's early days yet but the code is translating nicely to C and if it remains this straightforward, it'll be the easiest transcode I've done thus far. Given that Galaxian (same hardware) is supposed to be very similar software-wise, I'd be tempted to work on that next while it's all fresh in my mind.

Thursday 15 April 2021

Somewhat attractive so far...

 Not a lot of time so minimal progress, but something to show for it.


So far the code has been straightforward to transcode. I think that'll be the case for quite a while yet, as I work through the attract mode scripts and underlying functionality.

I'm not quite sure what the 'corruption' is on some of the tiles. Right now it's irrelevant to the process.

EDIT: I've just noticed a few issues with the above, namely the bottom half of the display is not in colour. I'll look into that. I also notice on MAME that '1UP' and the score & high score are displayed, even before the attract mode starts. I'll have to look into that as well!

Wednesday 14 April 2021

On a high!

 Very quick update as it's late... implementing the script processing and now it clears the rectangles and prints "HIGH SCORE" in attract mode.


There's a bit of jumping around in the code, but on closer inspection it can be unravelled into a single function... at least that's how it appears so far. So again, as yet, no gymnastics.

In the early stages of implementation - especially with script-driven logic - there's a lot of time spent setting up variables, creating tables and adding stub functions and their prototypes, so progress is slow.

Tuesday 13 April 2021

All sticking to the script (so far)...

Transcode is progressing well. I'm starting to get a better feel for the structure of the game. So far I haven't had to do any gymnastics to mimic the Z80 ASM code execution flow in C - but early days yet.

I've added an NMI (60Hz) and started on the transcoding of the handler, which drives all the main logic in the game. It's all script-driven which means jump tables everywhere. Because I want the C code to be as self-documenting as possible, it has meant some localised re-ordering of data structures and code to avoid pages and pages of declarations.

So far all the 'script' routines are stubs so I don't have anything (further) visually to show for it yet, but from what I've seen in the ASM code it shouldn't be too long before I start to see some text in attract mode.

My work schedule for the remainder of the week will be quite demanding though, so I'm not sure how much I'll get to work on it before the weekend.


Monday 12 April 2021

The first thing I C!

I got a few minutes to start on the transcode today. I did a very, very preliminary scan of the code to get an idea of the data and code structures and its suitability to be converted to C a few days ago; now I'm simply working through the execution path from cold reset, adding data variables and routines as I go.

This is what I saw tonight. It appeared 'magically' when I implemented the Scramble code to fill character RAM with white rectangles. The arcade code is running in one thread, whilst the Allegro-based OS-dependent code is refrshing the display at 60Hz.

Just to give you an idea of what the transcode looks like, here's the main routine so far...


void scramble (void)
{
  // $0000 disables interrupts and jumps here
  memset (wram, 0, 0x0800);
  // jumps to $0069, immedaitely above here
  // - so implement here
  //0069: 3E 9B       ld   a,$9B
  //006B: 32 03 81    ld   ($8103),a             ; does nothing
  //006E: 3E 88       ld   a,$88
  //0070: 32 03 82    ld   ($8203),a             ; does nothing
  //0073: 3E 08       ld   a,$08
  //0075: 32 42 42    ld   ($4242),a             ; set IRQTRIGGER_CTRL
  //0078: 32 01 82    ld   ($8201),a             ; bit 3 = interrupt trigger on audio CPU
  
  rst10_memset ((void *)circ_cmd_queue, 0xff, sizeof(circ_cmd_queue));
  rst10_memset ((void *)circ_sound_cmd_queue, 0xff, sizeof(circ_sound_cmd_queue));
  circ_sound_cmd_queue_ptr = circ_sound_cmd_queue;
  circ_sound_cmd_queue_proc = circ_sound_cmd_queue;
  
  // kick watchdog
  // disable interrupts
  //00E0: 32 05 70    ld   ($7005),a             ; does nothing
  //00E3: 32 06 68    ld   ($6806),a             ; disable screen vertical flip
  //00E6: 32 07 68    ld   ($6807),a             ; disable screen horizontal flip
    
  circ_cmd_queue_ptr = circ_cmd_queue;
  circ_cmd_queue_proc = circ_cmd_queue;
  
  //00F0: 32 04 68    ld   ($6804),a             ; enable stars
  temp_char_ram_ptr = cram;
  temp_counter_4008 = 0x20;
  bonus_jet_for = 10;                           // 10,000 points (originally BCD)
  uint8_t in2 = 0;
  coinage_value = (in2>>1) & 0x03;
  is_cocktail = (in2>>3) & 0x01;
  uint8_t in1 = 0 & 0x03;
  if (in1 == 3)
    default_player_lives = 255;
  else
    default_player_lives = in1 + 3;
  disable_sound ();
  // protection stuff
  memset ((void *)&objram, 0, sizeof(objram));
  //; Fill screen with 8x8 white rectangles
  memset ((void *)cram, 0x3f, sizeof(cram));
}

I've included the original assembler as comments for any instructions whose purpose is questionable. Ditto for functionality I probably won't need to implement (such as screen flipping). There's a few of these in the start-up code, as you can see above, but I suspect there's very few throughout the remainder of the code.

From here-on in, there's going to be quite a few weeks of simply working my way through the code. I'll be ignoring any protection schemes, watchdogs, sound hardware etc.

Friday 9 April 2021

Looking like a dump!

I've now got the Scramble code reading a memory dump from MAME and rendering the tiles and sprites to faithfully recreate the display, with the correct colours. The tiles and sprites are blitted from bitmap sheets in memory, so a single call to Allegro is all that is required. It's also cool that the sprite transparency also 'just works' using Allegro.

[Actually I've just realised I'm yet to implement column scrolling at the pixel level (only tile level) - I'll have to work that out at some point, but it's not important now.]


Rendered from a memory dump from MAME

To be honest, I've spent just as much time battling Allegro as I have coding logic for the game itself. At times I've stared at a blank window for half an hour before randomly stumbling on the issue, and fixing it whilst still not understanding why. But understanding the nuances of Allegro isn't the point of this exercise, so I'm not going to dwell on it for any longer than absolutely necessary. Hopefully from here-on in, I'll only be using routines I've already got working.

One last thing I will note about Allegro; it doesn't support the concept of indexed colour modes (palettes). Apparently you can simulate it with shaders, but that's another area I have zero experience with. Instead, I created an array of tile and sprite sheets, one for each palette entry. That'll do for a prototype.

One last thing I'll probably do before diving into the transcode proper is rearrange the code to (asynchronously) refresh the display every 60Hz. That way I don't have to worry about display output as updates will periodically occur whenever the game core updates the video and sprite RAM contents.

Thursday 8 April 2021

Has got to be seen to be believed!

Years ago I wrote some C/Allegro code to rip the Galaxian graphics for my FPGA implementation. It displayed the graphics so I knew the format was correct, and output some VHDL source code for the palette logic and graphics ROM contents (pre-rotated for a horizontal display).

Today I took that code (Scramble graphics are exactly the same format), updated it for the new Allegro library, and modified it to produce C source code for palette and graphics data arrays in their simplest format (1 byte per pixel). This simplifies further conversion on any platform; for example the PC Scramble protoype will create Allegro tiles and sprites (bitmaps) on-the-fly from these arrays at start-up.

FWIW, the output looks like this...

// tile data
uint8_t tile[256][64] =
{
  // $00
  {
    0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x00, 0x00,     //    ###  
    0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x03, 0x00,     //   #  ## 
    0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x03, 0x03,     //  ##   ##
    0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x03, 0x03,     //  ##   ##
    0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x03, 0x03,     //  ##   ##
    0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x03, 0x00,     //   ##  # 
    0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x00, 0x00,     //    ###  
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     //         
  },
  // $01
  {
    0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00,     //     ##  
    0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x00, 0x00,     //    ###  
    0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00,     //     ##  
    0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00,     //     ##  
    0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00,     //     ##  
    0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00,     //     ##  
    0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,     //   ######
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     //         
  },

In the mean-time, I've got the Scramble program displaying the tiles and sprites using pixel-drawing primitives from the data arrays (palette #6).

Next task is to create the tiles and sprites ready for use by Allegro. Once that's done, I can get on with the task of the transcoding, and be able to quickly and easily see the results on the display.


Wednesday 7 April 2021

Scrambled Priorities

I know I should be finishing off projects but I just can't get into them right now. I need something new to pique my interest before I return to that stuff. So for now, I've decided to look at Scott Tunstell's Scramble source code and see if I can transcode it to C.

First hurdle is to clone a project that allows me to prototype this on a Windows platform. Previously I've used a very old version of the Allegro graphics library under an equally old version of MinGW. But each time I return to these old projects I can't manage to get a working combination of a command environment, MinGW compiler and Allegro library - and tonight was no exception. Complicating matters is having three different Windows machines that I routinely build these projects on.

After struggling for a couple of hours with a few different combinations of issues I decided to bite the bullet and upgrade to the latest MinGW-gcc and Allegro library. That also required CMake but installation of the toolchains and building of Allegro was fairly straightforward.

Next step was to hack an existing project (makefile etc) and get it building under the new tools - in this case Lode Runner. It required some jiggery pokery with invoking an MSYS2 shell as the makefile was not designed for a Windows command shell but I got there in the end. Hopefully I'll remember how to invoke it all next time; I've made some notes in the makefile!

Last task tonight was to get something building and running. Allegro has changed quite radically from the old libraries I was using, so I had to change every single line of code that called Allegro routines. But finally I now have a running executable.


In the past I've simply created a new C source file for the transcode. That was nice and neat but the most annoying process was finding the correct place in the file to add new data, routines etc (I wanted them in the same order as the original code). This time I'm trialling a new process; I've copied the original ASM source file and commented-out every single line. I plan to add the C code in-place, probably deleting the ASM code as routines have been completed and tested.

Next task is to read up more on the new Allegro and work out how to interleave the Scramble C code with the Allegro framework. Then I'll rip some tiles and sprites and dump some video memory from MAME and see if I can render the display accurately.