reman3/Rayman_X/cpa/tempgrp/NET/L0TEN.c

821 lines
28 KiB
C
Raw Blame History

/*
* universal multiplayer library level 0 implementation file
* transport layer: TEN arena PC-windows 95
*/
/*
* Author: David Fournier
*
* Creation Date: 13/12/96
*
*/
#include "warnings.h"
#include <stdlib.h>
/*
* we need this one to fill the interface structure
* with pointers to the correct functions
*/
#include "Privl0ten.h"
#include "PrivNetDef.h"
#include "l0GlDef.h"
#include "NetMemCo.h"
#include "NetSock.h"
#include "NetEnd.h"
#include "PrivNetSer.h"
#include <NET\Netdebug.h>
#include <arena.h>
#include <button.h>
#include <debuglib.h>
#include <environ.h>
#include <tenutils.h>
#define TEN_MAXBUF 250
static char gs_bL0PCWin95TENInitState;
#pragma pack(1)
typedef struct
{
NetLib_tduxPlayerId pid; /* ID of the player. */
NetLib_tduwJoinType joinType; /* Create, Join or Watch. */
}NetLib_tdstInfoPlayer;
static NetLib_tdstInfoPlayer gs_InfoLocal; /* Informations of the local player. */
static long SendBufSize; /* Virtual buffer size. */
static unsigned long LastTime; /* Time for the last eL0PCWin95TENEngine. */
static unsigned long SendMaxRate; /* Maximum rate. */
static unsigned short NbrPlayer; /* Number of player. */
static NetLib_tdstInfoPlayer *TabPlayer; /* Table of player. */
typedef struct stFIFO
{
struct stFIFO *next; /* Next message of FIFO. */
unsigned long size; /* Size of message. */
NetLib_tduxPlayerId id; /* ID of sender. */
}FIFO;
static FIFO *FIFObegin; /* First message of file. */
static FIFO **FIFOend; /* Last pointer of the file. */
static unsigned short gs_uwCallBack;
static NetLib_tduwJoinType gs_JoinType;
typedef struct
{
NetLib_uxReadReceiptId m_ulReadReceiptId;
unsigned long uxPriority:7;
unsigned long uxReplaceType:7;
unsigned long uxReplace:1;
unsigned long eMessageType:5;
unsigned long uxHeadBigEndian:1;
unsigned long uxBodyBigEndian:1;
}TENHead;
#pragma pack()
/* Convert a bloc memory into a hexa string. */
void memtohexa(void *mem,unsigned short sizemem,char *hexa)
{
unsigned char *p=(unsigned char *)mem;
unsigned short c,i;
for (i=0;i<sizemem;i++)
{
c=((p[i]&0xF0)>>4);
if (c<10) hexa[i*2]=c+'0';
else hexa[i*2]=(c-10)+'A';
c=p[i]&0x0F;
if (c<10) hexa[i*2+1]=c+'0';
else hexa[i*2+1]=(c-10)+'A';
}
hexa[i*2]=0;
}
/* Convert a hexa string into a bloc memory. */
void hexatomem(void *mem,char *hexa)
{
unsigned char *p=(unsigned char *)mem;
unsigned short c,i,sizehexa;
sizehexa=strlen(hexa)/2;
for (i=0;i<sizehexa;i++)
{
p[i]=0;
c=hexa[i*2];
if ((c>='0') && (c<='9')) p[i]+=((c-'0')<<4);
else p[i]+=(((c-'A')+10)<<4);
c=hexa[i*2+1];
if ((c>='0') && (c<='9')) p[i]+=(c-'0');
else p[i]+=(c-'A')+10;
}
}
/* Process the maximum send rate. */
static void ProcMaxRate(void)
{
unsigned short i,nbrp=0;
unsigned long max=10000000L;
unsigned long rate;
for (i=0;i<NbrPlayer;i++)
{
if (TabPlayer[i].pid!=C_uxNetInvalidId)
{
size_t size=sizeof(long);
tenArGetPlayerInfo(TabPlayer[i].pid,kTenArPIBandwidth,&rate,&size);
if ((rate) && (max>rate)) max=rate;
nbrp++;
}
}
if (nbrp>1) SendMaxRate=max/(nbrp-1);
else SendMaxRate=10000000L;
SendMaxRate=5000;
}
/* Add a player info. */
static void AddPlayerInfo(NetLib_tduxPlayerId pid,NetLib_tduwJoinType joinType)
{
NetLib_tdstInfoPlayer *nTab;
unsigned short i;
if (pid+1>NbrPlayer)
{
nTab=(NetLib_tdstInfoPlayer *)pMalloc(sizeof(NetLib_tdstInfoPlayer)*(pid+1));
memcpy(nTab,TabPlayer,sizeof(NetLib_tdstInfoPlayer)*NbrPlayer);
for (i=NbrPlayer;i<pid;i++) TabPlayer[i].pid=C_uxNetInvalidId;
vFree((char *)TabPlayer);
TabPlayer=nTab;
NbrPlayer=pid+1;
}
TabPlayer[pid].pid=pid;
TabPlayer[pid].joinType=joinType;
ProcMaxRate();
}
/* Supprim a player info. */
static void SupPlayerInfo(NetLib_tduxPlayerId pid)
{
TabPlayer[pid].pid=C_uxNetInvalidId;
ProcMaxRate();
}
/*****************************************************************************
* Description: vL0PCWin95TENCloseChannel
* frees a slot in the channel table
*****************************************************************************
* Input: identifier of the channel
* Output: none
*****************************************************************************/
void vL0PCWin95TENCloseChannel(tduwNetChannel uwChannel)
{
}
/*****************************************************************************
* Description: uwL0PCWin95TENStartChannelScan
* returns the identification number of the first channel for the protocol
*****************************************************************************
* Input: none
* Output: 0
*****************************************************************************/
tduwNetChannel uwL0PCWin95TENStartChannelScan(void)
{
if(!(gs_bL0PCWin95TENInitState&0x02))
return C_uwNetInvalidChannel;
return 0;
}
/*****************************************************************************
* Description: uwL0PCWin95TENNextChannel
* returns the identification number of the channel following the last
*****************************************************************************
* Input: uwLastScannedChannel, index returned by the previous call
* Output: C_uwNetInvalidChannel
*****************************************************************************/
tduwNetChannel uwL0PCWin95TENNextChannel(tduwNetChannel uwLastScannedChannel)
{
return C_uwNetInvalidChannel;
}
/*****************************************************************************
* Description: uwL0PCWin95TENStartBroadcastChannelScan
* returns the identification number of the first broadcast channel
* for the protocol
*****************************************************************************
* Input: none
* Output: 0
*****************************************************************************/
tduwNetChannel uwL0PCWin95TENStartBroadcastChannelScan(void)
{
if(!(gs_bL0PCWin95TENInitState&0x02))
return C_uwNetInvalidChannel;
return 1;
}
/*****************************************************************************
* Description: uwL0PCWin95TENNextBroadcastChannel
* returns the identification number of the broadcast channel following
* the specified one
*****************************************************************************
* Input: uwLastScannedChannel, index returned by the previous call
* Output: identification of the channel following the specified one
*****************************************************************************/
tduwNetChannel uwL0PCWin95TENNextBroadcastChannel(tduwNetChannel uwLastScannedChannel)
{
return C_uwNetInvalidChannel;
}
/*****************************************************************************
* Description: L0PCWin95TENReadCallBack
*****************************************************************************
* Input: p_uwChannel, pointer on a field to store the identification of
* a new channel in case of access to a newly created broacast channel
* (irrelevant for the serial layer)
* ppData, address of the pointer to retrieve a full message if
* necessary.
* Output: an error condition.
*****************************************************************************/
static void L0PCWin95TENReadCallBack(int fromPid, void *buf, size_t size)
{
FIFO *cour;
#if defined(NET_USE_DEBUG)
TENHead *pSend=(TENHead *)buf;
vDebugSISISI(Net_C_Debug_Ten,"Receive Type",pSend->eMessageType,"Size",size-sizeof(TENHead),"Source",fromPid);
#endif
cour=(FIFO *)pMalloc(sizeof(FIFO)+size);
if (cour)
{
*FIFOend=cour;
cour->next=NULL;
cour->size=size;
cour->id=fromPid;
memcpy(cour+1,buf,size);
FIFOend=&(cour->next);
}
}
/*****************************************************************************
* Description: wL0PCWin95TENGetMessage
*****************************************************************************
* Input: ppData, address of the pointer to retrieve a full message if
* necessary.
* Output: return 1 if getting a message and 0 otherwise.
*****************************************************************************/
short wL0PCWin95TENGetMessage(tdstNetMessage **ppMes)
{
FIFO *cour;
tdstNetMessage *pMes;
TENHead *pSend;
if (FIFObegin==NULL)
{
*ppMes=NULL;
return 0;
}
else
{
pMes=(tdstNetMessage *)pMalloc(FIFObegin->size+sizeof(tdstNetMessage)-sizeof(TENHead));
if (pMes==NULL)
{
*ppMes=NULL;
return -1;
}
pSend=(TENHead *)(FIFObegin+1);
memcpy(pMes+1,pSend+1,FIFObegin->size-sizeof(TENHead));
pMes->m_uxReadReceiptId=pSend->m_ulReadReceiptId;
pMes->uxPriority=pSend->uxPriority;
pMes->uxReplace=pSend->uxReplace;
pMes->uxReplaceType=pSend->uxReplaceType;
pMes->eMessageType=pSend->eMessageType;
pMes->uxHeadBigEndian=pSend->uxHeadBigEndian;
pMes->uxBodyBigEndian=pSend->uxBodyBigEndian;
pMes->uxSessionId=0;
pMes->uxSenderId=FIFObegin->id;
pMes->uxRecipientId=gs_InfoLocal.pid;
pMes->uwMessageSizeInBytes=(unsigned short)(FIFObegin->size-sizeof(TENHead));
pMes->ulReserved=M_ulMakeReserved(M_uwProcessCheckSum(pMes),
M_uwProcessCheckSumBody(pMes));
cour=FIFObegin->next;
vFree((char *)FIFObegin);
FIFObegin=cour;
if (cour==NULL) FIFOend=&FIFObegin;
*ppMes=pMes;
return 1;
}
}
/*****************************************************************************
* Description: eL0PCWin95TENReadData
*****************************************************************************
* Input: p_uwChannel, pointer on a field to store the identification of
* a new channel in case of access to a newly created broacast channel
* (irrelevant for the serial layer)
* ppData, address of the pointer to retrieve a full message if
* necessary.
* Output: an error condition.
*****************************************************************************/
NetLib_tdeErrorStatus eL0PCWin95TENReadData(tduwNetChannel *p_uwChannel, tdpPointer *ppData)
{
short r;
/* verify the validity of the Channel */
if(*p_uwChannel>1) return NetLib_E_es_InvalidChannel;
/* no : try to get a message from the FIFO */
r=wL0PCWin95TENGetMessage((tdstNetMessage **)ppData);
if (r>0) return NetLib_E_es_NoError;
else if (r==0) return NetLib_E_es_FIFOIsEmpty;
else return NetLib_E_es_NotEnoughMemory;
}
/*****************************************************************************
* Description: eL0PCWin95TENSendData
*****************************************************************************
* Input: uwChannel, channel to send the message into.
* pData, pointer on the block to send
* Output: an error condition.
*****************************************************************************/
NetLib_tdeErrorStatus eL0PCWin95TENSendData(tduwNetChannel uwChannel, tdpPointer pData)
{
unsigned long ulBytestoSend;
tdstNetMessage *pMes=(tdstNetMessage *)pData;
int NumErr;
TENHead *pSend;
unsigned long NewTime;
/* verify the validity of the Channel */
if(uwChannel>1)
{
#if defined(NET_USE_DEBUG)
vDebugS(Net_C_Debug_Ten,"Invalid channel");
#endif
return NetLib_E_es_InvalidChannel;
}
if (pMes->uxRecipientId==C_uxNetBroadcastId) uwChannel=1;
ulBytestoSend= pMes->uwMessageSizeInBytes + sizeof(TENHead);
NewTime=GetTickCount();
SendBufSize-=((NewTime-LastTime)*(float)SendMaxRate)/1000;
LastTime=NewTime;
if (SendBufSize<0) SendBufSize=0;
if (SendBufSize>=TEN_MAXBUF)
{
#if defined(NET_USE_DEBUG)
vDebugS(Net_C_Debug_Ten,"Controle de flot.");
#endif
return NetLib_E_es_BufferIsFull;
}
SendBufSize+=ulBytestoSend+20;
pSend=(TENHead *)pMalloc(ulBytestoSend);
if (!pSend)
{
#if defined(NET_USE_DEBUG)
vDebugS(Net_C_Debug_Ten,"Manque de m<>moire.");
#endif
return NetLib_E_es_NotEnoughMemory;
}
memcpy(pSend+1,pMes+1,pMes->uwMessageSizeInBytes);
pSend->m_ulReadReceiptId=pMes->m_uxReadReceiptId;
pSend->uxPriority=pMes->uxPriority;
pSend->uxReplace=pMes->uxReplace;
pSend->uxReplaceType=pMes->uxReplaceType;
pSend->eMessageType=pMes->eMessageType;
pSend->uxHeadBigEndian=pMes->uxHeadBigEndian;
pSend->uxBodyBigEndian=pMes->uxBodyBigEndian;
if (uwChannel!=1)
{
#if defined(NET_USE_DEBUG)
vDebugSISISI(Net_C_Debug_Ten,"Send to one player. Type",pMes->eMessageType,"Size",pMes->uwMessageSizeInBytes,"Recipient",pMes->uxRecipientId);
#endif
NumErr=tenArSendToPlayer(pMes->uxRecipientId,pSend,ulBytestoSend);
}
else
{
#if defined(NET_USE_DEBUG)
vDebugSISISI(Net_C_Debug_Ten,"Send to all players. Type",pMes->eMessageType,"Size",pMes->uwMessageSizeInBytes,"Recipient",pMes->uxRecipientId);
#endif
NumErr=tenArSendToOtherPlayers(pSend,ulBytestoSend);
}
vFree((char *)pSend);
if (NumErr)
{
#if defined(NET_USE_DEBUG)
vDebugSI(Net_C_Debug_Ten,"Emission en attente",NumErr);
#endif
return NetLib_E_es_BufferIsFull;
}
/* free the message buffer */
vFree(pData);
return NetLib_E_es_NoError;
}
/*****************************************************************************
* Description: eL0PCWin95TENQueryChannelStatus
* returns the current status of the channel
*****************************************************************************
* Input: uwChannel, channel to query
* Output: an error condition.
*****************************************************************************/
NetLib_tdeErrorStatus eL0PCWin95TENQueryChannelStatus(tduwNetChannel uwChannel)
{
return NetLib_E_es_NoError;
}
/*****************************************************************************
* Description: eL0PCWin95TENEngine
*****************************************************************************
* Input: none
* Output: none
*****************************************************************************/
void eL0PCWin95TENEngine(void)
{
tenArIdleArena();
}
/*****************************************************************************
* Description : vL0PCWin95TENCloseProtocol(void)
* TEN-Level 0 closing function
*****************************************************************************
* Input : none
* Output : none
*****************************************************************************/
void vL0PCWin95TENCloseProtocol(void)
{
FIFO *p;
while (FIFObegin)
{
p=FIFObegin->next;
vFree((char*)FIFObegin);
FIFObegin=p;
}
FIFObegin=NULL;
FIFOend=&FIFObegin;
vLevel1RemoveProtocol(E_Net_pr_Windows95TENProtocol);
}
/*****************************************************************************
* Description: L0PCWin95TENNewPlayerCallBack
*****************************************************************************
* Input: none
* Output: none
*****************************************************************************/
static void L0PCWin95TENNewPlayerCallBack(int pid, int isYou, char *options,
char *termOptions, char *address, long uniqueId, char *joinType)
{
NetLib_tdstAddPlayerDesc PlDesc;
char typeToken[16];
char hexa[500],mem[250];
short j=-1;
#if defined(NET_USE_DEBUG)
vDebugSI(Net_C_Debug_Ten,"NewPlayerCallBack Pid",pid);
#endif
sscanf(joinType, "%s", typeToken); /* peel off the first word*/
if (!strcmp(typeToken, "create")) j=NetLib_Join_Create;
else if (!strcmp(typeToken, "join")) j=NetLib_Join_Join;
else if (!strcmp(typeToken, "watch")) j=NetLib_Join_Watch;
if (isYou)
{
#if defined(NET_USE_DEBUG)
vDebugS(Net_C_Debug_Ten,"Is me");
#endif
gs_InfoLocal.pid = pid;
gs_InfoLocal.joinType = j;
gs_uwCallBack|=1;
}
PlDesc.m_tduxPlayerId=pid;
getStringParam(options,"NetlibOptions",hexa,sizeof(hexa));
hexatomem(mem,hexa);
PlDesc.m_pPlayerDescriptionData=mem;
PlDesc.m_uxPlayerDesciptionLength=strlen(hexa)/2;
PlDesc.m_stL1AddPlayerDesc.m_eProtocol=E_Net_pr_Windows95TENProtocol;
PlDesc.m_stL1AddPlayerDesc.m_vL0Param=NULL;
PlDesc.IsYou=isYou;
PlDesc.JoinType=j;
PlDesc.Options=options;
NetLib_eAddNewPlayer(&PlDesc);
AddPlayerInfo((NetLib_tduxPlayerId)pid,(NetLib_tduwJoinType)j);
}
/*****************************************************************************
* Description: L0PCWin95TENDoPlayerLeft
* A user has left the game.
*****************************************************************************
* Input: pid : ID of player who left the game.
* Output: none
*****************************************************************************/
static void L0PCWin95TENDoPlayerLeft(int pid)
{
#if defined(NET_USE_DEBUG)
vDebugSI(Net_C_Debug_Ten,"DoPlayerLeft Pid",pid);
#endif
eNetDisconnectPlayer((NetLib_tduxPlayerId)pid,1);
SupPlayerInfo((NetLib_tduxPlayerId)pid);
}
#include <stdio.h>
/*****************************************************************************
* Description: eL0PCWin95TENDoAlert
* Callback receive the error messages.
*****************************************************************************/
static void eL0PCWin95TENDoAlert(int type, int err, char *msg)
{
printf("%s\n", msg);
}
/*****************************************************************************
* Description: eL0PCWin95TENDebugMessage
* Callback for verifyNoErr.
*****************************************************************************/
static void eL0PCWin95TENDebugMessage(int msgLevel, char *msg)
{
fprintf(stderr, "%s", msg);
}
/*****************************************************************************
* Description : eL0PCWin95TENSetGameOptions
* Set the game options.
*****************************************************************************
* Input : GameOptions : the game options.
* Output : none.
*****************************************************************************/
_NET_EXPORT_ void _NET_CALLING_CONV_ eL0PCWin95TENSetGameOptions(char *GameName,void *GameOptions,unsigned short SizeOptions)
{
char options[500],conv[500];
options[0]=0;
addStringParam(options,sizeof(options),"name",GameName);
memtohexa(GameOptions,SizeOptions,conv);
addStringParam(options,sizeof(options),"NetlibOptions",conv);
tenArRegisterGame(options);
NetLib_eSetSessionDescription((unsigned char)SizeOptions,(char *)GameOptions,0);
}
/*****************************************************************************
* Description : eL0PCWin95TENSetPlayerOptions
* Set the player options.
*****************************************************************************
* Input : GameOptions : the game options.
* Output : none.
*****************************************************************************/
_NET_EXPORT_ void _NET_CALLING_CONV_ eL0PCWin95TENSetPlayerOptions(char *PlayerName,char *PlayerOptions,unsigned short SizeOptions)
{
char options[500],conv[500];
options[0]=0;
addStringParam(options,sizeof(options),"name",PlayerName);
memtohexa(PlayerOptions,SizeOptions,conv);
addStringParam(options,sizeof(options),"NetlibOptions",conv);
tenArRegisterPlayer(options);
do
{
tenArIdleArena();
}while (!((gs_uwCallBack&1) && ((gs_uwCallBack&4) || (gs_JoinType==NetLib_Join_Create))));
}
/*****************************************************************************
* Description: eL0PCWin95TENDoPregameHook
* Callback for verifyNoErr.
*****************************************************************************/
static void eL0PCWin95TENDoPregameHook(char *joinType, char *gameTermOptions,
char *playerTermOptions, char *name, char *alias, char *address)
{
char typeToken[16];
sscanf(joinType, "%s", typeToken); /* peel off the first word*/
if (!strcmp(typeToken, "create")) gs_JoinType=NetLib_Join_Create;
else if (!strcmp(typeToken, "join")) gs_JoinType=NetLib_Join_Join;
else if (!strcmp(typeToken, "watch")) gs_JoinType=NetLib_Join_Watch;
gs_uwCallBack|=2;
}
/*****************************************************************************
* Description: eL0PCWin95TENDoGameOptions
* Callback for recept change of game options.
*****************************************************************************/
void eL0PCWin95TENDoGameOptions(char *options, char *termOptions)
{
char hexa[500],mem[250];
getStringParam(options,"NetlibOptions",hexa,sizeof(hexa));
hexatomem(mem,hexa);
NetLib_eSetSessionDescription((char)(strlen(hexa)/2),mem,0);
gs_uwCallBack|=4;
}
/*****************************************************************************
* Description: vL0PCWin95TENAddNewPlayer
*****************************************************************************
* Input: pChanel : adress of returned chanel.
* par : extern parameter.
* Output: error code.
*****************************************************************************/
NetLib_tdeErrorStatus vL0PCWin95TENAddNewPlayer(tduwNetChannel *pChanel,void *par)
{
*pChanel=0;
return NetLib_E_es_NoError;
}
/*****************************************************************************
* Description: vL0PCWin95TENOpenProtocol
* initialize the specified interface structure with the correct function
* pointers to enable a protocol-independent data transmission process.
*****************************************************************************
* Input: p_stProtocolInterface, pointer to the interface structure
* uwPortNumber, port number to bind the socket to
* Output: none
*****************************************************************************/
void _NET_CALLING_CONV_ vL0PCWin95TENOpenProtocol(void)
{
tdstNetProtocolInterface *p_stProtocolInterface;
#if defined(NET_USE_DEBUG)
vDebugClear(Net_C_Debug_Ten);
vDebugS(Net_C_Debug_Ten,"SetupInterface");
#endif
p_stProtocolInterface=pstLevel1AddProtocol();
FIFObegin=NULL;
FIFOend=&FIFObegin;
/* logical identification of the protocol */
p_stProtocolInterface->eProtocol = E_Net_pr_Windows95TENProtocol;
/* setup the function pointers */
p_stProtocolInterface->fn_uwStartChannelScan = uwL0PCWin95TENStartChannelScan;
p_stProtocolInterface->fn_uwStartBroadcastChannelScan= uwL0PCWin95TENStartBroadcastChannelScan;
p_stProtocolInterface->fn_uwNextChannel= uwL0PCWin95TENNextChannel;
p_stProtocolInterface->fn_uwNextBroadcastChannel= uwL0PCWin95TENNextBroadcastChannel;
p_stProtocolInterface->fn_eReadData= eL0PCWin95TENReadData;
p_stProtocolInterface->fn_eSendData= eL0PCWin95TENSendData;
p_stProtocolInterface->fn_eQueryChannelStatus= eL0PCWin95TENQueryChannelStatus;
p_stProtocolInterface->fn_vLevel0NetEngine = eL0PCWin95TENEngine;
p_stProtocolInterface->fn_vCloseChannel = vL0PCWin95TENCloseChannel;
p_stProtocolInterface->fn_vLevel0CloseProtocol = vL0PCWin95TENCloseProtocol;
p_stProtocolInterface->fn_eAddNewPlayer = vL0PCWin95TENAddNewPlayer;
gs_bL0PCWin95TENInitState = 0x01;
setDebugMsgRoutine(eL0PCWin95TENDebugMessage);
tenArSetPregameHookRoutine(eL0PCWin95TENDoPregameHook);
tenArSetGameOptionsRoutine(eL0PCWin95TENDoGameOptions);
tenArSetPlayerLeftRoutine(L0PCWin95TENDoPlayerLeft);
tenArSetPlayerEnteredRoutine(L0PCWin95TENNewPlayerCallBack);
tenArSetIncomingPacketRoutine(L0PCWin95TENReadCallBack);
tenArSetAlertMessageRoutine(eL0PCWin95TENDoAlert);
}
/*****************************************************************************
* Description: eL0PCWin95TENStart
* Start a game with TEN
*****************************************************************************
* Input: ppGameOptions : Adresse of a pointer wich receive the adresse of
* game options.
* Output: join type.
*****************************************************************************/
_NET_EXPORT_ NetLib_tduwJoinType _NET_CALLING_CONV_ eL0PCWin95TENStart(void)
{
#if defined(NET_USE_DEBUG)
vDebugS(Net_C_Debug_Ten,"Start");
#endif
SendMaxRate=10000000L;
NbrPlayer=0;
SendBufSize=0;
TabPlayer=NULL;
LastTime=GetTickCount();
FIFObegin=NULL;
FIFOend=&FIFObegin;
verifyNoErr(tenArInitArena("Lobby"));
do
{
tenArIdleArena();
}while (!(gs_uwCallBack&2));
gs_bL0PCWin95TENInitState|=0x02;
return gs_JoinType;
}
/*****************************************************************************
* Description: eL0PCWin95TENFinish
* Finish a game with TEN.
*****************************************************************************
* Input: none
* Output: none
*****************************************************************************/
_NET_EXPORT_ void _NET_CALLING_CONV_ eL0PCWin95TENFinish(void)
{
FIFO *p;
#if defined(NET_USE_DEBUG)
vDebugS(Net_C_Debug_Ten,"Finish");
#endif
vFree((char *)TabPlayer);
while (FIFObegin)
{
p=FIFObegin->next;
vFree((char*)FIFObegin);
FIFObegin=p;
}
FIFObegin=NULL;
FIFOend=&FIFObegin;
tenArExitArena();
gs_bL0PCWin95TENInitState&=~0x02;
NetLib_eFlushSendingList(500);
NetLib_vDisconnectAllRemotePlayers();
}
/*****************************************************************************
* Description: eL0PCWin95TENGamePrivate
* Refuse all new players in the game.
*****************************************************************************/
_NET_EXPORT_ void _NET_CALLING_CONV_ eL0PCWin95TENGamePrivate(void)
{
char options[20];
options[0]=0;
addStringParam(options,sizeof(options),"lock","y");
tenArSetGameState(options);
}
/*****************************************************************************
* Description: eL0PCWin95TENGamePublic
* Accept all new players in the game (if maximum number of player allow it).
*****************************************************************************/
_NET_EXPORT_ void _NET_CALLING_CONV_ eL0PCWin95TENGamePublic(void)
{
char options[20];
options[0]=0;
addStringParam(options,sizeof(options),"lock","n");
tenArSetGameState(options);
}
/*****************************************************************************
* Description : eL0PCWin95TENIsProtocolSet
* Check if the protocol is correctly initialize or not
*****************************************************************************
* Input : none
* Output :
* NetLib_E_es_ProtocolNotInitialized : the vLevel0SetupWin95PCTENInterface has not
* been called yet or it has failed, the application should call the level 2
* eInitializeGlobalData function.
* NetLib_E_es_InitialisationSocketError : the eLevel0InitWin95PCTEN function has not been
* called yet or it has failed, the application should call the level 2
* eInitializeGlobalData function
* NetLib_E_es_NoPortSelected : the eL0PCWin95TENAddPort has not been called yet. The
* protocol has been correctly initialised, it can be used, but it won't give any
* results since no port is avaible. The application should call it.
*****************************************************************************/
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eL0PCWin95TENIsProtocolSet(void)
{
if(!(gs_bL0PCWin95TENInitState&0x01)) return NetLib_E_es_ProtocolNotInitialized;
return NetLib_E_es_True;
}
/*****************************************************************************
* Description : eL0PCWin95TENIsProtocolAvailable
* Check if the protocol is avaible for use or not
*****************************************************************************
* Input : A port number to test
* Output : NetLib_E_es_True if the port is avaible
* An error code otherwise
*****************************************************************************/
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eL0PCWin95TENIsProtocolAvailable(void)
{
if(!(gs_bL0PCWin95TENInitState&0x01)) return NetLib_E_es_ProtocolNotInitialized;
return NetLib_E_es_True;
}
/*****************************************************************************
* Description : eL0PCWin95TENPlayerInfo
* Return player bandwith and latency.
* Return non null value if error.
*****************************************************************************/
int _NET_CALLING_CONV_ eL0PCWin95TENPlayerInfo(NetLib_tduxPlayerId PId,long *bandwhith,long *latency)
{
int r;
size_t size=sizeof(long);
r=tenArGetPlayerInfo(PId,kTenArPIBandwidth,bandwhith,&size);
if (r!=0) return r;
size=sizeof(long);
r=tenArGetPlayerInfo(PId,kTenArPIAveLatency,latency,&size);
return r;
}
/*****************************************************************************
* Description : eL0PCWin95TENLaunchTenClient
* Input : a quit callback function.
*****************************************************************************/
void _NET_CALLING_CONV_ eL0PCWin95TENLaunchTenClient(void (*rtn)(void))
{
tenBnSetExitRtn(rtn);
tenBnStart();
}