S i m o n Sphere Homepage

over 5000 lines of original assembly

Ben Nick : Team Leader, 3d Graphics

Paul Pawola : Game Logic, Random Functions, Integration

Drew Roedersheimer : Sound Designer

Paul Whitaker : Mouse Interface, Fading Effects

Introduction


The classic game of Simon takes on a new twist: Instead of matching four colors flashed on a 2D board, match 8 colors on a rotating sphere. The object is to mimic the computers randomized color sequences for as long as possible. With five difficulty settings and adjustable delay constants, this task is as easy or hard as you can make it.

Implementation

	The game starts with an animated introduction sequence followed
by a menu screen which lets the player choose from the following
options:  Intro, Options Menu, See Instructions, Play Simon, Quit.
In the options menu the player will be able to customize game play by
setting soundscape offsets, delay constants, irq setting and difficulty
ratings.  The intruction menu will explain the basic rules, objectives and
controls.  Game play gets interesting.  Based on the difficulty level
selected, the computer adds random characters (corresponding to the colors
on the simonsphere) to an array, one at a time. Then it proceeds to 
demostrate the sequence on the rotating sphere.  The player mimics the
sequence by right clicking to rotate the sphere and left clicking to
select the correct color. If the selected color matches the one in the
array the play is successful, and the computer adds another random color
the array and demonstrates the sequence once again. After a set number of
colors are repeated successful the player "levels-up" and delay counters
are decremented and the color sequences maximium length grows.   
Once the player makes a mistake, it is all over. A fitting losing
animation happens and the player is sent to the menu screen.

Challenges

The main challenge is rendering a convincing rotating sphere in realtime.
this is accomplished in three stages.  
Zero: a VGA pallet with eight shades of thirty-one colors is put into menu
	in such a way so that increasing a colors brightness is a matter 
	of adding eight to its color value.
One: an array of eight bytes keeps track of the orientation of the colors
	on our Sphere.
Two: A 256x256 lookup table with indexs to colors stored in the
	orientation table is stored in the SphSeg.
Three: The fisheye function takes a 128x128 segment from the SphSeg,
	passes it through a sphical lense via look up table in
	MSKseg (making a square peg fit in a round hole) and displays it
	in the screen buffer.  
Four: A masking function, with data stored in MSKseg. Applies a
	spherical gradient to the data in the memory buffer,
	brightening section of the sphere giving it a 3d look.
Five: display with screen buffer with fast graphics

Displaying a rotating sphere is only a matter of calling the previous
function in a loop, and incrementing the coordinates of the 128x128 sphere 
data taken from the 256x256 lookup table in the SPHSEG.

Game Logic is also and issue:
	The computer chooses from 16 random number seeds when play is
started to generate the random numbers needed for the array.  I chooses
them by polling the dos function, so the sequence is dependent on time.

Variables

newlevel db 'grphx/newlevel.pcx', 0    ;pcx file for new level

WinBackPCX db 'grphx/youwin.pcx', 0


simon_color_seq db 100 dup(0)          ;array for color sequence

game_level_initial db 1,2,3,4,5,8      ;table for initial number of moves
per tier

game_level_increment db 1,1,1,2,2,4    ;table for increment of moves,
tiers

game_level_start db 4,6,8,10,13,16     ;initial number of tiers per level

game_level_tab db 6,9,12,18,23,40      ;max number of tiers per game

tier_moves dw ?                        ;the current number of moves on
tier

level_tiers_max dw ?                   ;the max # of tiers for level

game_level_max dw ?                    ;max number of levels per game

Sphere_delayC dw 20000                 ;computer demo delay


rotateflag dw 0                        ;0 means no rotate, 1-4 is
direction
                                       ;1=up, 2=right, 3=down, 4=left

highlightflag db 0                     ;0 means no highlight, else 1-8 is 
                                       ;color to highlight 

rippos dw 16448                        ;position to take from lookup table

destpos dw 11235                       ;place to put sphere on screen
(upper left corner)

orientation db 0,1,2,3,4,5,6,7,8 ;(0=no position, 1-4 front, 5-8 back)
                                         ;1=up left, 2=up right, 3=lo
right, 4=lo left
                                         ;5=back up right, 6=back up left,
7=back lo left, 8=back lo right

reset_orien db 0,1,2,3,4,5,6,7,8       ;original orientation of sphere


lookuppos db 0, 6, 7, 0, 6, 1, 4, 7, 5, 2, 3, 8, 0, 5, 8, 0  ;look up init
data

