Monkey Fighter Monkey Fighter
Games Help Help Search Search Shop Shop
Biker Babe from Barbados

Name: Biker Babe from Barbados
Author: Robert Walsh
Platform: Amiga
Language: M68000 Assembly
License: Free

Images

Opening Screen
Level One
Cemetary Level
Background Bitmap
Objects Bitmap

Source

Runtime Document
BikerBabe.s
Misc.i
ProPlay.i
Map.i
Back.i
Title.i
Sounds.i
Death.i
Babe.i
Death.i

Executable

Biker Babe


Pervert Blown Away!

Overview:

I wrote Biker Babe one weekend as a testament to senseless violence in video games. A friend helped by composing the complementary music and by drawing some of the graphics. The overall tone and artistic impression came out exactly as I wanted. Ironically, I now believe video game violence needs to be monitored to prevent the desensitization to humanity.


Game Design:

Biker Babe is a platform shooter with several levels. It is designed to be simple but absurd. To win, all you need to do is move Biker Babe to the far right end of each level while avoiding perverts, aliens, werewolves, and the typical male narcissist. The game is over when Biker Babe dies. That happens when she falls to an off screen location or gets way to close to an enemy.

Biker Babe A woman with a shotgun visually represents the playable character (Biker Babe). She has the ability to move left, right, jump or shoot and is affected by simulated gravity. Jumping is executed with a single button push. However, shooting requires two; the first cocks the gun and the second shoots. Animation is limited to a three-frame cycle for walking both right and left. Jumping requires one frame. Cocking the shotgun requires three-frames and halts player movement until complete.

There are several types of enemies. Each cycle through three frames of animation when walking and three addition frames are cycled when the enemy is blown apart. The first enemy (a pervert) only moves right and looks like an foul overweight male. In all, there are three left-only moving enemies. One looks innocent; but he is a pervert is disguise. Other enemies looks like a wizard and aliens. Each of the previously mentioned characters cannot junp. So, they drop of the screen when not supported by a platform. The werewolf is the exception. It is a left-only moving character. It is faster than the others and will jump when encountering the edge of a platform. The narcissist is the last character. It is left-only moving and fast. I can't recall if he jumps. Anyhow, all enemies are blown apart if hit by shot. After cycling the death animation, the enemies' image becomes part of the background. An enemy at that state cannot kill the player character.

There are multiple levels. The first looks like a park the second looks medieval. There is one that requires leaping through the trees to complete and another is an alien spaceship. They all look like a poorly drawn coloring book; takes the edge off the violence.

Mushroom The game utilizes Protracker mods for theme music and background music. A friend composed both of these awesome tracks. Thanks! The game wouldn't be the same without them!


Game Development:

The following is a detailed explanation of the key design choices I made while developing this game. The code snippets are taken from BikerBabe.s.

[deleted code...]

  lea backname,a1
  moveq #0,d0
  CALLEXEC OpenLibrary
  tst.l d0
  beq QUIT
  move.l  d0,_BackBase
  move.l  _BackBase,a6
  moveq #1,d0
  jsr -30(a6)
  tst.l d0
  bne QU
									

Games run best without the OS especially when the game reads and writes directly to the hardware devices. So, the OS is halted and a snapshot of the current state is recorded so it can be restored when the game exits. The BackStab library contains a routine to do this. So, let's use it!


[deleted code...]

SETUP move.w  #32,$DFF1
									

When coding a game, I prefer PAL over NTSC because it gives more clock cycles during the vertical blank period - err... I mean, PAL allows more pretty smooth moving graphics than NTSC.


[deleted code...]

MOVECOP lea CList1,a1
  move.l  a1,$DFF080
  move.w  #$FFFF,$DFF088
  move.w  #$83C0,$DFF0
									

I cool feature of the Amiga is writing custom code for the Copper chip. My Copper list is used to create the pretty blue shaded background. However, one might use it to trace the raster as it is drawn in real time!


[deleted code...]

MAIN  cmp.b #$45,Key
  beq QUIT
  cmp.w #195,BabeY
  bgt DEAD
  cmp.w #212,Distance
  bge S1ANIM
  jsr SHOOT
  jsr DOMAIN
  cmp.b #255,Help
  beq mn6
  cmp.w #18,PervA
  bge mn5
  move.w  PervX,d0
  move.w  PervY,d1
  sub.w BabeX,d0
  bpl mn1
  neg.w d0
mn1 sub.w BabeY,d1
  bpl mn2
  neg.w d1
mn2 add.w d0,d1
  cmp.w #12,d1
  ble TOUCH
mn5 cmp.w #18,BervA
  bge mn6
  move.w  BervX,d0
  move.w  BervY,d1
  sub.w BabeX,d0
  bpl mn3
  neg.w d0
mn3 sub.w BabeY,d1
  bpl mn4
  neg.w d1
mn4 add.w d0,d1
  cmp.w #12,d1
  ble TOUCH
mn6 jmp MA
									

This looks like a sloppy wrapper routine for the main routine, DOMAIN. This code iterates though all the possible ways which the game may end. End key pressed -Babe fell off screen - Level completed - Or, one of the two enemies got too close.


[deleted code...]

TOUCH move.w  #45,Count
  move.w  #3600,BabeD
  move.w  #36,BabeA
  move.w  #15,BabeS
t1  jsr DOMAIN
  sub.w #1,BabeS
  bpl t2
  move.w  #6,BabeS
  add.w #1800,BabeD
t2  sub.w #1,Count
  bpl

You were touched by a pervert and the end animation needs to play before the game over is displayed.


[deleted code...]

DEAD  cmp.w #9,Level
  bne de0
  cmp.w #200,Distance
  bge THE
									

We fell off the screen but if this is the last level and we are at the end, the game is won.


