home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2002 September
/
Chip_2002-09_cd1.bin
/
ctenari
/
Veber
/
src
/
Sputnik.asm
< prev
next >
Wrap
Assembly Source File
|
2002-07-21
|
19KB
|
743 lines
;
; Game Sputnik
; Copyright (C) 2001 Jaromφr Veber
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
;
;Jaromir Veber
;5.11.2001 - changed game kernel
;Jaromir Veber
;6.11.2001 - small change
;Jaromir Veber
;10.11.2001 - ver 2.0 changes
;Jaromφr Veber
;18.11.2001 - brutal changes
;Jaromφr Veber
;1.06.2002 - reported one bug in detection of fences so I found it
; and removed it...
;Jaromφr Veber
;8.06.2002 - Totaly rebuilded and optimised, applied jump optimisation...
;Jaromφr Veber
;21.07.2002 - Small bug in keyboard detected and repaired...
%define MODE 0x13
%define P80386
org 100H
%include "Macros.asm"
;STACICS - WITCH - CAN BE CHNAGED
;#######################################################################
;menu
MAX_MENU_POS equ 1 ;maximal position in menu (it is number of menu texts -1)
START_GAME_POS equ 0 ;position of START_GAME in menu
MENU_RECT_SIZE_X equ 84 ;size of rectangle in menu X
MENU_RECT_SIZE_Y equ 11 ;size of rectangle in menu Y
MENU_RECT_COLOR equ 130 ;color of menu
MENU_BACKGR_COLOR equ 0 ;color of menu background
MENU_RECT_START_X equ 109 ;start position of restangle X
MENU_RECT_START_Y equ 69 ;start position of restangle Y
;land under sputnik
LAND_POS_Y equ 180 ;positon of land on start
LAND_COLOR equ 3 ;land color
SPUT_SHIMMER_TIME equ 10
MAX_LAND_POS equ 198
MIN_LAND_POS equ 100
;sputnik
SPUT_SIZE_X equ 25 ;size of sputnik X
SPUT_SIZE_Y equ 9 ;size of sputnik Y
SPUT_START_POS_X equ 100 ;X start position
SPUT_START_POS_Y equ 100 ;Y start position
SPUT_BODY_COLOR equ 12 ;color of sputnik
SPUT_BACKGROUND equ 0 ;sputnik background color
;2.0
SPUT_FROM_LAND equ 1 ;sput from land
;game data
SPUT_FLY_POINTS equ 1 ;rate of change up down
SPUT_STEP_RATE equ 2 ;rate of change left right
START_GAME_SPEED equ 9 ;start delay
LIFES equ 3 ;number of lifes
SPUT_MAX_FLY_POS equ 50 ;height of sputnik jump
COMMAND_JUMP equ 1
FENCE_FROM_LAND equ 0
FENCE_SIZE_X equ 10 ;size of fence X
FENCE_SIZE_Y equ 10 ; Y
FENCE_COLOR equ 34
FENCE_SPEED equ 5 ;speed of fence
;FENCES
LAND_UP equ 1
LAND_DOWN equ 2
FENCE_UP_TAPE1 equ 3
SCORE_TO_SPEED_UP equ 10 ;how many fences to speed up
;#######################################################################
;STACICS - WITCH - SHOULD NOT BE CHANGED (DO NOT CHANGE THEM)!
;LAND
LAND_FLUMMOX_POINTS equ 2 ;this is is needent to compute real positon of Y
;for units moving on the land
;SPUTNIK
SPUT_FLY_POINT equ LAND_FLUMMOX_POINTS + SPUT_FROM_LAND
SPUT_START_MIN_Y equ LAND_POS_Y - (SPUT_FLY_POINT + SPUT_SIZE_Y)
SPUT_START_MAX_Y equ SPUT_START_MIN_Y - SPUT_MAX_FLY_POS
START_SIZE_DOWN equ (LAND_POS_Y - SPUT_START_POS_Y - SPUT_SIZE_Y - SPUT_FLY_POINT) / SPUT_FLY_POINTS
SPUT_FROM_LAND_OK equ FENCE_FROM_LAND + LAND_FLUMMOX_POINTS
SPUT_SHRIM equ SPUT_SHIMMER_TIME*16
SPUT_MAX_POS_X equ 318 - SPUT_SIZE_X - SPUT_STEP_RATE
SPUT_MIN_POS_X equ SPUT_STEP_RATE
;FENCE
FENCE_EXIST equ 1
FENCE_START_X equ 319
FENCE_START_Y equ (LAND_POS_Y - 2) - FENCE_SIZE_Y
LAND_WIDTH equ 2
;#######################################################################
;=======================================================================
;GAME CODE
;=======================================================================
start:
mov AX,0A000H
mov FS,AX
;ok
;=======================================================================
;MENU
;=======================================================================
Draw_menu:
;;set vide mode
mov ax,MODE
int 10h
;;write menu texts
xor BX,BX
mov AH,02H
mov DX,030FH
int 10H
writestr text3
mov AH,02H
mov DX,090EH
int 10H
writestr text1
mov AH,02H
mov DX,0B0EH
int 10H
writestr text2
;ok
mov byte [menu_rect_position],0
;initialize positoion of rectangle
;111111111111111111111111
;wait key looper
;111111111111111111111111
push word MENU_RECT_START_X
push word MENU_RECT_START_Y
push word MENU_RECT_SIZE_X
push word MENU_RECT_SIZE_Y
push word MENU_RECT_COLOR
Exit_arrow: ;draw graphical rectangle
call New_Rectangle
waitme:
Wait_char
cmp AL,0DH ;was it key with extended scan code
jz do
mov AL,AH
cmp AL,48H ;up
mov BL,0
mov CX,MENU_RECT_START_Y
jz .do
mov BL,1
add CX,16
cmp AL,50H ;down
jnz waitme
.do
mov [menu_rect_position],BL
mov bp,sp
mov [var],CX ;save CX
mov word [BP],0
call New_Rectangle
mov BP,SP
mov AX,[var]
mov word [BP],MENU_RECT_COLOR
mov [BP+6],AX
jmp Exit_arrow
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;end of looper
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
do:
mov AL,[menu_rect_position]
cmp AL,START_GAME_POS ;was rectangle on SATRT GAME
jnz near EXIT ;position
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;GAME STARTING
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov byte [lifes],LIFES
mov word [Land_pos_Y],LAND_POS_Y
XOR ax,ax
MOV BYTE [score],al
mov word [game_speed],START_GAME_SPEED
GAME:
clear_display
xor BX,BX
mov AH,02H
mov DX,0102H
int 10H
writestr text5
mov AL,byte [lifes]
writeAL
mov AH,02H
mov DX,0202H
int 10H
writestr text6
mov AL,[score]
writeAL
linex 1,[Land_pos_Y],318,LAND_COLOR
xor AX,AX
mov word [Sput_pos_X_cahnge],AX
mov byte [LandUP_exist],AL
mov word [LandUP_pos_X],AX
mov AX,[Land_pos_Y]
mov [Land_new_pos_Y],AX
mov word [Sput_pos_X],SPUT_START_POS_X
mov word [Fence_pos_X],200
mov word [Fence_pos_Y],200
mov word [Fence_sizeX],2
mov word [Fence_sizeY],2
START_GAME:
mov AX,[Land_pos_Y]
sub AX,SPUT_MAX_FLY_POS
mov word [Sput_pos_Y],AX
mov AX,0
mov word [Sput_fly],AX
;changing position X
;shrimming
mov word [Sput_shimmer],0
;land
align 16
GAME_CYKLUS:
inc word [citac]
mov AX,[Sput_pos_Y]
mov BX,[Sput_shimmer]
cmp BX,SPUT_SHRIM
ja .dal
inc word [Sput_shimmer]
shr BX,4
mov word [Sput_act_color],SPUT_BODY_COLOR
jnc .dal
mov word [Sput_act_color],SPUT_BACKGROUND
.dal
mov BX,[Sput_pos_X]
mov [Sput_old_pos_Y],AX ;save old Sputnik position
mov [Sput_old_pos_X],BX ;
invoke delay,word [game_speed] ;game dalay (game speed)
mov AH,1 ;check for keyboard
int 16H ;pressed?
jz NEXT
Wait_char
cmp AL,1BH
jz Draw_menu
shr AX,8
sub ax,48H
jc NEXT
mov SI,AX
shl SI,1
jb NEXT
mov AX,[SI+keyboard]
jmp AX
NEXT:
mov AX,[Sput_pos_X]
mov BX,[Sput_pos_X_cahnge]
mov CX,SPUT_MAX_POS_X
add AX,BX
cmp CX,AX
sbb BX,0
cmp CX,AX
sbb AX,0
cmp AX,SPUT_MIN_POS_X
adc BX,0
cmp AX,SPUT_MIN_POS_X
mov [Sput_pos_X_cahnge],BX
adc AX,0
mov [Sput_pos_X],AX
;Is sputnik falling or is on land or fly up?
mov AX,[Sput_pos_Y]
mov BX,[Land_pos_Y]
mov CX,AX
add AX,SPUT_SIZE_Y+LAND_WIDTH+SPUT_FROM_LAND
cmp AX,BX
jz .sputnik_on_land
;Sputnik is flying
;this can seems confused it's cause I use jum elimination and i need
;some temporary instructions I thig that this solution is very good,
;because it is realy fast
;But I thing, that I'll inprove it in leter versions, becouse it can be inproved
mov AX,SPUT_FLY_POINTS
;in ax is number of points to fly
mov DI,[Sput_fly] ;;optimised number for compute the fly direction
; it can be a bit frustrating for ALU, a lot of alu instructions, but
; a lot of processors have more than one ALU..
xor AX,DI ;temporary computation to get change for
mov DX,CX
add DX,AX
sub BX,DX
mov AX,SPUT_MAX_FLY_POS
sub AX,BX
adc DI,0
;ok [Sput_fly] is changed...
;the right compution starts there
mov AX,SPUT_FLY_POINTS
xor AX,DI
mov [Sput_fly],DI
add CX,AX
mov [Sput_pos_Y],CX
;it is pretty short..!
.sputnik_on_land
LAND:
cmp word [LandUP_pos_X],0
ja near .land_existing
;try to generate land
mov AX,[citac]
and AX,[Sput_pos_X]
push AX
push word 10 ;possibility to do new land is 1:20
call Random
add SP,4
test AX,AX
jnz near .no_land_generated
;.land_generated
;optimazation, only to try it...
;PPro, PII, PIII instruction sheduling
;ok jump elimination applied..
;ok instructin sheduling enabled for PPro
mov word [LandUP_pos_X],318 ;set existence of land.. ;2UOPS
mov AX,[Sput_pos_X] ;1UOP
MOV CX,[citac] ;1UOP
sbb AX,[Sput_pos_Y] ;2UOPs
xor AX,CX ;1UOP
push AX ;3UOPs
push word 2 ;3UOPs
call Random ;4UOPs
;;;
dec AX ;1UOP
mov bp,sp ;1UOP
mov word [LandUP_code],AX ;2UOPs
mov AX,[Sput_pos_X] ;1UOP
xor [bp+2],AX ;4UOPs
mov word [bp],20 ;2UOPs
call Random ;4UOPs
;;;;
add SP,4 ;1Uop
inc AX ;1Uop
mov CX,AX ;1Uop
;OK AX and BX is for computing, so I'll use it for this
;CX,DX,SI is used to store smome values that are often used
mov BX,AX ;1Uop
add BX,LAND_FLUMMOX_POINTS+1 ;1Uop
mov DX,[LandUP_code] ;1Uop
;;CX - [LandUP_size]
mov word [LandUP_size],BX ;2Uops
mov BX,[Land_pos_Y] ;1UOP
xor AX,DX ;1Uop
;DX = [LandUP_code]
;BX = [Land_pos_Y]
;hmm, but throught RAT can go only 3 uops per cycle so no problem...
add AX,BX ;1Uop
cmp AX,MIN_LAND_POS ;1Uop
adc DX,0 ;2Uops
mov SI,MAX_LAND_POS ;1Uop
cmp SI,AX ;1Uop
sbb DX,0 ;2Uops
mov AX,CX ;1UOP
and AX,DX ;1Uop
;BX = [Land_pos_Y]
mov [LandUP_code],DX ;2Uops
mov SI,BX ;1Uop
sub BX,AX ;1Uop
;SI = [Land_pos_Y]
mov [LandUP_pos_Y],BX ;2Uops
xor DX,CX ;1Uop
add SI,DX ;1Uop
mov [Land_new_pos_Y],SI ;2uops
.land_existing
liney [LandUP_pos_X],[LandUP_pos_Y],[LandUP_size],0
dec word [LandUP_pos_X]
liney [LandUP_pos_X],[LandUP_pos_Y],[LandUP_size],LAND_COLOR
linex [LandUP_pos_X],[Land_new_pos_Y],2,LAND_COLOR
mov AX,[Sput_pos_X]
mov BX,SPUT_SIZE_X
mov DX,[LandUP_code]
and BX,DX
add AX,BX
mov CX,AX
cmp AX,[LandUP_pos_X]
jb .dal
mov BX,[Land_new_pos_Y]
mov AX,[Sput_pos_Y]
add AX,SPUT_SIZE_Y
cmp BX,AX
jb near LIFE_LOST
mov [Land_pos_Y],BX
.dal
.no_land_generated
FENCES:
mov AX,[Fence_pos_X]
cmp AX,0
ja near .fence_exist
rectangle [Fence_pos_X],[Fence_pos_Y],[Fence_sizeX],[Fence_sizeY],SPUT_BACKGROUND
xor BX,BX
mov ah,2
mov DX,0208H
int 10H
mov AL,[score]
inc AL
writeAL
mov [score],AL
mov CL,SCORE_TO_SPEED_UP
div CL
mov AL,AH
test AL,AL
jnz .dal
dec word [game_speed]
jz near GAME_WIN
.dal
mov AX,word [citac]
mov BX,[LandUP_pos_X]
mov CX,[Sput_pos_X]
mov DX,[Sput_pos_Y]
and AX,DX
or DX,CX
sbb BX,DX
xor AX,DX
and CX,BX
adc AX,CX
sub AX,BX
xor AX,CX
push AX
push 16
call Random
add AX,2
mov BX,[LandUP_pos_X]
mov word [Fence_sizeX],AX
shr AX,5
and AX,BX
xor BX,AX
add AX,[Sput_pos_X]
or AX,BX
mov bp,sp
mov [bp+2],AX
call Random
add SP,4
add AX,2
mov BX,[Fence_sizeX]
mov CX,318
mov word [Fence_sizeY],AX
mov DX,[Land_new_pos_Y]
sub cx,bx
mov word [Fence_pos_X],CX
sub DX,AX
sub DX,LAND_FLUMMOX_POINTS
mov word [Fence_pos_Y],DX
.fence_exist
rectangle [Fence_pos_X],[Fence_pos_Y],[Fence_sizeX],[Fence_sizeY],SPUT_BACKGROUND
dec word [Fence_pos_X]
rectangle [Fence_pos_X],[Fence_pos_Y],[Fence_sizeX],[Fence_sizeY],FENCE_COLOR
.check_sputnik
mov AX,[Sput_pos_X]
mov BX,[Fence_pos_X]
add AX,SPUT_SIZE_X
cmp AX,BX
jb .sput_before_fence
mov DX,[Fence_sizeX]
add BX,DX
cmp [Sput_pos_X],BX
ja .sput_after_fence
mov AX,[Sput_pos_Y]
add AX,SPUT_SIZE_Y+2
cmp AX,[Fence_pos_Y]
jb .sput_over_fence
jmp LIFE_LOST
.sput_before_fence
.sput_after_fence
.sput_over_fence
liney 0,MIN_LAND_POS,MAX_LAND_POS-MIN_LAND_POS+LAND_FLUMMOX_POINTS+1,0
DRAW_SPUTNIK:
;clear old sputnik....
push word [Sput_old_pos_X]
push word [Sput_old_pos_Y]
push word SPUT_SIZE_X
push word SPUT_SIZE_Y
push word SPUT_BACKGROUND
call New_Rectangle
mov bp,sp
mov AX,[Sput_pos_Y]
mov BX,[Sput_pos_X]
mov [bp+6],AX
mov CX,[Sput_act_color]
mov [bp+8],BX
mov word [bp],CX
call New_Rectangle
add sp,10
;ok
jmp GAME_CYKLUS
GAME_WIN:
clear_display
xor BX,BX
mov AH,02H
mov DX,0608H
int 10H
writestr text9
Wait_char
Wait_char
;;exit to DOS
EXIT:
mov ax,03H
int 10h
writestr ver
EXIT_E:
int 20H
;ok
LIFE_LOST:
mov AL,[lifes]
dec AL
test AL,AL
jz GAME_OVER
xor BX,BX
mov AH,02H
mov DX,0108H
int 10H
writeAL
mov [lifes],AL
push word [Sput_old_pos_X]
push word [Sput_old_pos_Y]
push word SPUT_SIZE_X
push word SPUT_SIZE_Y
push word SPUT_BACKGROUND
call New_Rectangle
add SP,8
jmp START_GAME
GAME_OVER:
clear_display
xor BX,BX
mov AH,02H
mov DX,060DH
int 10H
writestr text10
mov AH,02H
mov DX,080DH
int 10H
writestr text6
mov AH,02H
mov DX,0814H
int 10H
mov AL,[score]
writeAL
Wait_char
Wait_char
jmp Draw_menu
arrow_up:
mov AX,[Sput_pos_Y] ;is Sputnik on the land..
mov BX,[Land_pos_Y]
sub BX,SPUT_SIZE_Y+LAND_WIDTH+SPUT_FROM_LAND
cmp AX,BX
jnz NEXT
dec AX
mov BX,-1
mov [Sput_pos_Y],AX
mov [Sput_fly],BX
jmp NEXT
arrow_down:
mov word [Sput_fly],0
jmp NEXT
arrow_right:
mov word [Sput_pos_X_cahnge],1
jmp NEXT
arrow_left:
mov word [Sput_pos_X_cahnge],-1
jmp NEXT
num_five:
mov word [Sput_pos_X_cahnge],0
jmp NEXT
num_End:
num_minus:
num_plus:
numPgDown:
numPgUp:
num_Ins:
jmp NEXT
num_del:
jmp EXIT_E
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%include "PROCS.ASM"
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
segment .data
text1: db "START GAME",0
text2: db "EXIT GAME",0
text3: db "SPUTNIK",0
text5: db "lifes:",0
text6: db "score:",0
text9: db "YOU WIN",0
text10: db "GAME OVER",0
ver: db "SPUTNIK ver. 2.2",0
keyboard: dw arrow_up,
dw numPgUp,
dw num_minus,
dw arrow_left,
dw num_five,
dw arrow_right,
dw num_plus,
dw num_End,
dw arrow_down,
dw numPgDown,
dw num_Ins,
dw num_del
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
segment .bss
;MENU variables
menu_rect_position resb 1 ;position of rectangle in menu
lifes resb 1
score resb 1
citac resw 1
Sput_fly resw 1
game_speed resw 1
var resw 1
Sput_pos_X resw 1
Sput_pos_Y resw 1
Sput_old_pos_X resw 1
Sput_old_pos_Y resw 1
Sput_pos_X_cahnge resw 1
Sput_shimmer resw 1
Sput_act_color resw 1
Land_pos_Y resw 1
LandUP_pos_Y resw 1
LandUP_exist resw 1
LandUP_code resw 1
LandUP_size resw 1
LandUP_pos_X resw 1
Land_new_pos_Y resw 1
Fence_sizeX resw 1
Fence_sizeY resw 1
Fence_pos_X resw 1
Fence_pos_Y resw 1
end