adradius dw ?                                    ;adjusted radius, used by
calc_circle
grradius dw ?                                    ;used by calc_circle
radiussquared dw ?                               ;used by calc_circle
gcolor dw ?                                      ;used by calc_circle
valid dw ?                                       ;look up init data
maskcheck dw ?                                   ;used by backup_calc   
inputx dw ?                                      ;used by FPU operation
initsphseg_calc
testrad dw ?                                     ;backup_calc and
circle_calc
inputy dw ?                            ;interface with FPU functions
outputx dw ?                           ;interface with FPU functions
outputy dw ?                           ;interface with FPU functions
piconstant real4 0.024543692606        ;interface with FPU functions
temp real4 ?                                     ;interface with FPU
isinpy real4 ?                                   ;interface with FPU
isinpx real4 ?                                   ;interface with FPU
maindiv real4 ?                                  ;interface with FPU
sixtyfour dw 64                                  ;interface with FPU
one       dw 1                                   ;interface with FPU
two       dw 2                                   ;interface with FPU

LosePCX db 'grphx/lose.pcx', 0
LosePCX1 db 'grphx/grave1.pcx', 0      ;you lose picture #1
LosePCX2 db 'grphx/grave2.pcx', 0      ;you lose picture #2
WinPCX1 db 'grphx/smiley1.pcx', 0      ;you win images used to create
smile
WinPCX2 db 'grphx/smiley2.pcx', 0
WinPCX3 db 'grphx/smiley3.pcx', 0
WinPCX4 db 'grphx/smiley4.pcx', 0
WinPCX5 db 'grphx/smiley5.pcx', 0
WinPCX6 db 'grphx/smiley6.pcx', 0
WinPCX7 db 'grphx/smiley7.pcx', 0
WinPCX8 db 'grphx/smiley8.pcx', 0

LeftButton  dw 0        ; 1 if pressed
RightButton dw 0

AbsoluteX   dw 0        ; actual screen coordinates
AbsoluteY   dw 0

RelativeX   dw 0        ; relative to CenterX and CenterY
RelativeY   dw 0

XMinusWidth     dw 0    ;used by mouse functions
YMinusHeight    dw 0

RotateDir   dw NoDir    ;direction to rotate sphere

ColorSelected dw 0  ;color choosen by player

ReturnToMenu dw 0   ;return to menu flag

menuaction      dw 0    ;option choosen in main menu

oldv      dd   ?   ; Old vector (far pointer to old interrupt function)

opt_chosen dw 0     ;used by options screen to animate bars 
opt_delta  dw 0
            ;options variables
difficulty      dw 1    ; 0 to 5
sound_scheme    dw 1    ; 0 to 3
cursor_type     dw 1    ; 0 to 2
game_speed      dw 3    ; 0 to 5

IntroPCX  db 'grphx/intro.pcx', 0   ;address of intro pcx
ShadePCX  db 'grphx/shading.pcx', 0    ;address of shading pcx
Instr1A   db 'grphx/instr1a.pcx', 0    ;instrucitons pcx's
Instr1B   db 'grphx/instr1b.pcx', 0
Instr1C   db 'grphx/instr1c.pcx', 0
Instr1D   db 'grphx/instr1d.pcx', 0
Instr2   db 'grphx/instr2.pcx', 0
Instr3   db 'grphx/instr3.pcx', 0
Instr4   db 'grphx/instr4.pcx', 0
Instr5   db 'grphx/instr5.pcx', 0
Credits1 db 'grphx/rotcred.pcx', 0            ;credits pcx's
Credits2 db 'grphx/quescred.pcx', 0
Credits3 db 'grphx/goodcred.pcx', 0
Credits4 db 'grphx/yellback.pcx', 0
Credits5 db 'grphx/regcred.pcx', 0

MenuPCX   db 'grphx/mainmenu.pcx', 0   ;address of main menu pcx

OptionPCX db 'grphx/options.pcx', 0    ;address of option menu pcx

StaticPCX db 'grphx/static2.pcx', 0     ;address of the game play pcx

amount_bar_change dw 24, 40, 60, 24    ;array of amount bar has to change

current_bar_level dw 24, 40, 60, 72    ;array of current bar positions
                                        ;array of starting bar locations
start_bar_val dw 17410, 27330, 44290, 54210

bar_color db 3                         ;bar color

draw_bar_color db ?                    ;color to draw bar

bar_count dw ?                         ;count to animate bar

var_x     dw ?                         ;x value of current bar animation
    
LetterToShow    dw      0       ;used for intro
LastWritten     dw      0
LastOverwritten dw      0

FadeSpeed dw    6           ;delay constants
ScrollSpeed dw  3

DelayC    dw   80           
ModDelayC dw   0AFFFh

LetterX   dw   60, 100, 140, 180, 220, 40, 80, 120, 160, 200, 240 ;intro
letter locations
LetterY   dw   50, 50, 50, 50, 50, 110, 110, 110, 110, 110, 110 


max_rand_val    dw 10                   ; maximum random number

small_rand_val  dw ?                   ; random value in range
(0..max_rand_val)

rand_value dw ?                        ;previous random number

rand_seed1 dw ?                        ;random seed 1

rand_seed2 dw ?                        ;random seed 2

randcall db 0                          ;flag for first random call

