Tazz-Mania

developing/porting a new game or gaming framework? post in here!
User avatar
tricky
Posts: 7695
Joined: Tue Jun 21, 2011 9:25 am
Contact:

Re: Tazz-Mania

Post by tricky »

Bricks look good and that things in the top left is great :)
User avatar
cardboardguru
Posts: 239
Joined: Fri Mar 09, 2018 10:26 pm
Contact:

Re: Tazz-Mania

Post by cardboardguru »

Day 9 - Now You See 'Em...

Not a huge amount done today. I started moving the enemy sprites around, and immediately hit the problem that they are invisible when in the top half of the screen. I've hit the moving beam problem. Had to happen sooner or later.

So, this is the point at which I need to think about the order I draw things. At the moment I'm just doing the obvious game loop:

1) Wait for vSync.
2) Erase sprites.
3) Get keyboard input.
4) Do game logic.
5) Draw over any tiles that have changed.
6) Draw the sprites.

The first problem is I'm leaving a lot of time between erasing the sprites and drawing them again. And then there's the worse problem that I'm erasing the sprites at the top of the screen just before the raster paints them. So the revised plan is:

1) Wait for vSync.
2) Set a timer interrupt for when raster is on line 129
3) Get keyboard input
4) Do game logic. Keeping copy of old sprite coordinates for erasing.
5) Draw over changed tiles from scan line 128 to 255.
6) Erase any sprites that have their bottom line at >=128.
7) Draw any sprites that have their top line >= 128.
8 ) Wait for timer interrupt. (poll a flag set by the interrupt)
9) Draw over changed tiles from scan line <128.
10 Erase any sprites that have their bottom line at <128.
11) Draw any sprites that have their top line <128.

I think that should work. I might have to tweak the 128 up or down a bit. But it would be good not to because the scanning of the tiles will work better if it's two exact halves.

I haven't yet started on this. It's one for tomorrow.
User avatar
tricky
Posts: 7695
Joined: Tue Jun 21, 2011 9:25 am
Contact:

Re: Tazz-Mania

Post by tricky »

My centipede does this and my vertical scrolling demo/spy Hunter proof of concept solid the screen into four. Frogger draws things a row at a time, so let's the beam get to the middle of the screen and then just goes for it. Most of my other games have some elements that stay in a vertical part of the screen and can just have a few different times to wait for before drawing them. Astro blaster, rally-x and PAC man do their drawing while the beam is off screen. Asteroids tries to do most of its drawing off screen but as it moves one asteroid at a time, the flicker isn't too bad when it fails.
User avatar
Iapetus
Posts: 81
Joined: Wed Feb 12, 2014 1:08 pm
Contact:

Re: Tazz-Mania

Post by Iapetus »

cardboardguru wrote: Wed Mar 03, 2021 4:10 am Day 9 - Now You See 'Em...

Not a huge amount done today. I started moving the enemy sprites around, and immediately hit the problem that they are invisible when in the top half of the screen. I've hit the moving beam problem. Had to happen sooner or later.

So, this is the point at which I need to think about the order I draw things. At the moment I'm just doing the obvious game loop:

1) Wait for vSync.
2) Erase sprites.
3) Get keyboard input.
4) Do game logic.
5) Draw over any tiles that have changed.
6) Draw the sprites.

The first problem is I'm leaving a lot of time between erasing the sprites and drawing them again. And then there's the worse problem that I'm erasing the sprites at the top of the screen just before the raster paints them. So the revised plan is:

1) Wait for vSync.
2) Set a timer interrupt for when raster is on line 129
3) Get keyboard input
4) Do game logic. Keeping copy of old sprite coordinates for erasing.
5) Draw over changed tiles from scan line 128 to 255.
6) Erase any sprites that have their bottom line at >=128.
7) Draw any sprites that have their top line >= 128.
8 ) Wait for timer interrupt. (poll a flag set by the interrupt)
9) Draw over changed tiles from scan line <128.
10 Erase any sprites that have their bottom line at <128.
11) Draw any sprites that have their top line <128.

I think that should work. I might have to tweak the 128 up or down a bit. But it would be good not to because the scanning of the tiles will work better if it's two exact halves.

I haven't yet started on this. It's one for tomorrow.
This is all very interesting. Great job and I will be looking for your new implementation so I can learn from it :). If you are curious how I do stuff in my patolas game please check the game thread.
User avatar
cardboardguru
Posts: 239
Joined: Fri Mar 09, 2018 10:26 pm
Contact:

Re: Tazz-Mania

Post by cardboardguru »

Day 10 - Flicker Free

