INTRODUCTION
We plan to recreate the game Klax written in Assembly for the final project with special sound effects as well as some slightly different modifications from the original Klax. One of the feature is as the player makes a klax, a picture of a female model will be pulled down little by little.
TEAM MEMBERS
GAME DESCRIPTIONS
The game compose of blocks falling down from a 5-lane conveyor. We will simulate the conveyor moving down by using the red strips (see picture) and w/ a variety of colors painted on it, after a unit of time the color of the current strip will be moving down to the next strip and the block will be moving down 1 unit (if there is a block there). The player's task is to catch all the blocks roling down (using a BlockHolder that acts similar to a stack) by moving left & right and either:
OVERALL DESIGN
Game compose of the following modules:
We will represent each lane of the conveyor as an array of size 9 and a FrontQueue pointer is initialized first at 0, so that after each unit of time, FrontQueue is decreased and eventually will be "wrapped around" when it reach 0
The BlockHolder behave as a stack, but we'll implement using an array with a BlockHoldertos variable to indicate the top of stack.
There are 5 BlockContainers each of which behaves just like a stack. The maximum allowed is 5 blocks per container. Similar to BlockHoldertos, we have 5 BlockContainertos to point to the top most available space for a block to throw down to.
Video Graphics
In order to reduce the screen flicker when we draw to the screen we will use double-buffering. After an entire image has been created, it will be quickly transferred directly to the screen by the ShowScreenBuffer routine. Because of double buffering, you will not see this image while it is being changed. To hold all the graphics for this project, the following segments have been defined:
Sound Effects
To load all the sound files neccessary for the project into a segment
Keyboard Control
This project uses the keyboard to control movement. To recognize keys that are pressed simultaneously, we need to replace the default keyboard handler with our own code. Our InstKey routine is called to install a new handler into the vector table. The DeInstallKey routine is used to remove it (and restore the DOS default routine).
Key presses affect special keyboard variables that we have define for this project. When a key is down, the appropriate keyboard variable is set to one. When the key is released, the same variable is then set back to zero.
Look-Up Tables
To optimize performance for the game engine, we define a few look-up
tables:
Lane1LocTab
Lane2LocTab
Lane3LocTab
Lane4LocTab
Lane5LocTab
All these lanes is of type LaneCell is defined as follow:
LaneCell STRUCT
LC_xPos ;is used to identify location where we put the block at. LC_yPos ;(same as xPos) LC_height ;Uses for scaling the image so when it is far away, you will see it smaller LC_widthLaneLocTabOffTable of offsets of 5 lane location tables
location ;where you can draw the bar and the block length ;the length of the barThis data structure is used to "fill out" the parameter of AnimationScalePicture.
SAO_xStart ; x-position of the starting point SAO_yStart ;y-position of the starting point SAO_xStop ;x-position of the destination point SAO_yStop ;y-position of the destination point SAO_srcSeg ;source segment SAO_srcOff ;source offset SAO_srcHeight ;the height of the source picture SAO_srcWidth ;the width of th source picture SAO_scaleHeight ;the height of the scale picture SAO_scaleWidth ;the width of the scale picture SAO_delayVal ;the delay constant used during animation SAO_crossBar ;used for whether running crossBarAnimation or not
; data structure for parameter of AnimationPicture
PictRec struct
xStart word ? ; x-position of the starting point
yStart word ? ; y-position of the starting point
xStop word ? ; x-position of the destination point
yStop word ? ; y-position of the destination point
srcSeg word ? ; source segment
srcOff word ? ; source offset
srcHeight word ? ; height of the source picture
srcWidth word ? ; width of th source picture
delayVal word ? ; delay constant used during animation
crossBar word ? ; including the invoke of
CrossBarAnimation ; crossBar = 0 : don't invoke
; 1 : invoke CrossBarAnimation
PictRec ends
ContainerCell is a STRUCT
CC_xPos ;the x-position of a block in a container on the screen CC_yPos ;the y-position of a block in a container on the screen CC_height ;the width of a block in a container CC_width ;the height of a block in a container The following Structure is used for sound: Sound STRUC SOffset dw ? SSegment dw ? SLength dw ? SWOffset dw ? SWSegment dw ? SFreq dw ?Container1LocTab to indicate where we would display the block given the Container1tos (see below for variable name)
Defined Variables
Constants:
MAXNUMOFBLOCKS EQU 9 ; define the maximum number of blocks on a lane
NUMBLOCKTYPE EQU 8 ; 7 different types of blocks
NUMBEROFBARS EQU 9 ; define number of bars
CONTAINERCAPACITY EQU 5 ; max. number of blocks can be contained
; in a container
BLOCKWIDTH EQU 40 ; 20x40 source block width
BLOCKHEIGHT EQU 20 ; 20x40 source block height
CONTAINERBLOCKWIDTH EQU 40 ; 8x40 container block
CONTAINERBLOCKHEIGHT EQU 8 ; 8x40 container block
MAXFREQUENCY EQU 4 ; maximum number of blocks allowed in BlockDispatcher
BLOCKHOLDER_YPOS EQU 99 ; default blockholder y-position
SRCBLOCKFRAME EQU 90*320 ; offset of block frame in ForeGround
STACKCAPACITY EQU 5 ; maximum number of blocks in BlockHolder
FRAMEBASEHEIGHT EQU 10 ; height of base of the frame in BlockHolder
BH_MAXHEIGHT EQU 30 ; maximum height of BlockHolder
MAX_DROP EQU 32 ; maximum number of drops
MAX_KLAXS EQU 64 ; maximum Klaxes
BONUS_SCORE EQU 13 ; score inceased at a time
Variables
Variables for Random procedure
RandVal dd 3
K1 dd 9301
K2 dd 49297
MaxValue dd 233280
Variables for BlockDispatcher
Check db 0
Lane db 0
BlockColor db 0
Lane1Freq db MAXFREQUENCY ;At most 5 blocks can come out
Lane2Freq db MAXFREQUENCY ;per given lane. Then no block will
come out
Lane3Freq db MAXFREQUENCY ;of that lane before all blocks come
out of
Lane4Freq db MAXFREQUENCY ;other lane.
Lane5Freq db MAXFREQUENCY
HiddenBlock dw 1
CountTrack dw 1
Variables for AnimateBlockHolder and ShowBlockHolder
BlockHolderPosition dw 2 ; current position of the BlockHolder in the BlockHolder
BlockHoldercurrentXPos db 60, 80, 100, 120, 140 ; for movement (left & right)
BlockHoldercurrentYPos db 25, 30, 35, 40, 45 ; for stack (BlockHolder)
BlockReleaseRate db 4 ; level 1
BlockHoldertos dw STACKCAPACITY ; top of the BlockHolder
stack
BlockHolder db STACKCAPACITY dup(0) ; stack of blocks which can be contained
; in BlockHolder
Direction dw 0 ; = 0 : mean BlockHolder should move left
; = 1 : mean BlockHolder should move right
Variables used for ShowIndicator
X-position table-lookup of indicator and BlockHolder
IndicatorLoc dw 34 ; loc 1
dw 34 + 40 ; loc 2
dw 34 + 2*40 ; loc 3
dw 34 + 3*40 ; loc 4
dw 34 + 4*40 ; loc 5
Variables used by ProcessTempBlockHolder
TempBlockHolder db 5 dup(0) ; temporary storage for the blocks
which
; are cleared from the lanes
Crucial variables for the Game Engine
KlaxsToGo dw MAX_KLAXS ; number of klaxs to go for all
levels
CurrentScore dw 0 ; current score of the user
sofar
NumberOfDrop dw MAX_DROP ; numbers of block allowed to be
droped for all levels
DropScore dw 0 ; used to increase NumberOfDrop
Frequency of BlockDispatcher for each level
BlockFrequency dw 250 ; level 1 (in second)
dw 200 ; level 2
dw 150 ; level 3
dw 100 ; level 4
dw 50 ; level 5
GameFrequency dw ? ; how fast the blocks are released on the lanes
CoolLevel1 dw 0 ; add sound effect "Cool"
PlayWave2
CoolLevel2 dw 0 ; sound effect "Wow"
PlayWave3
variables used for ShowScore, ShowWave
Itemp0 dw 0
Itemp1 dw 0
Itemp2 dw 0
Itemp3 dw 0
Itemp4 dw 0
Itemp5 dw 0
Itemp6 dw 0
Itemp7 dw 0
Itemp8 dw 0
Itemp9 dw 0
Score4 dw 0 ;Offsets of the source for each digit
Score3 dw 0
Score2 dw 0
Score1 dw 0
Score0 dw 0
liscale db 2
liscale2 dw 16
liscale3 dw 0
litemp1 dw 0
litemp2 dw 0
liscale22 dw 0
liscale23 dw 0
Container1: A 1-D array of size 5 that holds the blockPROCEDURES
ReadRandomSeed
Inputs : randfile
Output : None
Purpose: opens the random file and initialize the value of RandVal
CheckBonusPoint
Inputs : ax = number of blocks on a run
CurrentScore = current score of a player
Outputs: adds CurrentScore to 5 points if ax = 4 or 10 if ax = 5
Purpose: To check for bonus points (if any)
WriteRandomSeed
Inputs : RandVal
Outputs : random file
Purposes: save the RandVal to the random file
CheckNumberOfDrop
Inputs : NumberOfDrop and DropScore
Outputs : NumberOfDrop and DropScore
Purposes: increases NumberOfDrop (life time) as the player get the score 100
Gameover
Input : None
Outputs : Print the word "Game Over" on the screen when a player has failed to finish any of the five level
Purpose : When game is over, this function is called to display "Game Over" message.
Goodjob
Input : None
Output : Print the word "Good job!" on the screen when a player has finished all five levels
Purpose : Display a message when a player finish a level
CreateBlockHolderImage
Inputs : BlockHolderPosition = current position of BlockHolder
BlockHolder = stack containing the blocks
Outputs: ax = height of BlockHolder image
dx = scale of BlockHolder image
Purpose: creates the BlockHolder image in Foreground2 segment at offset 0
ShowBlockHolder
Inputs : BlockHolderPosition = current position of BlockHolder
Outputs: ScreenBuffer
Purpose: displays the BlockHolder
MoveBlockHolder
Inputs : BlockHolderPosition = current position of BlockHolder
Direction = 0: move left
= 1: move right
Output : BlockHolderPosition
Purpose: moves the BlockHolder and updates BlockHolderPosition accordingly
DrawVerticalStrip2
Inputs: Scale = height of the strip to be drawn
xScreen = x (middle) position of the strip
yScreen = y-position where the strip to be drawn
orgWidth = original width of the picture
orgHeight= original height of the picture
stripNum = the location of the strip in the picture
srcSeg = the segment that holds the picture
srcOff = The picture to take the strip from
destSeg = destination segment
Outputs: Places a picture strip into the destination segment
Purpose: Draws a picture strip scaled to the right length in the correct column
ShowScaleObject
Inputs: SCOPara = an scale object
Outputs: the specified destination segment
Purposes: load scale object with the scaled picture
ShowIndicator
Input: BlockHolderPosition where the indicator will be displayed, starting at X=34
Output:Show the indicator on the screen
Purpose: To display where the indicator is relative to the BlockHolder
ShowLifeleft
Input: NumberOfDrop, by default NumberOfDrop
Outout:ScreenBuffer
Purpose: display the Lifeleft meter on the screen
ShowKlaxleft
Input: KlaxsToGo the total number of klaxes in each level by default, KlaxsToGo=64
Output:ScreenBuffer
Purpose: show the Klax meter on the screen
ShowScore
Input: Currentscore: player's current score
Output:Update score on the screen
Purpose: To display score on the screen
ShowWave
Input: Wave
Output: Display wave number on the screen
Purpose: To display Wave number on the screen.
CleanUpContainers
Inputs : variables for containers
Outputs: updates variables for containers
Purposes: clean up the containers
CheckRightRun
Inputs: X = x-position
Y = y-position
Val = checking value
dx = 1: checking the run
0: negate the current value
Outputs: ax = length of the run sofar in the right direction
Purposes: returns the length of the run so that the caller can decide whether there is a collision.
CheckDownRun
Inputs: X = x-position
Y = y-position
Val = checking value
dx = 1: checking the run
0: negate the current value
Outputs: ax = length of the run sofar in the down direction
Purposes: returns the length of the run so that the caller can decide whether there is a collision.
CheckDiagonalRun1
Inputs: X = x-position
Y = y-position
Val = checking value
dx = 1: checking the run
0: negate the current value
Outputs: ax = length of the run sofar in the diagonal direction 1
Purposes: returns the length of the run so that the caller can decide whether there is a collision.
CheckDiagonalRun2
Inputs : X = x-position
Y = y-position
Val = checking value
dx = 1: checking the run
0: negate the current value
Outputs : ax = length of the run sofar in the diagonal direction 2
Purposes: returns the length of the run so that the caller can decide whether there is a collision.
ProcessContainers
Inputs : Containers, and KlaxsToGo
Outputs : modifies containers
Purposes: check the containers to see whether there is any Klax.
If yes, process these Klaxs, make collision effects,
and clean up the containers
LoadTempBlockHolder
Inputs: TempBlockHolder, Lanes, and LaneIndex
Outputs: update TempBlockHolder
Purpose: Uses for processing between the blocks out of queue and BlockHolder
ProcessTempBlockHolder
Inputs: TempBlockHolder, Lanes, and LaneIndex
Outputs: update TempBlockHolder
Purpose: Process those block holder on tempBlockholer
ThrowDown
Inputs : BlockHoldertos = top of the stack for BlockHolder
Container variables, tos of containers, BlockHolderPosition
Outputs: Containers, and BlockHolder
Purposes: updates BlockHolder and Containers
BlockDispatcher
Inputs : none
Outputs: randomly puts a block type to a randomly picked lane
Purpose: Generate a block w/ a color and a specified lane
Random
Inputs: randval - random seed
Outputs: AX - Random number between 0..2^16 - 1
Description: The random function is defined as below
R(1) = randval
R(i+1) = randval = (K1*R(i) + K2) % MaxValue
where K1 and K2 are some large prime constants
ShowBlocks
Inputs: LaneIndex
Outputs: none
Purposes: load the blocks in the lanes to ScreenBuffer
ShowABlock
Inputs: si = block index
Outputs: load a scaled block to the ScreenBuffer
Purposes: scan through all five lanes and display the block
on that lane if available
ShowCrossBar
Inputs: colorindex
Outputs: ScreenBuffer
Purpose: draws the cross bars
CrossBarAnimation
Inputs : colorindex = index of the color in ColorArray
Outputs: ScreenBuffer
Purposes: animate the cross bars in the screen by changing colorindex
and call ShowCrossBar
TransferSeg
Inputs : SourceSeg = source segment
DestSeg = destination segment
Outputs: transfer [SourceSeg:0] to [DestSeg:0]
AnimatePicture
Inputs: APPara record
Outputs: ScreenBuffer
Purposes: Animate a picture on the screen from (xStart, yStart) to
(xStop, yStop) specified in APPara
AnimateScalePicture
Inputs : ASPPara record
Outputs : ScreenBuffer
Purposes: Animate a scaled picture on the screen from (xStart, yStart)
to (xStop, yStop) specified in ASPPara
ShowContainers
Inputs : container variables
Output : load the ScreenBuffer with the blocks in the containers
SetupGameData
Inputs : File names for graphic, sound variables
Outputs : Foreground = load with the foreground graphic
Background = load with the background graphic
MainSound = load with the sound used by this game engine
Purposes: load graphic resources for Game Engine
ResetGameData
Input : None
Output : None
Purposes: reset Game data
UpdateScreen
Inputs: none
Outputs: update Screen
Purposes: update all the screen
LoadSound
Inputs:
ax - Segment were sound is te be held in memory.
di - Offset to memory location for sound storage.
cx - Length of sound to be loaded.
dx - Offset to string with filename.
Output:
Sound is loaded to memory
Purpose:
Load Sound to memeory
PlayWave
Inputs:
ax - Offset to WAVESOUND
dx - Variable WaveLENGTH
si - Offset of SOUND structure used by Digpak.
Output:
Plays the raw sound data blaster2.raw using the inputs below.
Purpose: To play sound with the specified wave
PlayWave2
Inputs:
ax - Offset to WAVESOUND2
dx - Variable Wave2LENGTH
si - Offset of SOUND structure used by Digpak.
Output:
Plays the raw sound data blaster2.raw using the inputs below.
Purpose: To play sound w/ the specified wave
PlayWave3
Inputs:
ax - Offset to WAVESOUND3
dx - Variable Wave3LENGTH
si - Offset of SOUND structure used by Digpak.
Output:
Plays the raw sound data blaster2.raw using the inputs below.
Purpose: To play sound w/ the specified wave
RegisterXMIDI
Input : None
Output : None
Purpose: Registers the selected XMIDI data and places it in
Midpak's internal buffer using the inputs below.
PlaySequence
Input : None
Output : None
Purpose: Plays the currently registered XMIDI data using
the inputs below.
StopMidi
Inputs : None
Output : Song stop playing
Purpose: Stops the play of the currently playing XMIDI data using
Midpak's function 705h on INT 66h.
PlayMidi1
Input : nothing
Output: Music is on
Purpose: play midi sound in midi segment
PlayMidi2
Input : nothing
Output: Music is on
Purpose: play midi sound in midi segment
PlayMidi3
Input : nothing
Output: Music is on
Purpose: play midi sound in midi segment
PlaySound
Input : none
Output : Sound on
Purpose: To play sound
MouseInt
Inputs : mouse interrupt
Output : none
DisplayTable
Purpose : Draw menu icons on the screen
Input : SrcSeg:word, SrcOff:word, YScreen:word, XScreen:word,
Row:word, Col:word
Output : On the screen
Game
Inputs: Wav = level of the game from the menu module
Outputs: none
Purpose: entry point of Game Engine module
Intro
Inputs : none
Outputs: none
Purpose: entry point of Introduction module
Menu
Inputs: none
Outputs: Wave = level which an user chooses
Purpose: entry point of Menu module
Comments & Suggestions: pv-pham@students.uiuc.edu