seed_array1 dw 13757, 14011, 14177, 14369  ;array of possible random seed1
            dw 14551, 13009, 15017, 13259
            dw 15149, 13597, 11411, 12823
            dw 10993, 9511, 9349, 13109
            dw 13879, 10607, 11633, 15401
            dw 9001, 11117, 13883, 10909
            dw 15307, 9413, 12829, 9007
            dw 12781, 9787, 12001, 15001


seed_array2 dw 13879, 14851, 15307, 12781  ;array of possible random seed2
            dw 10607, 11117, 9413, 9787
            dw 11633, 13883, 12829, 15551
            dw 15401, 10909, 9007, 8999
            dw 13109, 12823, 13259, 9007
            dw 9349, 11411, 15017, 14177
            dw 9511, 13597, 13009, 14011
            dw 10993, 15149, 14551, 13757

rand_ini_tab dw 1, 3, 5, 7              ;table to find initial value
             dw 2, 4, 6, 8
             dw 4, 7, 2, 5
             dw 8, 1, 3, 6
             dw 1, 2, 3, 7
             dw 4, 5, 6, 8
             dw 1, 4, 2, 6
             dw 3, 8, 7, 5

Cursor1 dw 1111111111111111b    ; begin screen mask
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b    ; end screen mask

        dw 0000000000000000b    ; begin cursor mask
        dw 0000011111000000b
        dw 0001100000110000b
        dw 0010000000001000b
        dw 0100000000000100b
        dw 0100010001000100b
        dw 1000010001000010b
        dw 1000000000000010b
        dw 1000000100000010b
        dw 1000000000000010b
        dw 1001000000010010b
        dw 0100100000100100b
        dw 0100011111000100b
        dw 0010000000001000b
        dw 0001100000110000b
        dw 0000011111000000b    ; end cursor mask

Smiley  dw 1111111111111111b    ; begin screen mask
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b    ; end screen mask

        dw 0000000000000000b    ; begin cursor mask
        dw 0000011111000000b
        dw 0001100000110000b
        dw 0010000000001000b
        dw 0100000000000100b
        dw 0100010001000100b
        dw 1000010001000010b
        dw 1000000000000010b
        dw 1000000100000010b
        dw 1000000000000010b
        dw 1001000000010010b
        dw 0100100000100100b
        dw 0100011111000100b
        dw 0010000000001000b
        dw 0001100000110000b
        dw 0000011111000000b    ; end cursor mask


Spiral  dw 1111111111111111b    ; begin screen mask
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b    ; end screen mask

        dw 0000000000000000b    ; begin cursor mask
        dw 0010000000000000b
        dw 0111000000000000b
        dw 1111100000000000b
        dw 0010001111110000b
        dw 0010010000001000b
        dw 0010100111100100b
        dw 0010101000010010b
        dw 0010101011001010b
        dw 0010101000101010b
        dw 0010100111001010b
        dw 0010010000010010b
        dw 0001001111100100b
        dw 0000100000001000b
        dw 0000011111110000b
        dw 0000000000000000b    ; end cursor mask


Spiral5 dw 1111111111111111b    ; begin screen mask
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b    ; end screen mask

        dw 0000000000000000b    ; begin cursor mask
        dw 0010000000000000b
        dw 0111000000000000b
        dw 1111100000000000b
        dw 0010001111100000b
        dw 0010010000010000b
        dw 0010100111001000b
        dw 0010101000100100b
        dw 0010101010010100b
        dw 0010101001010100b
        dw 0010100110010100b
        dw 0010010000100100b
        dw 0001001111001000b
        dw 0000100000010000b
        dw 0000011111100000b
        dw 0000000000000000b    ; end cursor mask


Spiral4 dw 1111111111111111b    ; begin screen mask
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b    ; end screen mask

        dw 0000000000000000b    ; begin cursor mask
        dw 0010000000000000b
        dw 0111000000000000b
        dw 1111100000000000b
        dw 0010001111110000b
        dw 0010010000001000b
        dw 0010100111100100b
        dw 0010101000010100b
        dw 0010101011010100b
        dw 0010101001010100b
        dw 0010100110010100b
        dw 0010010000100100b
        dw 0001001111001000b
        dw 0000100000010000b
        dw 0000011111100000b
        dw 0000000000000000b    ; end cursor mask


Spiral3 dw 1111111111111111b    ; begin screen mask
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b    ; end screen mask

        dw 0000000000000000b    ; begin cursor mask
        dw 0010000000000000b
        dw 0111000000000000b
        dw 1111101111100000b
        dw 0010010000010000b
        dw 0010100111001000b
        dw 0010101000100100b
        dw 0010101010010100b
        dw 0010101011010100b
        dw 0010101001010100b
        dw 0010100110010100b
        dw 0010010000100100b
        dw 0001001111001000b
        dw 0000100000010000b
        dw 0000011111100000b
        dw 0000000000000000b    ; end cursor mask