https://youtu.be/JbuaHIxje8s
Screenshot 2021-03-05 at 07.50.18.png
A couple of days off because I was feeling tired, then back to it yesterday. I implemented the plan for the new flicker free game loop. It was close to working. But not quite - the sprites disappeared near the middle line. It turned out I was overthinking it having different conditions for whether I was erasing or drawing.

The real situation is this. I have to draw the background tiles (the walls and the hoopers) before the erase and the sprite. for a particular part of the screen. The code will always draw the bottom half of the tilemap first, the the top half.

So first draw the bottom tilemap. Then erase and redraw any sprites for which BOTH erase and redraw rectangles are ENTIRELY in the bottom half of the screen. Then, once the raster has passed halfway, draw the top half of the tilemap, together with any sprite erasure and redraws that haven't been done yet, including those that overlap both areas.

It's now flicker free.

In full:
1) Wait for vSync.
2) Set a timer interrupt for when raster is on line 129
3) Get keyboard input
4) Do game logic. Keeping copy of old sprite coordinates for erasing.
5) Draw over changed tiles from scan line 128 to 255.
6) Erase any sprites that have their top line at >=128. (for both erasing and drawing)
7) Draw any sprites that have their top line >= 128. (same)
8 ) Wait for timer interrupt. (poll a flag set by the interrupt)
9) Draw over changed tiles from scan line <128.
10 Erase any sprites that have their top line at <128. (for both erasing and drawing)
11) Draw any sprites that have their top line <128. (same)

There's the occasional bug where not all of the player is erased. One to track down another day.

Also, it's going to take a fair bit of optimising to get another enemy sprite in. The Arcade game gets up to at least 6 enemies and loads of hoppers on higher screens. I can't see that happening.
User avatar
tricky
Posts: 7695
Joined: Tue Jun 21, 2011 9:25 am
Contact:

Re: Tazz-Mania

Post by tricky »

How long does it take to draw the enemy sprite?
Is it masked?
Could you get away with having red as colour 3 and ORing the outside of the sprite and just SToring the inside?
User avatar
Iapetus
Posts: 81
Joined: Wed Feb 12, 2014 1:08 pm
Contact:

Re: Tazz-Mania

Post by Iapetus »

cardboardguru wrote: Fri Mar 05, 2021 8:06 am Day 10 - Flicker Free
Congrats. :D
User avatar
cardboardguru
Posts: 239
Joined: Fri Mar 09, 2018 10:26 pm
Contact:

Re: Tazz-Mania

Post by cardboardguru »

tricky wrote: Fri Mar 05, 2021 1:11 pm How long does it take to draw the enemy sprite?
Is it masked?
It's a really good question Tricky, and I'm glad you asked, because you nudged me into timing them individually with palette changes.
Screenshot 2021-03-05 at 17.56.52.png
Yellow = Erase enemy 1 by plotting tiles.
Blue = Erase enemy 2 by plotting tiles.
1st Green = Erase player by drawing black.

Magenta = Draw Enemy 1, masked.
Cyan = Draw Enemy 2, masked.
2nd Green = Draw player with no masking.
tricky wrote: Fri Mar 05, 2021 1:11 pm Could you get away with having red as colour 3 and ORing the outside of the sprite and just SToring the inside?
Interesting idea. It would even stop the background coming through the black on the eyes and mouth. But the other enemies are very different designs. It's possible though. I could base redesigns of those enemies around the idea.

But I reckon there's a lot I can do before then. First is to get the advancing walls drawing quicker. If anything it going to cause me to drop a frame it's that. At the moment I'm just plotting tiles by their XY coordinates. Which involves lots of calculations and plotting 8 pixels wide when 4 would do. Instead I should do some code to quickly draw a full 4 pixel column from the tile data.

And there's the self-modifying code idea that you mentioned for sprite plotting.
Last edited by cardboardguru on Fri Mar 05, 2021 7:01 pm, edited 1 time in total.
User avatar
tricky
Posts: 7695
Joined: Tue Jun 21, 2011 9:25 am
Contact:

Re: Tazz-Mania

Post by tricky »

for drawing the columns you can:

Code: Select all

.lp
lda brick,y
sta wall0,x ; row0
sta wall1,x ; row1
sta wall2,x
sta wall3,x
sta wall4,x
...
dex
dey
bpl lp
If you have separate loops for left and right, you only need to start with the correct X to draw the column.
you could self mod lp+2 to select the correct part of the brick before the loop.

If you have the memory, you could do the same with the small sprites, but that would be more self modding, but probably faster overall. This is what I did with Phoenix and Astro Blaster, but with Centipede, it was overkill!
User avatar
cardboardguru
Posts: 239
Joined: Fri Mar 09, 2018 10:26 pm
Contact:

Re: Tazz-Mania

Post by cardboardguru »

Took me a moment to work out what you were doing with the code there, Tricky. But now I get it. That would be like greased lightning compared to what it's doing now!
User avatar
cardboardguru
Posts: 239
Joined: Fri Mar 09, 2018 10:26 pm
Contact:

Re: Tazz-Mania

Post by cardboardguru »

Another thought I just had is that I can probably write the enemy movement code to balance the number of sprites that are in the top and bottom area. Two of them could even swap sides, so long as they cross the line on the same frame.

Theoretically that would mean being able to double the number of enemy sprites whilst maintaining the same worst case scenario.
User avatar
cardboardguru
Posts: 239
Joined: Fri Mar 09, 2018 10:26 pm
Contact:

Re: Tazz-Mania

Post by cardboardguru »

Days 11, 12 & 13 - Baddies and bullets

Things are progressing.

1) I've done the faster wall drawing suggested by Tricky. Works well.
2) I've done the first level enemy movement. It'll probably need tweaking once the full game it working, but it looks good for now.
3) I've got the player shooting bullets. The bullets bounce off the walls.

I think I'm going to have Tazz shooting constantly whilst the baddies are on screen. That's pretty much how the game is played anyway, as there is no penalty to shooting. And if playing from the keyboard there's already 4 keys to use. Permanently bending another finger to keep the fire button pressed down as well seems a waste of time and a recipe for a sore finger.

In the arcade it was different as you had a joystick.

https://youtu.be/wHaSSbdaUNU
Screenshot 2021-03-09 at 22.51.41.png
User avatar
lovebug
Posts: 1739
Joined: Sun Jan 31, 2021 5:07 pm
Location: Magrathea
Contact:

Re: Tazz-Mania

Post by lovebug »

fantastic

its all looking great and working perfectly

and I love the particle effect when the player enters the game, nice
Image Image Image Image
User avatar
cardboardguru
Posts: 239
Joined: Fri Mar 09, 2018 10:26 pm
Contact:

Re: Tazz-Mania

Post by cardboardguru »

Thanks lovebug. Funnily enough the particle effect is unintended. At the moment Tazz shoots bullets all the time, and he does it in the direction the player lat move him. At the start of the level he hasn't been moved yet, so the bullets have no velocity and just stay where they are when they were emitted till their time is up.

It'd be nice to do something with actual particles sometime. I don't know that they'd yet come into vogue when BITD. I think maybe it was more of a 90s thing.
User avatar
lurkio
Posts: 4351
Joined: Wed Apr 10, 2013 12:30 am
Location: Doomawangara
Contact:

Re: Tazz-Mania

Post by lurkio »

Looking good!

:D =D> =D>
User avatar
leenew
Posts: 4900
Joined: Wed Jul 04, 2012 4:27 pm
Location: Doncaster, Yorkshire
Contact:

Re: Tazz-Mania

Post by leenew »

Excellent progress =D>

Lee.
User avatar
cardboardguru
Posts: 239
Joined: Fri Mar 09, 2018 10:26 pm
Contact:

Re: Tazz-Mania

Post by cardboardguru »

Thanks guys!
User avatar
cardboardguru
Posts: 239
Joined: Fri Mar 09, 2018 10:26 pm
Contact:

Re: Tazz-Mania

Post by cardboardguru »

Day 14 - Hoppers Are In Season

Now you can shoot the hoppers.

https://youtu.be/7pO5S_eGYE4
User avatar
cardboardguru
Posts: 239
Joined: Fri Mar 09, 2018 10:26 pm
Contact:

Re: Tazz-Mania

Post by cardboardguru »

Day 15 - I Gotta Get Out Of This Place

A bit more coding done.

Implemented shooting of the enemy sprites. And the explosion.

Up to now, sprites have all been paired up for preshifting. Sprite 0 is the player character. Sprite 1 is the player sprite 2 pixels to the right. So you ask for sprite 0 and you get wither sprite 0 or sprite 1 depending on the X coordinate. But this would be wasteful for the explosions, which don't move, and don't need positioning that exactly. So now sprite image numbers work as singles ordinarily, but if it 7 is set, they work in pairs with the preshifting.

The enemies also respawn after they have been shot. They do so in the opposite corner from where the player is.

Also when you've killed all the hoppers, the exits open. Although you can't actually get out yet. That's next. End of the level.

