ﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄ
;             *** BOULDER DASH (Final version) ***
ﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄ
;   My first attempt to write a game. Hope it turn out nice ;)
;   No it did NOT turn out as nive as I hoped :(
;   But who gives a fuck !
;
;   Starting day  :  Tue  02.11.1995
;   Ending day    :  Wen  30.04.1997
;  
;   (C) Copyright 1997  Suicide Software  All Rights Reserved.
ﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄ


        IDEAL
        P386N


ﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄ
; *** Equates ***
   
_Delay          =       2               ; Game speed
P_Extra         =       5000            ; Points for extra life
;Key_Up          =       26h
;Key_Down        =       34h
;Key_Left        =       2Ch
;Key_Right       =       2Dh
Key_Up          =       26h
Key_Down        =       34h
Key_Left        =       2Ch
Key_Right       =       2Dh

LF              =       10
CR              =       13
EOS             =       '$'
Icon_Res        =       12
Icon_Size       =       12*12
Num_Icons       =       29
Page_1          =       X_Byte*12
Page_2          =       Page_Size + X_Byte*12
Icon_Offset     =       Page_Size*2



; *** Macros ***
Macro   IODELAY
        jmp     short $+2               ; Short delay between I/O
        jmp     short $+2               ; to same device
EndM    IODELAY


INCLUDE         "BD.INC"
ﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄ


ASSUME  CS:Code_Seg, SS:Stack_Seg


SEGMENT Code_Seg        Para    Public          'CODE'          USE16
ﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄ
Start:  mov     ax,Data_Seg             ; DS = GS = Data Seg
        mov     ds,ax
        mov     gs,ax
        cld


; *** Test system ***
        pushf                           ; Test for 386+
        pop     ax
        or      ax,0F000h
        push    ax
        popf
        pushf
        pop     ax
        test    ax,0F000h
        jz      @@10                    ; Not passed

        mov     ax,01A00h               ; Check for VGA+
        int     10h
        cmp     al,01Ah
        jne     @@10

        mov     ax,3306h                ; Get MS DOS version
        int     21h
        cmp     bl,5
        jb      @@10

        jmp     @@20
@@10:   mov     dx,Offset Str_Sys_Error
        jmp     Error3


; Ok, System is good
@@20:   xor     ax,ax                   ; FS = 0
        mov     fs,ax


; Get the parameter string
        call    Get_Param               ; ES = PSP
        mov     [Word ds:Param_Num],bx


; Get allocated memory
        mov     ah,4Ah
        mov     bx,0FFFFh
        int     21h
        mov     [Word ds:Free_Mem],bx

        call    Setup_Int
        call    ModeX
        call    Init


; Get level segment
        mov     ax,Stack_Seg
        add     ax,(64*2) / 16
        mov     [Word ds:Level_Seg],ax


; Load level file
        mov     dx,Offset Level_File
        cmp     [Word ds:Param_Num],0   ; Have user given a level name?
        je      @@30
        mov     dx,Offset Param_Str     ; Use new level name

@@30:   call    Load_File               ; AX = Level segment
        jc      Disk_Err
        cmp     ah,-1                   ; Mem error?
        jne     @@35
        mov     dx,Offset Str_Mem
        jmp     Exit_Write

@@35:   mov     ax,[Word ds:Level_Seg]  ; Check if level file is valid
        mov     es,ax
        mov     al,-3
        cmp     [Word es:0],'DB'
        jne     Error


; Load high score file
        call    Load_High
        jc      Disk_Err
        call    Count_Levels
        mov     al,-1                   ; First time playing


ﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄ
; *** Menu system ***
ﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄ
@@40:   mov     dx,Offset Gen_Str       ; Test for error
        cmp     [Byte ds:Crit_Error],0
        jne     Exit_Write

        call    Menu
        or      al,al
        jnz     Exit


; *** Ok, here we start playing! ***
        call    Play_Game
        or      al,al
        js      Error
        jmp     @@40                    ; Goto menu again


ﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄ
; *** Clean up and exit ***
ﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄ
Exit:   call    Exit_Stuff
        mov     ax,0003h
        int     10h
        mov     ax,04C00h
        int     21h



ﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄ
; Somthing screwed up :(
ﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄ
Error:  cmp     al,-2                   ; Keyb error
        je      Exit_Error
        mov     dx,Offset Map_Str       ; Level error (Level_Num = Level)
        cmp     al,-1
        je      Exit_Write
        mov     dx,Offset File_Error    ; Game file error
        cmp     al,-3
        je      Exit_Write

        mov     dx,Offset Gen_Str       ; Somthing realy bad happend :)
        jmp     Exit_Write


; *** Disk error ***
Disk_Err:
        mov     bx,Data_Seg             ; DS = Data
        mov     ds,bx
        mov     dx,Offset Disk_Str
        cmp     al,2                    ; File not found?
        jne     Exit_Write

        mov     ax,03h                  ; Reset screen
        int     10h
        mov     si,Offset Str_File_Err  ; Write file is missing
        call    Str_Write
        mov     si,[Word ds:Curr_File]  ; Write file name
        call    Str_Write
        call    New_Line
        jmp     Exit2

Exit_Error:
        in      al,60h
        in      al,60h
        in      al,60h
        in      al,60h
        mov     dx,Offset Keyb_Str


; Write message in DX
Exit_Write:
        mov     ax,03h
        int     10h
        mov     ah,09h
        int     21h
Exit2:  call    Exit_Stuff
        mov     ax,04CFFh
        int     21h


; Exit with out doing 'Exit_Stuff'
Error3: mov     ah,09h                  ; Write string in DX
        int     21h
        mov     ax,04CFFh
        int     21h


INCLUDE         "MENU.INC"
INCLUDE         "GAME.INC"
INCLUDE         "INTERUPT.INC"
ﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄ
EndS    Code_Seg




SEGMENT Data_Seg        Para    Public          'DATA'          USE16
ﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄ
INCLUDE         "PAL.INC"               ; The palette
INCLUDE         "FONT.INC"              ; The font set
INCLUDE         "GRAPHICS.INC"          ; The graphics/icons


; *** Messages ***
Map_Str         db      CR,LF,'ERROR: Invalid entry in the map !!!',CR,LF,EOS
Keyb_Str        db      CR,LF,'FATAL: Hardware keyboard error !',CR,LF,EOS
Disk_Str        db      CR,LF,'ERROR: Some of the game file(s) is corrupted :('
                db      CR,LF,'       Please reinstall Bolder Dash...',CR,LF,EOS
File_Error      db      CR,LF,'ERROR: This is not a valid game file !',CR,LF,EOS
Gen_Str         db      CR,LF,'ERROR: Something screwed up !',CR,LF,EOS
Str_Mem         db      CR,LF,'Sorry dude, you''re out of memory...',CR,LF,EOS
Str_File_Err    db      CR,LF,'File not found: ',0
Str_Sys_Error   db      CR,LF,'You need : 386+, VGA+ and DOS 5.0+ to run Boulder Dash...',CR,LF,EOS

; 25 = White
; 26 = Red
; 27 = Green
; 28 = Yellow
; 29 = Magenta (Unused)
; 30 = Ocean blue
; 31 = Light red
; 32 = Blue (Unused)

; *** Game messages ***
Nul_Str         db      0,0
Dead_Str        db      0,26,'       - You are dead!. Press ESC -       ',0,0
GameOver_Str    db      0,26,'              - GAME OVER! -              ',0,0
TimeUp_Str      db      0,28,"        - Sorry, time's up dude! -        ",0,0
Pause_Str       db      0,25,'    - Pause! Press space to continue -    ',0,0

Bonus_Str       db      0,27,'- Bonus Life -',0,0

; Using Pal 2! (Sub 18)
Str_Finished    db      0,30-18,'Congratulations!',0,0
High1_Str       db      0,25-18,'High score list:',0,0
Menu_Str        db      0,27-18,'Level: ',0,25-18,'xx                  H',0,29-18,'igh: ',0,31-18,'xxxxxxxxxx',0,0
Menu_Level      =       Offset Menu_Str + 11            ; 2 Digits
Menu_Name       =       Offset Menu_Str + 41            ; 10 Digits

Level_Str       db      0,29,'Level ',0,25,'xx',0,29,', ',0,26,'xxxxxxxxxxxxx     ',0,29,'Men : ',0,25,'xx',0,0
Str_Level       =       Offset Level_Str + 10           ; 2 Digits
Str_Name        =       Offset Level_Str + 18           ; 13 chars
Str_Men         =       Offset Level_Str + 46           ; 2 Digits

Status_String   db      0,28,'000$000',0,25,' 000',0,27,' 000 ',0,30,'SCORE:',0,25,'000000',0,0
Str_D_Take      =       Offset Status_String + 2        ; 3 Digits
Str_D_Score     =       Offset Status_String + 6        ; 3 Digits
Str_D_Count     =       Offset Status_String + 12       ; 3 Digits
;andre Str_Time        =       Offset Status_String + 18       ; 3 Digits
Str_Time        =       Offset Status_String + 33       ; 3 Digits
Str_Score       =       Offset Status_String + 32       ; 6 Digits
Time_Color      =       Offset Status_String + 16


; Default High score list
High_List2:     db      'Sorry pal, this is encrypted :)',CR,LF ; 33 bytes
High_List:      dd      100000
                db      'Greven    '
                dd      50000
                db      'Acid Boy  '
                dd      25000
                db      'Weed      '
                dd      10000
                db      'Mr. E     '
                dd      5000
                db      'Crack head'
                dd      1000
                db      'Dick head '


; *** Lockup tables ***
Label   Icon_Table      Word            ; Offsets to icons

I = Icon_Offset

Rept    Num_Icons
 dw     I
 I=I+(Icon_Size/4)
EndM


Action_Table    dw      Offset Special_Wall
                dw      Offset Special_Wall
                dw      Offset Stone
                dw      Offset Green
                dw      Offset Map_Error
                dw      Offset Dimond
                dw      Offset Map_Error
                dw      Offset Map_Error
                dw      Offset Monster
                dw      Offset Map_Error
                dw      Offset Map_Error
                dw      Offset Monster
                dw      Offset Skipp
                dw      Offset Explosion
                dw      Offset Explosion
                dw      Offset Explosion
                dw      Offset Home
                dw      Offset Guy
                dw      Offset Guy
                dw      Offset Guy
                dw      Offset Guy
                dw      Offset Guy
                dw      Offset Guy
                dw      Offset Guy


; *** Global data ***
Level_File      db      'LEVEL.DAT',0
High_File       db      'LEVEL.HIG',0
Delay           db      _Delay


; *** Setup every game ***
        ALIGN   DWORD
Score           dd      0
Level_Num       db      1
Men             db      0



; *** Setup every level ***

        ALIGN   DWORD
Random_Number   dd      ?
Info_String     dw      ?
Time            dw      ?
Map_Size        dw      ?               ; H * V
Map_H           db      ?
Map_V           db      ?
Green_All       db      ?
Char_Space      db      ?
Guy_Last        db      ?

D_Take          db      ?               ; How many dimonds to take
D_Score         db      ?               ; What each dimond score
D_Score2        db      ?               ; After taking enogh dimonds
Magic_Time      db      ?               ; Time the magic wall is active
Pos_H           db      ?
Pos_V           db      ?
Bonus           db      ?
Level_Name      db      14 Dup(?)



; *** Clear every level ***

        ALIGN   WORD
D_Count         dw      ?               ; Dimond count
Wall_Finished   dw      ?
Frame1          db      ?               ; 2 Normal
Frame2          db      ?               ; 3 Normal
Frame3          db      ?               ; 2 Slow (0 - 3)
Frame4          db      ?               ; 2 Fast
Walk_Frame      db      ?
Update          db      ?               ; Time to update screen
Update2         db      ?               ; Do one move tick
Curr_Map        db      ?
Curr_Page       db      ?
Finished        db      ?               ; 1,2=Yes, 3=Goal, 4=Next level, bit 8 = Game over
Green_Count     db      ?
Green_Delay     db      ?
Green_Expand    db      ?
Green_Stop      db      ?
Green_Traped    db      ?
Green_Traped2   db      ?
Green_Transform db      ?
Wall_Status     db      ?               ; 0=Nothing, 1 = Transform, 2 = End
Guy_H           db      ?
Guy_V           db      ?
Guy_Move        db      ?               ; 0 = No, 1 = Yes
Last_Move       db      ?               ; Direction
Scroll_H        db      ?
Scroll_V        db      ?
ESC_Flagg       db      ?               ; 1 = ESC, 2 = TAB - ESC
Extra_Life      db      ?               ; 0 = No, xx = Countdown
                dw      ?       ; align
        ;ALIGN   DWORD
Level_Clear     =       $ - D_Count     ; Bytes to clear





; *** Clear only once ***
        ;ALIGN   WORD
Rot_Count       dw      ?               ; Pallete rotation count
High_Handle     dw      ?               ; Handle for high score file
Last_Key        db      ?
Keyb_Error      db      ?
Crit_Error      db      ?
Playing         db      ?               ; 0 = No, 1 = Yes
Pause           db      ?
BIOS_Keyb       db      ?               ; 1 = Use BIOS handler
Currsor         db      ?               ; 0 or 1
                db      ?       ; align
Key_Map         db      128 Dup (?)
Global_Clear    =       $ - Rot_Count



        ;ALIGN   DWORD

; *** Uninstaled data ***
Level_Seg       dw      ?
Free_Mem        dw      ?
Param_Num       dw      ?               ; Number of parameters
Curr_File       dw      ?               ; File name we try to load
Guy_Alive       db      ?
Menu_Active     db      ?               ; 0 = No, 1 = Menu system
Num_Level       db      ?               ; Number of levels in file
Param_Str       db      128+1 Dup(?)
Map1            db      100*100 + 4 Dup(?)      ; Temp map 1
Map2            db      100*100 + 4 Dup(?)      ; Temp map 2
ﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄ
EndS    Data_Seg



ﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄ
SEGMENT Stack_Seg       Para    Stack           'STACK'         USE16
        dw      64 Dup (?)      ; A 64 words stack
EndS    Stack_Seg
ﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄﾄ
        End     Start
