;---------------------------------------------------------------------------- ; tron.asm public beta version 0.4 Copyright (C) 1997, brioche/aspirine ;---------------------------------------------------------------------------- ; Kinda 2 player nibble game as seen in a well known old movie called 'Tron' ;---------------------------------------------------------------------------- ; Mainly optimized for size but my first goal was to have fun! :) ; This proggy assumes that all the common registers are set to zero and that ; the direction flag is cleared... ; Nothing more to say about this source except that it has been assembled ; with some good old Borland tasm 3.1 and linked with tlink 5.1 ;---------------------------------------------------------------------------- ; Version 0.4 fixes another bug about the 'both crashed' case (4 bytes lost) ; and I'm wondering if it is really necessary to support the escape key... ; The brand new stuff is a few self-modifying code in the main loop, I saved ; plenty of bytes and ticks! assembler rules! ;---------------------------------------------------------------------------- ; About the lack of comments: real coders don't need comments! :) ;---------------------------------------------------------------------------- ; This is freeware but e-mails are welcome! 106146.1452@compuserve.com ;---------------------------------------------------------------------------- .386 .model tiny SC_ESC equ 1 ;several scancodes in use SC_UP equ 72 SC_DOWN equ 80 SC_LEFT equ 75 SC_RIGHT equ 77 SC_A equ 16 SC_Q equ 30 SC_W equ 44 ;oops! SC_X equ 45 ;azerty frenchy keyboard! :) movseg macro _dst, _src ;quite useful macro push _src pop _dst endm code segment use16 assume cs:code, ds:code, es:code, ss:code org 100h start: mov al, 13h ;init video mode int 10h xor ax, ax ;init palette mov dx, 3c8h out dx, al inc dx mov cl, 5*3 mov si, offset palette rep outsb mov ax, 3509h ;init keyboard handler int 21h mov word ptr old9, bx mov word ptr old9+2, es mov ah, 25h mov dx, offset new9 int 21h movseg es, 0a000h ;now es = VGA memory segment mov eax, 01010101h ;build the back grid xor di, di mov bl, 25 ;draw inner grid gridlp1: mov cx, 40*7 gridlp2: stosb add di, 7 loop gridlp2 call hline dec bl jnz gridlp1 xor di, di ;outer grid (game bounds) shl eax, 1 ;now, eax=02020202h call hline mov cl, 198 gridlp3: stosb add di, 318 stosb loop gridlp3 call hline mainloop: mov dx, 3dah ;wait for vertical retrace in al, dx ;to slow it down... :) test al, 8 jz $-3 in al, dx test al, 8 jnz $-3 mov di, plyr1 ;di = player1 offset mov si, plyr2 ;si = player2 offset cli ;disable interrupts db 81h, 0c6h ;opcode of add di, xxxx patch1: dw -1 db 81h, 0c7h ;opcode of add si, xxxx patch2: dw 1 sti ;interrupts enabled now mov plyr1, di ;save new offsets mov plyr2, si cmp byte ptr es:[di], 1 seta cl ;player1 crashed? cmp byte ptr es:[si], 1 seta ch ;player2 crashed? mov byte ptr es:[di], 3 ;draw both players on screen mov byte ptr es:[si], 4 cmp di, si ;both crashed je bye jcxz chkesc ;nobody crashed cmp cl, ch jb win1 ;player1 wins ja win2 ;player2 wins je bye ;both crashed on boundaries chkesc: cmp escape, 0 ;check if escape has been hit je mainloop jmp bye win1: mov winplyr, '1' ;just show who won... jmp bye win2: mov winplyr, '2' bye: mov ax, 3 int 10h mov ah, 09h ;print some messages mov dx, offset msg-1 ;get CR from the palette! int 21h lds dx, dword ptr old9 ;reset keyboard stuff mov ax, 2509h int 21h ret ;get back to DOS! ;-- new keyboard handler ---------------------------------------------------- new9: push ax ;ugly 'switch() case...' push bx in al, 60h new9_esc: cmp al, SC_ESC ;exit jne new9_up1 mov escape, 1 ;gosh! teacher's coming! :) jmp new9_ack new9_up1: mov bx, offset patch1 cmp al, SC_UP ;player1 up jne new9_down1 jmp mvup new9_down1: cmp al, SC_DOWN ;player1 down jne new9_left1 jmp mvdown new9_left1: cmp al, SC_LEFT ;player1 left jne new9_right1 jmp mvleft new9_right1: cmp al, SC_RIGHT ;player1 right jne new9_up2 jmp mvright new9_up2: mov bx, offset patch2 cmp al, SC_A ;player2 up jne new9_down2 jmp mvup new9_down2: cmp al, SC_Q ;player2 down jne new9_left2 jmp mvdown new9_left2: cmp al, SC_W ;player2 left jne new9_right2 jmp mvleft new9_right2: cmp al, SC_X ;player2 right jne new9_ack jmp mvright new9_ack: in al, 61h ;send release code to kb ctrl mov ah, al or al, 80h out 61h, al mov al, ah out 61h, al new9_eoi: mov al, 20h ;end of interrupt out 20h, al pop bx pop ax iret ;-- misc support routines --------------------------------------------------- mvup: cmp byte ptr [bx], (320 and 255) ;going down? je new9_ack mov word ptr [bx], -320 jmp new9_ack mvdown: cmp byte ptr [bx], (-320 and 255) ;going up? je new9_ack mov word ptr [bx], 320 jmp new9_ack mvleft: cmp byte ptr [bx], 1 ;going right? je new9_ack mov word ptr [bx], -1 jmp new9_ack mvright: cmp byte ptr [bx], -1 ;going left? je new9_ack mov word ptr [bx], 1 jmp new9_ack hline: mov cl, 80 ;vacuum clouds... rep stosd ret ;-- data -------------------------------------------------------------------- X1 = 159-100 ;initial coordinates Y1 = 99 X2 = 159+100 Y2 = 99 plyr1 dw (Y1*320)+X1 ;initial offsets plyr2 dw (Y2*320)+X2 escape db 0 palette db 3, 8, 13 ;bknd db 6, 11, 16 ;inner grid db 8, 13, 18 ;outer grid db 0, 29, 63 ;player2 db 56, 0, 13 ;player1 msg db 10 ;message db 'player ' winplyr db '?' db ' wins!' db 13, 10, 10 db 'brioche/aspirine$' old9 dd 0 ;removable zero data code ends end start ;eat this! :)