• entries
    222
  • comments
    608
  • views
    588399

Starting to look a bit like a game!

Sign in to follow this  

351 views


Jump straight in with the latest video (2.27AVI, MPEG-4)

Apologies for quality/wonkiness.

Well, we just had a weekend which meant I got a bit more time to spend on Fire Track (I have no social life whatsoever. Hooray).
Last time I showed you the simple scrolling level. There is now:

  • Player sprite.

  • Bullets being fired by the player.

  • Hit detection with the terrain below, swapping out hit blocks with "blown up" ground.

  • Support for collision detection with 1x1, 2x1 and 2x2 "buildings" on grid.

  • Eye-watering abuse of sine tables and vcount - yes, it's the pause screen.

  • Simple animated title screen to mimic the BBC Micro title screen.

  • 'Levels' table, telling the engine which landscape and palettes to use.

  • Sprite helper functions reset_sprites, any number of calls to draw_sprite or draw_large_sprite finished with finish_sprites to handle writing to the sprite table.

  • Four complete landscapes copied from the BBC Micro version, accomplished with a BBC Micro emulator, a tool to record an area of the screen to a GIF and a LOT of patience.

  • Yet another revision of the background tiles.

  • Upgraded support tools to allow for easy production of multiple level sets, minor bug fixes.

  • Minor bugfixes and one new awesome feature to Latenite Z80 editor.


Good grief, I need to get out more!
First of all, the NEW AWESOME feature to Latenite. Actually, it's not that awesome, but I like it.
Before, if you hit F5 or clicked 'Compile-[Target Platform]' it would compile the file open in the current tab. So, if you made a fix to scroll.asm you'd have to edit, swap to ftrack.z80, hit F5, swap back to scroll.asm and so on. URGH. Now, when you start a compile it goes through all the current loaded documents. If it encounters a file with the directive

;#latenite:main

in it it assumes that that is your main source file and compiles that instead. Much tab clicking has been reduced! The bug fixes were in the support tools (wlaerr.exe and tasmerr.exe) to fix some of the broken line number reporting.

The new tile set is this:


One day I'll get 'em right. [grin]

Anyhow, I thought I'd explain how Fire Track handles levels.

What you do is play through a number of zones. Each zone is made up of a couple (or more) levels. For most of the levels, they end with a large block of terrain that looks a bit like a snarling alien face.


Grrr. To move on to the next level, you must shoot out both eyes. (Of course, shoot all the other tiles around first to get more points). This same face loops around and around until you have shot out both eyes.

At the end of each zone you don't get the face at the end of the level, you instead get the starting platform again and as it approaches you get a sort of rising scale until you pass it when you get a 'waaaouwaaaouwaaaou' from the amazing square-wave sound chip and the name of the next zone. Rinse, lather, repeat.


The starting platform.


Now, it would be crazy to store hundreds of levels on such a low end platform. It would also be crazy to have very few levels. So... why not swap the palette around? Yeah, that'll convince 'em that it's actually a different level. Hmm, maybe not. Well.. swapping somes of the tiles around from time to time? You know that sort of big ring, swap that for the asterisk-shaped block. Or that doughnut-with-a-plus-sign-through-it, swap that for the weird pyramid. Hmm, maybe not. The still might notice. Ah, here is the best solution - as well as switch palettes and a few tiles, let's make the levels we've already seen go past a bit faster. They won't notice then, will they? Oh, as a final touch, in some levels make the player and enemy sprites white and magenta rather than red and yellow. GENIUS. [smile]

And so begins the tedious task of sitting through the BBC Micro game, noting which landscape, palette and tiles are in use. So far I have done four of the levels. My VB.NET editor dumps them out as .db lists for the assembler, but also as PNG files for the Ben. Here they are, GIFfed up and ready to go (note: they are very tall images, so make sure your browser doesn't scales them down too small to see!)

Level 1
Level 2
Level 3
Level 4

(Remember that we start from the bottom of the levels and move upwards). The original level designer(s) have 'hidden' a number of patterns in the levels - can you spot the question mark (easy), Pac-Man (complete with pips, a fruit and ghost), a hungry-looking snake or the sad face (easy)? Stay tuned for more Where's Wally-styled fun as some of the other levels have such gems as the number 42 made up out of question marks (someone liked Mr. Adams, I'm guessing), a stealth bomber and a Yin-Yang. I guess these little things make up for the RSI-inducing copying over and adapting from Beeb to Game Gear...

I am, at heart, a programmer so it is at this point that I need to muse on how I'm going to display the score on-screen. My idea was as follows:

Wait for vblank signal.
Jump screen scroll location to top-left of name table.
Write out a completely black palette apart from colour #15 (the last one) which is white.
Make sure that the score is displayed in the top-left of the name table (it is in the blank space to the left of the vertical scrolling block - see some of my earlier screenshots from the emulator).
Wait for the vertical line counter to hit a point 8 pixels down the visible screen.
Jump back the scrolling window to the "normal" position, write the normal full colour palette out.

This works fine... in an emulator. On hardware it ends up frying the name table, so the data gets garbled beyond all recognition. ARGH!
I've singled it down to aggressive reading of port $7E, the vertical line counter. However, my pause screen (which reads this port, uses it to look up a vertical shift from a sine table, sets the x-scroll from this value) is even more aggressive and works fine on hardware!
There seems to be a way to enable an interrupt to fire when the vertical line counter hits a particular line, but looking through documentation I have, I have found that information on this interrupt is:
  • Different in every document.

  • Confusingly phrased.

  • Not mentioned at all.