Spiral2 dw 1111111111111111b    ; begin screen mask
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b    ; end screen mask

        dw 1110111111110000b    ; begin cursor mask
        dw 1101000000001000b
        dw 1010011111100100b
        dw 0000100000010010b
        dw 0001001111001001b
        dw 0010010000100101b
        dw 0010100110010101b
        dw 0010101001010101b
        dw 0010101000010101b
        dw 0010101000100101b
        dw 0010100111001001b
        dw 0010010000010010b
        dw 0001001111100100b
        dw 0000100000001000b
        dw 0000011111110000b
        dw 0000000000000000b    ; end cursor mask

Spiral1 dw 1111111111111111b    ; begin screen mask
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b    ; end screen mask

        dw 1110000000000000b    ; begin cursor mask
        dw 1100000000000000b
        dw 1010111111111100b
        dw 0010100000000100b
        dw 0010101111110100b
        dw 0010101000010100b
        dw 0010101011010100b
        dw 0010101001010100b
        dw 0010101001010100b
        dw 0010101111010100b
        dw 0010100000010100b
        dw 0010111111110100b
        dw 0010000000000100b
        dw 0011111111111100b
        dw 0000000000000000b
        dw 0000000000000000b    ; end cursor mask

CrossHr dw 1111111111111111b    ; begin screen mask
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b    ; end screen mask

        dw 0000000000000000b    ; begin cursor mask
        dw 0000000110000000b
        dw 0000000110000000b
        dw 0000000110000000b
        dw 0000000110000000b
        dw 0000011111100000b
        dw 0000010000100000b
        dw 0111110110111110b
        dw 0111110110111110b
        dw 0000010000100000b
        dw 0000011111100000b
        dw 0000000110000000b
        dw 0000000110000000b
        dw 0000000110000000b
        dw 0000000110000000b
        dw 0000000000000000b    ; end cursor mask

NoCurs  dw 1111111111111111b    ; begin screen mask
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b    ; end screen mask

        dw 0000000000000000b    ; begin cursor mask
        dw 0000000000000000b
        dw 0000000000000000b
        dw 0000000000000000b
        dw 0000000000000000b
        dw 0000000000000000b
        dw 0000000000000000b
        dw 0000000000000000b
        dw 0000000000000000b
        dw 0000000000000000b
        dw 0000000000000000b
        dw 0000000000000000b
        dw 0000000000000000b
        dw 0000000000000000b
        dw 0000000000000000b
        dw 0000000000000000b    ; end cursor mask


Cursor5 dw 0000011111100000b    ; begin screen mask
        dw 0111001111001110b
        dw 0111100110011110b
        dw 0111110000111110b
        dw 0011111001111100b
        dw 1001111111111001b
        dw 1100111111110011b
        dw 1110011111100111b
        dw 1110011111100111b
        dw 1100111111110011b
        dw 1001111111111001b
        dw 0011111001111100b
        dw 0111110000111110b
        dw 0111100110011110b
        dw 0111001111001110b
        dw 0000011111100000b    ; end screen mask

        dw 0000000000000000b    ; begin cursor mask
        dw 0111000000001110b
        dw 0111100000011110b
        dw 0111110000111110b
        dw 0011111001111100b
        dw 0001111111111000b
        dw 0000111111110000b
        dw 0000011111100000b
        dw 0000011111100000b
        dw 0000111111110000b
        dw 0001111111111000b
	
        dw 0011111001111100b
        dw 0111110000111110b
        dw 0111100000011110b
        dw 0111000000001110b
        dw 0000000000000000b    ; end cursor mask

Cursor4 dw 1111111111111111b    ; begin screen mask
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b    ; end screen mask

        dw 1110000000000111b    ; begin cursor mask
        dw 1111000000001111b
        dw 1111100000011111b
        dw 0111110000111110b
        dw 0011111001111100b
        dw 0001111111111000b
        dw 0000111111110000b
        dw 0000011111100000b
        dw 0000011111100000b
        dw 0000111111110000b
        dw 0001111111111000b
        dw 0011111001111100b
        dw 0111110000111110b
        dw 1111100000011111b
        dw 1111000000001111b
        dw 1110000000000111b    ; end cursor mask

Cursor2 dw 1111111111111111b    ; begin screen mask
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 0000000000000000b
        dw 0000000000000000b
        dw 0000000000000000b
        dw 0000000000000000b
        dw 0000000000000000b
        dw 0000000000000000b
        dw 0000000000000000b
        dw 0000000000000000b    ; end screen mask

        dw 1111111100000000b    ; begin cursor mask
        dw 1111111100000000b
        dw 1111111100000000b
        dw 1111111100000000b
        dw 1111111100000000b
        dw 1111111100000000b
        dw 1111111100000000b
        dw 1111111100000000b
        dw 1111111100000000b
        dw 1111111100000000b
        dw 1111111100000000b
        dw 1111111100000000b
        dw 1111111100000000b
        dw 1111111100000000b
        dw 1111111100000000b
        dw 1111111100000000b    ; end cursor mask


