;
; T[ovO
;
#define	NEOZC_SERVER	1

//#define DEBUG

#include "..\\Library\\hsp261cmp.as"	;; HSP2.61݊}NLɂ
#include "..\\Library\\hspdef.as"

#include "..\\Library\\e3dhsp3.as"

; NCAg/T[oʒ`
#include "..\\Common\\neozc_cs_common.hsp"


#ifdef	USE_PCBNET
	#include "..\\Common\\AMdplayStub.hsp"
#else	; USE AMdplay
  #ifdef COM_DEBUG
	#include "..\\Library\\AMdplayD.as" ; for DEBUG
  #else
	#include "..\\Library\\AMdplay.as"
  #endif

  #include "..\\Library\\m_AMdplaySupport.as"
#endif

;; st@C쐬p
#packopt type 0
#packopt name "neozc_server.exe"
#packopt hide 0

; }N`
; `[̃|WVWf[^  %1: tH[[VA%2: `[ 
#define InitPosition( %1, %2 ) tmp_form=%1:tmp_tm=%2:gosub *sInitPosition

; |WV̍W擾 %1: `[  %2: |WV
#define GetPlayerPos( %1, %2 ) tmp_tm=%1:tmp_pos=%2:gosub *sGetPlayerPos

; W߂̃vC[̌  %1: `[A%2: XWA%3: ZW
#define SearchNearPlayer( %1, %2, %3 ) tmp_tm=%1:tmp_posx=%2:tmp_posz=%3:gosub *sSearchNearPlayer

; vC[ړ  %1: PlayerNo, %2: XW, %3: YW, %4: ZW, %5: , %6: R
#define ForthMovePlayer( %1, %2, %3, %4, %5, %6) tmp_pno=%1:tmp_posx=%2:tmp_posy=%3:tmp_posz=%4:tmp_ph=%5:tmp_cause=%6:gosub *sForthMovePlayer

; is̈̐ݒ %1: n_XW, %2: n_ZW, %3: I_XW, %4: I_ZW
#define SetInvArea( %1, %2, %3, %4 ) tmp_posx0=(%1):tmp_posz0=(%2):tmp_posx1=(%3):tmp_posz1=(%4):gosub *sSetInvArea

#define WAIT_TIME 1	; msec

; O\p
#define EM_SETSEL	$b1
#define EM_SCROLLCARET	$b7
#define EM_GETLINECOUNT	$ba
#define EM_REPLACESEL	$c2

#define	SYNC_TIMEOUT_VAL	3	; M̃^CAEg(b)

#define MES_DISP_TIME		5	; bZ[W̕\ (b)

#define GAME_BREAK_TIME		10	; Half TimeȂǒf(b)

#define WAIT_TIMEOUT_VAL	15	; NCAg̉^CAEg


dim	sync_flag, PlayerMax
dim	sync_count, PlayerMax
dim	sync_timeout, PlayerMax
dim	sync_send_time, PlayerMax

onexit goto *bye

; ݒt@C̓ǂݍ
sdim ini_file, 1024
sdim Dest_ADDR, 32
;sdim Port, 32
	bload "server.ini", ini_file
	instr str_index, ini_file, "IP_Addr=", 0
	if str_index != -1 {
		str_index += 8
		instr rtn_index, ini_file, "\n", str_index
		strmid Dest_ADDR, ini_file, str_index, rtn_index
	}
	else {
		Dest_ADDR="127.0.0.1"	
	}
#ifdef	USE_PCBNET
	instr str_index, ini_file, "Port=", 0
	if str_index != -1 {
		str_index += 5
		instr rtn_index, ini_file, "\n", str_index
		strmid Port, ini_file, str_index, rtn_index
	}
	else {
		Port=GAME_PORT
	}
#endif

*entry_ip
	pos 0, 20:color 0,0,0:mes "Server IP:"
	pos 120,20:objsize 120,24:input Dest_ADDR
#ifdef	USE_PCBNET
	pos 0, 50:color 0,0,0:mes "Port:"
	pos 120,50:objsize 120,24:input Port
#endif	
	pos 0, 60
	pos 400,20:objsize 64,24:button "OK",*start_game
stop

*start_game
	;<<<<<<<<<<	Initialize	>>>>>>>>>>
	screen 0,640,480,1,0,0
	GameName = GAME_NAME
	title GameName + " Server " + GAME_VERSION
	DPGameName = GAME_NAME + GAME_VERSION
 
	sdim logmsg,32000,1:mesbox logmsg,640,480,1:msg=""
	objlog = stat
	gettime old_time,7

	my_fameNo = 0

	E3DInit SCR_MAIN, -1, 0, 16, 0, scid

	;-----				-----

;/////	AMdplay̏iT[o@\j	/////
gsel 0

	;ʐMݒ

	MP_Name="NEOZC_Server"		;ғQ[T[o
	BootSes=SESSION_NAME		;Q[T[oŊJZbV

#ifndef USE_PCBNET
	Port=GAME_PORT			;|[gԍ
#endif
	dim Players,1:Players=0	;QPlayer̃JEgpϐ

	; DirectPlay̏
	AMdplayInitialize DPGameName : m_ec

	; Q[T[oݒ
	AMdplaySetPlayerName MP_Name : m_ec

	; RlNVTCP/IPŐݒ
	AMdplaySelectSpecifiedConnection Dest_ADDR,Port,AMDPLAY_CONNECT_TCPIP : m_ec
	if Port=="":Port="****"

	; Q[T[o̒ʐMғݒ
	Server_flag =     DPSESSION_CLIENTSERVER		; C/SZbVw
	Server_flag = Server_flag | DPSESSION_KEEPALIVE		; ُvC[폜w
	Server_flag = Server_flag | DPSESSION_OPTIMIZELATENCY	; xŏœKw
	Server_flag = Server_flag | DPSESSION_NODATAMESSAGES	; f[^ύXʒmw
;	Server_flag = Server_flag | DPSESSION_NOMESSAGEID	; ʐMɃbZ[WIDpȂw
	Server_flag = Server_flag | DPSESSION_DIRECTPLAYPROTOCOL; DirectPlayvgRw
	Server_flag = Server_flag | DPSESSION_NOPRESERVEORDER	; MێȂ

	; ZbVJ
	AMdplayHostSession BootSes ,Server_flag : m_ec

	; JZbV̍ő哯ڑݒ
	AMdplaySetSession 1, PlayerMAX : m_ec

	; Mobt@o^
	sdim netbuf, 8192,1
	AMdplaySetReceiveBuffer netbuf,8192:m_ec
	dup bufmes, netbuf					; f[^Mpobt@
;	dup bufnum, netbuf: int bufnum		; lf[^Mpobt@
	dupptr bufnum, varptr(netbuf), 8192, 4

	; Mi[ϐo^
	dim info,16 : AMdplaySetReceiveInfo info:m_ec
	dup info_0,info.0

	; Alϐo^
	dim ret_stat,1024
	AMdplaySetResultVariable ret_stat:m_ec

	; MfBeB[̏
	dim send_flg, 16
	AMdplayGetPointer send_flg:m_ec
	pflg = ret_stat
		dup Set_DataProperty,send_flg.0
		dup Set_DataType,send_flg.1
		dup Set_SendType,send_flg.2
		dup Set_Priority,send_flg.3
		dup Set_TimeOut,send_flg.4	

	; MfBeB[̏ݒ
	Set_DataProperty = AMDPLAY_SEND_ARRAY_AUTO		; MIvV= ȈՈk/
	Set_DataType = 0					; f[^^Cv	= ftHg:0
	Set_SendType = DPSEND_ASYNC | DPSEND_NOSENDCOMPLETEMSG	; MtO	= 񓯊M/BmFȂ
	Set_Priority = Normal_Priority				; Dx	= m[}vCIeB:256
	Set_TimeOut = 0						; ^CAEg	= Ȃ:0

	; ғQ[T[õj[NID擾
	AMdplayGetMyID Server_ID:m_ec

	; ғQ[T[o\
	msg = "Game Server Name : "+MP_Name:gosub *logput
	msg = "Game Server ADDR : "+Dest_ADDR+" / Port : "+Port:gosub *logput
	msg = "Boot Session     : "+BootSes:gosub *logput
	msg = "Game Server  ID  : "+Server_ID:gosub *logput

	;------------------------------------------------------------------

	; tH[[Vʂ̍Wf[^
	InitPosition FORM_352, TEAM_BLUE
	InitPosition FORM_352, TEAM_RED

	dim tmpmsg,1024

*restart_main	; T[oX^[g

	;-----	Player̍\	-----
*Players_Init
	repeat PlayerMAX
		pno = cnt
		pl_infdat.pno.iINFPNO	= pno
		pl_infdat.pno.iINFPID	= 0
		pl_infdat.pno.iINFTM	= 0
		pl_infdat.pno.iINFPOS	= 0
		pl_infdat.pno.iINFPOSX	= 0
		pl_infdat.pno.iINFPOSY	= 0
		pl_infdat.pno.iINFPOSZ	= 0
		pl_infdat.pno.iINFPH	= 0
		pl_infdat.pno.iINFHOST	= 0

		pl_mvdat.pno.iMVPNO	= pno
		pl_mvdat.pno.iMVMX	= 0
		pl_mvdat.pno.iMVMY	= 0
		pl_mvdat.pno.iMVMZ	= 0
		pl_mvdat.pno.iMVPH	= 0
		pl_mvdat.pno.iMVMF	= MT_STOP
		pl_mvdat.pno.iMVMP	= 0

		player_name.pno = "]"
		player_team.pno = ""

		ball_data_updt.pno = 0

		repeat PlayerMAX
			pl_mvdat_updt.pno.tmp = 0
		loop
	loop

	Players = 0

	; zXgPlayerNo
	host_pno = -1

	game_state = STAT_PRE_GAME
	game_start_flag = 0

	; t[ԍ
	my_frameNo = 0
	sub_frameNo = 0

*gameinit_main

	; Jn̏
	gosub *GameStartInit

*main	;<<<<<<<<<<	C	>>>>>>>>>>

#ifdef SERVER_WAIT_FPS
	waitbyfps FPS_SERVER, chkfps
#else
	await WAIT_TIME
#endif

	gosub *Receive_Check

	switch game_state
	case STAT_PRE_GAME
	case STAT_GAME_PLAYING

		gosub *BallMoveJudge	; M{[f[^̔

		repeat PlayerMax
			if ( pl_infdat.cnt.iINFPID != 0 ) {
				tmp_pno = cnt
				If ( sync_flag.tmp_pno == 0 ) {
					gosub *Send_Sync

					; {[𑗐M
					if ( ball_data_updt.tmp_pno == 1 ) {
						send_ball_dest = pl_infdat.tmp_pno.iINFPID
						dest_pno = tmp_pno
						gosub *Send_Ball_Move
					}
					; vC[ړ𑗐M
					dest_pno = tmp_pno
					gosub *Send_Player_Move
				}
				else {
					gosub *GetCurTime

					If ( (ret_time - sync_send_time.tmp_pno) >= SYNC_TIMEOUT_VAL ) {
						sync_timeout.tmp_pno = SYNC_TIMEOUT_VAL
						gosub *Sync_Receive
					}
				}
			}	
		loop
		
		gosub *BallChk

		if ( ba_stat == BA_STAT_MOVING ) {
			gosub *MoveBall
		}
		else {
			if ( ymove > (BA_CONF_YMV_THRESH + 100) ) {
				; {[ƂłƂ܂Ă܂ꍇ̎b΍
				ba_stat = BA_STAT_MOVING
				ymove = 0
				/* ball_moving = 1 */
			}
		}

		;; ړ̃^CAEg`FbN
		if ( fmv_time_end > 0 ) {
			gosub *GetCurTime
			if ( ret_time >= fmv_time_end ) {

			}
		}

		if ( game_state == STAT_GAME_PLAYING ) {
			gosub *GetCurTime

			; Ԍo
			if ( prev_time != ret_time ) {
				tmptime = end_time - ret_time
				if ( tmptime <= 0 ) {
					gosub *NextGamePhase
				}
#ifdef DEBUG
				timestr = (tmptime/60)
				timestr = "0" + timestr
				strmid secstr, timestr, -1, 2
				timestr = (tmptime\60)
				timestr = "0" + timestr
				strmid minstr, timestr, -1, 2

				msg = secstr + ":" + minstr
				gosub *logput
#endif
			}
		}
		prev_time = ret_time

		swbreak
	case STAT_GAME_BREAK
		gosub *GetCurTime

		If ( (ret_time - break_start_time) >= GAME_BREAK_TIME ) {
			if ( game_phase == PHASE_END ) {

				game_state = STAT_PRE_GAME
				game_start_flag = 0
				goto *gameinit_main
			}
			else {
				switch game_phase
				case PHASE_HALF2
					ini_ball_owner_team = TEAM_RED
					swbreak
				case PHASE_EXTRA_HALF1
					ini_ball_owner_team = TEAM_RED
					swbreak
				case PHASE_EXTRA_HALF2
					ini_ball_owner_team = TEAM_BLUE
					swbreak
				default
					ini_ball_owner_team = TEAM_BLUE
					swbreak
				swend
	
				gc_submsg = GC_Game_Restart
				game_ctrl.iGCTEAM = ini_ball_owner_team
				gosub *Send_GameCtrl

				; vC[f[^̏
				gosub *InitPlayers

				; {[f[^̏
				gosub *InitBallData

				; NCAg̉҂Ƃ
				gosub *WaitReady
			}
		}
		swbreak
	case STAT_WAIT_READY
		gosub *GetCurTime

		if ( ret_time >= wait_timeout ) {
			; SẴNCAgAck󂯂̂Ƃ݂Ȃ
			repeat PlayerMAX
				player_ready.cnt = 1
			loop
			tmp_pno = 0
			gosub *Receive_Game_Ack
		}
	swend

#ifdef SERVER_WAIT_FPS
	; t[ԍ̍XV
	sub_frameNo++
#if 0
	if ( sub_frameNo >= FPS_SVR_MUL ) {
		sub_frameNo = 0
		my_frameNo++
		if ( my_frameNo > FRAME_NO_MAX ) {
			my_frameNo = 0
		}
		If ( (my_frameNo \ 50) == 0 ) {
			repeat PlayerMax
				if ( pl_infdat.cnt.iINFPID != 0 ) {
					tmp_pno = cnt
					gosub *Send_Sync_Restart
				}
			loop
		}
	}
#endif

#endif

	if ( dri_ign_cnt > 0 ) {
		dri_ign_cnt--
	}

goto *main

*Receive_Check
	; M`FbN

result = 1
while (result==1)
	AMdplayReceive result:m_ec
	if ( result==-1 ) {
		gosub *Receive_System_Msg
	}
	if ( result == 1 ) {
		;/////	f[^^Cv̔f	/////
		if info_0 == MSG_Player_Move : gosub *Player_Move
		if info_0 == MSG_Start_Ball_Move : gosub *Start_Ball_Move
		if info_0 == MSG_Ball_Move : gosub *Receive_Ball_Move
		if info_0 == MSG_Entry_Logon : gosub *Entry_Player
		if info_0 == MSG_Game_Sync_Ack : gosub *Sync_Receive
		if info_0 == MSG_Sound : gosub *Send_Sound
		if info_0 == MSG_Game_Ctrl : gosub *Receive_Game_Ctrl
		if info_0 == MSG_ChatMsg_All : gosub *Receive_ChatMsg_All
		if info_0 == MSG_ChatMsg_Team : gosub *Receive_ChatMsg_Team
	}
wend

return

*Receive_System_Msg
	msg = "Sys Msg " + info_0
	gosub *logput
	if info_0 == DPSYS_DESTROYPLAYERORGROUP : goto *Delete_Player
return

*Entry_Player

;	if ( game_state != STAT_PRE_GAME ) : return

	; eXgɂAOC\
;	if ( game_start_flag > 0 ) : return		; ̃OC֎~ 

	; Q[ւ̎Qv͂
;	Players++

#if 0
	; Ƃ肠`[́AT[o烉_Ɏw
	rnd rt, 2
#else
	rt = bufnum.iELTEAM
#endif

	pno = 0
	found = 0

	while (( pno < PlayerMAX ) && ( found == 0 ))
		if ( pl_infdat.pno.iINFPID == bufnum.iELPID ) {	; ɑݒ
			return
		}
		if ( pl_infdat.pno.iINFPID == 0 ) {
			pl_infdat.pno.iINFPID = bufnum.iELPID
			pl_infdat.pno.iINFPNO = pno
			pl_infdat.pno.iINFTM = rt
			pl_infdat.pno.iINFPOS = bufnum.iELPOS
			tmp = pno
			found = 1
		}
		pno++
	wend

	if ( found == 0 ) {
		return		; 蓖Ďs
	}

	; |WVɉW擾
	GetPlayerPos pl_infdat.tmp.iINFTM, pl_infdat.tmp.iINFPOS
	pl_infdat.tmp.iINFPOSX = ret_posx
	pl_infdat.tmp.iINFPOSY = 0
	pl_infdat.tmp.iINFPOSZ = ret_posz

	; ̐ݒ
	if ( pl_infdat.tmp.iINFTM == TEAM_BLUE ) {
		pl_infdat.tmp.iINFPH = 270
	}
	else {
		pl_infdat.tmp.iINFPH = 90
	}
	
	tmpstr = ""
	AMdplayGetPlayerName tmpstr,pl_infdat.tmp.iINFPID:m_ec	;vC[̎擾
	await
	player_name.tmp=tmpstr			;vC[̕ۑ

;	msg = "Player Entry. PID = "+pid.tmp+" Player No. = "+tmp+" PlayerName = "+player_name.tmp
;	gosub *logput

	msg = "Player Entry PID:" + pl_infdat.tmp.iINFPID + " PNO:" + pl_infdat.tmp.iINFPNO + " Name:[" + player_name.tmp
	gosub *logput

;	Set_DataType = MSG_Logon_Ok
;	AMdplaySend tmp, 4, pflg, pl_infdat.tmp.iINFPID:m_ec	;PlayerNoNCAg֕Ԃ
;	await

	; zXg̐ݒ
	if ( host_pno == -1 ) {
		pl_infdat.tmp.iINFHOST = 1
		host_pno = tmp
	}
	else {
		pl_infdat.tmp.iINFHOST = 0
	}

	; ̃vC[𑗂
	repeat PL_INFDAT_SIZE
		send_pl_infdat.cnt = pl_infdat.tmp.cnt
	loop
	Set_DataType = MSG_Logon_Ok		; bZ[W^Cv̂Logon_OkƂ
	AMdplaySend send_pl_infdat, PL_INFDAT_SIZE*4, pflg, pl_infdat.tmp.iINFPID : m_ec
	await	

	; === Gg ===

	; GgPlayerɂłɃOIς݂PlayerԂ
	repeat PlayerMAX		;őPlayerJԂ
		if pl_infdat.cnt.iINFPID==0:continue
		if tmp==cnt:continue	;M̃f[^͑Ȃ
		j=cnt
		repeat PL_INFDAT_SIZE	;Playerf[^ʐMpɍč\z
			send_pl_infdat.cnt = pl_infdat.j.cnt
		loop
		Set_DataType = MSG_Player_Info
		AMdplaySend send_pl_infdat, PL_INFDAT_SIZE*4, pflg, pl_infdat.tmp.iINFPID : m_ec
;		await
	loop

	; GgPlayerɂłɃOIς݂PlayerړԂ
	repeat PlayerMAX		;őPlayerJԂ
		if pl_infdat.cnt.iINFPID==0:continue
		if tmp==cnt:continue	;M̃f[^͑Ȃ
		;Playerf[^ʐMpɍč\z
		tmp_pno = cnt
		gosub *MakeMVSendData

		Set_DataType = MSG_Player_Move
		AMdplaySend send_pl_cmvdat, PL_CMVDAT_SIZE*4, pflg, pl_infdat.tmp.iINFPID : m_ec		
;		await
	loop
	
	; {[n
	Set_DataType = MSG_Ball_Move
	; Ballf[^ʐMpɍč\z
	ba_pno = 255		; ȊO
	gosub *MakeBallSendData
;	repeat BALL_DATA_SIZE
;		send_ball_data.cnt = cur_ball_data.cnt
;	loop
	AMdplaySend send_ball_data, BALL_CDATA_SIZE*4, pflg, pl_infdat.tmp.iINFPID : m_ec
;	await

	tmpmsg=""
	repeat PlayerMAX
		tmpmsg+=player_name.cnt+"|"	;"|"͋؂蕶
	loop
	Set_DataProperty = AMDPLAY_SEND_STRING	;ʐMtO𕶎񑗐Mɐݒ
	Set_DataType = MSG_Entry_Player	;PlayerGgꂽ̃f[^^Cvɐݒ
	save_sendtype = Set_SendType
	Set_SendType = DPSEND_ASYNC | DPSEND_GUARANTEED
	strlen len, tmpmsg
	AMdplaySend tmpmsg,len,pflg,DPID_ALLPLAYERS : m_ec

;	await
	Set_DataProperty = AMDPLAY_SEND_ARRAY_AUTO	;ʐMtOʏɖ߂Ă
	Set_SendType = save_sendtype

	; GgPlayer𑼂̃vC[ɑ
	repeat PL_INFDAT_SIZE
		send_pl_infdat.cnt = pl_infdat.tmp.cnt
	loop
	Set_DataType = MSG_Player_Info
	AMdplaySend send_pl_infdat, PL_INFDAT_SIZE*4, pflg, DPID_ALLPLAYERS : m_ec
;	await

	; vC[Zbg
	AMdplayGetPlayerCount pltmp
	Players = pltmp - 1

	; t[̍ēs
	tmp_pno = tmp
	gosub *Send_Sync_Restart

return

*Delete_Player
	
	; PlayerQ[甲
	tmp=-1:dup info_4,info.4	;DPID̈ꎞێ
	repeat PlayerMAX
		if ( pl_infdat.cnt.iINFPID == info_4 ) {
			pl_infdat.cnt.iINFPID=0		;DPIDNo.蓖Ă
			tmp=cnt
			break	
		}
	loop
	if tmp==-1:return	;Y҂Ȃ̓^[iG[΍Ȃj

	; ړvC[ꍇ
	if ( fmv_player_pno == tmp ) {
		; {[ړ
		gosub *Forth_Move_Ball
		fmv_player_pno = -1

		; is̈
		gosub *DisableInvArea
	}

	; vC[Zbg
	AMdplayGetPlayerCount pltmp
	Players = pltmp - 1
	msg = "pltmp=" + pltmp
	gosub *logput

	msg = "Player Delete. PID = "+info_4+" : Player No. = "+tmp + " : Players = " + Players
	gosub *logput	;Oɏo
	Set_DataType = MSG_Delete_Player
	AmdplaySend tmp,4,pflg,DPID_ALLPLAYERS : m_ec

	player_name.tmp = "]"

	; OCĂvC[ȂȂꍇ́AT[o
	if ( Players <= 0 ) {
		msg = "Restart"
		gosub *logput
		goto *restart_main
	}

	; zXgꍇÃvC[ɃzXg蓖
	if ( host_pno == tmp ) {
		msg = "Host Changed"
		gosub *logput
		gosub *ChangeHost
	}


;	await
return

*ChangeHost
	repeat PlayerMAX
		if ( pl_infdat.cnt.iINFPID == 0 ) : continue
		pl_infdat.cnt.iINFHOST = 1
		host_pno = cnt
		break
	loop
	if ( host_pno >= PlayerMAX ) {
		host_pno = -1		; YȂ
	}
	else {
		; zXgPlayer𑗂
		repeat PL_INFDAT_SIZE
			send_pl_infdat.cnt = pl_infdat.host_pno.cnt
		loop
		Set_DataType = MSG_Player_Info
		AMdplaySend send_pl_infdat, PL_INFDAT_SIZE*4, pflg, DPID_ALLPLAYERS : m_ec
;		await
	}
return

*Player_Move
	if ( game_state != STAT_PRE_GAME ) && ( game_state != STAT_GAME_PLAYING ) {
		return
	}

	; PlayerLN^ړ
	tmp=(bufnum.iCMVPNO_MF_PH & 0xFF0000) >> 16
	If ( tmp >= 0 ) && ( tmp < PlayerMax) {
		if  ( pl_infdat.tmp.iINFPID != 0 ) {
			; Mf[^ړf[^𕜌
			pl_mvdat.tmp.iMVPNO = tmp
			pl_mvdat.tmp.iMVMF = (bufnum.iCMVPNO_MF_PH & 0xFF00) >> 8
			pl_mvdat.tmp.iMVPH = ((bufnum.iCMVPNO_MF_PH & 0xFF) - CMV_PH_BASE) * 2
			pl_mvdat.tmp.iMVMX = (((bufnum.iCMVMX_MZ) >> 16) - CMV_MX_BASE) * 10
			pl_mvdat.tmp.iMVMZ = ((bufnum.iCMVMX_MZ & 0x0000FFFF) - CMV_MZ_BASE) * 10
			pl_mvdat.tmp.iMVMY = 0

#if 0
			msg = "MX:" + pl_mvdat.tmp.iMVMX + " MZ:" + pl_mvdat.tmp.iMVMZ
			gosub *logput
			msg =  " PH:" + pl_mvdat.tmp.iMVPH + " MF:" + pl_mvdat.tmp.iMVMF
			gosub *logput
#endif
	
			repeat PlayerMAX
				pl_mvdat_updt.cnt.tmp = 1
			loop

;msg = "R " + tmp + " " + bufnum.iMVMX
;gosub *logput
		}
	}
return

*Send_Player_Move
	Set_DataType = MSG_Player_Move

	repeat PlayerMAX		;őPlayerJԂ
		if pl_infdat.cnt.iINFPID==0:continue
		if pl_infdat.cnt.iINFPID==pl_mvdat_dest:continue	;M̃f[^͑Ȃ
		if pl_mvdat_updt.dest_pno.cnt == 0: continue
		;Playerf[^ʐMpɍč\z
		tmp_pno = cnt
		gosub *MakeMVSendData
		Set_DataType = MSG_Player_Move
		AMdplaySend send_pl_cmvdat, PL_CMVDAT_SIZE*4, pflg, pl_infdat.dest_pno.iINFPID : m_ec		
		pl_mvdat_updt.dest_pno.cnt = 0

;		await
	loop
return

; vC[ړf[^AMpf[^쐬
*MakeMVSendData
	pno = (tmp_pno << 16)
	mf = (pl_mvdat.tmp_pno.iMVMF) << 8
	ph = (pl_mvdat.tmp_pno.iMVPH)/2 + CMV_PH_BASE
	mx = ((pl_mvdat.tmp_pno.iMVMX/10) + CMV_MX_BASE) << 16
	mz = ((pl_mvdat.tmp_pno.iMVMZ/10) + CMV_MZ_BASE)

	send_pl_cmvdat.iCMVPNO_MF_PH = pno | mf | ph
	send_pl_cmvdat.iCMVMX_MZ = mx | mz
return

*Receive_Ball_Move
	if ( game_state != STAT_PRE_GAME ) && ( game_state != STAT_GAME_PLAYING ) {
		return
	}

	if ( cross_flag != 0 ) {	; {[OɏoĂ鎞͎󂯕tȂ
		return					
	}

	; Mf[^{[f[^𕜌
	tmp_ball.iBAPNO = ((bufnum.iCBAPNO_STAT_TEAM) & 0xFF0000) >> 16
	tmp_ball.iBASTAT = ((bufnum.iCBAPNO_STAT_TEAM) & 0xFF00) >> 8
	tmp_ball.iBATEAM = ((bufnum.iCBAPNO_STAT_TEAM) & 0xFF)
	tmp_ball.iBAMX = ((bufnum.iCBAMX_MZ >> 16) - CMV_MX_BASE) * 10
	tmp_ball.iBAMZ = ((bufnum.iCBAMX_MZ & 0xFFFF) - CMV_MZ_BASE) * 10
	tmp_ball.iBAMY = (bufnum.iCBAYMV_MY & 0xFFFF)
	tmp_ball.iBAYMV = ((bufnum.iCBAYMV_MY & 0xFFFF0000) >> 16) * 10

#if 0
	msg = "BA PNO:" + tmp_ball.iBAPNO + " STAT:" + tmp_ball.iBASTAT + " TM:" + tmp_ball.iBATEAM
	gosub *logput
	msg = "BA MX:" + tmp_ball.iBAMX + " BA MY:" + tmp_ball.iBAMY + " BA MZ:" + tmp_ball.iBAMZ + " YMV:" + tmp_ball.iBAYMV
	gosub *logput
#endif

	tmp = tmp_ball.iBAPNO

	If ( tmp < 0 ) || ( tmp >= PlayerMax ) || ( pl_infdat.tmp.iINFPID == 0 ) {
		return
	}


	; Mf[^Ã݂{[̈ʒuƑ傫Ăꍇ͖ (OĂ\)
	if ( cur_ball_data.iBAPNO != tmp_ball.iBAPNO ) {
		diffx = cur_ball_data.iBAMX - tmp_ball.iBAMX
		if ( diffx < 0) : diffx = -diffx
		diffz = cur_ball_data.iBAMZ - tmp_ball.iBAMZ
		if ( diffz < 0) : diffz = -diffz
		if (( diffx > 1500 ) || ( diffz > 1500 )) {
			msg = "Invalid Ball Move Received from PNO=" + tmp_ball.iBAPNO + " BX " + cur_ball_data.iBAMX + " TX " + tmp_ball.iBAMX
			gosub *logput
			tmp_pno = tmp_ball.iBAPNO
			send_ball_dest = pl_infdat.tmp_pno.iINFPID
			gosub *Send_Ball_Move							; ʒu𑗂
			return
		}
	}

	; hȕL҂ς́AL҈ȊÕf[^͖
	if (dri_ign_cnt > 0) && ((tmp_ball.iBASTAT & $7F) == BA_STAT_DRIBBLE) && (tmp != cur_ball_data.iBAPNO ) {
		msg = "Dribble Ignored"
		gosub *logput
		return
	}

	if ( ball_data_buf.tmp.iBAPNO < 0 ) {	; t[2ȏMꍇ̓JEgȂ
		ball_data_buf_cnt++

		; {[Xe[^Xʂ̃JEg
		ba_st = (tmp_ball.iBASTAT & $7F)
		ball_bufst_cnt.ba_st++ 
	}

	; {[Mf[^obt@ɕ
	repeat BALL_DATA_SIZE
		ball_data_buf.tmp.cnt = tmp_ball.cnt
	loop

#if 0
	msg = "FR:" + my_frameNo + " Ball Move " + " PNO:" + cur_ball_data.iBAPNO + " stat:" + cur_ball_data.iBASTAT + " YM:" + ymove + " " 
	gosub *logput
#endif

return

*Send_Sync
	if pl_infdat.tmp_pno.iINFPID == 0 : return

	Set_DataType = MSG_Game_Sync	;f[^^Cv̐ݒ
	save_prio = Set_Priority
	Set_Priority = MAX_Priority	; ꎞIɗDxō
	bufnum.0 = sync_count.tmp_pno

	bufnum.1 = my_frameNo


	AmdplaySend bufnum,8,pflg,pl_infdat.tmp_pno.iINFPID

	sync_flag.tmp_pno = 1
	sync_timeout.tmp_pno = 0

	sync_count.tmp_pno++
	If ( sync_count.tmp_pno > 65535 ) {
		sync_count.tmp_pno = 0
	}

;	msg = "Sync Send " + my_frameNo
;	gosub *logput
	
	gosub *GetCurTime
	sync_send_time.tmp_pno = ret_time
	
	Set_Priority = save_prio	; vCIeBɖ߂
return

; t[ē
*Send_Sync_Restart
	if pl_infdat.tmp_pno.iINFPID == 0 : return

	Set_DataType = MSG_Game_Sync_Restart	;f[^^Cv̐ݒ
	save_prio = Set_Priority
	Set_Priority = MAX_Priority		; ꎞIɗDxō
	bufnum.0 = sync_count.tmp_pno
	bufnum.1 = my_frameNo

	AmdplaySend bufnum,8,pflg,pl_infdat.tmp_pno.iINFPID

;	msg = "Send Sync Restart " + my_frameNo
;	gosub *logput

	Set_Priority = save_prio	; vCIeBɖ߂
return	


*Sync_Receive

	If ( sync_timeout.tmp_pno >= SYNC_TIMEOUT_VAL ) {
		msg = "SYNC TIMEOUT  PNO=" + tmp_pno
		gosub *logput
	}
	else {
		tmp_pno=bufnum.0
	}

	sync_flag.tmp_pno = 0

#if 0	; Sync̑Mɑ悤ɕύX
	; {[𑗐M
	if ( ball_data_updt.tmp_pno == 1 ) {
		send_ball_dest = pl_infdat.tmp_pno.iINFPID
		gosub *Send_Ball_Move
		ball_data_updt.tmp_pno = 0
	}

	; vC[ړ𑗐M
	dest_pno = tmp_pno
	gosub *Send_Player_Move
#endif
;	msg = "Sync Recv " + my_frameNo + " " + bufnum.1
;	gosub *logput

return

*Start_Ball_Move
	if ( game_state != STAT_PRE_GAME ) && ( game_state != STAT_GAME_PLAYING ) {
		return
	}

	if ( ba_stat == BA_STAT_MOVING ) {		;@Ɉړ
		return
	}
	if ( cross_flag == 2 ) {			; X[CAt[LbNsꂽ
		cross_flag = 0
	}
	else {
		if ( cross_flag == 1 ) {		; OɏoĂꍇ
			return
		}
	}

	if (( ba_stat == BA_STAT_DRIBBLE ) || ( ba_stat == BA_STAT_HOLD )) && ( cur_ball_data.iBAPNO != bufnum.iBMVPNO ) {
		return		; L҂s
	}

#ifdef DEBUG
	msg = "Start Ball Move "
	gosub *logput
#endif
	gosub *DisableInvArea	; is̈

	if ( fmv_ball_move == 0 ) {
		;@NCAg̃bZ[W̏ꍇ
		ball_owner_pno = bufnum.iBMVPNO

		posxb = bufnum.iBMVMX
		posyb = bufnum.iBMVMY
		poszb = bufnum.iBMVMZ
		ball_speed = bufnum.iBMFSPD
		yspeed = bufnum.iBMYSPD
		ymove = bufnum.iMBYMOVE
		ymovef = bufnum.iBMYMOVEF	
		bdiffx = bufnum.iBMBDIFX
		bdiffz = bufnum.iBMBDIFZ

		msg = "SBM: spd="+ball_speed+ "yspd="+yspeed + "ymove="+ymove + "ymovef="+ymovef + "bdiffx="+bdiffx + "bdiffz="+bdiffz
		gosub *logput
	}
	else {
		; T[oŋIɃ{[𓮂ꍇ
		fmv_ball_move = 0
	}

#if 0
	msg = "MX " + bufnum.iBMVMX + " MY " + bufnum.iBMVMY + " MZ " + bufnum.iBMVMZ
	gosub *logput
#endif


#if 0
	ball_moving = 1
	ba_dribble = 0
	ball_hold = 0
#endif
	ba_stat = BA_STAT_MOVING
	
	ba_team = pl_infdat.ball_owner_pno.iINFTM

	cross_flag = 0
	ball_speed10 = ball_speed * 10

	fmv_player_pno = -1

	cur_ball_data.iBAPNO = -1
return

*MoveBall
#ifdef SERVER_WAIT_FPS
repeat BALL_SPD_ADJUST
#endif
	; {[̈ړxNg߂
	E3DVec3Normalize bdiffx, 0, bdiffz, bmovex, bmovey, bmovez
	posxb = posxb - int(bmovex*ball_speed)
	posyb = posyb - int(bmovey*ball_speed)
	poszb = poszb - int(bmovez*ball_speed)

#ifdef DEBUG
	msg = "Move Ball " + ball_speed + " " + ba_stat
	gosub *logput
#endif

	If ( ymovef > 0 ) {		; u or V[g
		ymove += yspeed
		if ( ymovef == 2 ) {
			if ( yspeed > 10 ) {
				yspeed -= 2
			}
			else {
				yspeed -= 4
			}
		}
		else {
			yspeed -= 5
		}
		If ( ymove <= 0 ) {
			yspeed = yspeed * 100 / 200 ; oEh
			yspeed = yspeed * -1

;			ball_speed = ball_speed * 400 / 500
			ball_speed10 = ball_speed10 * 40 / 50

			ymovef = 1

			If ( yspeed < 20 ) && ( yspeed > -20 ) {
				ymovef = 0
				ymove = 0
			}

			ymove += yspeed 
		}
	}
	else {				; sS
;		ball_speed -= 1
		if ( ball_speed < 100 ) {
			ball_speed10 = ball_speed10 - 5
		}
		else {
			ball_speed10 = ball_speed10 - 10
		}
	}
	ball_speed = ball_speed10 / 10 

	; lƂ̓蔻
	if ( ball_speed > BA_CONF_SPD_THRESH ) || ( ymovef == 1 ) {
		if ( ymove < BA_CONF_YMV_THRESH ) {
			gosub *ChkManConf

			if ( chk_manconf == 1 ) {
				bdiffx = -bdiffx
				bdiffz = -bdiffz
				ball_speed10 = ball_speed10 / 4
				ball_speed = ball_speed10 / 10
				ymovef = 0
				ymove = 0
			}
		}
	}

	; tB[hO
	gosub *ChkBallOut

	; S[Ƃ̓蔻
	gosub *ChkGoalConf
	if ( chk_goalconf == 1 ) {	; S[lbg
		bdiffx = -bdiffx/2
		bdiffz = -bdiffz/2
		ball_speed10 = ball_speed10 / 5
		ball_speed = ball_speed10 / 10
;		ymovef = 0
;		ymove = 0
	}
	else {
		if ( chk_goalconf == 2 ) {	; |Xg or o[
			bdiffx = -bdiffx
		;	bdiffz = -bdiffz
			ball_speed10 = ball_speed10 / 2
			ball_speed = ball_speed10 / 10
		}
	}

	; {[~
	If ( ball_speed <= 0 ) {
	/*	ball_moving = 0 */
		if ( ba_stat == BA_STAT_MOVING ) {
			ba_stat = BA_STAT_NORMAL
		}
		ymove = 0
	}
#ifdef SERVER_WAIT_FPS
loop
#endif
	repeat PlayerMAX
		ball_data_updt.cnt = 1
	loop
#if 0
	; {[𑗐M
	send_ball_dest = DPID_ALLPLAYERS
	gosub *Send_Ball_Move
#endif

return

; Q[p̃bZ[W𑗂
*Send_GameCtrl
	save_sendtype = Set_SendType
	Set_SendType = DPSEND_ASYNC | DPSEND_GUARANTEED

	Set_DataType = MSG_Game_Ctrl
	game_ctrl.iGCSUB = gc_submsg

#ifdef DEBUG
	if ( game_ctrl.iGCTEAM == 0 ) {
		team = "Blue"
	}
	else {
		team = "Red"
	}

	if gc_submsg==GC_Throw_In: msg="Throw In " + team
	if gc_submsg==GC_Goal: msg="Goal Blue " + game_ctrl.iGCSCBLUE + " - " + game_ctrl.iGCSCRED + " Red"
	if gc_submsg==GC_Goal_Kick: msg="Goal Kick " + team
	if gc_submsg==GC_Corner_Kick: msg="Corner Kick " + team

	gosub *logput
#endif

	AMdplaySend game_ctrl, GAME_CTRLDATA_SIZE*4, pflg, DPID_ALLPLAYERS : m_ec

	Set_SendType = save_sendtype
return

; Q[pf[^̑ޔ
*Save_GameCtrl
	repeat GAME_CTRLDATA_SIZE
		svgm_ctrl.cnt = game_ctrl.cnt
	loop
return

; {[ړ𑗐M
*Send_Ball_Move
	tmp = cur_ball_data.iBAPNO
	if ( tmp != -1 ) {
		; huAz[h̃vCɑ΂Ă͑MȂ
		if (( cur_ball_data.iBASTAT == BA_STAT_DRIBBLE ) || ( cur_ball_data.iBASTAT == BA_STAT_HOLD )) && ( pl_infdat.tmp.iINFPID == send_ball_dest ) : return
	}

	; {[𑗐M
	Set_DataType = MSG_Ball_Move
	;Ballf[^ʐMpɍč\z
	ba_pno=255
	gosub *MakeBallSendData
;	repeat BALL_DATA_SIZE	
;		send_ball_data.cnt = cur_ball_data.cnt
;	loop
;	send_ball_data.iBAPNO = -1		; PNOɎȊOw肷
	AMdplaySend send_ball_data, BALL_CDATA_SIZE*4, pflg, send_ball_dest : m_ec
	if ( send_ball_dest == DPID_ALLPLAYERS ) {
		repeat PlayerMAX
			ball_data_updt.cnt = 0
		loop
	}
	else {
		repeat PlayerMAX
			if ( send_ball_dest == pl_infdat.cnt.iINFPID ) {
				ball_data_updt.cnt = 0
				break
			}
		loop
	}
;	await
return

; {[ړ{[L҂ɑM
*Send_Ball_Move_Owner
	if ( cur_ball_data.iBAPNO == -1 ) : return
	; {[𑗐M
	Set_DataType = MSG_Ball_Move
	ba_pno = cur_ball_data.iBAPNO
	gosub *MakeBallSendData
	AMdplaySend send_ball_data, BALL_CDATA_SIZE*4, pflg, pl_infdat.ba_pno.iINFPID: m_ec
	ball_data_updt.ba_pno = 0
return
	

; {[Mpf[^쐬
*MakeBallSendData
	pno = (ba_pno << 16)
	bastat = (cur_ball_data.iBASTAT << 8)
	team = (cur_ball_data.iBATEAM)

	bamx = ((cur_ball_data.iBAMX/10) + CMV_MX_BASE) << 16
	bamz = ((cur_ball_data.iBAMZ/10) + CMV_MZ_BASE)

	ymv  = (cur_ball_data.iBAYMV/10) << 16	
	bamy = cur_ball_data.iBAMY

	send_ball_data.iCBAPNO_STAT_TEAM = pno | bastat | team
	send_ball_data.iCBAMX_MZ = bamx | bamz
	send_ball_data.iCBAYMV_MY = ymv | bamy

return

; is̈Zbg
*sSetInvArea
#ifdef DEBUG
	msg = "X0:"+tmp_posx0+" Z0:"+tmp_posz0+" X1:"+tmp_posx1+" Z1"+tmp_posz1
	gosub *logput
#endif
	inv_area.iIAEN 		= 1
	inv_area.iIAPOSX0	= tmp_posx0
	inv_area.iIAPOSZ0	= tmp_posz0
	inv_area.iIAPOSX1	= tmp_posx1
	inv_area.iIAPOSZ1	= tmp_posz1
return

; is̈
*DisableInvArea
	if ( inv_area.iIAEN == 1 ) {
		inv_area.iIAEN = 0
		gosub *Send_Inv_Area
	}
	fmv_time_end = 0
return

; is̈̑M
*Send_Inv_Area
#ifdef DEBUG
	msg = "Send Inv Area"
	gosub *logput
#endif

	Set_DataType = MSG_Inv_Area

	AMdplaySend inv_area, IA_DAT_SIZE*4, pflg, DPID_ALLPLAYERS : m_ec	
return

; TEh̑M
*Send_Sound
	Set_DataType = MSG_Sound

	sound_dat.iSNDPNO = bufnum.iSNDPNO
	sound_dat.iSNDNO = bufnum.iSNDNO
#if 0
	msg = "SND PNO=" + sound_dat.iSNDPNO
	gosub *logput
	msg = "SND NO=" + sound_dat.iSNDNO
	gosub *logput
#endif
	
	repeat PlayerMAX		;őPlayerJԂ
		if pl_infdat.cnt.iINFPID==0:continue
		if pl_infdat.cnt.iINFPNO==sound_dat.iSNDPNO:continue	;M̃f[^͑Ȃ
#if 0
		msg = "Snd"
		gosub *logput
#endif
		AMdplaySend sound_dat, SND_DAT_SIZE*4, pflg, pl_infdat.cnt.iINFPID : m_ec
	loop
return

; ǂ̃vC{[邩̔f
*BallMoveJudge
	tmp_sel = -1
	if ( ball_data_buf_cnt <= 0 ) {
		return		; Mf[^Ȃ
	}
	
	if ( ball_data_buf_cnt == 1 ) {	; f[^ЂƂȂ
		repeat PlayerMax
			if ( ball_data_buf.cnt.iBAPNO >= 0 ) {
				tmp_sel = cnt
#ifdef DEBUG
					msg = "Ball Judge DRIBBLE " + tmp_sel + " PNO:" + ball_data_buf.tmp_sel.iBAPNO
					gosub *logput
#endif
				break
			}
		loop	
	}
	else {
		; GK̃Lb`΁AD悷
		if ( ball_bufst_cnt.BA_STAT_HOLD > 0 ) {
			repeat PlayerMax
				if ( (ball_data_buf.cnt.iBASTAT & $7F) == BA_STAT_HOLD ) {
					tmp_sel = cnt
;#ifdef DEBUG
					msg = "Ball Judge HOLD " + tmp_sel + " PNO:" + ball_data_buf.tmp_sel.iBAPNO
					gosub *logput
;#endif
					break
				}
			loop
		}
		else {
			if ( ball_bufst_cnt.BA_STAT_DRIBBLE > 0 ) {
				if ( ball_bufst_cnt.BA_STAT_DIRBBLE == 1 ) {
					tmp_sel = cnt
;#ifdef DEBUG
					msg = "Ball Judge DRIBBLE " + tmp_sel + " PNO:" + ball_data_buf.tmp_sel.iBAPNO
					gosub *logput
;#endif
				}
				else {
					; ̃huvꍇAɃhũvC̓hus({[ƂꂽƂ݂Ȃ)
					; ̑̃vCŏɎMf[^LƂ
					repeat PlayerMax
						if ( ((ball_data_buf.cnt.iBASTAT & $7F) == BA_STAT_DRIBBLE) && (cnt != cur_ball_data.iBAPNO) ) {
							tmp_sel = cnt
;#ifdef DEBUG
							msg = "Ball Judge DRIBBLE " + tmp_sel + " PNO:" + ball_data_buf.tmp_sel.iBAPNO
							gosub *logput
;#endif
							break
						}
					loop
				}
			}
			else {
				if ( ball_bufst_cnt.BA_STAT_STOP > 0 ) {
					repeat PlayerMax
						if ( (ball_data_buf.cnt.iBASTAT & $7F) == BA_STAT_STOP ) {
							tmp_sel = cnt
;#ifdef DEBUG
							msg = "Ball Judge STOP " + tmp_sel + " PNO:" + ball_data_buf.tmp_sel.iBAPNO
							gosub *logput
;#endif
							break
						}
					loop
				}
				else {	; 肦ȂHH
					tmp_sel = 0
;#ifdef DEBUG
					msg = "Ball Judge Other " + tmp_sel + " PNO:" + ball_data_buf.tmp_sel.iBAPNO
					gosub *logput
;#endif
				}
			}
		}
	}

	if ( tmp_pno == -1 ) {
		msg = "Ball Move Error"
		gosub *logput
	}

	tmp_pno=ball_data_buf.tmp_sel.iBAPNO	; PlayerNo
	Sender_ID=pl_infdat.tmp_pno.iINFPID

	if ( ball_data_buf.tmp_sel.iBASTAT & BA_STAT_START_DRIBBLE_FLAG ) {
		start_dribble = 1
		ball_data_buf.tmp_sel.iBASTAT = (ball_data_buf.tmp_sel.iBASTAT & $7F)
	}
	else {
		start_dribble = 0
	}

	if ( Sender_ID != 0 ) {
		if ( ball_data_buf.tmp_sel.iBASTAT == BA_STAT_HOLD ) {

			ba_stat = BA_STAT_HOLD
#ifdef DEBUG
			msg = "BALL Hold"
			gosub *logput
#endif
		}
		else {
			if ( ball_data_buf.tmp_sel.iBASTAT == BA_STAT_DRIBBLE ) && ( ymove < BA_YMOVE_THRESH ) {

				ba_stat = BA_STAT_DRIBBLE
				ymove = 0
#ifdef DEBUG
				msg = "Ball Stop " + ba_stat
				gosub *logput
#endif
			}
		}

		if ( ba_stat == BA_STAT_MOVING ) && ( ymove >= BA_YMOVE_THRESH ) {
			return
		}
		
	}

	prev_pno = cur_ball_data.iBAPNO

	; {[f[^ɃRs[
	repeat BALL_DATA_SIZE
		cur_ball_data.cnt = ball_data_buf.tmp_sel.cnt
	loop

	ball_owner_pno = tmp_pno
	
	; {[̃tB[hO
	gosub *ChkBallOut

	; {[XVtOZbg
	repeat PlayerMAX
		ball_data_updt.cnt = 1
	loop

	; {[̏L҂ςꍇ́ÃvCɕKM
	if ( prev_pno != cur_ball_data.iBAPNO ) {
		save_prio = Set_Priority
		Set_Priority = MAX_Priority	; ꎞIɗDxō

		if ( prev_pno != -1 ) {
			send_ball_dest = pl_infdat.prev_pno.iINFPID	; ̏L
			gosub *Send_Ball_Move
		}

;		msg = "Ball Send " + prv_pno + " BS:" + cur_ball_data.iBASTAT
;		gosub *logput

		Set_Priority = save_prio	; vCIeBɖ߂

		if ( ba_stat == BA_STAT_DRIBBLE ) {
			; hȕL҂ςꍇ́AbÃvC̃hu𖳎
			dri_ign_cnt = 5
		}
	}

	if ( start_dribble == 1 ) {
		msg = "Start Dribble PNO=" + cur_ball_data.iBAPNO
		gosub *logput
		gosub *Send_Ball_Move_Owner		; huJńAKL҂ɑM
	}

	; {[Mf[^@JE^̃NA
	gosub *InitBallDataBuf
return

*ChkBallOut
	; {[̃tB[hO & S[
	if ( cross_flag == 0 ) {
		if ( posxb < (LINE_X0 - 50) ) || ( posxb > (LINE_X1 + 50) ) {
#if 0
			if ( posxb < LINE_X0 ) {
				crossxb = LINE_X0 + 200
			}
			else {
				crossxb = LINE_X1 - 200
			}
			crosszb = poszb
			crossym = 0
#endif
			cross_flag = 1

			; S[ǂ`FbN
			gosub *ChkGoal

;			cross_cnt = 200
			gosub *GetCurTime
			disp_end_time = ret_time + MES_DISP_TIME
		}
		if ( poszb < LINE_Z0 ) || ( poszb > LINE_Z1 ) {
			crossxb = posxb
			if ( poszb < LINE_Z0 ) {
				crosszb = LINE_Z0 - 300
				crossph = 180
				fmv_xoffs = 0
				fmv_zoffs = -500
			}
			else {
				crosszb = LINE_Z1 + 300
				crossph = 0
				fmv_xoffs = 0
				fmv_zoffs = 500
			}
			crossym = 950
			cross_flag = 1

			if ( pl_infdat.ball_owner_pno.iINFTM == TEAM_BLUE ) {
				game_ctrl.iGCTEAM = TEAM_RED	; ԃ`[
			}
			else {
				game_ctrl.iGCTEAM = TEAM_BLUE	; `[
			}

			gc_submsg = GC_Throw_In
			gosub *Send_GameCtrl

			gosub *Save_GameCtrl

;			cross_cnt = 200
			gosub *GetCurTime
			disp_end_time = ret_time + MES_DISP_TIME

		}
	}
return

; {[Oɏo or S[̌㏈
*BallChk
	if ( cross_flag == 1 ) {
;		cross_cnt --
		gosub *GetCurTime
;		if ( cross_cnt <= 0 ) {
		if ( ret_time >= disp_end_time ) {
			switch svgm_ctrl.iGCSUB
			case GC_Goal
				gc_submsg = GC_Game_Restart
				game_ctrl.iGCTEAM = ini_ball_owner_team
				gosub *Send_GameCtrl

				; vC[f[^̏
				gosub *InitPlayers

				; {[f[^̏
				gosub *InitBallData

				; NCAg̉҂Ƃ
				gosub *WaitReady
				swbreak
			case GC_Throw_In
			case GC_Goal_Kick
			case GC_Corner_Kick
			case GC_Offside
			case GC_Foul
#if 0
				ball_moving = 0
				ba_dribble = 0
				ball_hold = 0
#endif
				ba_stat = BA_STAT_NORMAL

				; {[ړ
				posxb = crossxb
				poszb = crosszb
				ymove = crossym

				; {[𑗐M
				send_ball_dest = DPID_ALLPLAYERS
				gosub *Send_Ball_Move

				; ߂̃vC[
				SearchNearPlayer svgm_ctrl.iGCTEAM, posxb, poszb

				; vC[ړ
				ForthMovePlayer ret_pno, (posxb+fmv_xoffs), 0, (poszb+fmv_zoffs), crossph, svgm_ctrl.iGCSUB
				fmv_gcsub = svgm_ctrl.iGCSUB

				; ړ̃^CAEgݒ (NCAg̃^CAEgȂꍇ̏p)
				gosub *GetCurTime
				fmv_time_end = ret_time + FMV_TIME_OUT + 3

				; is̈̐ݒ
				if ( svgm_ctrl.iGCSUB == GC_Goal_Kick ) {
					if ( svgm_ctrl.iGCTEAM == TEAM_BLUE ) {
						SetInvArea PA_LINE_X0, PA_LINE_Z0, PA_LINE_X1, PA_LINE_Z1
					}
					else {
						SetInvArea -(PA_LINE_X1), PA_LINE_Z0, -PA_LINE_X0, PA_LINE_Z1
					}
				}
				else {
					SetInvArea (crossxb-6000), (crosszb-6000), (crossxb+6000), (crosszb+6000)
				}
				gosub *Send_Inv_Area

				swbreak
			swend

			cross_flag = 2		; {[ړ҂
		}
	}
return

; S[̔
*ChkGoal
	if ( poszb > GOAL_LINE_Z0 ) && ( poszb < GOAL_LINE_Z1 ) && ( (posyb + ymove * 2) < GOAL_HEIGHT ) {
		; S[Ɣ
		if ( posxb <= LINE_X0 ) {
			game_ctrl.iGCTEAM = TEAM_RED
			game_ctrl.iGCSCRED++
			ini_ball_owner_team = TEAM_BLUE
		}
		else {
			game_ctrl.iGCTEAM = TEAM_BLUE
			game_ctrl.iGCSCBLUE++
			ini_ball_owner_team = TEAM_RED
		}
		crossxb = 0
		crosszb = 0
		crossym = 0
		crossph = 0
		
		gc_submsg = GC_Goal
		gosub *Send_GameCtrl
		gosub *Save_GameCtrl
	}
	else {
		if ( posxb <= LINE_X0 ) {

			if ( pl_infdat.ball_owner_pno.iINFTM == TEAM_BLUE ) {
				game_ctrl.iGCTEAM = TEAM_RED
				gc_submsg = GC_Corner_Kick
				crossxb = LINE_X0
				if ( poszb > 0 ) {
					crosszb = LINE_Z1
					crossph = 315
					fmv_xoffs = -800
					fmv_zoffs = 800
				}
				else {
					crosszb = LINE_Z0
					crossph = 225
					fmv_xoffs = -800
					fmv_zoffs = -800
				}
				crossym = 0
			}
			else {
				game_ctrl.iGCTEAM = TEAM_BLUE
				gc_submsg = GC_Goal_Kick
				crossxb = LINE_X0 + GK_XOFFS
				if ( poszb > 0 ) {
					crosszb = GK_ZOFFS
				}
				else {
					crosszb = -GK_ZOFFS
				}
				crossym = 0
				crossph = 270
				fmv_xoffs = -800
				fmv_zoffs = 0
			}
		}
		else {
			if ( pl_infdat.ball_owner_pno.iINFTM == TEAM_BLUE ) {
				game_ctrl.iGCTEAM = TEAM_RED
				gc_submsg = GC_Goal_Kick
				crossxb = LINE_X1 - GK_XOFFS
				if ( poszb > 0 ) {
					crosszb = GK_ZOFFS
				}
				else {
					crosszb = -GK_ZOFFS
				}
				crossym = 0
				crossph = 90
				fmv_xoffs = 800
				fmv_zoffs = 0
			}
			else {
				game_ctrl.iGCTEAM = TEAM_BLUE
				gc_submsg = GC_Corner_Kick
				crossxb = LINE_X1
				if ( poszb > 0 ) {
					crosszb = LINE_Z1
					crossph = 45
					fmv_xoffs = 800
					fmv_zoffs = 800
				}
				else {
					crosszb = LINE_Z0
					crossph = 135
					fmv_xoffs = 800
					fmv_zoffs = -800
				}
				crossym = 0
			}	
		}
		gosub *Send_GameCtrl
		gosub *Save_GameCtrl
	}
return

; {[ƐlƂ̓蔻
*ChkManConf
	chk_manconf = 0

#ifdef DEBUG
	msg = "Chk Man Conf " + ball_speed
	gosub *logput
#endif
	
	repeat PlayerMax
		pno = cnt
		if ( pl_infdat.pno.iINFPID != 0 ) && ( pno != ball_owner_pno ) {
			tmpx = pl_mvdat.pno.iMVMX
			tmpz = pl_mvdat.pno.iMVMZ

			if ( pl_infdat.pno.iINFPOS == GKPOS ) {
				; GK̎PÁA͂˕ԂȂ悤ɂ
				if ( pl_infdat.pno.iINFTM == BLUE_TEAM ) {
					if (( tmpx > PA_LINE_X0 ) && ( tmpx < PA_LINE_X1) && ( tmpz > PA_LINE_Z0 ) && ( tmpz < PA_LINE_Z1 )) {
						chk_manconf = 0
						break
					}
				}
				else {
					if (( tmpx > -(PA_LINE_X1) ) && ( tmpx < -(PA_LINE_X0)) && ( tmpz > PA_LINE_Z0 ) && ( tmpz < PA_LINE_Z1 )) {
						chk_manconf = 0
						break
					}
				}
			}

			mdiffx = posxb - tmpx
			mdiffz = poszb - tmpz

			if mdiffx < 0 : mdiffx = - mdiffx
			if mdiffz < 0 : mdiffz = - mdiffz

			if ( mdiffx < 500 ) && ( mdiffz < 500 ) {
				chk_manconf = 1

#ifdef DEBUG
				msg = pno + " " + mdiffx + " " + mdiffz
				gosub *logput
#endif
				break
			}
		}
	loop	
return

; {[ƃS[Ƃ̓蔻
*ChkGoalConf
	chk_goalconf = 0
	if ( ((posxb <= (LINE_X0 + 100)) && (posxb >= (LINE_X0 - 100))) || ((posxb <= (LINE_X1 + 100)) && (posxb >= (LINE_X1 - 100))) ) {
		; |XgƂ̓蔻
		if ( ((poszb <= (GOAL_LINE_Z0 + 100)) && (poszb >= (GOAL_LINE_Z0 - 100))) || ((poszb <= (GOAL_LINE_Z1 + 100)) && (poszb >= (GOAL_LINE_Z1 - 100))) ) {
			chk_goalconf = 2
		} else {
			if ( (poszb >= GOAL_LINE_Z0) && (poszb <= GOAL_LINE_Z1) && ( ((posyb + ymove * 2) <= (GOAL_HEIGHT+100)) && ((posyb + ymove * 2) >= (GOAL_HEIGHT-100)) )) {
				; o[Ƃ̓蔻
				chk_goalconf = 2
			}
		}
	}
	else {
		if ( ((posyb + ymove * 2) < GOAL_HEIGHT) && ((posxb <= LINE_X0) || (posxb >= LINE_X1)) ) {
			; TChlbgƂ̓蔻
			if ( ((poszb <= (GOAL_LINE_Z0 + 100)) && (poszb >= (GOAL_LINE_Z0 - 100))) || ((poszb <= (GOAL_LINE_Z1 + 100)) && (poszb >= (GOAL_LINE_Z1 - 100))) ) {
				chk_goalconf = 1
			} 
			; S[lbgƂ̓蔻
			if ( ((posxb <= (GOAL_LINE_X0 + 100)) && (posxb >= (GOAL_LINE_X0 - 100))) || ((posxb <= (GOAL_LINE_X1 + 100)) && (posxb >= (GOAL_LINE_X1 - 100))) ) {
				chk_goalconf = 1
			}
		}
	}

return

; {[ړ (ړ̃^CAEg or ړvC)
*Forth_Move_Ball
	ball_owner_pno = fmv_player_pno
	if ( fmv_gcsub == GC_Throw_In ) {
		ball_speed = 100
			yspeed = 10
	}
	else {
		ball_speed = 200
		yspeed = 100
	}
	ymovef = 1	
	bdiffx = fmv_xoffs/50
	bdiffz = fmv_zoffs/50

	fmv_ball_move = 1
	gosub *Start_Ball_Move
						
	fmv_time_end = 0
return	


; W߂̃vC[
*sSearchNearPlayer
	found = 0
	range = 1000
	ret_pno = 0
	
	; S[LbŃAL[p[D
	if ( svgm_ctrl.iGCSUB == GC_Goal_Kick ) {
		repeat PlayerMAX
			if ( pl_infdat.cnt.iINFPID == 0 ) : continue
			if ( pl_infdat.cnt.iINFTM != svgm_ctrl.iGCTEAM ) : continue
			if ( pl_infdat.cnt.iINFPOS != GKPOS ): continue
			ret_pno = cnt
			found = 1
			break
		loop
	}

	while (( range < 120000 ) && ( found == 0 ))
		repeat PlayerMAX
			if ( pl_infdat.cnt.iINFPID == 0 ) : continue
			if ( pl_infdat.cnt.iINFTM != svgm_ctrl.iGCTEAM ) : continue
			if ( pl_infdat.cnt.iINFPOS == GKPOS ) : continue	; S[LbNȊO̓L[p[͑IȂ
			mdiffx = tmp_posx - pl_mvdat.cnt.iMVMX
			mdiffz = tmp_posz - pl_mvdat.cnt.iMVMZ

			if ( mdiffx < 0 ) : mdiffx = -mdiffx
			if ( mdiffz < 0 ) : mdiffz = -mdiffz

			if ( mdiffx < range ) && ( mdiffz < range ) {
				ret_pno = cnt
				found = 1
				break
			}
		loop

		range += 2000
	wend

	; Ȃꍇ́Aŏ̗LIDgp
	if ( found == 0 ) {
		repeat PlayerMax
			if ( pl_infdat.cnt.iINFPID != 0 ) : ret_pno = cnt: break
		loop
	}

return

; vC[̋ړ
*sForthMovePlayer
	if ( pl_infdat.tmp_pno.iINFPID == 0 ) : return

	send_pl_fmvdat.iFMVPNO = tmp_pno
	send_pl_fmvdat.iFMVMX  = tmp_posx
	send_pl_fmvdat.iFMVMY  = tmp_posy
	send_pl_fmvdat.iFMVMZ  = tmp_posz
	send_pl_fmvdat.iFMVPH  = tmp_ph
	send_pl_fmvdat.iFMVMF  = MT_STOP
	send_pl_fmvdat.iFMVCAUSE = tmp_cause

	save_sendtype = Set_SendType
	Set_SendType = DPSEND_ASYNC | DPSEND_GUARANTEED

	Set_DataType = MSG_Player_FMove

	AMdplaySend send_pl_fmvdat, PL_FMVDAT_SIZE*4, pflg, pl_infdat.tmp_pno.iINFPID : m_ec

	fmv_player_pno = tmp_pno

	Set_SendType = save_sendtype
return

; Q[䃁bZ[WM
*Receive_Game_Ctrl
	tmp=bufnum.iGCPNO

	switch bufnum.iGCSUB

		case GC_Game_Start
			tmp_pno = tmp
			goto *Receive_Game_Start
			swbreak
		case GC_Game_Ack
			tmp_pno = tmp
			goto *Receive_Game_Ack
			swbreak
	swend

return

; Q[JnÕvC[f[^̏
*InitPlayers
	repeat PlayerMAX
		pl_mvdat.cnt.iMVMX	= pl_infdat.cnt.iINFPOSX
		pl_mvdat.cnt.iMVMY	= pl_infdat.cnt.iINFPOSY
		pl_mvdat.cnt.iMVMZ	= pl_infdat.cnt.iINFPOSZ
		pl_mvdat.cnt.iMVPH	= pl_infdat.cnt.iINFPH
		pl_mvdat.cnt.iMVMF	= MT_STOP
		pl_mvdat.cnt.iMVMP	= 0

		if ( pl_infdat.cnt.iINFTM == ini_ball_owner_team ) {
			if ( pl_infdat.cnt.iINFPOS == 0 ) {
				if ( ini_ball_owner_team == TEAM_BLUE ) {
					pl_mvdat.cnt.iMVMX = LFW_INIPOSX
				}
				else {
					pl_mvdat.cnt.iMVMX = -(LFW_INIPOSX)
				}
				pl_mvdat.cnt.iMVMZ = LFW_INIPOSZ
			}
			if ( pl_infdat.cnt.iINFPOS == 1 ) {
				if ( ini_ball_owner_team == TEAM_BLUE ) {
					pl_mvdat.cnt.iMVMX = RFW_INIPOSX
				}
				else {
					pl_mvdat.cnt.iMVMX = -(RFW_INIPOSX)
				}
				pl_mvdat.cnt.iMVMZ = RFW_INIPOSZ
			}
		}
	loop
return

; Q[JnÕ{[f[^̏
*InitBallData
	cur_ball_data.iBAPNO = -1
	cur_ball_data.iBAMX = 0
	cur_ball_data.iBAMY = BALL_INIY
	cur_ball_data.iBAMZ = 0
	cur_ball_data.iBASTAT = BA_STAT_NORMAL
	cur_ball_data.iBAYMV = 0
#if 0
	cur_ball_data.iBADBL = 0
	cur_ball_data.iBAHOLD = 0
#endif

	send_ball_dest = DPID_ALLPLAYERS
	gosub *Send_Ball_Move

#if 0
	ball_moving = 0
	ba_dribble = 0
	ball_hold = 0
#endif

	ba_stat = BA_STAT_NORMAL
	ba_team = TEAM_BLUE
	
	; is̈
	gosub *DisableInvArea

	cross_flag = 0
;	cross_cnt = 0
	
	; {[Mobt@̏
	gosub *InitBallDataBuf
return

; {[Mobt@̏
*InitBallDataBuf
	repeat PlayerMax
		ball_data_buf.cnt.iBAPNO = -1
		ball_data_buf.cnt.iBAMX = 0
		ball_data_buf.cnt.iBAMY = BALL_INIY
		ball_data_buf.cnt.iBAMZ = 0
		ball_data_buf.cnt.iBASTAT = BA_STAT_NORMAL
		ball_data_buf.cnt.iBAYMV = 0
	loop
	ball_data_buf_cnt = 0
	
	repeat BA_STATS
		ball_bufst_cnt.cnt = 0
	loop
return

; Q[JnvM
*Receive_Game_Start
	if ( game_state != STAT_PRE_GAME ) : return	; ɊJnς

	; Q[Jn̏
	gosub *GameStartInit

	; Ԍv̊Jn
	time_start_flag = 1

	; Q[Jn𑗂
	gc_submsg = GC_Game_Start
	gosub *Send_GameCtrl

	; NCAg̉҂Ԃɂ
	gosub *WaitReady

	; JnvoNCAǵAAckԂƂ݂Ȃ
	player_ready.tmp_pno = 1

	; JntOZbg
	game_start_flag = 1
return

; NCAg̉҂ԂƂ
*WaitReady
	repeat PlayerMAX
		player_ready.cnt = 0
	loop

	; ҂^CAEgݒ
	gosub *GetCurTime
	wait_timeout = ret_time + WAIT_TIMEOUT_VAL

	game_state = STAT_WAIT_READY
return

; GameCtrlbZ[Wɑ΂鉞M
*Receive_Game_Ack
	if ( game_state != STAT_WAIT_READY ) : return

	player_ready.tmp_pno = 1

	tmp_cnt = 0
	repeat PlayerMAX
		if pl_infdat.cnt.iINFPID==0:continue
		if ( player_ready.cnt == 1 ) {
			tmp_cnt++
		}
	loop
	
	if ( tmp_cnt >= Players ) {
		if ( game_start_flag == 1 ) {
			game_state = STAT_GAME_PLAYING
		}
		else {
			game_state = STAT_PRE_GAME
			time_start_flag = 0
		}

		; ʒm
		gc_submsg = GC_Ready
		gosub *Send_GameCtrl	
#ifdef DEBUG
		msg = "Send Ready"
		gosub *logput
#endif
		gosub *SetInitialBallMove
	
		; Q[JńAԂݒ
		if ( time_start_flag == 1 ) {
			gosub *GetCurTime
			end_time = ret_time + game_time

			Set_DataType = MSG_Start_Time
			AMdplaySend game_time, 4, pflg, DPID_ALLPLAYERS : m_ec
	
			time_start_flag = 0
		}
	}
return

; `bgbZ[WM (ALL)
*Receive_ChatMsg_All
	Set_DataProperty = AMDPLAY_SEND_STRING
	Set_DataType = MSG_ChatMsg_All
	save_sendtype = Set_SendType
	Set_SendType = DPSEND_ASYNC | DPSEND_GUARANTEED

	tmpmsg = ""
	getstr tmpmsg, bufmes, 0, $13

#ifdef DEBUG
	msg = "Mes " + tmpmsg
	gosub *logput
#endif
	strlen len, tmpmsg
	tmpmsg = tmpmsg + "\n"
	AMdplaySend tmpmsg,len+1,pflg,DPID_ALLPLAYERS : m_ec

	Set_DataProperty = AMDPLAY_SEND_ARRAY_AUTO
	Set_SendType = save_sendtype
return

; `bgbZ[WM (`[)
*Receive_ChatMsg_Team
	Set_DataProperty = AMDPLAY_SEND_STRING
	Set_DataType = MSG_ChatMsg_Team
	save_sendtype = Set_SendType
	Set_SendType = DPSEND_ASYNC | DPSEND_GUARANTEED

	getstr tmpmsg, bufmes, 0, $13

	strmid teamch, tmpmsg, 0, 1	; `[ʂo
	if ( teamch == "B" ) {
		tmptm = TEAM_BLUE
	}
	else {
		tmptm = TEAM_RED
	}

#ifdef DEBUG
	msg = "Mes " + tmpmsg + " " + teamch
	gosub *logput
#endif
	; `[ʂ폜
	strlen len, tmpmsg
	strmid tmpmsg, tmpmsg, 1, len-1

	strlen len, tmpmsg
	tmpmsg = tmpmsg + "\n"
	repeat PlayerMax
		if pl_infdat.cnt.iINFPID == 0 : continue
		if ( pl_infdat.cnt.iINFTM == tmptm ) {
			; `[̃o[ɂ̂ݑ
			AMdplaySend tmpmsg,len+1,pflg,pl_infdat.cnt.iINFPID : m_ec
		}
	loop

	Set_DataProperty = AMDPLAY_SEND_ARRAY_AUTO
	Set_SendType = save_sendtype

return

; Jñ{[̓ (FWEFW)
*SetInitialBallMove

	ball_speed = 40

	yspeed = 0
	ymove = 0
	ymovef = 0	
	bdiffx = 0
	if ( ini_ball_owner_team == TEAM_BLUE ) {
		poszb = LFW_INIPOSZ
		bdiffz = 1000
		ba_team = TEAM_BLUE
	}
	else {
		poszb = -LFW_INIPOSZ
		bdiffz = -1000
		ba_team = TEAM_RED
	}
#if 0
	ball_moving = 1
	ba_dribble = 0
	ball_hold = 0
#endif
	ba_stat = BA_STAT_MOVING
	cross_flag = 0
	ball_speed10 = ball_speed * 10
return

; n[t^C̏
*NextGamePhase
	game_phase++

	if ( game_phase >= PHASE_EXTRA_HALF1 ) && ( game_ctrl.iGCSCBLUE + game_ctrl.iGCSCRED > 0 ) {
		; _ꍇAɂ͂炸IƂ
		gc_submsg = GC_Game_End
		game_phase = PHASE_END
	}
	else {
		if ( game_phase > PHASE_EXTRA_HALF2 ) {
			; PKɂAIƂ
			gc_submsg = GC_Game_End
			game_phase = PHASE_END
		}
		else {
			gc_submsg = GC_Half_Time
			time_start_flag = 1
		}
	}

	gosub *Send_GameCtrl

	gosub *GetCurTime
	break_start_time = ret_time

	game_state = STAT_GAME_BREAK

return

; Q[Jn̏
*GameStartInit
	; tOAJEg̏
	repeat PlayerMax
		sync_flag.cnt = 0
		sync_count.cnt = 0
		sync_timeout.cnt = 0
		sync_send_time.cnt = 0
	loop

	; _̏
	game_ctrl.iGCSCRED = 0
	game_ctrl.iGCSCBLUE = 0

	; vC[f[^̏
	gosub *InitPlayers

	; {[̏
	gosub *InitBallData

	; is̈̏
	inv_area.iIAEN = 0
	inv_area.iIAPOSX0 = 0
	inv_area.iIAPOSZ0 = 0
	inv_area.iIAPOSX1 = 0
	inv_area.iIAPOSZ1 = 0

	ini_ball_owner_team = TEAM_BLUE	

	end_time = 0
	game_time = 120		; 2 (Half)
	game_phase = PHASE_HALF1

	game_break_min = 0

	wait_timeout = 0

	fmv_player_pno = -1
	fmv_time_end = 0

	dri_ign_cnt = 0
return

*GetCurTime
	gettime hour, 4
	gettime min, 5
	gettime sec, 6

	ret_time = (hour * 60 * 60) + (min * 60) + sec
return


*GetCurTimeMsec
	gettime hour, 4
	gettime min, 5
	gettime sec, 6
	gettime msec, 7

	ret_time = (hour * 60 * 60) + (min * 60) + sec
	ret_time = ret_time * 1000 + msec
return

*logput
	;/////	O\̍XV	/////
#if 0
	msg = "\n" + msg
	l_i = 0 : strlen l_i, logmsg
	objsend 0, EM_SETSEL, l_i, l_i, 1
	objsend 0, EM_REPLACESEL, l_i, msg, 0
	l_i = 0 : objsend 0, EM_SCROLLCARET, l_i, l_i, 1
	msg=""
#else
	msg = "\n" + msg
	len = 0 : strlen len, logmsg

	if ( len > 31500 ) {
		; OςɂȂNA
		repeat 32000
			poke logmsg, cnt, 0
		loop
		sendmsg objinfo(objlog, 2), EM_SETSEL, 0, MSGBUF_SIZE
		sendmsg objinfo(objlog, 2), EM_REPLACESEL, MSGBUF_SIZE, varptr(logmsg)
		len = 0
	}
	sendmsg objinfo(objlog, 2), EM_SETSEL, len, len
	sendmsg objinfo(objlog, 2), EM_REPLACESEL, len, varptr(msg)
	sendmsg objinfo(objlog, 2), EM_SCROLLCARET, 0, 0
#endif
return

*bye
	E3DInit 0, -1, 0, 16, 0, scid		; E3DInitĂ΂ȂƃG[ƂȂ邽
	end

; |WVpWf[^[`
#include "neozc_position.hsp"