https://youtu.be/z9wJT-000NA
Screenshot 2021-03-16 at 06.27.03.png
User avatar
Arcadian
Site Admin
Posts: 4223
Joined: Fri Nov 24, 2000 12:16 pm
Contact:

Re: Tazz-Mania

Post by Arcadian »

Love the rapid progress you're making on this, look so good already!

At this rate you'll have it completed within a month! (That would be a true 80s games dev timeframe!)
Please subscribe to the ABug YouTube channel!
User avatar
cardboardguru
Posts: 239
Joined: Fri Mar 09, 2018 10:26 pm
Contact:

Re: Tazz-Mania

Post by cardboardguru »

Thanks guys. It's been about a month already in calendar time. But for the purposes of the day number I put here it's just days where I've actually done some work on the game.

My admiration for the guys that did this back in the 1980s only increases. We have the benefit of coding on Macs/PCs with hi-res screens, decent text editors, pixel art packages with mouse control, the wonderful Beebasm and so on. And access via the internet to answers to coding problems when we have them.

People who made games with nothing more than a Beeb, the assembler in BASIC, and sometimes only cassette for storage. I'm full of respect for them.
User avatar
cardboardguru
Posts: 239
Joined: Fri Mar 09, 2018 10:26 pm
Contact:

Re: Tazz-Mania

Post by cardboardguru »

Day 16 and 17 - Tazz and his Amazing Technicolor Text

I added some more text around the screen to make it look a bit more game like.

Then I worked on interrupt driven palette changes, so that I get an extra colour in. There's the fifth colour of Yellow for the scores.

Also the EXIT sign now pulses with colour changes. So that's now all 8 colours used. 6 of them at the same time.

https://youtu.be/1d85tGfTwKA
Screenshot 2021-03-18 at 21.34.52.png
Since I was doing multiple timers per frame, I figured now would be a good time to kick the OS out. This wasn't straightforward. Initially the game froze when I did this. I figured I should turn off the interrupt sources that I wasn't personally using.

Code: Select all

    LDA #&7F                            ; Disable all interrupt sources
    STA &FE4E
    STA &FE6E
    
    LDA #&82                            ; A=%100000010 (enable vsync interrupt)
    STA &FE4E                           ; set Interrupt enable register on System VIA

    LDA #&A0                            ; A=%10100000 (enable Timer 2 interrupt)
    STA &FE6E                           ; set Interrupt enable register on User VIA
After trying this, the game was still freezing. After much blindly cancelling of any and all interrupts the system was capable of sending, I narrowed it down to the VSync interrupt not being cleared after I caught it. Previously the OS had been clearing that down for me. This is the line that made it work for me again.

Code: Select all

    LDA &FE41                           ; Clear VSync interrupt
Loads of thanks to Kieran for his ABUG talks on Interrupts, and the demo code. It's entirely down to those sources that I've been able to do the interrupt magic.
Last edited by cardboardguru on Fri Mar 19, 2021 11:53 am, edited 1 time in total.
RobC
Posts: 3816
Joined: Sat Sep 01, 2007 10:41 pm
Contact:

Re: Tazz-Mania

Post by RobC »

Great stuff - looking really good =D>

And many thanks for the write up.
User avatar
tricky
Posts: 7695
Joined: Tue Jun 21, 2011 9:25 am
Contact:

Re: Tazz-Mania

Post by tricky »

It's really getting there now.
User avatar
cardboardguru
Posts: 239
Joined: Fri Mar 09, 2018 10:26 pm
Contact:

Re: Tazz-Mania

Post by cardboardguru »

Thanks for the encouragement guys. It really helps to keep motivation going!

I've knocked up a Mode 7 loading screen, for no better reason than games tend to have one, and I wasn't in the mood for programming tonight.

I have no knowledge of what best practice is for loading games, as I never had a disc drive BITD, so never explored game discs. I guess the big picture is to switch to mode 7, display the teletext image, load the main file as high in memory as Mode 7 allows to avoid the memory used by DFS, and then copy it to lower in memory to create the space for bitmapped graphics mode, stomping over the DFS memory.

So 3 files?
1) !Boot (possibly BASIC?) that loads...
2) File containing loading screen plus relocation routine. Loads from say &7B00-&7FFF. This loads main file, then relocates it.
3) Main file. Loads from ????-&7AFF. Then is relocated to ????-&3FFF (To avoid my 16kb screen mode).

Does that sound about right? Is it best practice? Is there some better way? Any thing that I've missed? What ???? to go down to? I've kicked the OS out, so I know I can go low.

Any sample code? This is one part of the game I don't feel any compelling need to write from scratch.

