; CALCnet2 Testbed Application

;===Standard Includes and Equates===
.nolist
#define TASM
#include "ti83plus.inc"
#include "dcs7.inc"

;===Build Flags for CALCnet2===
#define enableCn22
#define enablecn2eis
#define cn2fakeserial
#define cn2debug
;#define cn2fakeserial_gcnhost

#define PONG_BALL_HEIGHT 12
#define GAMEOVER_SCORE	 11
ballx		.equ		saferam2
bally		.equ		ballx+1
vel_x		.equ		bally+1
vel_y		.equ		vel_x+1
whichcalc 	.equ		vel_y+1
onscreen 	.equ		whichcalc+1
calccount	.equ		onscreen+1
paddle_y	.equ		calccount+1
paddle_h	.equ		paddle_y+1
paddle_drty .equ		paddle_h+1
score_l		.equ		paddle_drty+1
score_r		.equ		score_l+1
idarray		.equ		score_r+1

.list
	.org progstart
#IFDEF TI83P
	.db $BB,$6D
#ENDIF
INIT:
	xor d
#IFDEF TI83P
	.db $C9
#ENDIF
	jr Start
	.dw Description
	.db $07,$00
	.dw Icon
	.dw $0000
	.dw $0000			;the routine to open files.  DCS will start you here instead of at $9D95
						;if a file is pending
Description:
	.db "CALCnet2.2 NetPong v0.2b",0
Icon:				;a 16x16 icon
	.db %00110000,%00000000
	.db %01111000,%00000110
	.db %11011000,%00001011
	.db %11000000,%00000011
	.db %11000000,%00000110
	.db %11000000,%00001100
	.db %11000000,%00001111
	.db %11000010,%11100000
	.db %11000011,%10110000
	.db %11000011,%00110000
	.db %11000011,%00110000
	.db %11000011,%00110000
	.db %11000011,%00110000
	.db %11011011,%00110000
	.db %01111011,%00110000
	.db %00110011,%00110000

START:                          	;main routines
	set textwrite,(iy+sgrflags)
Start_DBLoop:						;debounce...
	ld b,16
Start_DBInnerLoop:
	call Cn2_GetK
	or a
	jr nz,Start_DBLoop
	djnz Start_DBInnerLoop
	call Cn2_Setup					;set up calcnet 2.2

	xor a
	ld (calccount),a
	ld a,$ff
	ld (whichcalc),a
	ld ($890F),a					;show debug info
Start_FindCalcsRedraw:
	call QuickLCDClear
	ld hl,npsplash
	ld de,gbuf
	ld bc,31*12
	ldir
	ld hl,(31*256)+1
	ld (pencol),hl
	ld hl,WaitOthers
	bcall(_vputs)
	ld hl,(56*256)+1
	ld (pencol),hl
	ld hl,MyName
	bcall(_vputs)
	ld a,(calccount)
	push af
		ld hl,(37*256)+1
		ld (pencol),hl
		ld b,'0'
		add a,b
		call DPutMap
		ld hl,CalcsFoundText
		bcall(_vputs)
		pop af
	or a
	jr z,Start_FindCalcsRedraw_NoPosition
	ld hl,(43*256)+1
	ld (pencol),hl
	ld hl,PressNum
	bcall(_vputs)
	ld hl,(49*256)+1
	ld (pencol),hl
	ld a,(whichcalc)
	or a
	jr nz,Start_FindCalcsRedraw_NoFirstPosition
	ld hl,PressEnterToStart
	bcall(_vputs)
	jr Start_FindCalcsRedraw_NoPosition
Start_FindCalcsRedraw_NoFirstPosition:
	cp $ff
	jr z,Start_FindCalcsRedraw_NoPosition
	push af
		ld hl,PositionTxt
		bcall(_vputs)
		pop af
	ld b,'0'+1
	add a,b
	call DPutMap
Start_FindCalcsRedraw_NoPosition:
	ei				;for all the vputs/vputmaps
Start_FindCalcsOuter:
	call iFastCopy
	call Cn2_GetK
	cp skClear
	jp z,FinalExit
	ld b,0
	cp sk1
	jr z,Start_SetCalcPos
	inc b
	cp sk2
	jr z,Start_SetCalcPos
	inc b
	cp sk3
	jr z,Start_SetCalcPos
	inc b
	cp sk4
	jr z,Start_SetCalcPos
	inc b
	cp sk5
	jr z,Start_SetCalcPos
	inc b
	cp sk6
	jr z,Start_SetCalcPos
	inc b
	cp sk7
	jr z,Start_SetCalcPos
	inc b
	cp sk8
	jr z,Start_SetCalcPos
	cp skEnter
	jr nz,Start_FindCalcsRandPause
	ld a,(whichcalc)
	or a
	jr nz,Start_FindCalcsRandPause
Start_FindCalcs_GetReadyToStart:
	ld c,3
	call SingleBytePacket_SendToAll
	jp LetTheGamesBegin