Cursor3 dw 0000000000000000b    ; begin screen mask
        dw 0000000000000000b
        dw 0000000000000000b
        dw 0000000000000000b
        dw 0000000000000000b
        dw 0000000000000000b
        dw 0000000000000000b
        dw 0000000000000000b
        dw 0000000000000000b
        dw 0000000000000000b
        dw 0000000000000000b
        dw 0000000000000000b
        dw 0000000000000000b
        dw 0000000000000000b
        dw 0000000000000000b
        dw 0000000000000000b    ; end screen mask

        dw 1111111111111111b    ; begin cursor mask
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b
        dw 1111111111111111b    ; end cursor mask


Procedures

----------------------------------
gameplay.asm -- PAUL PAWOLA

Function : PlayGame
Inputs   : Difficulty - the game difficulty
           StaticPCX - the game play background pcx
           Orientation - the current orientation of the sphere
           ColorSelected - the color selected by player (from mouse
control)
           Sound - which sound to play (goes to PlaySound)
           HighlightFlag - which color to highlight
           Sphere_DelayC - the delay constant used
Outputs  : none
What it does  : this function is the actual game play of SimonSphere.
Initials the playing screen, sets up the random sequence, the traverses
through the sequence, first showing the player the sequence, then
resetting the sphere, and keeping track of the players moves.  If the
player correctly matches the sequence, PlayGame displays the sequence
again, only with more colors added.  The player must again match.  If 
the player finished a level, PlayGame shows the newlevel PCX, and resets
the sequence.  If the player wins the game, YouWin is called, and if the
player misses the color, YouLose is called.                 
What it calls : YouWin - the winning sequence
                YouLose - the losing sequence
                BuildSequence - builds random sequence
                SphereGameDelay - delay between colors shown
                SelectDelay - how long a color is highlighted
                DrawSphere - draws the sphere
                ResetSPhere - resets sphere and playing area
                LoadPallet - initializes game pallet
                InitLookup - initializes sphere lookup table
                RotateSphere - rotates sphere
                FadeOut - fades out of scene
                Play(midi song) - plays various midis
                StopMidi - stops midi
                MouseControl - the game mouse control
                LoadPCX - load background image
                ShowScreenBuffer - shows screenbuffer to screen
                Initmask - initializes sphere mask
                HideMouseCursor - hides the mouse cursor during animation
                ShowMouseCursor - shows the mouse cursor 
                

Function : SphereGameDelay
Inputs   : game_speed - the user-set game speed
           difficulty - the game difficulty level
           Sphere_delayC - the delay constant
Outputs  : none
What it does  : this is the delay between colors shown to the player.
                As the player gets to higher level, or increases
		difficulty or speed, this delay shortens.
What it calls : none

Function : BuildSequence
Inputs   : Rand_Value - the random number returned from the random
function
Outputs  : simon_color_seq - the array of the sequence of colors to
		display player.
What it does  :  this function builds the color sequence that the player
                 must match.
What it calls :  Random - the random number generator

Function : ResetSphere
Inputs   : reset_orien - the original orientation of the sphere
           orientation - the current orientation of the sphere
Outputs  : orientation 
What it does  : sets orientation back to original to reset
What it calls : DrawSphee, ShowScreenBuffer - show resetted sphere

Function : YouLose
Inputs   : PCX files "grave1" and "grave2"
Outputs  : To the display
What it does  : This function displays a graveyard, and then uses
	FadeInBuffer to show the same picture with the words "You Lose"
	superimposed
What it calls : FadeInBuffer, ShowScreenBuffer, HideMouseCursor,
ShowMouseCursor, FadeOut

Function : SelectDelay
Inputs   : Difficulty - the game difficulty
           Sphere_delayC - delay constant
Outputs  :  none
What it does  : delays the game during a color highlight
What it calls : none

Function : YouWin
Inputs   : PCX files "smiley1" through "smiley8"
Outputs  : To the display
What it does  : This function animates a smiley face which gradually
		smiles by showing a sequence of 8 PCX files
What it calls : FadeInBuffer, ShowScreenBuffer, HideMouseCursor,
		ShowMouseCursor, FadeOut

----------------------------------------
interfce.asm -- PAUL WHITAKER

Function : ShowMouseCursor
Inputs   : none
Outputs  : none
What it does  : Shows the mouse cursor
What it calls : no functions, just interrupts

Function : HideMouseCursor
Inputs   : none
Outputs  : none
What it does  : Hides the mouse cursor
What it calls : no functions, just interrupts

Function : InitCursor
Inputs   : cursor_type, Spiral, CrossHr, Smiley
Outputs  : none
What it does  : This function initializes the cursor to the cursor
                specified by cursor_type:
                   -1 = transparent (no cursor)
                    0 = Spiral
                    1 = CrossHair
                    2 = Smiley Face
