; -WonderWorm--v0.9- ; by Matthew Shepcar 30.XII.98 ; modified by Jonah Cohen 19.XI .99 ; and Shiar 01.XII.99 ;to-do: ; * picks not correctly removed ; * linkplay ; * hot pursuit + ctf ; * ending (+stats after multiplayer) #include "TI86.inc" .org _asm_exec_ram _divHLby10 = $4044 _getcsc = _getky _clrWindow = $4a86 _runIndicOff = _runindicoff _flushAllMenus = _flushallmenus _SHRACC = _shracc _SHLACC = $438B nop jp Start .dw 0,WormMsg Start: ; ld (SpSave),sp call _runIndicOff call _flushAllMenus call _clrLCD ld a,r ld (Seed),a xor a ld (_asapvar+1),a ;----------------------------- ;----- build trig tables ----- ;----------------------------- ld hl,TrigPrecalc ld de,SinCosTable push de ; >> 1 ld bc,65 ldir dec hl ld b,63 MirrorSineWave: dec hl ld a,(hl) ld (de),a inc de djnz MirrorSineWave pop hl ; << 0k ld b,128+64 NegativeSineWave: xor a sub (hl) ld (de),a inc hl inc de djnz NegativeSineWave ;----------------------------- ;---------- menu ------------- ;----------------------------- DisplayMenu: call _clrLCD ld hl,txtWelcome call _puts ld hl,txtMenu ld de,$0203 ld b,4 DispMenuLoop: inc de ld (_curRow),de call _puts djnz DispMenuLoop ld hl,$0805 ld (_curRow),hl ld hl,txtGame call _puts xor a menudraw: and 3 ;-1>>3; 4>>0 push af ld h,0 add a,4 ld l,a ld (_curRow),hl ld a,5 ;arrow call _putc ld h,0 ld a,1 Previous =$-1 add a,4 ld l,a ld (_curRow),hl ld a,' ' call _putc pop af push af ld (Previous),a WKCP: halt \ halt call GET_KEY cp K_EXIT jp z,Exit cp K_ENTER jr z,select cp K_SECOND jr z,select cp K_UP jr nz,notup pop af dec a jr menudraw notup: cp K_DOWN jr nz,WKCP pop af inc a jr menudraw select: pop af ld b,a or a ;1st jr z,ThePartyIsOn dec a ;2nd jr z,Variation dec a ;3rd jp Exit Variation: ld hl,$0805 ld (_curRow),hl ld a,0 Gametype =$-1 ld hl,txtGame2 NEXTtxtGame =$-2 inc a and 3 jr nz,okilydokily ld hl,txtGame okilydokily: ld (Gametype),a call _puts ld (NEXTtxtGame),hl ld a,b jr menudraw singleplayer: inc a ld (nrworms),a ld de,LevelsS jr GameOver ThePartyIsOn: ld a,(Gametype) or a jr z,singleplayer ld a,2 ld (nrworms),a ld de,LevelsDM ;----------------------------- ;--------- game over --------- ;----------------------------- GameOver: push de call _clrLCD pop de ld a,1 ld (Level),a ld hl,0 ld (worm1+score),hl ld (worm2+score),hl ld a,3 ld (worm1+lives),a ld (worm2+lives),a StartLevel: ld a,(de) ld (Left),a inc de ld a,(de) ld (Speed),a inc de ld a,15 ld (worm1+grow),a ld (worm2+grow),a NextLife: push de ; >> levelp old ld b,2 ld hl,worm1 worminit: push bc ; >> 1 ld a,(de) ld (hl),a ;d inc de inc hl ld a,SinCosTable/256 ld (hl),a inc hl ld a,(de) ld (hl),a ;y inc de inc hl ld a,(de) ld (hl),a ;x inc de inc hl xor a ld (hl),a ;y2 inc hl ld (hl),a ;x2 ld bc,20-5 add hl,bc pop bc ; << 0k djnz worminit ld hl,Worm1 ld (worm1+head),hl ld (worm1+tail),hl ld hl,Worm2 ld (worm2+head),hl ld (worm2+tail),hl ;-------- draw level --------- ld a,(de) inc de sub 128 ld (FieldWidth),a ld a,(de) inc de sub 57 ld (FieldHeight),a add a,57-5 push de ; >> levelp ld l,a ld h,0 add hl,hl add hl,hl add hl,hl add hl,hl add hl,hl ex de,hl ld hl,ScrBuffer push hl ; >> 1 push de ; >> 2 ld de,ScrBuffer+1 ld bc,63 ld (hl),%11111111 ldir inc hl ld (hl),%11000000 inc hl ld b,31 ClearLine: ld (hl),c inc hl djnz ClearLine push hl ; >> 3 ld a,(FieldWidth) add a,126 push af ; >> 4 and %11111000 rra rra rra ld l,a ld h,0 add hl,de pop af ; << 3 and %00000111 ld b,a ld c,0 ld a,%11000000 jr z,NoVertShift VertShift: rra rr c djnz VertShift NoVertShift: ld (hl),a inc hl ld (hl),c ex de,hl pop de ; << 2 pop bc ; << 1 ldir pop hl ; << 0k ld c,64 ldir ;-draw lines- pop hl ; << levelp ld a,(hl) inc hl or a jr z,NoLines DrawLines: push af ; >> 1 ld d,(hl) inc hl ld e,(hl) inc hl ld a,(hl) inc hl push hl ; >> 2 ld l,(hl) ld h,a call Line inc d inc h call Line inc e inc l call Line dec d dec h call Line pop hl ; << 1 inc hl pop af ; << 0k dec a jr nz,DrawLines NoLines: ;----------------------------- push hl ; >> levelp new ld hl,0 ld (_penCol),hl ld hl,LivesMsg call _vputs ld a,(worm1+lives) add a,'0' call _vputmap ld a,40 ld (_penCol),a call _vputs ;scoremsg ld a,100 ld (_penCol),a call _vputs ld a,1 Left =$-1 call PutNum ld ix,worm1 call PutScore call NewPea pop hl ; << levelp new push hl ; >> levelp new ld bc,(worm1+pos) call DisplayField ld hl,LevelMsg ld a,7 push hl ; >> 1 ld h,a ld l,4 ld (_curRow),hl ld hl,0FDE0h ld de,0FDE1h ld (hl),-1 ld bc,0BFh ldir pop hl ; << 0k set 3,(iy+5) call _puts ld a,(Level) cp 10 jr c,LevelBelowTen ld l,a ld h,0 call _divHLby10 push af ; >> 1 ld a,l add a,'0' call _putc pop af ; << 0k LevelBelowTen: add a,'0' call _putc res 3,(iy+5) ld b,0 ReadyDelay: halt djnz ReadyDelay ;----------------------------- ;----------- LOOP ------------ ;----------------------------- GameLoop: ld bc,(worm1+pos) call DisplayField ld a,0 Speed =$-1 or a jr z,NoDelay Delay: halt dec a jr nz,Delay NoDelay: ld ix,worm1 call HandleWorm ld ix,worm2 ld a,(nrworms) cp 2 call z,HandleWorm ;----------------------------- ;---------- keys ------------- ;----------------------------- HandleKeys: ld a,%10111111 out (1),a in a,(1) rla jr c,NotPaused ld bc,$0103 out (c),b halt ld b,11 out (c),b NotPaused: rla jp c,GameLoop Exit2pop: pop hl ; << levelp new Exit1pop: pop hl ; << levelp old jr Exit Exit5pop: pop hl pop hl pop hl jr Exit2pop WormDead: pop hl ; << call pop hl ; << levelp new ld hl,(worm1+head) ld de,(worm1+tail) sbc hl,de ld a,l rr h rra ld (worm1+grow),a ld hl,(worm2+head) ld de,(worm2+tail) sbc hl,de ld a,l rr h rra ld (worm2+grow),a ld a,(ix+lives) dec a ld (ix+lives),a pop de ; << levelp old jp nz,NextLife Exit: #if 0 ld a,(Eaten) ld hl,HiScore cp (hl) jr c,NotNewHigh ld (hl),a ld hl,_asapvar rst 20h rst 10h call 460Bh ld de,HiScore-_asm_exec_ram+2 add hl,de adc a,0 call _load_ram_ahl ld a,(HiScore) ld (hl),a NotNewHigh: #endif res 4,(iy+9) ; ld sp,0 SpSave = $-2 jp _clrWindow ;----------------------------- ;----------- worm ------------ ;----------------------------- inlink: ld a,0 sendbyte =$-1 call SendByte jr c,receivefirst call receive ret receivefirst: call receive ld a,(sendbyte) call SendByte ret receive: receiveloop: call GET_KEY cp K_EXIT jp z,Exit5pop call TryReceiveByte jr c,receiveloop ld l,a ret inkeys: out (1),a in a,(1) ld b,a and (ix+right) jr z,NotRight ld a,l add a,8 ld l,a NotRight: ld a,b and (ix+left) ret z ld a,l sub 8 ld l,a ret ;------- handle worm --------- HandleWorm: ld l,(ix+heading) ld a,(ix+input) or a jr nz,keys call inlink jr donelydone keys: call inkeys donelydone: ld a,l ld (sendbyte),a ld (ix+heading),l ld h,(ix+heading+1) ld c,(ix+pos) ld b,(ix+pos+1) ld e,(ix+pos2) ld d,(ix+pos2+1) ;-------- move worm ---------- Wormmove: push bc ; >> pos ld a,(hl) add a,a add a,d ld d,a bit 7,(hl) jr z,NotNegX dec b NotNegX: jr nc,NotMoveX inc b NotMoveX: ld a,l add a,40h ld l,a ld a,(hl) add a,a add a,e ld e,a bit 7,(hl) jr z,NotNegY dec c NotNegY: jr nc,NotMoveY inc c NotMoveY: ;bc=newpos ;-check- pop hl ; << pos (old) push de ; >> pos2 ld a,h sub b and 1 ld h,a ld a,l sub c and 1 add a,h ld d,4 jr z,GotFour xor 3 ld d,a GotFour: call CheckPixel inc b call CheckPixel inc c call CheckPixel dec b call CheckPixel dec c rl d pop de ; << pos2 ld (ix+pos2),e ld (ix+pos2+1),d ld (ix+pos),c ld (ix+pos+1),b jr nc,Drawworm ;--------- worm hit ---------- Hitworm: ld hl,0 PeaY =$-2 PeaX =$-1 ld a,b sub h inc a cp 4 jp nc,WormDead ld a,c sub l inc a cp 4 jp nc,WormDead push bc ; >> 1 call DrawPea ld a,(ix+grow) add a,15 ld (ix+grow),a call NewPea ld de,10 call IncScore ld a,119 ld (_penCol),a ld hl,Left dec (hl) jr nz,NotNextLevel ld hl,Level ld a,(hl) inc (hl) pop bc ; << 0k pop hl ; << call pop de ; << levelp new pop hl ; << levelp old cp NUM_LEVELS jp z,Exit ld a,(Gametype) or a jp z,StartLevel jp Exit NotNextLevel: ld a,(hl) call PutNum pop bc ; << 0k ;-------- draw worm ---------- Drawworm: ld l,(ix+head) ld h,(ix+head+1) ld (hl),c inc hl ld (hl),b inc hl res resbit,h ld (ix+head),l ld (ix+head+1),h call SetPixel inc b call SetPixel inc c call SetPixel dec b call SetPixel ld a,(ix+grow) dec a jr z,removetail ld (ix+grow),a ret removetail: ld l,(ix+tail) ld h,(ix+tail+1) ld c,(hl) inc hl ld b,(hl) inc hl res resbit,h ld (ix+tail),l ld (ix+tail+1),h call ResPixel inc b call ResPixel inc c call ResPixel dec b jp ResPixel ;----------------------------- ;----------- procs ----------- ;----------------------------- NewPea: ;random routine ld hl,0 ld de,12345 Seed =$-2 ld a,7921 & 255 ld bc,1000h+(7921/256) domult16: add hl,hl rla rl c jr nc,noadd16 add hl,de noadd16: djnz domult16 inc hl ld (Seed),hl ;seed=(seed*7921+1) MOD 65536 ld a,(FieldWidth) add a,123 cp h jr c,NewPea inc h inc h ld a,(FieldHeight) add a,51 cp l jr c,NewPea inc l inc l ld (PeaY),hl ld d,2 push hl ; >> 1 call CheckPea pop hl ; << 0k dec d jr z,NewPea DrawPea: ld d,0 CheckPea: ld b,h ld c,l call PeaPixel inc c call PeaPixel inc b call PeaPixel dec c PeaPixel: push de ; >> 1 call FindPixel pop de ; << 0k ld e,a ld a,d or a ld a,e jr z,DrawPeaPixel and (hl) ret z ld d,1 ret DrawPeaPixel: xor (hl) ld (hl),a ret ;-------- pixelprocs --------- ResPixel: ;at bc call FindPixel cpl and (hl) ld (hl),a ret SetPixel: ;at bc call FindPixel or (hl) ld (hl),a ret CheckPixel: ;at bc in d push de ; >> 1 call FindPixel and (hl) pop de ; << 0k ret z dec d ret FindPixel: ;bc to ahl + de gone push de ; >> 1 push bc ; >> 2 ld a,b and 7 add a,offsets_table & 255 ld e,a ld d,offsets_table/256 ld h,0 ld l,c add hl,hl add hl,hl add hl,hl add hl,hl add hl,hl ld a,b and %11111000 rra rra rra or l ld l,a ld a,(de) ld de,ScrBuffer add hl,de pop bc ; << 1 pop de ; << 0k ret ;----------------------------- IncScore: ld h,(ix+score+1) ld l,(ix+score) add hl,de ld (ix+score+1),h ld (ix+score),l PutScore: ld de,_penCol ld a,79 ld (de),a ld b,5 DoPutScore: push bc ; >> 1 push de ; >> 2 call _divHLby10 call PutDigit pop de ; << 1 ld a,(de) sub 8 ld (de),a pop bc ; << 0k djnz DoPutScore ret PutNum: ld l,a ld h,0 call _divHLby10 push af ; >> 1 ld a,l call PutDigit pop af ; << 0k PutDigit: add a,'0' jp _vputmap ;----------------------------- offsets_table: .db 128,64,32,16,8,4,2,1 DisplayField: ld a,c sub 29 jr nc,NotMinYScroll xor a NotMinYScroll: cp 43 FieldHeight =$-1 jr c,NotMaxYScroll ld a,(FieldHeight) NotMaxYScroll: ld l,a ld h,0 add hl,hl add hl,hl add hl,hl add hl,hl add hl,hl push bc ; >> 1 push de ; >> 2 ld de,ScrBuffer add hl,de ld a,b sub 64 jr nc,NotMinXScroll xor a NotMinXScroll: cp 128 FieldWidth = $-1 jr c,NotMaxXScroll ld a,(FieldWidth) NotMaxXScroll: push af ; >> 3 and %11111000 rra rra rra ld c,a ld b,0 ld de,DispBuffer pop af ; << 2 and %00000111 push af ; >> 3 cp 6 jr c,CopyScreen inc c CopyScreen: add hl,bc ld b,57 CopyScreenLoop: push bc ; >> 4 ld bc,16 ldir ld c,16 add hl,bc pop bc ; << 3 djnz CopyScreenLoop pop af ; << 2 ld c,$b7 ;or a Bit0: jr nz,Bit1 halt halt jr AfterShiftDelay Bit1: dec a jr nz,Bit2 call ShiftRight1 jr AfterShiftDelay Bit2: dec a jr nz,Bit3 ld a,2 call ShiftRight jr AfterShiftDelay Bit3: dec a jr nz,Bit4 call Chunk call ShiftLeft1 jr AfterShift Bit4: dec a jr nz,Bit5 call Chunk jr AfterShiftDelay Bit5: dec a jr nz,Bit6 call Chunk call ShiftRight1 jr AfterShift Bit6: dec a jr nz,Bit7 ld a,2 call ShiftLeft jr AfterShift Bit7: call ShiftLeft AfterShiftDelay: halt AfterShift: ld hl,DispBuffer ld de,$fc00+$70 ld bc,1024-$70 ldir pop de ; << 1 pop bc ; << 0k ret ShiftRight1: ld a,1 ShiftRight: ld (ShiftRightCounter),a ld a,c ld (ShiftRightChunk),a ld c,16 add hl,bc ld b,57 ShiftRightLoop: push bc ; >> 1 ld bc,-32 add hl,bc ex de,hl ld a,(de) ShiftRightChunk: or a call c,_SHLACC ld c,0 ShiftRightCounter = $-1 ShiftRowsLeft: push hl ; >> 2 rla ld b,16 ShiftRowLeft: dec hl rl (hl) djnz ShiftRowLeft pop hl ; << 1 dec c jr nz,ShiftRowsLeft ld bc,-16 add hl,bc ex de,hl pop bc ; << 0k djnz ShiftRightLoop ret ShiftLeft1: ld a,1 ShiftLeft: ld (ShiftLeftCounter),a ld a,c ld (ShiftLeftChunk),a rla jr nc,ShiftLeftSameByte dec hl ShiftLeftSameByte: ex de,hl ld bc,-16 add hl,bc ex de,hl ld b,57 ShiftLeftLoop: push bc ; >> 1 ld bc,-32 add hl,bc ex de,hl ld a,(de) ShiftLeftChunk: or a call c,_SHRACC ld c,0 ShiftLeftCounter = $-1 ShiftRowsRight: push hl ; >> 2 rra ld b,16 ShiftRowRight: rr (hl) inc hl djnz ShiftRowRight pop hl ; << 1 dec c jr nz,ShiftRowsRight ld bc,-16 add hl,bc ex de,hl pop bc ; << 0k djnz ShiftLeftLoop ret Chunk: push hl ; >> 1 push de ; >> 2 ld c,16 add hl,bc ld b,57 ChunkScreen: push bc ; >> 3 ld bc,-32 add hl,bc ex de,hl ld a,(de) call _SHRACC ld b,16 ChunkRow: dec hl rld djnz ChunkRow ex de,hl pop bc ; << 2 djnz ChunkScreen pop de ; << 1 pop hl ; << 0k ld c,$37 ;scf ret ;----------------------------- ;----------- link ------------ ;----------------------------- LINKMASK =3 LINKPORT =7 TIMEOUT =$1000 LinkPrep: ex (sp),hl push bc push de set 2,(iy+12h) ld b,8 jp (hl) TryReceiveByte: in a,(LINKPORT) and LINKMASK cp LINKMASK scf ret z ReceiveByteCont: call LinkPrep jr ReceiveCont ReceiveByte: call LinkPrep ReceiveBits: ld de,TIMEOUT WaitRecBit: call CheckLink jr z,LinkFailed cp LINKMASK jr z,WaitRecBit ReceiveCont: sub LINKMASK/3*2 ld a,LINKMASK/3*2 ld d,D0LD1H jr c,ReceiveLow rra ld d,D0HD1L ReceiveLow: rr c ld (AckBit),a ld a,d out (LINKPORT),a ld de,TIMEOUT WaitAckRec: call CheckLink cp 0 AckBit =$-1 jr nz,WaitAckRec ld a,D0HD1H out (LINKPORT),a ld d,4 WaitReadyRec: dec d jr z,ReadyRec in a,(LINKPORT) cp LINKMASK jr nz,WaitReadyRec ReadyRec: djnz ReceiveBits jr LinkSuccess SendByte: call LinkPrep ld c,a inc b jr SendAcked SendBits: rr c ld a,D0LD1H jr nc,SendLow ld a,D0HD1L SendLow: out (LINKPORT),a ld de,TIMEOUT WaitAckSend: call CheckLink jr nz,WaitAckSend SendAcked: ld a,D0HD1H out (LINKPORT),a ld de,TIMEOUT WaitReadySend: call CheckLink cp LINKMASK jr nz,WaitReadySend djnz SendBits LinkSuccess: or 0 .org $-1 LinkFailed: scf ld a,c res 2,(iy+12h) pop de pop bc pop hl ret CheckLink: pop hl dec de ld a,d or e jr z,LinkFailed ld a,0BFh call _readkeypad bit 6,a jr z,LinkFailed in a,(LINKPORT) and LINKMASK jp (hl) _readkeypad: out (1),a in a,(1) push af ld a,255 out (1),a pop af ret ;----------------------------- ;---------- levels ----------- ;----------------------------- LevelsDM: .db 8,0 .db $40,30,4,$C0,30,123 .db 0,0 ; .db 128,57 .db 0 NUM_LEVELS = 9 LevelsS: .db 5,3 ;5 peas, speed 5 .db 0,4,64,0,0,0 ;d,y,x .db 0,0 ;field width, height .db 0 ;no additional lines .db 8,4 .db $40,14,4,0,0,0 .db 128,57 .db 1 .db 28,28,100,28 .db 9,4 .db $40,8,4,0,0,0 .db 128,57 .db 2 .db 28,14,100,14 .db 28,41,100,41 .db 9,3 .db $40,8,4,0,0,0 .db 128,80 .db 2 .db 64,14,64,66 .db 20,40,108,40 .db 10,3 .db 4,8,$40,0,0,0 .db 128,90 .db 3 .db 18,20,18,70 .db 110,20,110,70 .db 18,45,110,45 .db 7,3 .db 64,4,0,0,0,0 .db 128,86 .db 6 .db 34,13,56,35 .db 34,71,56,49 .db 72,35,94,13 .db 72,49,94,71 .db 16,20,16,64 .db 110,20,110,64 .db 9,2 .db 4,10,$40,0,0,0 .db 128,82 .db 3 .db 0,20,74,20 .db 54,40,128,40 .db 0,60,74,60 .db 12,2 .db 64,4,0,0,0,0 .db 128,90 .db 6 .db 20,16,54,16 .db 74,16,110,16 .db 20,16,20,72 .db 110,16,110,72 .db 20,72,54,72 .db 74,72,110,72 .db 8,2 .db 72,52,$c0,0,0,0 .db 128,128 .db 13 .db 34,56,56,34 .db 34,72,56,94 .db 72,34,94,56 .db 72,94,94,72 .db 46,64,80,64 .db 22,11,22,33 .db 11,22,33,22 .db 22,95,22,117 .db 11,106,33,106 .db 103,11,103,33 .db 91,22,115,22 .db 103,95,103,117 .db 91,106,115,106 ;----------------------------- ;---------- data ------------- ;----------------------------- TrigPrecalc: .db 0, 3, 6, 9, 12, 15, 18, 21 .db 24, 27, 30, 33, 36, 39, 42, 45 .db 48, 51, 54, 57, 59, 62, 65, 67 .db 70, 73, 75, 78, 80, 82, 85, 87 .db 89, 91, 94, 96, 98,100,102,103 .db 105,107,108,110,112,113,114,116 .db 117,118,119,120,121,122,123,123 .db 124,125,125,126,126,126,126,126 .db 127 #include "line.asm" txtWelcome .db "Welcome to PeaWorm!! ", .db "by Jonah and Shiar",0 txtMenu .db "Start Game",0 .db "Game: ",0 .db "Options",0 .db "Quit",0 txtGame .db "Singleplayer",0 txtGame2 .db "Deathmatch ",0 .db "Hot Pursuit",0 .db "CTF ",0 WormMsg .db "Wonderworm!",0 LevelMsg .db "Level ",0 LivesMsg .db "Lives: ",0 ScoreMsg .db "Score: ",0 LeftMsg .db "Food: ",0 HiScore .db 0 nrworms .db 2 worm1 .dw 0,0,0,0,0,0,0,0 .db 0,%11111110,%10,%100 worm2 .dw 0,0,0,0,0,0,0,0 .db 0,0,%10000,%1000 ; .db 0,%00111111,%10000,%1000 ;set: heading = 0 ;level* pos = 2 ;level* pos2 = 4 ;level head = 6 ;level tail = 8 ;level grow = 10 ;level lives = 13 ;game score = 15 ;game input = 17 ; left = 18 ; right = 19 ; Worm1 = $B000 Worm2 = $B800 resbit = 2 Level =$+1 DispBuffer =$+2 ScrBuffer = $8200 ;32x256 bytes SinCosTable = $A200 ;----------------------------- ;----------- end ------------- ;----------------------------- .end