Start_SetCalcPos:
	ld a,(calccount)
	or a
	jr z,Start_FindCalcsOuter
	cp b
	jr c,Start_FindCalcsOuter
	ld a,b
	ld (whichcalc),a
	jp Start_FindCalcsRedraw
Start_FindCalcsRandPause:
	ld b,254
	call iRandom
	ld b,a
Start_FindCalcRandWait:
	push hl \ pop hl
	push hl \ pop hl
	djnz Start_FindCalcRandWait
	ld a,(Cn2_Int_RecBuf+6)
	or a
	jr nz,Start_FindCalcs_BCastReqRecvd
	ld a,(Cn2_Int_SendBuf+6)
	or a
	jr nz,Start_FindCalcsOuter
	ld b,20
	call iRandom
	or a
	jr nz,Start_FindCalcsOuter
Start_FindCalcs_SendBcast:
	ld hl,FindCalcsMsg
	ld de,Cn2_Int_SendBuf
	ld bc,FindCalcsMsgEnd-FindCalcsMsg
	ldir
	ld hl,Cn2_Int_SendBuf+6
	ld a,(hl)
	or $80
	ld (hl),a
	jp Start_FindCalcsOuter
Start_FindCalcs_BCastReqRecvd:
	ld a,(Cn2_Int_RecBuf+7)
	cp $02				;message 2 is "ack bcast probe"
	jr z,Start_FindCalcs_BCastRespRecvd
	cp $03
	jr z,LetTheGamesBegin
	cp $01
	jp nz,Start_FindCalcsOuter
						;message 1 is "bcast probe"
	ld hl,Cn2_Int_RecBuf
	ld de,Cn2_Int_SendBuf
	ld bc,5
	ldir
	ld a,1				;message length is 1
	ld (de),a
	inc de
	inc de
	inc a
	ld (de),a			;message 2 is "ack bcast probe"
	dec de
	ld a,$80
	ld (de),a			;message length is $0001 | 48000
	ld hl,0
	ld (Cn2_Int_RecBuf+5),hl
	jp Start_FindCalcsOuter
Start_FindCalcs_BCastRespRecvd:
	ld a,(calccount)
	ld hl,idarray
Start_FindCalcs_BCastRespRecvd_CheckExist:
	or a
	jr z,Start_FindCalcs_BCastRespRecvd_CalcIsNew
	push af
		ld c,0
		ld b,5
		ld de,Cn2_Int_RecBuf
Start_FindCalcs_BCastRespRecvd_CheckExist_Loop:
		ld a,(de)
		add a,c
;		ld a,c
		ld c,(hl)
		sub c
		ld c,a
		inc hl
		inc de
		djnz Start_FindCalcs_BCastRespRecvd_CheckExist_Loop
		ld a,c
		or a
		jr z,Start_FindCalcs_BCastRespRecvd_CalcExists
		pop af
	dec a
	jr Start_FindCalcs_BCastRespRecvd_CheckExist
Start_FindCalcs_BCastRespRecvd_CalcExists:
		pop af
	ld hl,0
	ld (Cn2_Int_RecBuf+5),hl
	jp Start_FindCalcsOuter
Start_FindCalcs_BCastRespRecvd_CalcIsNew:
	ld de,Cn2_Int_RecBuf
	ex de,hl
	ld bc,5
	ldir
	ld a,(calccount)
	inc a
	ld (calccount),a
	ld hl,0
	ld (Cn2_Int_RecBuf+5),hl
	jp Start_FindCalcsRedraw
	
LetTheGamesBegin:
	ld a,24
	ld (paddle_y),a
	ld a,16
	ld (paddle_h),a
	xor a
	ld (score_l),a
	ld (score_r),a
LetTheRoundBegin:
	call QuickLCDClear
	ld a,1								;don't want to throw a ball at the left player immediately
	ld (vel_x),a
	ld b,2
	call iRandom
	add a,a
	dec a
	ld (vel_y),a
	ld b,88-8
	call iRandom
	add a,4
	ld (ballx),a
	ld b,56-PONG_BALL_HEIGHT
	call iRandom
	add a,4
	ld (bally),a
	ld (paddle_drty),a					;just as good as 1 :)
	ld a,(whichcalc)
	ld b,1
	or a
	jr z,LetTheGamesBegin_Onscreen
	ld b,0
LetTheGamesBegin_Onscreen:
	ld a,b
	ld (onscreen),a
	jp Gameplay_Loop_ClearRecBuf
	
Gameplay_Loop:
	ld a,(paddle_drty)
	or a
	call nz,DrawPaddle	
	ld a,(onscreen)
	or a
	jp z,Gameplay_Loop_NoShow
	ld a,(bally)
	ld l,a
	ld b,PONG_BALL_HEIGHT
	ld ix,Pong_Ball
	ld a,(ballx)
	call iPutSprite
	call iFastCopy

	ld a,(bally)
	ld l,a
	ld b,PONG_BALL_HEIGHT
	ld ix,Pong_Ball
	ld a,(ballx)
	call iPutSprite
	
	ld a,(ballx)
	ld b,a
	ld a,(vel_x)
	add a,b
	ld (ballx),a

	ld b,a
	ld a,(whichcalc)
	ld c,a
	ld a,(calccount)
	sub c
	jr z,Gameplay_Loop_CheckHitPaddleRight
	ld a,b
	cp 96+1-8
	jr nz,Gameplay_Loop_CheckXLeft
	jp Gameplay_Loop_GoToAnotherCalc