What it calls : no functions, just interrupts

Function : InitMouse
Inputs   : none
Outputs  : none
What it does  : Initializes the mouse driver
What it calls : no functions, just interrupts

Function : GetPresentColor
Inputs   : cx, dx
Outputs  : ColorSelected
What it does  : This function returns the color of the pixel at the
                coordinates (cx, dx).  This function in meant to be
                run immediately after calling int 33h (function 0004h)
                which outputs the position of the mouse cursor into
                (cx, dx).
What it calls : no functions

Function : MouseControl
Inputs   : none
Outputs  : LeftButton, RightButton, ColorSelected, RotateDir,
           AbsoluteX, AbsoluteY, ReturnToMenu
What it does  : Gets user input via the mouse (during gameplay), and
                returns this information through variables
What it calls : GetPresentColor

Function : MenuMouseControl
Inputs   : none
Outputs  : LeftButton, menuaction, AbsoluteX, AbsoluteY
What it does  : Gets user input for the menu via the mouse, and
                returns this information through variables
What it calls : no functions

Function : OptionsMouseControl
Inputs   : none
Outputs  : LeftButton, AbsoluteX, AbsoluteY, opt_chosen, opt_delta
What it does  : Gets user input for the options screen via the mouse, and
                returns this information through variables
What it calls : no functions

Function : WaitForMouseRelease
Inputs   : none
Outputs  : none
What it does  : This function waits for the user to click the left mouse
                button and then release all buttons.  In essence, it
                creates a "click to continue" delay.
What it calls : no functions

Function : DummyKeyInt
Inputs   : none
Outputs  : none
What it does  : This dummy keyboard interrupt handler does nothing but
                acknowledge that the keyboard is sending keystrokes.
                Keyboard input is not acted upon.
What it calls : no functions

Function : RemoveKeyboard
Inputs   : none
Outputs  : none
What it does  : This code was used in MP4.  This function removes the
	default keyboard interrupt handler and replaces it with 
	DummyKeyInt.
What it calls : no functions

Function : RestoreKeyboard
Inputs   : none
Outputs  : none
What it does  : This code was used in MP4.  This function restores the
                default keyboard handler.
What it calls : no functions

---------------------------------------
image.asm -- PAUL WHITAKER

Function : LoadPCX
Inputs   : ax - address of destination segment
           dx - pointer to string containing PCX filename
Outputs  : Fills Destination segment with picture
           Fills palette registers with colors
           Uses scratchpad to hold compressed image
What it does  : See outputs.  This code was used in MP4.
What it calls : no functions

Function : ShowScreenBuffer
Inputs   : ScreenBuffer - segment containing screen image
Outputs  : To the display
What it does  : moves the ScreenBuffer into video memory and clears the
	buffer
What it calls : HideMouseCursor, ShowMouseCursor

Function : ModifiedDelay
Inputs   : DelayC
Outputs  : time
What it does  : Wastes CPU time.  This function is necessary for
                ScrollInBuffer.  ScrollInBuffer takes slightly longer with
                each pass because it has to write more and more of the
                ScreenBuffer.  ModifiedDelay compensates to keep the
		scroll	smoother.
What it calls :  no functions

Function : ScrollInBuffer
Inputs   : ScrollSpeed, ScreenBuffer
Outputs  : None
What it does  : This function scrolls the ScreenBuffer up the screen.  The
                concept is fairly simple: the source is always reset to 0
                (the beginning of the ScreenBuffer).  The destination
		begins at the lower-left hand corner of the display and
		moves upward, one pixel at a time.  On each pass, the
		function writes until it reaches the end of the video display.
What it calls : HideMouseCursor, ShowMouseCursor, Modified Delay

Function : FadeInBuffer
Inputs   : FadeSpeed, ScreenBuffer
Outputs  : none
What it does  : This function makes the ScreenBuffer "fade into" the
	display.  This effect is accomplished by making 13 pixels through
	the buffer (plotting every 13th pixel each time).  The number
	13 was chosen because it is a prime number.  If, for example,
	10 was used, distinct lines would appear as the buffer was
	being drawn.
	What it calls : HideMouseCursor, ShowMouseCursor

Function : FadeOut
Inputs   : FadeSpeed
Outputs  : none
What it does  : This function writes black pixels (palette entry 0) over
	the display in a manner exactly like FadeInBuffer.  See FadeInBuffer
	for more information.
What it calls : HideMouseCursor, ShowMouseCursor

--------------------------------------------------
intro.asm -- Random functions -- PAUL PAWOLA 
          -- intro functions  -- PAUL WHITAKER

Function : Random
Inputs   : Randval - previous generated random number
           max_rand_val - maximum random value
Outputs  : rand_value - new random number
What it does  : generates a random number from 0 to FFFFh
What it calls : no functions