[deleted code...]

S1ANIM  add.w #1,Lev
									

The SxANIM routines are all in-game animation routines.


[deleted code...]

MVBACK  btst.b  #0,$DFF005
  beq MVBACK
mb0 cmp.b #$30,$DFF006
  bne mb0
  move.l  _BitMapY,d1
  move.l  _BitMapN,d0
  move.l  d1,_BitMapN
  move.l  d0,_BitMa
									

If you swap buffers while the CRT is drawing the screen, a noticable rift will appear in your game screen. So, we wait for the raster to reach the vertical blanking period (The time after the screen is drawn but before the next time it is drawn). Then, we swap buffers. This is an ideal time to begin writing to the alternate buffer because the display hardware isn't controlling the bus.


[deleted code...]

ADDMAP  move.w  #1,d1
ap1 move.l  a1,a3
  move.l  CurMap,a0
  lea BackMap,a4
  move.w  BMapOff,d7
  sub.w d1,d7
  cmp.w #13,d7
  bge ap5
  cmp.w #0,d7
  blt ap5
  move.w  Distance,d6
  move.w  BMapOff,d7
  sub.w d1,d7

ap3 lea 64(a3,d6),a3
  move.w  d7,d0
  mulu  #2304,d0
  lea 64(a3,d0),a3

  lsr.w #1,d6
  add.w d6,a0
  lsl.w #7,d7
  lea 64(a0,d7),a0

  moveq #0,d0
  move.b  (a0)+,d0
  divu  #20,d0
  swap  d0
  lsl.w #1,d0
  add.w d0,a4
  swap  d0
  mulu  #720,d0
  add.w d0,a4

  moveq #4,d5
  jsr BLTWAIT
  move.l  #$FFFFFFFF,$DFF044
  move.l  #$0026007E,$DFF064
  move.l  #$09F00000,$DFF040
ap4 move.l  a4,$DFF050
  move.l  a3,$DFF054
  move.w  #$0481,$DFF058
  add.l #30000,a3
  add.w #8000,a4
  jsr BLTWAIT
  dbf d5,ap4
ap5 dbf d1,ap1
  r
									

The background is rendered using the classic tile technique. That is, tiles are taken from a source bitmap (The GetMap - see background image) and placed in the background during game play. We know what tile goes where because a data array (the LevMap) stores the tile arrangement. The code near BLTxxx annotation sets up the blitter hardware for an asyncronous data movement.


[deleted code...]

CLEANUP move.l  _BitMapN,a5
  add.l #158000,a5
  move.l  (a5)+,a0
  jsr CLNDUDE

cu2 move.l  _BitMapN,a5
  add.l #160000,a5
cb2 move.l  (a5)+,a0
  jsr CLNDUDE

cb6 move.l  _BitMapN,a5
  add.l #156000,a5
  move.l  (a5),a0
  move.l  #0,(a5)+
  jsr CLNDUDE

cu8 move.l  _BitMapN,a5
  add.l #154000,a5
  move.l  (a5),a0
  move.l  #0,(a5
									

All moving characters are blits (as opposed to a sprite). So, we need to restore the background (which we saved previously) before we move the character. Sprites do not require these extra data movements but they have size, number, and color restrictions.


[deleted code...]

QUIT  tst.l _BackBase
  beq q1
  jsr mt_end
  move.l  _BackBase,a6
  jsr -36(a6)
q1  tst.l _BckGrnd1
  beq q2
  move.l  _BckGrnd1,a1
  move.l  #162000,d0
  CALLEXEC FreeMem
q2  tst.l _BckGrnd2
  beq q3
  move.l  _BckGrnd2,a1
  move.l  #162000,d0
  CALLEXEC FreeMem
q3  move.l  #0,d0
  r
									

Oh yeah, before halting the OS, we did request the memory we needed for the game. This prevents writing over data currently used by the OS which would prevent the OS from properly restarting. So, the memory is freed before the program is exits.


[deleted code...]

CList1  dc.w  $102,$0000
  dc.w  $E0,$0000
  dc.w  $E2,$0000
  dc.w  $E4,$0000
  dc.w  $E6,$0000
  dc.w  $E8,$0000
  dc.w  $EA,$0000
  dc.w  $EC,$0000
  dc.w  $EE,$0000
  dc.w  $F0,$0000
  dc.w  $F2,$0000
  dc.w  $FFFF,$FFFE
  dc.w  $1001,$FF00
  dc.w  $180,$000F
  dc.w  $2001,$FF00
  dc.w  $180,$000E
  dc.w  $3001,$FF00
  dc.w  $180,$000D
  dc.w  $4001,$FF00
  dc.w  $180,$000C
  dc.w  $5001,$FF00
  dc.w  $180,$000B
  dc.w  $6001,$FF00
  dc.w  $180,$000A
  dc.w  $7001,$FF00
  dc.w  $180,$0009
  dc.w  $8001,$FF00
  dc.w  $180,$0008
  dc.w  $9001,$FF00
  dc.w  $180,$0007
  dc.w  $A001,$FF00
  dc.w  $180,$0006
  dc.w  $B001,$FF00
  dc.w  $180,$0005
  dc.w  $C001,$FF00
  dc.w  $180,$0004
  dc.w  $D001,$FF00
  dc.w  $180,$0003
  dc.w  $E001,$FF00
  dc.w  $180,$0002
  dc.w  $F001,$FF00
  dc.w  $180,$0001
  dc.w  $FF01,$FF00
  dc.w  $180,$0000
  dc.w  $FFFF,$FF
									

This is the copper list. It is a program executable by the copper chip. This is clearly one of the coolest features of the Amiga. This is what makes midscreen resolution/palette changes possible.


Copyright ©2005, Robert Walsh, All Rights reserved.