Gameplay_Loop_CheckHitPaddleRight:
	ld a,b
	cp 96+1-8-4
	jr nz,Gameplay_Loop_CheckXLeft
Gameplay_Loop_XHitRight:
	;b and a are both ball x atm
	ld a,(bally)
	add a,PONG_BALL_HEIGHT-1
	ld b,a	
	ld a,(paddle_y)
	cp b
	jr nc,Gameplay_Loop_XHit_LeftScores
	ld c,a
	ld a,(bally)
	ld b,a
	ld a,(paddle_h)
	add a,c
	cp b
	jr nc,Gameplay_Loop_XHit_BounceR
	;if we're here, the left player failed to bounce the ball.
	;therefore, right gains a point
Gameplay_Loop_XHit_LeftScores:
	ld c,253
	call SingleBytePacket_SendToAll
	jp PointScored_Left
Gameplay_Loop_XHit_BounceR:
	ld a,96-8-4
	ld (ballx),a
	ld a,$ff
	ld (vel_x),a
	jr Gameplay_Loop_AdjustY
Gameplay_Loop_CheckXLeft:
	ld a,(ballx)
	ld b,a
	ld a,(whichcalc)
	or a
	jr z,Gameplay_Loop_CheckHitPaddleLeft
	ld a,b
	cp $ff
	jr nz,Gameplay_Loop_AdjustY
	jp Gameplay_Loop_GoToAnotherCalc
Gameplay_Loop_CheckHitPaddleLeft:
	ld a,b
	cp 3
	jr nz,Gameplay_Loop_AdjustY
Gameplay_Loop_XHitLeft:
	;b and a are both ball x atm
	ld a,(bally)
	add a,PONG_BALL_HEIGHT-1
	ld b,a	
	ld a,(paddle_y)
	cp b
	jr nc,Gameplay_Loop_XHit_RightScores
	ld c,a
	ld a,(bally)
	ld b,a
	ld a,(paddle_h)
	add a,c
	cp b
	jr nc,Gameplay_Loop_XHit_BounceL
	;if we're here, the left player failed to bounce the ball.
	;therefore, right gains a point
Gameplay_Loop_XHit_RightScores:
	ld c,252
	call SingleBytePacket_SendToAll
	jp PointScored_Right
Gameplay_Loop_XHit_BounceL:
	ld a,4
	ld (ballx),a
	ld a,1
	ld (vel_x),a
;	jr Gameplay_Loop_AdjustY
Gameplay_Loop_AdjustY:
	ld a,(bally)
	ld b,a
	ld a,(vel_y)
	add a,b
	ld (bally),a
	cp $ff
	jr z,Gameplay_Loop_YHitTop
	cp 64+1-PONG_BALL_HEIGHT
	jr nz,Gameplay_Loop_AdjustY_Done
Gameplay_Loop_YHitBottom:
	dec a
	ld (bally),a
	ld a,$ff
	ld (vel_y),a
	jr Gameplay_Loop_AdjustY_Done
Gameplay_Loop_YHitTop:
	inc a
	ld (bally),a
	inc a
	ld (vel_y),a
Gameplay_Loop_AdjustY_Done:
	jr Gameplay_Loop_QuitNetCheck
Gameplay_Loop_NoShow:
	call iFastCopy
Gameplay_Loop_QuitNetCheck:
	call Cn2GetK_Sub
	cp skClear
	jp z,Gameplay_Exit
	cp skMode
	jp z,Gameplay_Pause_Broadcast
	cp skUp
	jr z,Gameplay_PaddleUp
	cp skDown
	jr z,Gameplay_PaddleDown
Gameplay_Loop_NetChecks:
	ld a,(Cn2_Int_RecBuf+6)
	and %10000000
	jp z,Gameplay_Loop
	
	ld hl,Cn2_Int_RecBuf+7
	ld a,(hl)
	cp 250								;pause
	jp z,Gameplay_Pause
	cp 251								;quit
	jp z,Gameplay_Quit
	cp 252
	jp z,Gameplay_PointScoredRight		;someone scored!
	cp 253
	jp z,Gameplay_PointScoredLeft		;someone scored!
	ld b,(hl)
	ld a,(whichcalc)
	sub b
	jr nz,Gameplay_Loop_ClearRecBuf

	inc hl
	ld a,(hl)
	ld (ballx),a
	inc hl
	ld a,(hl)
	ld (bally),a
	inc hl
	ld a,(hl)
	ld (vel_x),a
	inc hl
	ld a,(hl)
	ld (vel_y),a
	ld a,1
	ld (onscreen),a
Gameplay_Loop_ClearRecBuf:
	ld hl,0
	ld (Cn2_Int_RecBuf+5),hl
	jp Gameplay_Loop
	