Oh dear. Commercial games use a similar trick (waiting for the vertical line counter to hit a certain point, then do crazy things with the scroll/palette) but I can't work out how to do it myself... [sad]
*shrugs*
I will keep you posted!
Sign in to follow this  


9 Comments


Recommended Comments

Good luck. Your journal has been awesome to date. As someone who's looking at consoles to play with (Dreamcast right now), the energy in your journal really resonates with me :)

Share this comment


Link to comment
Mmmm, as always, awesome post. Is there any chance you might write a set of tutorials on homebrew Game Gear development? I'd wub that [grin]

Share this comment


Link to comment
Wow how the fuck did I miss this Journal???

Z80 asm and game gear = teh winnar!

I tried making a gamegear emulator once, but the complete lack of decent docs, PD roms and the fact that I had no idea what I was doing caused me to stop working on it :(

Anyway I might try it again after my GBA emualtor and the planned GB one. The original GameBoy uses the Z80 too so I should be able to use the same core.

Share this comment


Link to comment
@evolutional: Thanks! Good luck with the DC. I understand it's a great platform to develop for.

@Hippo: Maybe yes, maybe no. *shrugs* Most of the hardware is pretty well documented, and I'm not about to write a Z80 ASM tutorial as that is a subject already done to death. [smile]

@Scet: Most of the existing emulators are quite glitchy. The current one I'm using, Emukon, is a debugging emulator but has a fair share of problems (holds the CPU usage at 100% all the time!) and, like all emulators, doesn't catch some things that will stop a game from running. I was under the impression that the Game Boy used a Sharp clone of the Z80, which didn't support the full featureset (block copy operations)?

Share this comment


Link to comment
Quote:

@Scet: Most of the existing emulators are quite glitchy. The current one I'm using, Emukon, is a debugging emulator but has a fair share of problems (holds the CPU usage at 100% all the time!) and, like all emulators, doesn't catch some things that will stop a game from running. I was under the impression that the Game Boy used a Sharp clone of the Z80, which didn't support the full featureset (block copy operations)?


You're right that most are fairly unstable. It's like they don't validate pointers because it's "optimized". For my GBA emulator I'd rather have it slow than crash all the time. Oh and it only uses 100% when in use, like any decent program should.

And you're right that the GB has some instructions removed:

Any command that uses the IX or IY registers.
All IN/OUT instructions.
All exchange instructions.
All commands prefixed by ED (except remapped RETI).
All conditional jumps/calls/rets on parity/overflow and sign

Share this comment


Link to comment
Quote:
Any command that uses the IX/IY registers.
I like those registers. [sad]
Quote:
All IN/OUT instructions.
What the... how on Earth do you communicate with the Gameboy hardware, then? Is everything directly memory mapped?
Quote:
All exchange instructions.
Gah, they're pretty useful. Especially if you can access interrupt mode 2, exchanging all registers for the shadow registers in a single instruction is very very nice.
Quote:
All commands prefixed by ED (except remapped RETI).
Not sure what this means...? Is that $ED, so RET ($C9) becomes $ED,$C9? Or would it be EDRET? In which case, that's the job of the assembler, not the CPU...
Quote:
All conditional jumps/calls/rets on parity/overflow and sign
Never used those, so nothing lost.
Good thing I'm not developing for the Gameboy, then! It'd drive me mad! Are some of these "removed" instructions replaced with others?

Share this comment


Link to comment
Quote:

What the... how on Earth do you communicate with the Gameboy hardware, then? Is everything directly memory mapped?


Yeah. All hardware has access to certain parts of the RAM. It's the same for the GBA.

Quote:

Not sure what this means...? Is that $ED, so RET ($C9) becomes $ED,$C9? Or would it be EDRET? In which case, that's the job of the assembler, not the CPU...


It refers to the opcode value. All the 16-bit opcodes with ED as the high byte are gone. (except RET which doesn't have the ED prefix)

Quote:

Are some of these "removed" instructions replaced with others?


Not really. These are the added instructions:

ADD SP,nn ;nn = signed byte
LDI (HL),A ;Write A to (HL) and increment HL
LDD (HL),A ;Write A to (HL) and decrement HL
LDI A,(HL) ;Write (HL) to A and increment HL
LDD A,(HL) ;Write (HL) to A and decrement HL
LD A,($FF00+nn)
LD A,($FF00+C)
LD ($FF00+nn),A
LD ($FF00+C),A
LD (nnnn),SP
LD HL,SP+nn ;nn = signed byte
STOP ;Stop processor & screen until button press
SWAP r ;Swap high & low nibbles of r

Share this comment


Link to comment
Quote:

It refers to the opcode value. All the 16-bit opcodes with ED as the high byte are gone. (except RET which doesn't have the ED prefix)
Sorry, I misread. I forgot you were talking about removed commands, and assumed you meant that all commands were now prefixed with ED, which confused me to say the least. I have obviously not woken up fully yet... [smile]
I guess sharing the RAM with the hardware makes a lot of sense - most of what I'm doing is writing large amounts of data through the VDP ports, and if the name table was actually held on RAM that I could address like any other bit of RAM then it would make things MUCH easier. Having to duplicate the name table in RAM and write to both every time I change the tile map is a bit of a pain...

Share this comment


Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now