; graphics.asm ; Graphics Library ; Author: Matt .MODEL LARGE .586 ;For using 32 bit registers and pentium commands PUBLIC _SetVideoMode, _RestoreVideoMode, _DrawPixel, _LineDisplay, _DrawThingy, _DrawExplode, _DrawSolidBox, _Draw_Solid_Circle, _DrawBox, _SetPaletteColor, _CircleDisplay, _DrawLine, _DrawCharacterNoBG, _DrawCharacter, _ColorDisplay, _BulletDisplay, _StringLength, _putString13hNoBG, _putString13h, _ClearVideoBuffer, _GetString13h, _DrawBigExplode, _PrintVideoBuffer, _DrawBullet, _PixPutString13h, _Draw_Circle, _GetString13h, _ExplodeDisplay _TEXT SEGMENT WORD PUBLIC USE16 'CODE' ;---------------------------------------------------------- _SetVideoMode PROC FAR ; PAGE 566 ; This procedure saves the current video mode, switches to ; a new mode, and points ES to the video segment. ; Input: none ; Output: none ; Stack Frame none ;---------------------------------------------------------- push ax ; preserve ax mov ah,0Fh ; get current video mode int 10h ; call video bios interupt mov saveMode,al ; save mode mov ah,0 ; set new video mode mov al,13h ; to mode 13h int 10h ; call video bios interupt mov ax,fs ; save fs mov oldFS,ax mov ax,0A000h ; video segment address mov fs,ax ; FS = A000h (video segment). pop ax ; restore ax ret ; return to caller _SetVideoMode ENDP ;---------------------------------------------------------- _SetPaletteColor PROC FAR ; This procedure changes a color palette entry ; Input: (Red,Green,Blue,Palette entry) ; Output: none ; Stack Frame [ebp] old ebp ; [ebp+4] return address ; [ebp+8] Red intensity ; [ebp+10] Green intensity ; [ebp+12] Blue intensity ; [ebp+14] Palette Entry Number ;---------------------------------------------------------- push ebp mov ebp,esp push ax push dx mov dx,03C8h ; video palette port location mov al,[ebp+14] out dx,al mov dx,03C9h ; color port mov ax,[ebp+8] ; red out dx,al mov ax,[ebp+10] ; green out dx,al mov ax,[ebp+12] ; blue out dx,al pop dx pop ax pop ebp ret _SetPaletteColor ENDP ;---------------------------------------------------------- _ClearVideoBuffer PROC FAR ; This procedure makes video buffer black ; Input: none ; Output: none ; Stack Frame none ;---------------------------------------------------------- push bx ; preserve di push ecx ; preserve ecx push di ; preserve di push si ; preserve si mov di, OFFSET VideoBuffer ; si points to buffer start mov bx,di ; copy bx add bx,64000d ; di is end of video buffer mov si,4 ; si = 4, 4 bytes per cycle xor ecx,ecx ; ecx is 0, black ClearNextBytes: mov es:[di],ecx add di,si ; next counter/pixel cmp di,bx ; if bx < 64000 jnae ClearNextBytes ; clear next 4 pixels pop si ; restore si pop di ; restore di pop ecx ; restore ecx pop bx ; restore bx ret ; returm to caller _ClearVideoBuffer ENDP ;---------------------------------------------------------- _PrintVideoBuffer PROC FAR ; This procedure puts the video buffer to the screen ; I couldn't make this faster if my life depended on it. ; Input: none ; Output: none ; Stack Frame none ;---------------------------------------------------------- push ebp ; preserve ebp push eax ; preserve eax push ebx ; preserve ebx push ecx ; preserve ecx push edx ; preserve edx push di ; preserve di push si ; preserve si mov si, OFFSET VideoBuffer ; bx points to buffer start xor di,di ; si=0, points to pixel 0 mov bp,4 ; 4 bytes per copy CopyNextBytes: mov eax,es:[si] ; move buffer DWORD to eax add si,bp ; next chunk mov ebx,es:[si] ; move buffer DWORD to ebx add si,bp ; next chunk mov ecx,es:[si] ; move buffer DWORD to ecx add si,bp ; next chunk mov edx,es:[si] ; move buffer DWORD to edx add si,bp ; next chunk mov fs:[di],eax ; move chunk on screen add di,bp ; next chunk mov fs:[di],ebx ; move chunk on screen add di,bp ; next chunk mov fs:[di],ecx ; move chunk on screen add di,bp ; next chunk mov fs:[di],edx ; move chunk on screen add di,bp ; next chunk cmp di,64000 ; if di < 64000 jnae CopyNextBytes ; copy next pixels pop si ; restore si pop di ; restore di pop edx ; restore edx pop ecx ; restore ecx pop ebx ; restore ebx pop eax ; restore eax pop ebp ; restore ebp ret ; return to caller _PrintVideoBuffer ENDP ;---------------------------------------------------------- _DrawPixel PROC FAR ; Mode 13h is 320 X 200. ; This procedure draws a colored pixel at (x,y). ; If the pixel is offscreen it shifts it to the opposite side of screen. ; Input: (x value, y value, color index) ; Output: returns dh = -1 if collision takes place. else dh = 0 ; Stack Frame [ebp] old ebp ; [ebp+4] return address ; [ebp+8] color index ; [ebp+10] y value ; [ebp+12] x value ; ;---------------------------------------------------------- push ebp ; preserve old ebp mov ebp,esp ; link stack frame push ebx ; preserve bx push cx ; preserve cx push si ; preserve si LoadX: mov bx,[ebp+12] ; load x value CheckXNeg: cmp bx,0h ; if x>0 jg CheckXPos ; check to see if too big add bx,320d ; else add 320 to make positive jmp CheckXNeg ; then check again CheckXPos: cmp bx,319d ; if x <= 319 jbe LoadY ; goto LoadY sub bx,320d ; else subtract 320 jmp CheckXPos ; and check X value again LoadY: mov cx,[ebp+10] ; load y value CheckYNeg: cmp cx,0h ; if y>0 jg CheckYPos ; check to see i too big add cx,200d ; else add 200 to make positive jmp CheckYNeg ; then check again CheckYPos: cmp cx,199d ; if y <= 199 jbe CalcOffset ; goto CalcOffset sub cx,200d ; else subtract 200 jmp CheckYPos ; and check X value again CalcOffset: rol ebx,16 ; shove bx to left side of ebx mov bx,cx ; copy Y shl cx,8 ; mul Y by 256 using shift left shl bx,6 ; mul Y by 64 using shift left add cx,bx ; 320*Y = 256*Y+64*Y ror ebx,16 ; mov x value back into bx add bx,cx ; add x-coordinate mov si,OFFSET VideoBuffer ; bx points to video buffer mov cx,[ebp+8] ; load color index mov ch,fs:[bx] ; save pixel to be written on mov es:[bx+si],cl ; store color index CollideCheck: cmp ch,0h ; was next pixel black? je FinishDrawPix ; if so, no collision happened cmp ch,31d ; was next pixel black? je FinishDrawPix ; if so, no collision happened cmp ch,cl ; was next pixel same color je FinishDrawPix ; if so, no collision happened mov dh,-1d ; else, collision happened FinishDrawPix: pop si pop cx ; restore cx pop ebx ; restore bx pop ebp ; restore ebp Return: ret ; return to caller _DrawPixel ENDP ;---------------------------------------------------------- _DrawBox PROC FAR ; Mode 13h is 320 X 200. ; This procedure draws a box defined by any two x and two y values. ; ; Input: (x1 value, y1 value, x1 value, y2 value, color) ; Output: none ; Stack Frame [ebp] old ebp ; [ebp+4] return address ; [ebp+8] color index ; [ebp+10] y2 value ; [ebp+12] x2 value ; [ebp+14] y1 value ; [ebp+16] x1 value ; ;---------------------------------------------------------- push ebp ; save old ebp mov ebp,esp ; link stack frame push bx ; preserve bx push cx ; preserve cx push di ; preserve di push si ; preserve si mov bx,[ebp+16] ; x1 mov cx,[ebp+14] ; y1 mov di,[ebp+12] ; x2 mov si,[ebp+10] ; y2 push bx ; push x1 value push cx ; push y1 value push di ; push x2 value push cx ; push y2 value push [ebp+8] ; pixel pallete color call _DrawLine ; Top Horizontal add esp,10 ; clean up stack push bx ; push x1 value push si ; push y1 value push di ; push x2 value push si ; push y2 value push [ebp+8] ; pixel pallete color call _DrawLine ; Bottom Horizontal add esp,10 ; clean up stack push bx ; push x1 value push cx ; push y1 value push bx ; push x2 value push si ; push y2 value push [ebp+8] ; pixel pallete color call _DrawLine ; Left Vertical add esp,10 ; clean up stack push di ; push x1 value push cx ; push y1 value push di ; push x2 value push si ; push y2 value push [ebp+8] ; pixel pallete color call _DrawLine ; Right Vertical add esp,10 ; clean up stack pop si ; restore si pop di ; restore di pop cx ; restore cx pop bx ; restore bx pop ebp ; restore ebp ret ; return to caller _DrawBox ENDP ;---------------------------------------------------------- _DrawSolidBox PROC FAR ; Mode 13h is 320 X 200. ; This procedure draws a solid box defnined by any two x and two y values. ; ; Input: (x1 value, y1 value, x1 value, y2 value, color) ; Output: none ; Stack Frame [ebp] old ebp ; [ebp+4] return address ; [ebp+8] color index ; [ebp+10] y2 value ; [ebp+12] x2 value ; [ebp+14] y1 value ; [ebp+16] x1 value ; ;---------------------------------------------------------- push ebp ; save old ebp mov ebp,esp ; link stack frame push bx ; preserve bx push ecx ; preserve cx push di ; preserve di push si ; preserve si mov di,[ebp+16] ; x1 mov bx,[ebp+14] ; y1 mov cx,[ebp+12] ; x2 rol ecx,16 ; shove x2 left mov cx,[ebp+10] ; y2 xCheck: ror ecx,16 ; x2 active cmp di,cx ; if x1 < x2 jl yCheck ; check y xchg di,cx ; else swith values yCheck: rol ecx,16 ; y2 active cmp bx,cx ; if y1 < y2 jl BoxDraw1 ; draw box xchg bx,cx ; else switch values BoxDraw1: mov si,di ; store leftmost x value ror ecx,16 ; x2 active BoxDraw2: push si ; push x value push bx ; push y value push [ebp+8] ; pixel pallete color call _DrawPixel ; Draw a pixel! add esp,6 ; clean up stack inc si ; next x cmp si,cx ; if x <= xmax jbe BoxDraw2 ; next pixel right rol ecx,16 ; y2 active inc bx ; next y val cmp bx,cx ; if y <= ymax jbe BoxDraw1 ; next line pop si ; restore si pop di ; restore di pop ecx ; restore cx pop bx ; restore bx pop ebp ; restore ebp ret ; return to caller _DrawSolidBox ENDP ;---------------------------------------------------------- _Draw_Circle PROC FAR ; Mode 13h is 320 X 200. ; This procedure draws a circle defined by point(x,y) and a radius. ; This procedure uses Bresenham's algorithm. ; Input: (x,y,r,color) ; Output: none ; Stack Frame [ebp] old ebp ; [ebp+4] return address ; [ebp+8] color index ; [ebp+10] radius ; [ebp+12] y value ; [ebp+14] x value ; ;---------------------------------------------------------- push ebp ; save old ebp mov ebp,esp ; link stack frame push ax ; preserve ax push ebx ; preserve bx push cx ; preserve cx push di ; preserve di push si ; preserve si xor dx,dx ; clear dx for collision detection mov bx,[ebp+10] ; y = radius rol ebx,16 ; shove y into other 16 bits of ebx mov bx,[ebp+10] ; load radius shl bx,1 ; radius*2 neg bx ; -radius*2 add bx,3d ; d = 3-2*r xor ax,ax ; x = 0 ror ebx,16 ; Y active PlotCircPixles: push cx mov cx,ax CircleOctant1: mov di,[ebp+14] ; add di,bx ; push di ; push x value mov si,[ebp+12] ; add si,cx ; push si ; push y value push [ebp+8] ; pixel pallete color call _DrawPixel ; Draw a pixel add esp,6 ; clean up stack CircleOctant2: mov di,[ebp+14] ; add di,cx ; push di ; push x value mov si,[ebp+12] ; add si,bx ; push si ; push y value push [ebp+8] ; pixel pallete color call _DrawPixel ; Draw a pixel add esp,6 ; clean up stack CircleOctant3: mov di,[ebp+14] ; sub di,cx ; push di ; push x value mov si,[ebp+12] ; add si,bx ; push si ; push y value push [ebp+8] ; pixel pallete color call _DrawPixel ; Draw a pixel add esp,6 ; clean up stack CircleOctant4: mov di,[ebp+14] ; sub di,bx ; push di ; push x value mov si,[ebp+12] ; add si,cx ; push si ; push y value push [ebp+8] ; pixel pallete color call _DrawPixel ; Draw a pixel add esp,6 ; clean up stack CircleOctant5: mov di,[ebp+14] ; sub di,bx ; push di ; push x value mov si,[ebp+12] ; sub si,cx ; push si ; push y value push [ebp+8] ; pixel pallete color call _DrawPixel ; Draw a pixel add esp,6 ; clean up stack CircleOctant6: mov di,[ebp+14] ; sub di,cx ; push di ; push x value mov si,[ebp+12] ; sub si,bx ; push si ; push y value push [ebp+8] ; pixel pallete color call _DrawPixel ; Draw a pixel add esp,6 ; clean up stack CircleOctant7: mov di,[ebp+14] ; add di,cx ; push di ; push x value mov si,[ebp+12] ; sub si,bx ; push si ; push y value push [ebp+8] ; pixel pallete color call _DrawPixel ; Draw a pixel add esp,6 ; clean up stack CircleOctant8: mov di,[ebp+14] ; add di,bx ; push di ; push x value mov si,[ebp+12] ; sub si,cx ; push si ; push y value push [ebp+8] ; pixel pallete color call _DrawPixel ; Draw a pixel add esp,6 ; clean up stack mov ax,cx pop cx rol ebx,16 ; decision var active cmp bx,0h ; if d<0 jg CircDgreater0 ; no change in y mov cx,ax ; shl cx,2 ; add cx,6 ; add bx,cx ; d=d+4*x+6 jmp CircNextX ; CircDgreater0: ror ebx,16 ; Y active mov cx,ax ; sub cx,bx ; shl cx,2 ; add cx,10d ; rol ebx,16 ; decision var active add bx,cx ; d=d+4*(x-y)+10 ror ebx,16 ; Y active dec bx ; y=y-1 ror ebx,16 ; decision var active CircNextX: ror ebx,16 ; Y active cmp ax,bx ; jae ExitDrawCircle ; inc ax ; jmp PlotCircPixles ; ExitDrawCircle: mov dl,dh ; COLLISION DETECTION pop si ; restore si pop di ; restore di pop cx ; restore cx pop ebx ; restore bx pop ax ; restore ax pop ebp ; restore ebp ret _Draw_Circle ENDP ;---------------------------------------------------------- _Draw_Solid_Circle PROC FAR ; Mode 13h is 320 X 200. ; This procedure draws a circle defined by point(x,y) and a radius. ; This procedure uses Bresenham's algorithm. ; Input: (x,y,r,color) ; Output: none ; Stack Frame [ebp] old ebp ; [ebp+4] return address ; [ebp+8] color index ; [ebp+10] radius ; [ebp+12] y value ; [ebp+14] x value ; ;---------------------------------------------------------- push ebp ; save old ebp mov ebp,esp ; link stack frame push ax ; preserve ax push ebx ; preserve bx push cx ; preserve cx push di ; preserve di push si ; preserve si xor dx,dx ; clear dx for collision detection mov bx,[ebp+10] ; y = radius rol ebx,16 ; shove y into other 16 bits of ebx mov bx,[ebp+10] ; load radius shl bx,1 ; radius*2 neg bx ; -radius*2 add bx,3d ; d = 3-2*r xor ax,ax ; x = 0 ror ebx,16 ; Y active mov circleContact, al ;initialize circleContact PlotCircPixles: push cx mov cx,ax CircleOctant2: mov di,[ebp+14] ; add di,cx ; push di ; push x value mov si,[ebp+12] ; add si,bx ; push si ; push y value CircleOctant3: mov di,[ebp+14] ; sub di,cx ; push di ; push x value mov si,[ebp+12] ; add si,bx ; push si ; push y value push [ebp+8] ; pixel pallete color call _DrawLine ; draw a horizontal line add esp,10 ; clean up stack cmp dl, -1 ;see if contact made jne CircleOctant1 mov circleContact, dl CircleOctant1: mov di,[ebp+14] ; add di,bx ; push di ; push x value mov si,[ebp+12] ; add si,cx ; push si ; push y value CircleOctant4: mov di,[ebp+14] ; sub di,bx ; push di ; push x value mov si,[ebp+12] ; add si,cx ; push si ; push y value push [ebp+8] ; pixel pallete color call _DrawLine ; draw a horizontal line add esp,10 ; clean up stack cmp dl, -1 ;see if contact made jne CircleOctant5 mov circleContact, dl CircleOctant5: mov di,[ebp+14] ; sub di,bx ; push di ; push x value mov si,[ebp+12] ; sub si,cx ; push si ; push y value CircleOctant8: mov di,[ebp+14] ; add di,bx ; push di ; push x value mov si,[ebp+12] ; sub si,cx ; push si ; push y value push [ebp+8] ; pixel pallete color call _DrawLine ; draw a horizontal line add esp,10 ; clean up stack cmp dl, -1 ;see if contact made jne CircleOctant6 mov circleContact, dl CircleOctant6: mov di,[ebp+14] ; sub di,cx ; push di ; push x value mov si,[ebp+12] ; sub si,bx ; push si ; push y value CircleOctant7: mov di,[ebp+14] ; add di,cx ; push di ; push x value mov si,[ebp+12] ; sub si,bx ; push si ; push y value push [ebp+8] ; pixel pallete color call _DrawLine ; draw a horizontal line add esp,10 ; clean up stack cmp dl, -1 ;see if contact made jne continueCircle mov circleContact, dl continueCircle: mov ax,cx pop cx rol ebx,16 ; decision var active cmp bx,0h ; if d<0 jg CircDgreater0 ; no change in y mov cx,ax ; shl cx,2 ; add cx,6 ; add bx,cx ; d=d+4*x+6 jmp CircNextX ; CircDgreater0: ror ebx,16 ; Y active mov cx,ax ; sub cx,bx ; shl cx,2 ; add cx,10d ; rol ebx,16 ; decision var active add bx,cx ; d=d+4*(x-y)+10 ror ebx,16 ; Y active dec bx ; y=y-1 ror ebx,16 ; decision var active CircNextX: ror ebx,16 ; Y active cmp ax,bx ; jae ExitDrawCircle ; inc ax ; jmp PlotCircPixles ; ExitDrawCircle: mov dl,circleContact ; COLLISION DETECTION pop si ; restore si pop di ; restore di pop cx ; restore cx pop ebx ; restore bx pop ax ; restore ax pop ebp ; restore ebp ret _Draw_Solid_Circle ENDP ;---------------------------------------------------------- _DrawLine PROC FAR ; Mode 13h is 320 X 200. ; This procedure draws any line from (x1,y1) to (x2,y2). ; It uses the Bresenham Line Algorithm ; Input: (x value, y value, length, color index) ; Output: none ; Stack Frame [ebp] old ebp ; [ebp+4] return address ; [ebp+8] color index ; [ebp+10] y2 ; [ebp+12] x2 ; [ebp+14] y1 ; [ebp+16] x1 ; ;---------------------------------------------------------- push ebp ; save old ebp mov ebp,esp ; link stack frame push ebx ; preserve bx push ecx ; preserve cx push di ; preserve di push si ; preserve si xor dx,dx ; clear dx for collision detection mov bx,[ebp+16] ; right side of ebx has X1 rol ebx,16 ; stuff X1 to left side of ebx mov bx,[ebp+14] ; bx is Y1, Y1 active mov cx,[ebp+12] ; cx is X2 rol ecx,16 ; stuff X2 to left side of ecx mov cx,[ebp+10] ; cx is Y2, Y2 active ror ebx,16 ; X1, active ror ecx,16 ; X2, active _SortPoints: cmp bx,cx ; X1 X2 jl LineInitialize ; always left to right xchg bx,cx ; X1, X2 rol ebx,16 ; Y1 active rol ecx,16 ; Y2 active xchg bx,cx ; cmp bx,cx ; is Y1=Y2 je HorizLineCase ; if so draw horizontal line ror ebx,16 ; X1 active ror ecx,16 ; X2 active cmp bx,cx ; is X1=X2 je VertLineCase ; if so draw vertical line LineInitialize: mov di,cx ; sub di,bx ; dX=X2-X1 rol ebx,16 ; Y1 active rol ecx,16 ; Y2 active cmp bx,cx ; is Y1 > Y2 jg Y1greatthanY2 ; if so subtract in diff order mov si,cx ; sub si,bx ; dY=Y2-Y1 jmp ChooseOctant Y1greatthanY2: mov si,bx ; sub si,cx ; dY=Y1-Y2 ChooseOctant: cmp di,si ; if di=si je DiagLineCase ; then use diagonal line routine shl di,1 ; di=ABS(dX)*2 shl si,1 ; si=ABS(dY)*2 cmp di,si ; if dXY2, neg slope ;X dominant and Y is increasing as X increases RisingY: mov cx,di ; dx Y2 is now for decision var shr cx,1 ; neg cx ; add cx,si ; dx = ABS(dY)*2-ABS(dX) LineLoop1: ror ebx,16 ; X1 active push bx ; push x value rol ebx,16 ; Y1 active push bx ; push y value push [ebp+8] ; pixel pallete color call _DrawPixel ; Draw a pixel add esp,6 ; clean up stack ror ebx,16 ; X1 active ror ecx,16 ; X2 active cmp bx,cx ; if x=x2 je LineDrawnExit ; exit rol ecx,16 ; Y2 Decision var is active cmp cx,0h ; if dx<0 jl NegD1 ; don't increment y rol ebx,16 ; Y1 active inc bx ; y++ sub cx,di ; d -= ABS(dX)*2 ror ebx,16 ; X1 active NegD1: inc bx ; x++ add cx,si ; d += ABS(dY)*2 rol ebx,16 ; Y1 active jmp LineLoop1 ; loop until x1=x2 ;X dominant and Y is decreasing as X increases DroppingY: mov cx,di ; dx Y2 is now for decision var shr cx,1 ; neg cx ; add cx,si ; dx = ABS(dY)*2-ABS(dX) LineLoop2: ror ebx,16 ; X1 active push bx ; push x value rol ebx,16 ; Y1 active push bx ; push y value push [ebp+8] ; pixel pallete color call _DrawPixel ; Draw a pixel add esp,6 ; clean up stack ror ebx,16 ; X1 active ror ecx,16 ; X2 active cmp bx,cx ; if x=x2 je LineDrawnExit ; exit rol ecx,16 ; Y2 Decision var is active cmp cx,0h ; if dx<0 jl NegD2 ; don't decrement y rol ebx,16 ; Y1 active dec bx ; y-- sub cx,di ; d -= ABS(dX)*2 ror ebx,16 ; X1 active NegD2: inc bx ; x++ add cx,si ; d += ABS(dY)*2 rol ebx,16 ; Y1 active jmp LineLoop2 ; loop until x1=x2 Y_Dominant: _SortPoints2: cmp bx,cx ; if Y1>Y2, swap points jl PickSlope ; always low to high Y value xchg bx,cx ; swap Y1, Y2 ror ebx,16 ; X1 active ror ecx,16 ; X2 active xchg bx,cx ; swap X1, X2 ror ebx,16 ; X1 active ror ecx,16 ; X2 active PickSlope: ror ebx,16 ; X1 active ror ecx,16 ; X2 active cmp bx,cx ; if X1 X2 jg LineDrawnExit ; done plotting pixel jmp DoHorizLine ; else plot next pixel VertLineCase: mov si,bx ; load X1 rol ecx,16 ; Y2 active mov di,cx ; rol ebx,16 ; Y1 active cmp bx,di ; if Y1>Y, xchg values jl DoVertLine ; always lower to higher value xchg bx,di ; sorting DoVertLine: push si ; push x value push bx ; push y value push [ebp+8] ; pixel pallete color call _DrawPixel ; Draw a pixel add esp,6 ; clean up stack inc bx ; next y value cmp bx,di ; if y1 > y2 jg LineDrawnExit ; done plotting pixel jmp DoVertLine ; else plot next pixel DiagLineCase: mov di,[ebp+8] ; load color into di cmp bx,cx ; if Y1>Y2, neg line jg NegDiagline ; PosDiagLine: ror ebx,16 ; X1 active mov si,bx ; load x1 rol ebx,16 ; Y1 active ror ecx,16 ; X2 active DoPosDiagLine: push si ; push x value push bx ; push y value push di ; pixel pallete color call _DrawPixel ; Draw a pixel add esp,6 ; clean up stack inc si ; next x value inc bx ; next x value cmp si,cx ; if x1 > X2 jg LineDrawnExit ; done plotting pixel jmp DoPosDiagLine ; else plot next pixel NegDiagLine: ror ebx,16 ; X1 active mov si,bx ; load X1 rol ebx,16 ; Y1 active ror ecx,16 ; X2 active DoNegDiagLine: push si ; push x value push bx ; push y value push di ; pixel pallete color call _DrawPixel ; Draw a pixel add esp,6 ; clean up stack inc si ; next x value dec bx ; next y value cmp si,cx ; if x1 > X2 jg LineDrawnExit ; done plotting pixel jmp DoNegDiagLine ; else plot next pixel LineDrawnExit: mov dl,dh ; COLLISION DETECTION pop si ; restore si pop di ; restore di pop ecx ; restore cx pop ebx ; restore bx pop ebp ; restore ebp ret ; return to caller _DrawLine ENDP ;---------------------------------------------------------- _DrawBullet PROC FAR ; work around bullet procedure ; Input: (x value, y value, color index) ; Output: returns dl = -1 if collision takes place. else dl = 0 ; Stack Frame [ebp] old ebp ; [ebp+4] return address ; [ebp+8] color index ; [ebp+10] y value ; [ebp+12] x value ; ;---------------------------------------------------------- push ebp ; save old ebp mov ebp,esp ; link stack frame xor dx,dx ; clear dx for collision detection push [ebp+12] ; push x value push [ebp+10] ; push y value push [ebp+8] ; pixel pallete color call _DrawPixel ; Draw a pixel! add esp,6 ; clean up stack mov dl,dh ; COLLISION DETECTION pop ebp ; restore ebp ret ; return to caller _DrawBullet ENDP ;---------------------------------------------------------- _DrawCharacterNoBG PROC FAR ; Mode 13h is 320 X 200. ; 13h Text is 40 X 25. ; This proc draws a single character with transparent background in mode 13h ; Character Background is transparent. ; Input: (Color, Character, Column, Row) ; Output: none ; Stack Frame [ebp] old ebp ; [ebp+4] return address ; [ebp+8] color index ; [ebp+10] Character ; [ebp+12] Row Y Value ; [ebp+14] Column X value ; ;---------------------------------------------------------- push ebp ; preserve ebp mov ebp,esp ; link stack frame push ax ; preserve ax push bx ; preserve bx push cx ; preserve cx push dx ; preserve dx push di ; preserve di push esi ; preserve si push gs ; preserve gs push es ; preserve es, the next int call modifies it push ebp ; preserve ebp, the next int call modifies it xor ebp,ebp ; ebp=0 mov ax,1130h ; magical int 10h command mov bx,0300h ; magical int 10h command int 10h ; es:bp points to font usually F000:FA6E ?? mov ax,es ; temp copy es to ax mov gs,ax ; mov ax into gs mov esi,ebp ; gs:si points to font table pop ebp ; restore ebp pop es ; restore es xor eax,eax ; mov ax,[ebp+10] ; load char shl eax,3 ; offset into font table add esi,eax ; gs:si points to char in table mov ax,[ebp+14] ; Column X value shl ax,3 ; Pixel X Value, left side of char mov cx,[ebp+12] ; Row Y value shl cx,3 ; Pixel Y value bottom of char mov bl,0 ; Row counter Y mov di,ax ; Copy x pixel, it is changed and reset in loop ; nextRow: mov ax,di ; Reset leftmost x value mov dh,gs:[esi] ; load top byte of char mov dl,0 ; Column counter X BitChecker: rol dh,1 ; rotate and copy left bit to Carry flag jc C_One ; if carry is one print char bit C_Zero: ; optional background color pixelDraw inc ax ; next x pixel inc dl ; inc column counter cmp dl,8 ; if column counter < 8 jb BitChecker ; check next bit, else next row inc bl ; next Row counter inc esi ; next Byte/Row inc cx ; next Y pixel cmp bl,8 ; if row counter < 8 jb nextRow ; check next row, jmp CharDone ; else char done C_One: push ax ; x value push cx ; y value push [ebp+8] ; color call _DrawPixel add esp,6 ; clean up stack inc ax ; next x pixel inc dl ; inc column counter cmp dl,8 ; if column counter < 8 jb BitChecker ; check next bit, else next row inc bl ; next Row counter inc esi ; next Byte/Row inc cx ; next Y pixel cmp bl,8 ; if row counter < 8 jb nextRow ; check next row, else char done CharDone: pop gs ; restore gs pop esi ; restore si pop di ; restore di pop dx ; restore dx pop cx ; restore cx pop bx ; restore bx pop ax ; restore ax pop ebp ; restore ebp ret ; return to caller _DrawCharacterNoBG ENDP ;---------------------------------------------------------- _putString13hNoBG PROC FAR ; 13h Text is 40 X 25. ; This procedure draws a colored string at a given text locale. ; Character Background is transparent. ; Input: (x value, y value, length, color index) ; Output: none ; Stack Frame [ebp] old ebp ; [ebp+4] return address ; [ebp+8] String offset ; [ebp+10] String Segment ; [ebp+12] Color of letter ; [ebp+14] Row Y value ; [ebp+16] Column X value ; ;---------------------------------------------------------- push ebp ; preserve ebp mov ebp,esp ; link stack frame push eax ; preserve eax push ebx ; preserve ebx push ecx ; preserve ecx push edx ; preserve edx push di ; preserve di push esi ; preserve esi push ds ; preserve ds mov ax,[ebp+14] ; Row value Y mov bx,[ebp+16] ; Column value X mov cx,[ebp+12] ; Color mov dx,[ebp+10] ; load segment of string mov ds,dx ; into ds xor esi,esi ; esi=0 xor edx,edx ; wack edx mov si,[ebp+8] ; load offset of string putLoop: mov dl,[esi] ; put a character in dl cmp dl,0h ; does dl equal null je putLoopEND ; if so exit loop push bx ; Column Value push ax ; Row value push dx ; Character push cx ; color index call _DrawCharacterNoBG ; draw a char with trans bg add esp,8 ; Clean up Stack inc bx ; next column inc esi ; esi ++, get next character jmp putLoop ; loop to start of loop1 putLoopEND: pop ds pop esi pop di pop edx pop ecx pop ebx pop eax pop ebp ret ; return to caller _putString13hNoBG ENDP ;---------------------------------------------------------- _PixDrawChar PROC FAR ; Mode 13h is 320 X 200. ; 13h Text is 40 X 25. ; This proc draws a single character with background in mode 13h ; Character Background is colored. Starts at upper left corner of char ; Input: (Color, Character, (x,y)) ; Output: none ; Stack Frame [ebp] old ebp ; [ebp+4] return address ; [ebp+8] Character color index ; [ebp+10] BackGround Color index ; [ebp+12] Character ; [ebp+14] Pixel Y Value ; [ebp+16] Pixel X value ; ;---------------------------------------------------------- push ebp ; preserve ebp mov ebp,esp ; link stack frame push ax ; preserve ax push bx ; preserve bx push cx ; preserve cx push dx ; preserve dx push di ; preserve di push esi ; preserve si push gs ; preserve gs push es ; preserve es, the next int call modifies it push ebp ; preserve ebp, the next int call modifies it xor ebp,ebp ; wack ebp mov ax,1130h ; magical int 10h command mov bx,0300h ; magical int 10h command int 10h ; es:bp points to font usually F000:FA6E ?? mov ax,es ; temp copy es to ax mov gs,ax ; mov ax into gs mov esi,ebp ; gs:si points to font table pop ebp ; restore ebp pop es ; restore es xor eax,eax ; wack eax mov ax,[ebp+12] ; load char shl eax,3 ; offset into font table add esi,eax ; gs:si points to char in table mov ax,[ebp+16] ; Pixel X Value, left side of char ;;shl ax,3 ; Pixel X Value, left side of char mov cx,[ebp+14] ; Row Y value ;;shl cx,3 ; Pixel Y value bottom of char mov bl,0 ; Row counter Y mov di,ax ; Copy x pixel, it is changed and reset in loop nextRow: mov ax,di ; Reset leftmost x value mov dh,gs:[esi] ; load top byte of char mov dl,0 ; Column counter X BitChecker: rol dh,1 ; rotate and copy left bit to Carry flag jc C_One ; if carry is one print char bit C_Zero: push ax ; x value push cx ; y value push [ebp+10] ; color call _DrawPixel ; draw single pixel add esp,6 ; clean up stack inc ax ; next x pixel inc dl ; inc column counter cmp dl,8 ; if column counter < 8 jb BitChecker ; check next bit, else next row inc bl ; next Row counter inc esi ; next Byte/Row inc cx ; next Y pixel cmp bl,8 ; if row counter < 8 jb nextRow ; check next row, jmp CharDone ; else char done C_One: push ax ; x value push cx ; y value push [ebp+8] ; color call _DrawPixel ; draw single pixel add esp,6 ; clean up stack inc ax ; next x pixel inc dl ; inc column counter cmp dl,8 ; if column counter < 8 jb BitChecker ; check next bit, else next row inc bl ; next Row counter inc esi ; next Byte/Row inc cx ; next Y pixel cmp bl,8 ; if row counter < 8 jb nextRow ; check next row, else char done CharDone: pop gs ; restore gs pop esi ; restore si pop di ; restore di pop dx ; restore dx pop cx ; restore cx pop bx ; restore bx pop ax ; restore ax pop ebp ; restore ebp ret ; return to caller _PixDrawChar ENDP ;---------------------------------------------------------- _PixPutString13h PROC FAR ; 13h Text is 40 X 25. ; This procedure draws a colored string at a given text locale. ; Character Background is colored. Starts at upper left corner of string ; Input: (x value, y value, length, color index) ; Output: none ; Stack Frame [ebp] old ebp ; [ebp+4] return address ; [ebp+8] String offset ; [ebp+10] String Segment ; [ebp+12] Color of letter ; [ebp+14] Background Color ; [ebp+16] Row Y value in pixels ; [ebp+18] Column X value in pixels ; ;---------------------------------------------------------- push ebp ; prserve ebp mov ebp,esp ; link stack frame push eax ; preserve eax push ebx ; preserve ebx push ecx ; preserve ecx push edx ; preserve edx push di ; preserve di push esi ; preserve esi push ds ; preserve ds mov ax,[ebp+16] ; Row Value Y mov bx,[ebp+18] ; Column value X mov cx,[ebp+12] ; Color of char mov di,[ebp+14] ; BackGround Color mov dx,[ebp+10] ; load segment of string mov ds,dx ; load segment to ds xor esi,esi ; esi=0 xor edx,edx ; wack edx mov si,[ebp+8] ; load offset of string putLoop: mov dl,[esi] ; put a character in dl cmp dl,0h ; does dl equal null je putLoopEND ; if so exit loop push bx ; Column value, X pixels push ax ; Row Value, Y pixels push dx ; Character push di ; BackGround Color push cx ; color index call _PixDrawChar ; draw 1 char add esp,10 ; Clean up Stack add bx,8 ; next column inc esi ; esi ++, get next character jmp putLoop ; loop to start of loop1 putLoopEND: pop ds pop esi pop di pop edx pop ecx pop ebx pop eax pop ebp ret ; return to caller _PixPutString13h ENDP ;---------------------------------------------------------- _DrawCharacter PROC FAR ; Mode 13h is 320 X 200. ; 13h Text is 40 X 25. ; This proc draws a single character with background in mode 13h ; Character Background is colored. ; Input: (Color, Character, Column, Row) ; Output: none ; Stack Frame [ebp] old ebp ; [ebp+4] return address ; [ebp+8] Character color index ; [ebp+10] BackGround Color index ; [ebp+12] Character ; [ebp+14] Row Y Value ; [ebp+16] Column X value ; ;---------------------------------------------------------- push ebp ; preserve ebp mov ebp,esp ; link stack frame push ax ; preserve ax push bx ; preserve bx push cx ; preserve cx push dx ; preserve dx push di ; preserve di push esi ; preserve si push gs ; preserve gs push es ; preserve es, the next int call modifies it push ebp ; preserve ebp, the next int call modifies it xor ebp,ebp ; wack ebp mov ax,1130h ; magical int 10h command mov bx,0300h ; magical int 10h command int 10h ; es:bp points to font usually F000:FA6E ?? mov ax,es ; temp copy es to ax mov gs,ax ; mov ax into gs mov esi,ebp ; gs:si points to font table pop ebp ; restore ebp pop es ; restore es xor eax,eax ; wack eax mov ax,[ebp+12] ; load char shl eax,3 ; offset into font table add esi,eax ; gs:si points to char in table mov ax,[ebp+16] ; Column X value shl ax,3 ; Pixel X Value, left side of char mov cx,[ebp+14] ; Row Y value shl cx,3 ; Pixel Y value bottom of char mov bl,0 ; Row counter Y mov di,ax ; Copy x pixel, it is changed and reset in loop nextRow: mov ax,di ; Reset leftmost x value mov dh,gs:[esi] ; load top byte of char mov dl,0 ; Column counter X BitChecker: rol dh,1 ; rotate and copy left bit to Carry flag jc C_One ; if carry is one print char bit C_Zero: push ax ; x value push cx ; y value push [ebp+10] ; color call _DrawPixel ; draw single pixel add esp,6 ; clean up stack inc ax ; next x pixel inc dl ; inc column counter cmp dl,8 ; if column counter < 8 jb BitChecker ; check next bit, else next row inc bl ; next Row counter inc esi ; next Byte/Row inc cx ; next Y pixel cmp bl,8 ; if row counter < 8 jb nextRow ; check next row, jmp CharDone ; else char done C_One: push ax ; x value push cx ; y value push [ebp+8] ; color call _DrawPixel ; draw single pixel add esp,6 ; clean up stack inc ax ; next x pixel inc dl ; inc column counter cmp dl,8 ; if column counter < 8 jb BitChecker ; check next bit, else next row inc bl ; next Row counter inc esi ; next Byte/Row inc cx ; next Y pixel cmp bl,8 ; if row counter < 8 jb nextRow ; check next row, else char done CharDone: pop gs ; restore gs pop esi ; restore si pop di ; restore di pop dx ; restore dx pop cx ; restore cx pop bx ; restore bx pop ax ; restore ax pop ebp ; restore ebp ret ; return to caller _DrawCharacter ENDP ;---------------------------------------------------------- _putString13h PROC FAR ; 13h Text is 40 X 25. ; This procedure draws a colored string at a given text locale. ; Character Background is colored ; Input: (x value, y value, length, color index) ; Output: none ; Stack Frame [ebp] old ebp ; [ebp+4] return address ; [ebp+8] String offset ; [ebp+10] String Segment ; [ebp+12] Color of letter ; [ebp+14] Background Color ; [ebp+16] Row Y value ; [ebp+18] Column X value ; ;---------------------------------------------------------- push ebp ; prserve ebp mov ebp,esp ; link stack frame push eax ; preserve eax push ebx ; preserve ebx push ecx ; preserve ecx push edx ; preserve edx push di ; preserve di push esi ; preserve esi push ds ; preserve ds mov ax,[ebp+16] ; Row value Y mov bx,[ebp+18] ; Column value X mov cx,[ebp+12] ; Color of char mov di,[ebp+14] ; BackGround Color mov dx,[ebp+10] ; load segment of string mov ds,dx ; load segment to ds xor esi,esi ; esi=0 xor edx,edx ; wack edx mov si,[ebp+8] ; load offset of string putLoop: mov dl,[esi] ; put a character in dl cmp dl,0h ; does dl equal null je putLoopEND ; if so exit loop push bx ; Row value push ax ; Column Value push dx ; Character push di ; BackGround Color push cx ; color index call _DrawCharacter ; draw 1 char add esp,10 ; Clean up Stack inc bx ; next column inc esi ; esi ++, get next character jmp putLoop ; loop to start of loop1 putLoopEND: pop ds pop esi pop di pop edx pop ecx pop ebx pop eax pop ebp ret ; return to caller _putString13h ENDP ;---------------------------------------------------------- _RestoreVideoMode PROC FAR ; PAGE 566 ; This procedure waits for a key to be pressed and ; restores the video mode to its original value. ; Input: none ; Output: none ; Stack Frame none ;---------------------------------------------------------- push ax ; preserve ax mov ax,oldFS ; restore fs mov fs,ax ; to original value mov ah,0h ; reset video mode mov al,saveMode ; to saved mode int 10h ; video interupt pop ax ; restore ax ret ; return to caller _RestoreVideoMode ENDP ;---------------------------------------------------------- _StringLength PROC FAR ; ; Input: (segment, offset) ; Output: eax=length ; Stack Frame [ebp] old ebp ; [ebp+4] return address ; [ebp+8] Offset ; [ebp+10] Segment ;---------------------------------------------------------- push ebp ; preserve ebp mov ebp,esp ; link stack frame push ds ; restore ds push ebx ; preserve bx mov ax,[ebp+10] ; load string segment mov ds,ax ; into ds xor ebx,ebx mov bx,[ebp+8] ; load string offset xor eax,eax ; eax=0, for counter and return value NextChar: cmp BYTE PTR [ebx+eax],0h ; look for Null terminator je Done ; is so, dome counting inc eax ; next char jmp NextChar ; loop Done: pop ebx ; restore bx pop ds ; restore ds pop ebp ; restore ebp ret ; return to caller _StringLength ENDP ;---------------------------------------------------------- _LineDisplay PROC FAR ; This displays a rotating line eminating from the center of the screen ; Input: none ; Output: none ; Stack Frame ; ;---------------------------------------------------------- push ebp ; save old ebp mov ebp,esp ; link stack frame push eax ; push ebx ; push ecx ; push esi ; mov cx,1d ; xor si,si finit ; initialize fpu LineLoop: call _ClearVideoBuffer CircleLoop: fld Theta ; load theta vale to evaluate 7 fsin ; st(0) gets cos and st(1) gets sin 180 fld Theta ; 7 fcos ; 207 fld Radius ; Load radius 7 fld st(0) ; make copy of radius 7 fmulp st(2),st(0) ; cos(theta)*radius 7 fmulp st(2),st(0) ; sin(theta)*radius 7 ; st(0)=X st(1)=Y fistp xVal1 ; convert x to int and save 10 fistp yVal1 ; convert y to int and save 10 fld Theta ; push theta on fp stack 7 fld ThetaInc ; mov to next theta value 7 fadd ; Increment Theta 5 fstp Theta ; Store next Theta and pop 7 inc si ; next counter cmp si,720 ; jne DrawTheLine ; xor si,si ; inc cx ; DrawTheLine: push 160 ; push x1 value push 100 ; push y1 value add xVal1,160 push xVal1 ; push x2 value add yVal1,100 push yVal1 ; push y2 value push cx ; pixel pallete color call _DrawLine add esp,10 ; clean up stack push 7 ; col x 0 -> 39 push 24 ; row y 0 -> 24 push 15 ; foreground push ds ; segment 10 push Offset pStr ; offset 8 call _putString13hNoBG add esp,10 call _PrintVideoBuffer mov ah,11h ; check for keystroke int 16h jz LineLoop ; if no keystroke, then continue loop mov ah,10h ; wait for keystroke int 16h ; keyboard interupt pop esi ; pop ecx ; pop ebx ; pop eax ; pop ebp ; restore ebp ret ; return to caller _LineDisplay ENDP ;---------------------------------------------------------- _BulletDisplay PROC FAR ; work around bullet procedure ; Input: (x value, y value, color index) ; Output: returns Strike = -1 if collision takes place. else Strike = 0 ; ;---------------------------------------------------------- push eax ; preserve ax push ebx ; preserve bx push ecx ; preserve cx push di ; xor ecx,ecx ; xor di,di ; BulletDispLoop: call _ClearVideoBuffer ; rdtsc ; eax = clock cycles mov ebx,eax ; for compare mov edx,ecx neg edx add ebx,edx ; time diff DiffPos: cmp ebx,10000000d ; is time elapsed > time/pixel jb ExitBullet ; don't move bullet mov ecx,eax ; time of last new position draw push di ; push x value push 100 ; push y value push 10 ; pixel pallete color call _DrawBullet ; Draw a pixel add esp,6 ; clean up stack inc di ; next bullet x jmp BulletDone ; exit so as not to draw 2 pix ; rewrite previous position, no change ExitBullet: push di ; push x value push 100 ; push y value push 10 ; pixel pallete color call _DrawBullet ; Draw a pixel add esp,6 ; clean up stack BulletDone: push 7 ; col x 0 -> 39 push 24 ; row y 0 -> 24 push 15 ; foreground push ds ; segment 10 push Offset pStr ; offset 8 call _putString13hNoBG ; add esp,10 ; call _PrintVideoBuffer ; cmp di,319d ; jb KeyPressCheck ; sub di,319 ; KeyPressCheck: mov ah,11h ; check for keystroke int 16h ; jz BulletDispLoop ; if no keystroke, then continue loop ExitBulletDisp: mov ah,10h ; wait for keystroke int 16h ; keyboard interupt pop di ; pop ecx ; restore cx pop ebx ; restore bx pop eax ; restore ax ret ; return to caller _BulletDisplay ENDP ;---------------------------------------------------------- _CircleDisplay PROC FAR ; work around bullet procedure ; Input: (x value, y value, color index) ; Output: returns Strike = -1 if collision takes place. else Strike = 0 ; ;---------------------------------------------------------- push eax ; preserve ax push ebx ; preserve bx push ecx ; preserve cx push di ; push si xor ecx,ecx ; mov di,1 mov si,1 ; BulletDispLoop: call _ClearVideoBuffer ; rdtsc ; eax = clock cycles mov ebx,eax ; for compare mov edx,ecx neg edx add ebx,edx ; time diff DiffPos: cmp ebx,10000000d ; is time elapsed > time/pixel jb ExitBullet ; don't move bullet mov ecx,eax ; time of last new position draw push 160 ; push x value push 100 ; push y value push di ; push radius value push si ; pixel pallete color call _Draw_Circle add esp,8 ; clean up stack inc di jmp BulletDone ; exit so as not to draw 2 pix ; rewrite previous position, no change ExitBullet: push 160 ; push x value push 100 ; push y value push di ; push radius value push si ; pixel pallete color call _Draw_Circle add esp,8 ; clean up stack BulletDone: push 7 ; col x 0 -> 39 push 24 ; row y 0 -> 24 push 15 ; foreground push ds ; segment 10 push Offset pStr ; offset 8 call _putString13hNoBG ; add esp,10 ; call _PrintVideoBuffer ; cmp di,1000d ; jb KeyPressCheck ; sub di,999d ; inc si ; cmp si,16 ; jne KeyPressCheck ; sub si,15 ; KeyPressCheck: mov ah,11h ; check for keystroke int 16h ; jz BulletDispLoop ; if no keystroke, then continue loop ExitBulletDisp: mov ah,10h ; wait for keystroke int 16h ; keyboard interupt pop si ; pop di ; pop ecx ; restore cx pop ebx ; restore bx pop eax ; restore ax ret ; return to caller _CircleDisplay ENDP ;---------------------------------------------------------- _DrawThingy PROC FAR ; ; Input: (nada) ; Output: none ; Stack Frame none ; ;---------------------------------------------------------- push eax ; preserve ax push ebx ; preserve bx push ecx ; preserve cx push edx ; preserve dx rdtsc ; eax = clock cycles mov ebx,eax ; for compare mov edx,OldSec neg edx add ebx,edx ; time diff DiffPos: cmp ebx,10000000d ; is time elapsed > time/pixel jb ExitBullet ; don't move bullet mov OldSec,eax ; time of last draw push BulletX ; push x value push 100 ; push y value push 40 ; pixel pallete color call _DrawPixel ; Draw a pixel! add esp,6 inc BulletX ; next bullet x jmp BulletDone ; exit so as not to draw 2 pix ; rewrite previous position, no change ExitBullet: push BulletX ; push x value push 100 ; push y value push 40 ; pixel pallete color call _DrawPixel ; Draw a pixel! add esp,6 ; clean up stack BulletDone: pop edx ; restore dx pop ecx ; restore cx pop ebx ; restore bx pop eax ; restore ax ret ; return to caller _DrawThingy ENDP ;---------------------------------------------------------- _ColorDisplay PROC FAR ; This procedure shows all 256 current pallette colors using whole screen ; Input: none ; Output: none ; Stack Frame none ;---------------------------------------------------------- push bx ; preserve bx push ecx ; preserve cx push di ; preserve ax push si ; preserve si xor si,si ; si = 0 xor bx,bx ; bx = 0 ColorBoxColumn: xor di,di ; ax = 0 ColorBoxRow: push di ; push x1 value push bx ; push y1 value mov cx,di ; add cx,9 push cx ; push x2 value rol ecx,16 mov cx,bx add cx,24 push cx ; push y2 value ror ecx,16 push si ; pixel pallete color call _DrawSolidBox add esp,10 inc si add di,10 cmp di,310 jna ColorBoxRow add bx,25 cmp bx,175 jna ColorBoxColumn pop si ; restore si pop di ; restore ax pop ecx ; restore cx pop bx ; restore bx ret ; return to caller _ColorDisplay ENDP ;---------------------------------------------------------- _GetString13h PROC FAR ; This procedure shows all 256 current pallette colors using whole screen ; Input: (Offset, Segment, x, y, Max Chars, Char Col, BG Color) ; Output: dl = -1 to return, -2 t escape ; Stack Frame [ebp] old ebp ; [ebp+4] return address ; [ebp+8] Offset ; [ebp+10] Segment ; [ebp+12] X, Column Value ; [ebp+14] Y, Row Value ; [ebp+16] Maximum Number of Characters ; [ebp+18] Character Color ; [ebp+20] Background Color ;---------------------------------------------------------- push ebp ; Preserve ebp mov ebp,esp ; Link stack frame push ds ; preserve ds push eax ; preserve eax, just because push ebx ; preserve ebx push ecx ; preserve ecx push edi push esi ; preserve esi mov dx,[ebp+10] ; load segment of string mov ds,dx ; set segment of string xor eax,eax ; eax=0 xor esi,esi mov si,[ebp+8] ; load offset of string sub ecx,ecx ; edx=0 mov bx,[ebp+12] ; Column value mov dx,[ebp+12] ; again for later compare ops xor edi,edi mov di,[ebp+16] stringClear: mov BYTE PTR [esi+ecx],0h ; load string with 33 0's inc ecx ; move to next string spot cmp ecx,edi ; ecx == maxchar jna stringClear ; if not > maxchars, loop again xor ecx,ecx ; ecx = 0 getLoop: cmp ecx,edi ; cursor checker je NoCursor push bx ; Column Value push [ebp+14] ; Row value push '_' ; Character push [ebp+18] ; Color of 'cursor' call _DrawCharacterNoBG ; draw a char with trans bg add esp,8 ; Clean up Stack call _PrintVideoBuffer NoCursor: mov ah, 11h ;function code - check key int 16h ;keyboard services jz getLoop ;no key in buffer, loop ;clear keyboard buffer mov ah, 10h ;function code - remove key int 16h ;keyboard services xor ah,ah cmp al,0h ; 0h indicates extended key je NoExtended ; ignore 0h, and next ext char cmp al,1Bh ; does al equal ESC je terminate ; if so exit program cmp al,0Dh ; does al equal CR je ReturnStrike ; if so exit loop cmp al,08h ; does al equal BS je BackSpace ; Backspace function cmp al,20h ; char >= space, ok jae okToPrint ; all char above space pass cmp al,7Eh ; char <= ~, okay jbe okToPrint ; all char below tilde pass jmp getLoop ; if no extended get another char NoExtended: mov ah, 10h ;function code - remove key int 16h ;keyboard services jmp getLoop ; catch-all tries again. BackSpace: cmp bx,dx ; jna getLoop ; xor ah,ah ; dec ecx ; mov al,[esi+ecx] ; push bx ; Column Value push [ebp+14] ; Row value push '_' ; Character push 0h ; Black index, overwrite call _DrawCharacterNoBG ; draw a char with trans bg add esp,8 dec bx ; push bx ; Column Value push [ebp+14] ; Row value push ax ; Character push 0h ; Black index, overwrite call _DrawCharacterNoBG ; draw a char with trans bg add esp,8 ; Clean up Stack mov al,0h ; Null mov [esi+ecx],al ; put a Null in over last char call _PrintVideoBuffer ; jmp getLoop ; get another char okToPrint: cmp ecx,edi ; if ecx=3 je getLoop ; exit loop push bx ; Column Value push [ebp+14] ; Row value push '_' ; Character push 0h ; Blackout cursor call _DrawCharacterNoBG ; draw a char with trans bg add esp,8 ; Clean up Stack xor ah,ah ; push bx ; Column Value push [ebp+14] ; Row value push ax ; Character push [ebp+18] ; color index call _DrawCharacterNoBG ; draw a char with trans bg add esp,8 ; Clean up Stack call _PrintVideoBuffer ; mov [esi+ecx],al ; put a character in memory inc ecx ; esi ++, get next character inc bx ; jmp getLoop ; loop to start of loop1 ReturnStrike: cmp ecx,0h ja normalEnd mov dl,-2 jmp normalEnd ; bypass -1 return terminate: mov dl,-1 ; pass a -1, signal prog end normalEnd: inc ecx ; mov to last string space mov BYTE PTR [esi+ecx],0h ; insert string terminator pop esi ; restore esi pop edi pop ecx ; restore ecx pop ebx ; restore ebx pop eax ; restore eax pop ds ; restore ds pop ebp ; restore ebp ret ; return to caller _GetString13h ENDP ;---------------------------------------------------------- _DrawExplode PROC FAR ; This draws explosion frames. ; Input: (Color,Frame,Y,X) ; Output: none ; Stack Frame [ebp] old ebp ; [ebp+4] return address ; [ebp+8] Shrapnel color index ; [ebp+10] Frame Count ; [ebp+12] Pixel Y Value ; [ebp+14] Pixel X value ;---------------------------------------------------------- push ebp ; preserve ebp mov ebp,esp ; link stack frame push ax ; preserve ax push bx ; preserve bx push cx ; preserve cx push dx ; preserve dx push di ; preserve di push esi ; preserve si push gs ; preserve gs xor eax,eax mov ax,[ebp+10] ; Frame Count shl ax,3 lea esi,Explosion add esi,eax mov ax,[ebp+14] ; Pixel X Value, center of frame sub ax,3 ; left side mov cx,[ebp+12] ; Pixel Y value, center of frame sub cx,3 ; bottom of frame mov bl,0 ; Row counter Y mov di,ax ; Copy x pixel, it is changed and reset in loop nextRow: mov ax,di ; Reset leftmost x value mov dh,[esi] ; load top byte of char mov dl,0 ; Column counter X BitChecker: rol dh,1 ; rotate and copy left bit to Carry flag jc C_One ; if carry is one print char bit C_Zero: push ax ; x value push cx ; y value push [ebp+8] ; color ;call _DrawPixel ; draw single pixel add esp,6 ; clean up stack inc ax ; next x pixel inc dl ; inc column counter cmp dl,8 ; if column counter < 8 jb BitChecker ; check next bit, else next row inc bl ; next Row counter inc esi ; next Byte/Row inc cx ; next Y pixel cmp bl,8 ; if row counter < 8 jb nextRow ; check next row, jmp CharDone ; else char done C_One: push ax ; x value push cx ; y value push [ebp+8] ; color call _DrawPixel ; draw single pixel add esp,6 ; clean up stack inc ax ; next x pixel inc dl ; inc column counter cmp dl,8 ; if column counter < 8 jb BitChecker ; check next bit, else next row inc bl ; next Row counter inc esi ; next Byte/Row inc cx ; next Y pixel cmp bl,8 ; if row counter < 8 jb nextRow ; check next row, else char done CharDone: pop gs ; restore gs pop esi ; restore si pop di ; restore di pop dx ; restore dx pop cx ; restore cx pop bx ; restore bx pop ax ; restore ax pop ebp ; restore ebp ret ; return to caller _DrawExplode ENDP ;---------------------------------------------------------- _DrawBigExplode PROC FAR ; This draws explosion frames. ; Input: (Color,Frame,Y,X) ; Output: none ; Stack Frame [ebp] old ebp ; [ebp+4] return address ; [ebp+8] Shrapnel color index ; [ebp+10] Frame Count ; [ebp+12] Pixel Y Value ; [ebp+14] Pixel X value ;---------------------------------------------------------- push ebp ; preserve ebp mov ebp,esp ; link stack frame push ax ; preserve ax push bx ; preserve bx push cx ; preserve cx push dx ; preserve dx push di ; preserve di push esi ; preserve si push gs ; preserve gs xor eax,eax mov ax,[ebp+10] ; Frame Count shl ax,5 lea esi,BigExplosion add esi,eax mov ax,[ebp+14] ; Pixel X Value, center of frame sub ax,7 ; left side mov cx,[ebp+12] ; Pixel Y value, center of frame sub cx,7 ; bottom of frame mov bl,0 ; Row counter Y mov RowValue,ax ; Copy x pixel, it is changed and reset in loop nextRow: mov ax,RowValue ; Reset leftmost x value mov di,[esi] ; load top byte of char mov dl,0 ; Column counter X BitChecker: rol di,1 ; rotate and copy left bit to Carry flag jc C_One ; if carry is one print char bit C_Zero: ;push ax ; x value ;push cx ; y value ;push [ebp+8] ; color ;call _DrawPixel ; draw single pixel ;add esp,6 ; clean up stack inc ax ; next x pixel inc dl ; inc column counter cmp dl,16 ; if column counter < 8 jb BitChecker ; check next bit, else next row inc bl ; next Row counter inc esi ; next Byte/Row inc esi inc cx ; next Y pixel cmp bl,16 ; if row counter < 8 jb nextRow ; check next row, jmp CharDone ; else char done C_One: push ax ; x value push cx ; y value push [ebp+8] ; color call _DrawPixel ; draw single pixel add esp,6 ; clean up stack inc ax ; next x pixel inc dl ; inc column counter cmp dl,16 ; if column counter < 8 jb BitChecker ; check next bit, else next row inc bl ; next Row counter inc esi ; next Byte/Row inc esi inc cx ; next Y pixel cmp bl,16 ; if row counter < 8 jb nextRow ; check next row, else char done CharDone: pop gs ; restore gs pop esi ; restore si pop di ; restore di pop dx ; restore dx pop cx ; restore cx pop bx ; restore bx pop ax ; restore ax pop ebp ; restore ebp ret ; return to caller _DrawBigExplode ENDP ;---------------------------------------------------------- _ExplodeDisplay PROC FAR ; This display explosion animation. ; Input: (Color,Frame,Y,X) ; Output: none ; Stack Frame [ebp] old ebp ; [ebp+4] return address ; [ebp+8] Shrapnel color index ; [ebp+10] Frame Count ; [ebp+12] Pixel Y Value ; [ebp+14] Pixel X value ;---------------------------------------------------------- push eax push ecx xor cx,cx BlowUpDisplay: call _ClearVideoBuffer push 160 ; x value push 100 ; y value push cx ; frame count push 40 ; color of schrapnel ;call _DrawExplode ; blarmey call _DrawBigExplode ; yippey kayyeh MFer add esp,8 ; clean up stack call _PrintVideoBuffer mov ax,900 Delay: sub ax,1 call _ClearVideoBuffer cmp ax,0h jne Delay inc cl cmp cl,8 jbe KeyPressCheck sub cl,8 KeyPressCheck: mov ah,11h ; check for keystroke int 16h ; jz BlowUpDisplay ; if no keystroke, then continue loop ExitBulletDisp: mov ah,10h ; wait for keystroke int 16h ; keyboard interupt pop ecx pop eax ret _ExplodeDisplay ENDP _TEXT ENDS _DATA SEGMENT WORD PUBLIC USE16 'DATA' pStr db "Press any key to continue.",0 ; pStr points at string start saveMode BYTE 3h ; saved video mode saveMode2 BYTE 3h ; saved video mode 2 oldES WORD 0h ; previous es oldFS WORD 0h ; previous fs xVal1 SWORD 0h ; x-coordinate yVal1 SWORD 0h ; y-coordinate xVal2 SWORD 0h ; X2 yVal2 SWORD 0h ; Y2 Strike SBYTE 0h ; Pixel collision detection RowValue WORD ? Theta REAL8 0.00 ; current theta to evaluate ThetaInc REAL8 0.00872664626 ; theta to increment by Radius REAL8 99.00 ; fp radius TwoPie REAL8 6.30 ; 2*Pi Xint WORD 0h ; integer x val for fp circle Yint WORD 0h ; integer y val for fp circle Slope REAL8 0.00 ; slope of radius at given theta b_Yintercept REAL8 0.00 ; b, from y=mx+b YtoPrint WORD 0h ; FZERO REAL8 0.00 ; 0 NegativeOne REAL8 -1.00 ; -1, duh Two REAL8 2.00 ; 2.00 OldSec DWORD 0h ; last seconds BulletX WORD 0h TestRadius WORD 1h circleContact BYTE 0h ; Frames of explosion Explosion QWORD 0090000010000000h; 0 QWORD 0000001810000000h; 1 QWORD 0000140018000000h; 2 QWORD 0000140014020000h; 3 QWORD 00001C2024180000h; 4 QWORD 0000344024181000h; 5 QWORD 0010344000441000h; 6 QWORD 0810424000221008h; 7 QWORD 4014800200864108h; 8 BigExplosion WORD 0000000000000000b; 0 0 WORD 0000000000000000b; 0 1 WORD 0000000000000000b; 0 2 WORD 0000000000000000b; 0 3 WORD 0000000000000000b; 0 4 WORD 0000000000000000b; 0 5 WORD 0000000000000000b; 0 6 WORD 0000000010000000b; 0 7 - WORD 0000000101000000b; 0 8 - WORD 0000000010000000b; 0 9 WORD 0000000000000000b; 0 10 WORD 0000000000000000b; 0 11 WORD 0000000000000000b; 0 12 WORD 0000000000000000b; 0 13 WORD 0000000000000000b; 0 14 WORD 0000000000000000b; 0 15 WORD 0000000000000000b; 1 0 WORD 0000000000000000b; 0 1 WORD 0000000000000000b; 0 2 WORD 0000000000000000b; 0 3 WORD 0000000000000000b; 0 4 WORD 0000000000000000b; 0 5 WORD 0000000000100000b; 0 6 WORD 0000000010000000b; 0 7 - WORD 0000000100010000b; 0 8 - WORD 0000000000000000b; 0 9 WORD 0000000000000000b; 0 10 WORD 0000000000000000b; 0 11 WORD 0000000000000000b; 0 12 WORD 0000000000000000b; 0 13 WORD 0000000000000000b; 0 14 WORD 0000000000000000b; 0 15 WORD 0000000000000000b; 2 0 WORD 0000000000000000b; 0 1 WORD 0000000000000000b; 0 2 WORD 0000000000000000b; 0 3 WORD 0000000000000000b; 0 4 WORD 0000000000000000b; 0 5 WORD 0000001000100000b; 0 6 WORD 0000000001000000b; 0 7 - WORD 0000010000001000b; 0 8 - WORD 0000000000000000b; 0 9 WORD 0000001000010000b; 0 10 WORD 0000000000000000b; 0 11 WORD 0000000000000000b; 0 12 WORD 0000000000000000b; 0 13 WORD 0000000000000000b; 0 14 WORD 0000000000000000b; 0 15 WORD 0000000000000000b; 3 0 WORD 0000000000000000b; 0 1 WORD 0000000000000000b; 0 2 WORD 0000010000000000b; 0 3 WORD 0000000010100000b; 0 4 WORD 0001000000010000b; 0 5 WORD 0000000000010000b; 0 6 WORD 0000010000100000b; 0 7 - WORD 0000000000000100b; 0 8 - WORD 0000000000000000b; 0 9 WORD 0000100000010000b; 0 10 WORD 0000000100000000b; 0 11 WORD 0000000000000100b; 0 12 WORD 0000000000000000b; 0 13 WORD 0000000000000000b; 0 14 WORD 0000000000000000b; 0 15 WORD 0000000000000000b; 4 0 WORD 0000000000000000b; 0 1 WORD 0000000000000000b; 0 2 WORD 0000000000000000b; 0 3 WORD 0000010010000000b; 0 4 WORD 0000100000001000b; 0 5 WORD 0000000000010000b; 0 6 WORD 0000100000100000b; 0 7 - WORD 0000100000000100b; 0 8 - WORD 0000000000000000b; 0 9 WORD 0000100000000000b; 0 10 WORD 0000000100000000b; 0 11 WORD 0000000000000100b; 0 12 WORD 0000000000000000b; 0 13 WORD 0000000000000000b; 0 14 WORD 0000000000000000b; 0 15 WORD 0000000000000000b; 5 0 WORD 0000000000000000b; 0 1 WORD 0000000000000000b; 0 2 WORD 0000100001000000b; 0 3 WORD 0000000000001000b; 0 4 WORD 0001000000001000b; 0 5 WORD 0000000000010000b; 0 6 WORD 0010010000010000b; 0 7 - WORD 0001000000000100b; 0 8 - WORD 0000000000000000b; 0 9 WORD 0001100000000000b; 0 10 WORD 0001000100000000b; 0 11 WORD 0000001000000010b; 0 12 WORD 0000000000000000b; 0 13 WORD 0000000000000000b; 0 14 WORD 0000000000000000b; 0 15 WORD 0000000000000000b; 6 0 WORD 0000000000000000b; 0 1 WORD 0001000001000000b; 0 2 WORD 0000000000000100b; 0 3 WORD 0100000000000000b; 0 4 WORD 0000000000000010b; 0 5 WORD 0000000000000010b; 0 6 WORD 0100100000001000b; 0 7 - WORD 0000000000000100b; 0 8 - WORD 0010000000000000b; 0 9 WORD 0001000000000010b; 0 10 WORD 0000000000000000b; 0 11 WORD 0010000000000010b; 0 12 WORD 0000000100000000b; 0 13 WORD 0000000000000000b; 0 14 WORD 0000000000000000b; 0 15 WORD 0000000000000000b; 7 0 WORD 0010000001000000b; 0 1 WORD 0000000000000010b; 0 2 WORD 0000000000000000b; 0 3 WORD 1000000000000001b; 0 4 WORD 0100000000000000b; 0 5 WORD 0010000000000001b; 0 6 WORD 1000000000001000b; 0 7 - WORD 0010000000000100b; 0 8 - WORD 0000000000000000b; 0 9 WORD 0100000000000010b; 0 10 WORD 0010000000000000b; 0 11 WORD 0010000000000001b; 0 12 WORD 0100000000001000b; 0 13 WORD 0000010100001000b; 0 14 WORD 0000000000000000b; 0 15 WORD 0100000000100000b; 8 0 WORD 0010000000000001b; 0 1 WORD 0000001000000001b; 0 2 WORD 0001000000001000b; 0 3 WORD 1000000000000001b; 0 4 WORD 0100000000000000b; 0 5 WORD 0010000000000001b; 0 6 WORD 1000000000000100b; 0 7 - WORD 0100000000000010b; 0 8 - WORD 0000000000000000b; 0 9 WORD 1000000000000001b; 0 10 WORD 0000000000000100b; 0 11 WORD 1010000000000000b; 0 12 WORD 0100100000000001b; 0 13 WORD 0000000000001010b; 0 14 WORD 0100101000100000b; 0 15 _DATA ENDS VIDEO SEGMENT WORD PUBLIC USE16 'DATA' VideoBuffer TBYTE 6400 DUP(0h) ; video buffer, 64000 bytes, default black VIDEO ENDS END