Gameplay_PaddleDown:
	ld a,(paddle_y)
	ld b,a
	ld a,(paddle_h)
	add a,b
	cp 64
	jr z,Gameplay_Loop_NetChecks
	ld a,1
	ld (paddle_drty),a
	call DrawPaddle
	ld a,1
	ld (paddle_drty),a
	ld hl,paddle_y
	inc (hl)
	inc (hl)
	jp Gameplay_Loop_NetChecks
	
Gameplay_PaddleUp:
	ld a,(paddle_y)
	or a
	jr z,Gameplay_Loop_NetChecks
	ld a,1
	ld (paddle_drty),a
	call DrawPaddle
	ld a,1
	ld (paddle_drty),a
	ld hl,paddle_y
	dec (hl)
	dec (hl)
	jp Gameplay_Loop_NetChecks
	
Gameplay_Loop_GoToAnotherCalc:
	ld a,(calccount)
	ld b,a
	ld hl,idarray
Gameplay_Loop_GoToAnotherCalc_Loop:
	ld a,(Cn2_Int_SendBuf+6)
	or a
	jr nz,Gameplay_Loop_GoToAnotherCalc_Loop
	ld de,Cn2_Int_SendBuf
	push bc
		ld bc,5
		ldir
		pop bc
	ex de,hl			;length: 4 bytes
	ld (hl),5
	inc hl
	;xor a				;hi length byte: 0
	ld (hl),0
	inc hl
	ld a,(whichcalc)
	ld c,a
	ld a,(ballx)
	cp $ff
	jr z,Gameplay_Loop_GoToAnotherCalc_Loop_HitLeft
Gameplay_Loop_GoToAnotherCalc_Loop_HitRight:
	ld a,1
	add a,c
	ld c,0
	jr Gameplay_Loop_GoToAnotherCalc_LoopFinishPacket
Gameplay_Loop_GoToAnotherCalc_Loop_HitLeft:
	ld a,$ff
	add a,c
	ld c,96-8
Gameplay_Loop_GoToAnotherCalc_LoopFinishPacket:
	ld (hl),a
	inc hl
	ld (hl),c
	inc hl
	ld a,(bally)
	ld (hl),a
	inc hl
	ld a,(vel_x)
	ld (hl),a
	inc hl
	ld a,(vel_y)
	ld (hl),a
	ld a,(Cn2_Int_SendBuf+6)
	or $80
	ld (Cn2_Int_SendBuf+6),a
	ex de,hl
	djnz Gameplay_Loop_GoToAnotherCalc_Loop
	xor a
	ld (onscreen),a
	jp Gameplay_Loop
	
Gameplay_Pause_Broadcast:
	ld c,250
	call SingleBytePacket_SendToAll
;	jr Gameplay_Pause_Display
Gameplay_Pause:
	ld hl,0
	ld (Cn2_Int_Recbuf+5),hl
Gameplay_Pause_Display:
	call DispPause
	call QuickLCDClear
	ld a,1
	ld (paddle_drty),a
Gameplay_Pause_Loop:
	call Cn2_GetK
	cp skMode
	jr z,Gameplay_Pause_RestartAll
	ld a,(Cn2_Int_Recbuf+6)
	and %10000000
	jr z,Gameplay_Pause_Loop
	ld a,(Cn2_Int_Recbuf+7)
	cp 250
	jp c,Gameplay_Loop_NetChecks
	ld hl,0
	ld (Cn2_Int_Recbuf+5),hl
	jp Gameplay_Loop
Gameplay_Pause_RestartAll:
	ld hl,0
	ld (Cn2_Int_Recbuf+5),hl
	ld c,252
	call SingleBytePacket_SendToAll
	jp Gameplay_Loop
		
Game_Over:
	ld ix,GameOverSprite
	ld a,25
	ld l,18
	ld b,28
	ld c,5
	call iLargeSprite
	ld hl,(46*256)+4+7+14
	ld (pencol),hl
	ld hl,ScoreTxt_Left
	ld a,(score_r)
	ld c,a
	ld a,(score_l)
	sub c
	jr nc,Game_Over_Left
	ld hl,ScoreTxt_Right
Game_Over_Left:
	bcall(_vputs)
	ld hl,ScoreTxt_Wins
	bcall(_vputs)
	ei					;for the vputs
	call iFastCopy
Game_Over_Pause:
	call Cn2_GetK
	cp skEnter
	jr z,Gameplay_Quit
	cp skClear
	jr z,Gameplay_Quit
	cp sk2nd
	jr nz,Game_Over_Pause
Gameplay_Quit:
	ld hl,0
	ld (Cn2_Int_Recbuf+5),hl
	jr FinalExit
Gameplay_Exit:
	ld c,251
	call SingleBytePacket_SendToAll
FinalExit:
	call Cn2_Setdown
	ret