Function : CalculateSeed
Inputs   : seed_array1 - array of possible random seed 1
           seed_array2 - array of possible random seed 2
Outputs  : rand_seed1 - first random seed used
           rand_seed2 - second random seeed used
What it does  : This function calculates the random number seeds used
                in the Random number function.  To avoid getting the
                same numbers each time the program is run, it uses int
                10h to get the system time, and used the hundreths of
                seconds returned to access an array of possible random
                seeds.
What it calls : no functions

Function : Delay
Inputs   : DelayC
Outputs  : time
What it does  : This code was used in MP3.  This function wastes CPU time.
What it calls : no functions

Function : DrawIntroLines
Inputs   : none
Outputs  : none
What it does  : This function draws two lines moving across the screen in
                opposite directions.  Each line is two pixels tall.  When
                the lines span the screen, the color is changed to black,
                and the process is repeated, thus erasing the original
		lines.  Then the color is changed back to the original color
		(palette entry 255), and the entire sequence repeats until the user
                interrupts it with a mouse click.
What it calls : no functions

Function : ShowPartialBuffer
Inputs   : LetterToShow, ScreenBuffer, LetterX, LetterY
Outputs  : To display
What it does  : This function displays a 40x40 pixel tile of the
ScreenBuffer.  The upper-left hand corner of the tile is specifed by the
lookup tables LetterX and LetterY.  LetterToShow refers to a 
letter in "SIMON SPHERE".  For instance, if LetterToShow is 0,                the letter that will be drawn is the S in SIMON.  LetterX
and  LetterY hold the positions of each of the letters in the
buffer.
What it calls : no functions

Function : OverwritePartialBuffer
Inputs   : LetterToShow, LetterX, LetterY
Outputs  : To display
What it does  : This function overwrites the 40x40 tile which holds the
		letter
                specified by LetterToShow.  See ShowPartialBuffer for more
                information.
What it calls : no functions

Function : Introduction
Inputs   : IntroPCX
Outputs  : none
What it does  : Runs the introduction sequence for Simon Sphere.
What it calls : HideMouseCursor, ShowMouseCursor, ShowPartialBuffer,
                OverwritePartialBuffer, Delay, FadeInBuffer,
		DrawIntroLines, FadeOut

Function : Instructions
Inputs   : PCX files "Instr1A" to "Instr1D" and "Instr2" to "Instr5"
Outputs  : none
What it does  : Runs the instruction sequence for Simon Sphere.
What it calls : HideMouseCursor, ShowMouseCursor, Delay, FadeInBuffer,
                ScrollInBuffer, FadeOut

Function : ShowCredits
Inputs   : PCX files "Credits1" to "Credits5"
Outputs  : none
What it does  : Runs the credits sequence for Simon Sphere.
What it calls : HideMouseCursor, ShowMouseCursor, Delay, FadeInBuffer,
                ScrollInBuffer, FadeOut

------------------------
midi.asm -- DREW ROEDERSHEIMER

Function : RegisterMIDI
Inputs   : None
Outputs  : None
What it does  : Registers the MIDI file for output using function 704h and
	INT 66h. Initializes registers SI, DI, CX, and BX according to the
	values specified in the documentation for MIDIPAK 
What it calls : MIDIPAK (INT 66h)

Function : PlaySequence
Inputs   : None
Outputs  : Plays the registered MIDI file
What it does  : Plays the registered MIDI file that is loaded into the
		MIDISEG. Uses Function 702h and INT 66h
What it calls : MIDIPAK (INT 66h)

Function : StopMIDI
Inputs   : None
Outputs  : None
What it does  : Stops the currently playing MIDI file using function 705h
		& INT 66h What it calls : MIDIPAK (INT 66h)

Function : LoadSound
Inputs   : AX - holds the MIDISEG
           BX - holds the offset of the MIDI Buffer
           CX - holds the length of the MIDI
           DX - holds the offset of the file name           
Outputs  : None
What it does  : This function loads the file specified by the registers
		into the MIDISEG to then be registered and played by
		MIDIPAK 
What it calls : MIDIPAK (INT 66h)

Function : play_intro
Inputs   : None
Outputs  : None
What it does  : Plays the intro MIDI 
What it calls : LoadSound 
                RegisterMIDI
                PlaySequence

Function : play_menu
Inputs   : None
Outputs  : None
What it does  : Plays the menu MIDI 
What it calls : LoadSound 
                RegisterMIDI
                PlaySequence

Function : play_instru
Inputs   : None
Outputs  : None
What it does  : Plays the instruction menu MIDI 
What it calls : LoadSound 
                RegisterMIDI
                PlaySequence

Function : play_win
Inputs   : None
Outputs  : None
What it does  : Plays the winning MIDI 
What it calls : LoadSound 
                RegisterMIDI
                PlaySequence