I may start at &E00 for now though, for no better reason than as a cassette user I'm comfortable with it. Then go lower if and when I run out of space.
P8FF-3F7F.png
Last edited by cardboardguru on Sat Mar 20, 2021 8:41 am, edited 2 times in total.
User avatar
0xC0DE
Posts: 1300
Joined: Tue Mar 19, 2019 7:52 pm
Location: The Netherlands
Contact:

Re: Tazz-Mania

Post by 0xC0DE »

Load main binary from &1F00 if you want to support as many systems as possible. Then relocate down as low as you want to go. I relocate straight to 0 because nothing of the MOS is used. Some precautions must be taken if you want to do that because a few memory locations (mere bytes) shouldn't be trampled even with the MOS out of the picture. Let me know if you need more information about that. Your approach sounds about right.
0xC0DE
"I program my home computer / Beam myself into the future"
:arrow: Follow me on Twitter
:arrow: Visit my YouTube channel featuring my games and demos for Acorn Electron and BBC Micro
User avatar
cardboardguru
Posts: 239
Joined: Fri Mar 09, 2018 10:26 pm
Contact:

Re: Tazz-Mania

Post by cardboardguru »

Thanks 0xCODE. I've got your slide about memory locations you use.
Screenshot 2021-03-11 at 19.24.42.png
Thing is, that's not quite the same thing. I'm thinking about a wholesale relocation of the main file down in memory. But presumably you wouldn't do that all the way down to 0, as doing so would write over these locations. From your slide, relocating down as low as &028A looks safe.

With the one exception of the RTI at &D00. What's that doing there??? I've got my own interrupt handler hanging off IRQ1V, and I don't return to MOS, I do my own RTI. So presumably that's not relevant to me?
User avatar
tricky
Posts: 7695
Joined: Tue Jun 21, 2011 9:25 am
Contact:

Re: Tazz-Mania

Post by tricky »

I do something similar, but the relocation code is at the very end of the main code and !BOOT is just *EXECed as there is no auto CHAIN"" option.
I think there is a machine code header, probably by JGH, that you can attach but I have never done it.

The end of my game looked like:

Code: Select all

sm_lo = 1 \\ lo byte of addr
sm_hi = 2 \\ hi byte of addr
sm_im = 1 \\ immediate value

.BEGIN

;; GAME CODE

.MAIN

lda #0 : ldx #1 : jsr OSBYTE ;; get OS/machine type
SEI : stx fx0_joy_none : ldx #&FF : txs ;; turn off all interrupts

LDX #pages
LDY #0
.loop
LDA BEGIN,y
STA &E00,y
INY
BNE loop
INC LOOP+sm_hi
INC LOOP+3+sm_hi
DEX
BNE loop

JMP &E00
I have just written this in the browser, so hope it is correct!

Now I compress the main game and then instead of copying it down, I decompress it to 0...
I put the move/decompress code at the end as you don't want to overwrite it with the compressed/high version or the decompressed/low version and it doesn't matter if it is at the end as it can stick into &4000 and will just get cleared later.
I compress it as the game+gfx sometimes won't fit with OS+BASIC+loader+game+MODE 7 screen and it loads faster (not really an issue with SD card solutions, but still nice for GOTEK and floppy). Pacman has a copy of the maze in the loader as there is no spare room to keep the gfx or code to draw it once in MODE 1ish.
My compressort (PC) and decompressor <80 bytes are available on here, but can easily be added later if required.
User avatar
0xC0DE
Posts: 1300
Joined: Tue Mar 19, 2019 7:52 pm
Location: The Netherlands
Contact:

Re: Tazz-Mania

Post by 0xC0DE »

It's exactly the same thing. Just make sure those "special" memory locations are filled with meaningful values in your main binary. In your loader (high up in memory): disable interrupts, relocate the whole thing to 0, enable interrupts, jump to your main binary. For example, in my main binary at offset &D00 there will always be an RTI.

But, to simplify. Just relocate down to &300 and be done with it. Then make sure at offset &A00 (&D00 after relocation down to &300) in your main binary there's an RTI and you're good to go.

That RTI is there to make sure an NMI doesn't mess things up. A non-maskable interrupt is hardcoded to jump to &D00. Would be very unfortunate if that was right in the middle of some random code other than an RTI :mrgreen:

Are you sure you're not using anything the system provides? Sound, for instance? If so, then staying at &E00 may be the safer option for you.
0xC0DE
"I program my home computer / Beam myself into the future"
:arrow: Follow me on Twitter
:arrow: Visit my YouTube channel featuring my games and demos for Acorn Electron and BBC Micro
Post Reply

Return to “new projects in development: games”