Gameplay_PointScoredLeft:
PointScored_Left:
	ld hl,Score_L
	inc (hl)
	ld a,(hl)
	cp GAMEOVER_SCORE
	jp z,Game_Over
	ld hl,0
	ld (Cn2_Int_Recbuf+5),hl
	ld a,(whichcalc)
	or a
	jr nz,PointScored_Left_NotThisCalc
	ld ix,pointscoredimg
	ld a,22
	ld l,24
	ld b,16
	ld c,6
	jr PointScored_WaitNextRound
PointScored_Left_NotThisCalc:
	ld a,33
	ld l,20
	ld b,24
	ld c,3
	ld ix,arrowl
	jr PointScored_WaitNextRound
Gameplay_PointScoredRight:
PointScored_Right:
	ld hl,Score_R
	inc (hl)
	ld a,(hl)
	cp GAMEOVER_SCORE
	jp z,Game_Over
	ld hl,0
	ld (Cn2_Int_Recbuf+5),hl
	ld a,(whichcalc)
	ld b,a
	ld a,(calccount)
	sub b
	jr nz,PointScored_Right_NotThisCalc
	ld ix,pointscoredimg
	ld a,22
	ld l,24
	ld b,16
	ld c,6
	jr PointScored_WaitNextRound
PointScored_Right_NotThisCalc:
	ld a,33
	ld l,20
	ld b,24
	ld c,3
	ld ix,arrowr
PointScored_WaitNextRound:
	call iLargeSprite
PointScored_DispScores:
	ld hl,(46*256)+4+7
	ld (pencol),hl
	ld a,(score_r)
	ld c,a
	ld a,(score_l)
	ld d,a
	sub c
	jr z,PointScored_DispScores_Tied
	ld a,(whichcalc)
	or a
	jr nz,PointScored_DispScores_NotFirst
	ld a,c
	sub d
	jr nc,PointScored_DispScores_Trailing
	ld hl,ScoreTxt_Leading
	jr PointScored_DispScores_Finish
PointScored_DispScores_Tied:
	ld hl,ScoreTxt_Tied
	jr PointScored_DispScores_Finish
PointScored_DispScores_Trailing:
	ld hl,ScoreTxt_Trailing
	jr PointScored_DispScores_Finish
PointScored_DispScores_NotFirst:
	ld b,a
	ld a,(calccount)
	sub b
	jr nz,PointScored_DispScores_NotLast
	ld a,d
	sub c
	jr nc,PointScored_DispScores_Trailing
	ld hl,ScoreTxt_Leading
	jr PointScored_DispScores_Finish
PointScored_DispScores_NotLast:
	ld a,d
	sub c
	jr nc,PointScored_DispScores_DispLeft
	ld hl,ScoreTxt_Right
	jr PointScored_DispScores_NotLastFinish
PointScored_DispScores_DispLeft:
	ld hl,ScoreTxt_Left
PointScored_DispScores_NotLastFinish:
	bcall(_vputs)
	ld hl,ScoreTxt_Leading
PointScored_DispScores_Finish:
	bcall(_vputs)
	ld a,(score_l)
	ld c,a
	ld a,(score_r)
	ld d,a
	cp c
	jr c,PointScored_DispScores_FinishNoSwitch
	ld d,c
	ld c,a			;still d =score_r
PointScored_DispScores_FinishNoSwitch:
	push de
		ld h,0
		ld l,c
		call VDispHL
		ld hl,ScoreTxt_To
		bcall(_vputs)
		pop de
	ld h,0
	ld l,d
	call VDispHL
	ei					;for the vputs
PointScored_WaitNextRoundLoop:
	call iFastCopy
	ld a,(Cn2_Int_RecBuf+6)
	and %10000000
	jr nz,PointScored_WaitNextRound_ClearPacket
	call Cn2_GetK
	cp skEnter
	jr z,PointScored_GoNextRound
	cp sk2nd
	jr nz,PointScored_WaitNextRoundLoop
PointScored_GoNextRound:
	ld c,254
	call SingleBytePacket_SendToAll
	jp LetTheRoundBegin
PointScored_WaitNextRound_ClearPacket:
	ld hl,0
	ld (Cn2_Int_RecBuf+5),hl
	jp LetTheRoundBegin

DispPause:
	ld b,64
	ld hl,gbuf
	ld d,%10101010
PauseOuterLoop:
	in a,(1)
	inc a
	jr nz,PauseOuterLoop
	ld c,12
PauseInnerLoop:
	ld a,(hl)
	or d
	ld (hl),a
	inc hl
	dec c
	jr nz,PauseInnerLoop
	ld a,d
	cpl
	ld d,a
	djnz PauseOuterLoop
	ld hl,PausedSprite
	ld de,gbuf+12*17+1
	ld c,8
PauseSpriteOuter:
	ld b,10
PauseSpriteInner:
	ld a,(hl)
	ld (de),a
	inc hl
	inc de
	djnz PauseSpriteInner
	inc de
	inc de
	dec c
	jr nz,PauseSpriteOuter
	call iFastCopy
PauseKey:
	ret

QuickLCDClear:
	ld hl,gbuf
	push hl
		pop de
	inc de
	ld (hl),0
	ld bc,767
	ldir							;clear the gbuf
	ret
	