Function : play_lose
Inputs   : None
Outputs  : None
What it does  : Plays the losing MIDI 
What it calls : LoadSound 
                RegisterMIDI
                PlaySequence

Function : play_go
Inputs   : None
Outputs  : None
What it does  : Plays the MIDI after you have advance to the next level 
What it calls : LoadSound 
                RegisterMIDI
                PlaySequence

Function : play_credits
Inputs   : None
Outputs  : None
What it does  : Plays the MIDI for the credits menu 
What it calls : LoadSound 
                RegisterMIDI
                PlaySequence

-----------------------------------
sphere.asm -- BEN NICK
Function: DrawSphere
 Inputs  : lkseg, sphseg, mskseg, destpos, rippos, highlightflag
 outputs : screenbuffer
 displays a 3d sphere in constant time by referencing three segments,
  and array. the flow is as follows...
  apply mask movs 320x200 image containing concentric circle gradient 
 from mskseg into screen buffer (with fast graphics) 
 color is applied moving through jmp tables in the order:
 (note order is reversed to demonstrate flow of information)
 orientation segment (containing color locations) is referenced by the
 look up table in lkseg.  rippos offset is to determine which 128x128
 section is referenced by the "lense" in sphseg.
 image referenced by the lense is then added unto the image in the
 screen buffer inorder to make the gradient effect
 the second half of the function highlight a section of the circle based
 on color. 

Function : RotateSphere
Inputs   : orientation, mskseg, sphseg, lkseg, rotateflag, rippos
Outputs  : orientation, rippos
What it does  : Rearranges orientation and draws animation by
              calling draw sphere in a loop, inc or decing rippos
What it calls : DrawSphere, ShowScreenBuffer

Function : initmask
Inputs   : mskseg xinput,yinput
Outputs  : sbseg
calls circle_calc
what it does - movs concentric circle gradient on top of the pcx
               image already on the mskseg 

Function : circle_calc
Inputs   : gradius, inputx, inputy, gcolor
Outputs  : maskcheck
What it does  : calculates whether or not a pixel is inside or outside
gradius using pythagorian theroem, if inside puts gcolor in maskcheck, else
returns a value instrucing initmask to skip the pixel. uses FPU

Function : applymask
Inputs   : mskseg
Outputs  : sbseg
What it does  : movs 320X200 image in mskseg to screenbuff using 
		fast graphics 

Function : Initsphseg
Inputs   : sphseg
Outouts  : sphseg
calls : backup_calc
What it does : initializes the lense based on the formula
	determined by FPU operations in backup_calc. It loops through
	128x128x2 array in sphseg, assigning offsets to lkseg creaqting
	spherical effect.  
What it calls : backup_calc

Function : backup_calc
calls : inputx, inputy,sixtyfour, piconstant
outputs  : maskcheck
What it does : determines whether or not a pixel should be cropped based
		on pythagorians thereom, very similar to circle_calc.

Function : Loadpallet
calls : none
Outputs : vga pallet
What it does loads 31 shades of the eight colors arranged in such a way so
	that color shades are eight values apart accomplishes it 8 loops
	for each color allowing for quick modification of pallet

Function : initlookup
 inputs   : lkseg
 output   : lkseg
What it does : creates a 256x256 array of indexs to the orientation array
 	utilizes a quad nested loop drawing columns of 64x64 tiles of 64 
	horizontal lines of 64 pixels. basically initializes lkseg
-----------------------------------
sound.asm -- DREW ROEDERSHEIMER


Function : Play_Sound
Inputs   : Freq - the frequency of the sound to be played
           File - offset of the name of the file to be played
Outputs  : None
What it does  : Plays the specified sound 
What it calls : ResetDSP
                DMAPlay
Note : This code was taken from the web but modified                 
  
Function : DMAPlay
Inputs   : None
Outputs  : None
What it does  : Sets up and starts to play the specified sound
What it calls : WriteDSP 
Note : This code was taken from the web            

Function : MstrVol
Inputs   : None
Outputs  : None
What it does  : Sets the volume on the sound card to a reasonable value
What it calls : None
Note : This code was taken from the web   

Function : ResetDSP
Inputs   : None
Outputs  : None
What it does  : Resets the DSP for sound playing
What it calls : None
Note : This code was taken from the web


Function :  load_sound_scheme
Inputs   : sound_scheme - variable used so we set up our array with the
	   correct offsets and frequencies for each sound file
Outputs  : None
What it does  : This function loads the offsets of the filenames into the
	sound_array The function also loads the frequencies of each file into
	the sound_freq array
What it calls : None


Function : play_wave
Inputs   : sound_scheme - if sound_scheme is 0 we skip over the procedure
		(no sound) 
           sound - the variable used to access the arrays for each sound
Outputs  : None
What it does  : This function takes in the sound number (1-8) and accesses
	the arrays sound_array and sound_freq, loading the variables File and
	Freq with the correct values
What it calls : None