Cn2GetK_Sub:
	ld a,$ff		;
	out (1),a		;reset keyport
	ld e,$fe		;frist group
	ld c,$01		;key port
	ld l,0		;l holds key pressed
cscloop:
	out (c),e		;set keygroup
	ld b,8		;loop, Delay needed when work with key driver
	nop \ nop
	in a,(c)		;read key
cscbit:
	inc l			;inc to get key pressed
	rra 			; if key pressed done
	jr nc,donecsc
	djnz cscbit 	;loop 8
	rlc e			;next key group
	jp m,cscloop	;if bit 7 set loop
	ld l,0		;if no key pressed 0
donecsc:
	ld a,l		;
	or a
	ret

SingleBytePacket_SendToAllEscape:
		pop hl
	jp Gameplay_Quit
SingleBytePacket_SendToAll:
	call Cn2_GetK
	or a
	jr nz,SingleBytePacket_SendToAll
	ld a,(calccount)
	ld b,a
	ld hl,idarray
SingleBytePacket_SendToAll_Loop:
	call Cn2_GetK
	cp skClear
	jr z,SingleBytePacket_SendToAllEscape
	ld de,0
	ld (Cn2_Int_Recbuf+5),de						;very important to prevent deadlocks!
	ld a,(Cn2_Int_SendBuf+6)
	or a
	jr nz,SingleBytePacket_SendToAll_Loop
	ld de,Cn2_Int_SendBuf
	push bc
		ld bc,5
		ldir
		pop bc
	ld a,1
	ld (de),a
	inc de
	dec a
	ld (de),a
	inc de
	ld a,c										;specified packet
	ld (de),a
	dec de
	ld a,$80
	ld (de),a
	djnz SingleBytePacket_SendToAll_Loop
SingleBytePacket_SendToAll_Finish:
	call Cn2_GetK
	cp skClear
	jr z,SingleBytePacket_SendToAllEscape
	ld a,(Cn2_Int_SendBuf+6)
	or a
	jr nz,SingleBytePacket_SendToAll_Finish
	ret

DrawPaddle:
	xor a
	ld (paddle_drty),a
	ld a,(whichcalc)
	or a
	jr z,Gameplay_Loop_CheckDrawPaddle_0th
	ld b,a
	ld a,(calccount)
	sub b
	ret nz
Gameplay_Loop_CheckDrawPaddle_Nth:
	ld d,%00001110
	ld e,%00000100
	ld bc,11
	jr Gameplay_Loop_CheckDrawPaddle
Gameplay_Loop_CheckDrawPaddle_0th:
	ld d,%01110000
	ld e,%00100000
	ld bc,0
Gameplay_Loop_CheckDrawPaddle:
	push de
		ld a,(paddle_y)
		ld l,a
		ld h,0
		add hl,hl
		add hl,hl
		ld e,l
		ld d,h
		add hl,hl
		add hl,de
		ld de,gbuf
		add hl,de
		pop de
	add hl,bc
	ld a,(hl)
	xor e
	ld (hl),a
	ld bc,12
	add hl,bc
	ld a,(paddle_h)
	dec a
	dec a
	ld b,a
Gameplay_Loop_DrawPaddleLoop:
	ld a,(hl)
	xor d
	ld (hl),a
	push de
		ld de,12
		add hl,de
		pop de
	djnz Gameplay_Loop_DrawPaddleLoop
	ld a,(hl)
	xor e
	ld (hl),a
	ret

WaitOthers:
	.db "Waiting for other calcs...",0
CalcsFoundText:
	.db " calculator(s) found.",0
PressNum:
	.db "Press ",$c1,"1]-",$c1,"9] for position",0
PressEnterToStart:
	.db "Press Enter to start!",0
PositionTxt:
	.db "Position ",0
ScoreTxt_Left:
	.db "Left ",0
ScoreTxt_Right:
	.db "Right ",0
ScoreTxt_Leading:
	.db "Leading ",0
ScoreTxt_Trailing:
	.db "Trailing ",0
ScoreTxt_Tied:
	.db "Tied ",0
ScoreTxt_To:
	.db " to ",0
ScoreTxt_Wins:
	.db " Wins!",0
MyName:
	.db "By Kerm Martian",0
#ifdef cn2fakeserial
cn2MoveMessage:
	.db $00,$00,$00,$01,$00
	.dw (cn2MessageEnd-cn2MessageTxt)
cn2MessageTxt:
	.db 0,0,0
cn2MessageEnd:
#endif

FindCalcsMsg:
	.db $00,$00,$00,$00,$00
	.dw $0001
	.db 1
FindCalcsMsgEnd:

Pong_Ball:
	.db %00011000
	.db %00111110
	.db %01110100
	.db %11010010
	.db %11000110
	.db %00100000
	.db %01111010
	.db %11101101
	.db %10100011
	.db %11001001
	.db %00110110
	.db %01110111

PausedSprite:
	.db $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$80,$00,$00,$00,$00,$00
	.db $00,$00,$00,$01,$BB,$AB,$76,$19,$98,$5D,$D9,$C3,$AA,$E9,$AA,$AA
	.db $65,$45,$54,$9D,$55,$9A,$AA,$45,$BB,$A9,$45,$09,$54,$95,$55,$02
	.db $AA,$45,$A2,$BB,$76,$5D,$58,$55,$D9,$DB,$3A,$49,$80,$00,$00,$00
	.db $00,$00,$00,$00,$00,$01,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
	
pointscoredimg:
	.db %11111111,%11111111,%11111111,%11111111,%11111111,%11111100
	.db %10000000,%00000000,%00000000,%00000000,%00000000,%00000100
	.db %10111111,%11111111,%11111111,%11111111,%11111111,%11110100
	.db %10110000,%01110000,%01101100,%00001100,%00000001,%10110100
	.db %10100111,%00100111,%00100100,%11100110,%00000000,%10010100
	.db %10100111,%00100111,%00100100,%11100111,%11001111,%10010100
	.db %10100111,%00100111,%00100100,%11100111,%11001111,%10010100
	.db %10100111,%00100111,%00100100,%11100111,%11001111,%10010100
	.db %10100000,%01100111,%00100100,%11100111,%11001111,%10010100
	.db %10100111,%11100111,%00100100,%11100111,%11001111,%11010100
	.db %10100111,%11100111,%00100100,%11100111,%11001111,%10110100
	.db %10100111,%11100111,%00100100,%11100111,%11001111,%10010100
	.db %10110111,%11110000,%01110110,%11110111,%11101111,%11010100
	.db %10111111,%11111111,%11111111,%11111111,%11111111,%11110100
	.db %10000000,%00000000,%00000000,%00000000,%00000000,%00000100
	.db %11111111,%11111111,%11111111,%11111111,%11111111,%11111100

arrowl:
	.db %00000000,%00111000,%00000000
	.db %00000000,%01111100,%00000000
	.db %00000000,%11111110,%00000000
	.db %00000001,%11101110,%00000000
	.db %00000011,%11001110,%00000000
	.db %00000111,%10011100,%00000000
	.db %00001111,%00111000,%00000000
	.db %00011110,%01110000,%00000000
	.db %00111100,%11111111,%11111110
	.db %01111001,%11111111,%11111111
	.db %11110001,%11111111,%11111111
	.db %11100000,%00000000,%00000011
	.db %11100000,%00000000,%00000011
	.db %11110001,%11111111,%11111111
	.db %01111001,%11111111,%11111111
	.db %00111100,%11111111,%11111110
	.db %00011110,%01110000,%00000000
	.db %00001111,%00111000,%00000000
	.db %00000111,%10011100,%00000000
	.db %00000011,%11001110,%00000000
	.db %00000001,%11101110,%00000000
	.db %00000000,%11111110,%00000000
	.db %00000000,%01111100,%00000000
	.db %00000000,%00111000,%00000000

arrowr:
	.db %00000000,%00011100,%00000000
	.db %00000000,%00111110,%00000000
	.db %00000000,%01111111,%00000000
	.db %00000000,%01110111,%10000000
	.db %00000000,%01110011,%11000000
	.db %00000000,%00111001,%11100000
	.db %00000000,%00011100,%11110000
	.db %00000000,%00001110,%01111000
	.db %01111111,%11111111,%00111100
	.db %11111111,%11111111,%10011110
	.db %11111111,%11111111,%10001111
	.db %11000000,%00000000,%00000111
	.db %11000000,%00000000,%00000111
	.db %11111111,%11111111,%10001111
	.db %11111111,%11111111,%10011110
	.db %01111111,%11111111,%00111100
	.db %00000000,%00001110,%01111000
	.db %00000000,%00011100,%11110000
	.db %00000000,%00111001,%11100000
	.db %00000000,%01110011,%11000000
	.db %00000000,%01110111,%10000000
	.db %00000000,%01111111,%00000000
	.db %00000000,%00111110,%00000000
	.db %00000000,%00011100,%00000000

GameOverSprite:
	.db %11111111,%11111111,%11111111,%11111111,%11111110
	.db %10000000,%00000000,%00000000,%00000000,%00000010
	.db %10111111,%11111111,%11111111,%11111111,%11111010
	.db %10110000,%01110000,%01101111,%11011100,%00001010
	.db %10100111,%00100111,%00100111,%11001001,%11111010
	.db %10100111,%00100111,%00100011,%10001001,%11111010
	.db %10100111,%11100111,%00100001,%00001001,%11111010
	.db %10100111,%11100111,%00100100,%01001000,%00111010
	.db %10100100,%00100000,%00100110,%11001001,%11111010
	.db %10100111,%00100111,%00100111,%11001001,%11111010
	.db %10100111,%00100111,%00100111,%11001001,%11111010
	.db %10100111,%00100111,%00100111,%11001001,%11111010
	.db %10110000,%01110111,%10110111,%11101100,%00001010
	.db %10111111,%11111111,%11111111,%11111111,%11111010
	.db %10111111,%11111111,%11111111,%11111111,%11111010
	.db %10111000,%00110111,%10111000,%00010000,%00111010
	.db %10110011,%10010011,%10010011,%11110011,%10011010
	.db %10110011,%10010011,%10010011,%11110011,%10011010
	.db %10110011,%10010011,%10010011,%11110011,%10011010
	.db %10110011,%10010011,%10010000,%01110000,%00111010
	.db %10110011,%10010011,%10010011,%11110000,%11111010
	.db %10110011,%10011001,%00110011,%11110010,%01111010
	.db %10110011,%10011001,%00110011,%11110010,%01111010
	.db %10110011,%10011100,%01110011,%11110011,%00111010
	.db %10111000,%00111100,%01111000,%00011011,%10011010
	.db %10111111,%11111111,%11111111,%11111111,%11111010
	.db %10000000,%00000000,%00000000,%00000000,%00000010
	.db %11111111,%11111111,%11111111,%11111111,%11111110

npsplash:
	.db %11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111
	.db %11111111,%11111110,%00011110,%00011111,%11111111,%11110000,%00001111,%11111111,%11111111,%11111111,%11111111,%11111111
	.db %11111111,%11111110,%11001110,%11011111,%11111111,%11110111,%11100111,%11111111,%11111111,%11111111,%11111111,%11111111
	.db %11111111,%11111110,%11100110,%11011111,%11111111,%11110110,%01110111,%11111111,%11111111,%11111111,%11111111,%11111111
	.db %11111111,%11111110,%11110010,%11000000,%00000000,%00010110,%00110100,%00000000,%00110000,%00000001,%11111111,%11111111
	.db %11111111,%11111110,%11111000,%11011111,%10111111,%11010110,%01110001,%11110011,%10010110,%01111100,%11111111,%11111111
	.db %11001001,%00100110,%11011100,%11011000,%00000110,%00010111,%11100011,%00011011,%11000110,%11000110,%11001001,%00100111
	.db %11001001,%00100110,%11001110,%11011000,%00110110,%11110110,%00000011,%00011011,%11100110,%11000000,%11001001,%00100111
	.db %11111111,%11111110,%11000111,%11011111,%00110110,%11110110,%11111011,%00011011,%01110110,%11000000,%11111111,%11111111
	.db %11111111,%11111110,%11010011,%11011000,%00110110,%11110110,%11111011,%00011011,%00111110,%11001110,%11111111,%11111111
	.db %11111111,%11111110,%11011001,%11011000,%00110110,%11110110,%11111011,%00011011,%00011110,%11000110,%11111111,%11111111
	.db %11111111,%11111110,%11011100,%11011111,%10110110,%11110110,%11111001,%11110011,%01001110,%01111010,%11111111,%11111111
	.db %11111111,%11111110,%00011110,%00000000,%00110000,%11110000,%11111100,%00000000,%01100000,%00000000,%11111111,%11111111
	.db %11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111
	.db %10000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000001
	.db %10000000,%00000000,%00000000,%00000000,%00000000,%00000001,%11000000,%00000000,%00000000,%00000000,%01100001,%10000001
	.db %10000000,%00000000,%00000000,%00000000,%00000000,%00000010,%00000000,%00000000,%00000000,%00000000,%00010000,%01000001
	.db %10000111,%01110101,%01110110,%01110110,%00011001,%01000100,%11100110,%01000001,%11000000,%00000000,%00100000,%10000001
	.db %10000101,%01010101,%01100110,%01100101,%00011001,%01000101,%00001001,%01000010,%00011100,%11110111,%01110101,%11000001
	.db %10000111,%01010111,%01000101,%01000101,%00010100,%10000101,%00001111,%01000010,%00010010,%11000010,%00000000,%00000001
	.db %10000100,%01110111,%01110101,%01110110,%00011000,%10000100,%11101001,%01111001,%11010010,%11110010,%00100000,%00000001
	.db %10000000,%00000000,%00000000,%00000000,%00000000,%00000010,%00000000,%00000000,%00000000,%00000000,%00010000,%00000001
	.db %10000000,%00000000,%00000000,%00000000,%00000000,%00000001,%11111111,%11111111,%11111111,%11111111,%11111000,%00000001
	.db %10000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00010000,%00000001
	.db %10000000,%00000000,%00000000,%00000000,%00000000,%00000001,%00000000,%00100000,%00000000,%10000000,%00100000,%00000001
	.db %10000000,%01000101,%00010100,%01000011,%00100110,%10001001,%10010001,%10110000,%11000100,%11000000,%00000000,%00000001
	.db %10000000,%01010101,%01010101,%01000100,%01010101,%01010101,%00101010,%00101000,%10101010,%10000000,%00000000,%00000001
	.db %10000000,%01010101,%01010101,%01000100,%01100101,%01011001,%00110010,%00101000,%10101100,%10000000,%00000000,%00000001
	.db %10000000,%00101000,%10100010,%10010011,%00110101,%01001100,%10011001,%10101010,%10100110,%01000000,%00000000,%00000001
	.db %10000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000001
	.db %11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111

;#include "../source/calcnet2.asm"

.end
END