⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 multi.c

📁 小型游戏引擎
💻 C
📖 第 1 页 / 共 3 页
字号:
// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman// Ken Silverman's official web site: "http://www.advsys.net/ken"// See the included license file "BUILDLIC.TXT" for license info.// This file has been modified from Ken Silverman's original release#include <stdio.h>#include <stdlib.h>#include <string.h>#include "platform.h"extern long getcrc(char *buffer, short bufleng);extern void processreservedmessage(short tempbufleng, char *datempbuf);extern void initcrc(void);extern int comon(void);extern void comoff(void);extern int neton(void);extern void netoff(void);extern void startcom(void);extern int netinitconnection (long newconnectnum, char *newcompaddr);extern void installbicomhandlers(void);extern void uninstallbicomhandlers(void);#define COMBUFSIZ 16384#define COMCODEBYTES 384#define COMCODEOFFS 14#define NETCODEBYTES 384#define MAXPLAYERS 16#define ESC1 0x83#define ESC2 0x8f#define NETBACKPACKETS 4#define MAXIPXSIZ 546#define updatecrc16(crc,dat) crc = (((crc<<8)&65535)^crctable[((((unsigned short)crc)>>8)&65535)^dat])char syncstate = 0, hangup = 1;static char multioption = 0, comrateoption = 0;	//COM & NET variablesshort numplayers = 0, myconnectindex = 0;short connecthead, connectpoint2[MAXPLAYERS];char syncbuf[MAXIPXSIZ];long syncbufleng, outbufindex[128], outcnt;long myconnectnum, otherconnectnum, mypriority;long crctable[256];	//COM ONLY variableslong comnum, comvect, comspeed, comtemp, comi, comescape, comreset;#ifdef PLATFORM_DOS   // !!! this is a real mess. --ryan.static void interrupt far comhandler(void);static unsigned short orig_pm_sel, orig_rm_seg, orig_rm_off;static unsigned long orig_pm_off;#endifvolatile unsigned char *inbuf, *outbuf, *comerror, *incnt, *comtype;volatile unsigned char *comresend;volatile short *inbufplc, *inbufend, *outbufplc, *outbufend, *comport;#ifdef PLATFORM_DOS   // !!! this is a real mess. --ryan.static char rmbuffer[COMCODEBYTES] =        //See realcom.asm{	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	0x00,0x00,0x00,0x00,0x50,0x53,0x66,0x51,0x52,0x2e,	0x8b,0x16,0x08,0x00,0x83,0xc2,0x02,0xec,0x24,0x07,	0x8a,0xe0,0x80,0xfc,0x02,0x74,0x08,0x80,0xfc,0x04,	0x74,0x62,0xe9,0x89,0x00,0x2e,0x8b,0x16,0x08,0x00,	0x2e,0x8a,0x0e,0x0a,0x00,0x80,0xe9,0x01,0x78,0x7a,	0x2e,0x80,0x3e,0x0c,0x00,0x01,0x7c,0x10,0x74,0x04,	0xb0,0x83,0xeb,0x02,0xb0,0x8f,0xee,0x2e,0xfe,0x0e,	0x0c,0x00,0xeb,0xe3,0x2e,0x80,0x3e,0x0b,0x00,0x01,	0x7c,0x12,0x74,0x04,0xb0,0x83,0xeb,0x04,0x2e,0xa0,	0x0d,0x00,0xee,0x2e,0xfe,0x0e,0x0b,0x00,0xeb,0xc9,	0x2e,0x8b,0x1e,0x04,0x00,0x2e,0x3b,0x1e,0x06,0x00,	0x74,0x3c,0x2e,0x8a,0x87,0x80,0x41,0xee,0x43,0x81,	0xe3,0xff,0x3f,0x2e,0x89,0x1e,0x04,0x00,0xeb,0xab,	0x2e,0x8b,0x16,0x08,0x00,0xec,0x2e,0x8b,0x1e,0x02,	0x00,0x2e,0x88,0x87,0x80,0x01,0x43,0x81,0xe3,0xff,	0x3f,0x2e,0x89,0x1e,0x02,0x00,0x2e,0x80,0x3e,0x0a,	0x00,0x10,0x75,0x08,0x83,0xc2,0x05,0xec,0xa8,0x01,	0x75,0xd6,0xf6,0xc4,0x01,0x0f,0x84,0x56,0xff,0xb0,	0x20,0xe6,0x20,0x5a,0x66,0x59,0x5b,0x58,0xcf,};#endif	//NET ONLY variablesshort socket = 0x4949;char compaddr[MAXPLAYERS][12], mycompaddr[12];char netincnt[MAXPLAYERS], netoutcnt[MAXPLAYERS];char getmess[MAXIPXSIZ];char omessout[MAXPLAYERS][NETBACKPACKETS][MAXIPXSIZ];short omessleng[MAXPLAYERS][NETBACKPACKETS];short omessconnectindex[MAXPLAYERS][NETBACKPACKETS];short omessnum[MAXPLAYERS];long connectnum[MAXPLAYERS], rmoffset32, rmsegment16, neti;volatile char *ecbget, *ecbput, *ipxin, *ipxout, *messin, *messout;volatile char *tempinbuf, *tempoutbuf, *rmnethandler, *netinbuf;volatile short *netinbufplc, *netinbufend;static char rmnetbuffer[NETCODEBYTES] ={	0xfb,0x2e,0x8a,0x26,0x62,0x00,0x2e,0xa0,0x63,0x00,	0x83,0xe8,0x1e,0x2e,0x8b,0x1e,0xe2,0x06,0x2e,0x88,	0x87,0xe4,0x06,0x43,0x81,0xe3,0xff,0x3f,0x2e,0x88,	0xa7,0xe4,0x06,0x43,0x81,0xe3,0xff,0x3f,0x33,0xf6,	0x2e,0x8a,0x8c,0xa0,0x00,0x46,0x2e,0x88,0x8f,0xe4,	0x06,0x43,0x81,0xe3,0xff,0x3f,0x3b,0xf0,0x72,0xec,	0x2e,0x89,0x1e,0xe2,0x06,0xbb,0x04,0x00,0x8c,0xc8,	0x8e,0xc0,0xbe,0x00,0x00,0xcd,0x7a,0xcb,};static long my7a = 0;#ifdef PLATFORM_DOS#pragma aux koutp =\	"out dx, al",\	parm [edx][eax]\#pragma aux kinp =\	"in al, dx",\	parm [edx]#endiflong convalloc32 (long size){#ifdef PLATFORM_DOS		union REGS r;	r.x.eax = 0x0100;           //DPMI allocate DOS memory	r.x.ebx = ((size+15)>>4);   //Number of paragraphs requested	int386(0x31,&r,&r);	if (r.x.cflag != 0) return ((long)0);   //Failed	return ((long)((r.x.eax&0xffff)<<4));   //Returns full 32-bit offset#else	fprintf (stderr, "%s, line %d; convalloc32() called\n", __FILE__,		__LINE__);	return 0;#endif	}#ifdef PLATFORM_DOS#pragma aux fixregistersaftersimulate =\	"cld",\	"push ds",\	"pop es",\static struct rminfo{	long EDI, ESI, EBP, ESP, EBX, EDX, ECX, EAX;	short flags, ES, DS, FS, GS, IP, CS, SP, SS;} RMI;#endiflong simulateint(char intnum, long daeax, long daebx, long daecx, long daedx, long daesi, long daedi){#ifdef PLATFORM_DOS		union REGS regs;	struct SREGS sregs;	memset(&RMI,0,sizeof(RMI));    // Set up real-mode call structure	memset(&sregs,0,sizeof(sregs));	RMI.EAX = daeax;	RMI.EBX = daebx;	RMI.ECX = daecx;	RMI.EDX = daedx;	RMI.ESI = daesi-rmoffset32;	RMI.EDI = daedi-rmoffset32;	RMI.DS = rmsegment16;	RMI.ES = rmsegment16;	regs.w.ax = 0x0300;            // Use DMPI call 300h to issue the DOS interrupt	regs.h.bl = intnum;	regs.h.bh = 0;	regs.w.cx = 0;	sregs.es = FP_SEG(&RMI);	regs.x.edi = FP_OFF(&RMI);	int386x(0x31,&regs,&regs,&sregs);	fixregistersaftersimulate();	return(RMI.EAX);#else	fprintf(stderr, "%s line %d; simulateint() called\n",__FILE__,__LINE__);	return 0;#endif	}void initmultiplayers(char damultioption, char dacomrateoption, char dapriority){	long i;	multioption = damultioption;	comrateoption = dacomrateoption;	connecthead = 0;	for(i=MAXPLAYERS-1;i>=0;i--)		connectpoint2[i] = -1, connectnum[i] = 0x7fffffff;	mypriority = dapriority;	initcrc();	if ((multioption >= 1) && (multioption <= 4))	{		comnum = multioption;		switch(dacomrateoption&15)		{			case 0: comspeed = 2400; break;			case 1: comspeed = 4800; break;			case 2: comspeed = 9600; break;			case 3: comspeed = 14400; break;			case 4: comspeed = 19200; break;			case 5: comspeed = 28800; break;		}		comon();	}	if (multioption >= 5)	{		if ((i = neton()) != 0)		{			if (i == -1) printf("IPX driver not found\n");			if (i == -2) printf("Socket could not be opened\n");			exit(0);		}	}	numplayers = 1;}void uninitmultiplayers(){	if (numplayers > 0)	{		if ((multioption >= 1) && (multioption <= 4)) comoff();		if (multioption >= 5) netoff();  //Uninstall before timer	}}int neton(void){	long i, j;	if ((simulateint(0x2f,(long)0x7a00,0L,0L,0L,0L,0L)&255) != 255) return(-1);	if (*(long *)(0x7a<<2) == 0)	{#ifdef PLATFORM_DOS				printf("Faking int 0x7a to call IPX entry at: %4x:%4x\n",RMI.ES,RMI.EDI&65535);		my7a = convalloc32(16L);		*(short *)((0x7a<<2)+0) = (my7a&15);		*(short *)((0x7a<<2)+2) = (my7a>>4);		*(char *)(my7a+0) = 0x2e;               //call far ptr [L1]		*(char *)(my7a+1) = 0x9a;		*(long *)(my7a+2) = 7L;		*(char *)(my7a+6) = 0xcf;               //iret		*(short *)(my7a+7) = (RMI.EDI&65535);   //L1: ipxoff		*(short *)(my7a+9) = RMI.ES;            //    ipxseg#endif			}		//Special stuff for WATCOM C	if ((rmoffset32 = convalloc32(1380L+NETCODEBYTES+COMBUFSIZ)) == 0)		{ printf("Can't allocate memory for IPX\n"); exit; }	rmsegment16 = (rmoffset32>>4);	i = rmoffset32;	ecbget = (char *)i; i += 48;	ecbput = (char *)i; i += 48;	ipxin = (char *)i; i += 32;	ipxout = (char *)i; i += 32;	messin = (char *)i; i += 560;	messout = (char *)i; i += 560;	tempinbuf = (char *)i; i += 16;	tempoutbuf = (char *)i; i += 80;	rmnethandler = (char *)i; i += NETCODEBYTES;	netinbufplc = (short *)i; i += 2;	netinbufend = (short *)i; i += 2;	netinbuf = (char *)i; i += COMBUFSIZ;	memcpy((void *)rmnethandler,(void *)rmnetbuffer,NETCODEBYTES);	simulateint(0x7a,0L,(long)0x1,0L,(long)socket,0L,0L);                             //Closesocket	if ((simulateint(0x7a,(long)0xff,0L,0L,(long)socket,0L,0L)&255) != 0) return(-2); //Opensocket	simulateint(0x7a,0L,9L,0L,0L,(long)tempoutbuf,0L);    //Getinternetworkaddress	memcpy((void *)&mycompaddr[0],(void *)&tempoutbuf[0],10);	mycompaddr[10] = (socket&255);	mycompaddr[11] = (socket>>8);	myconnectnum = ((long)tempoutbuf[6])+(((long)tempoutbuf[7])<<8)+(((long)(tempoutbuf[8]^tempoutbuf[9]))<<16)+(((long)mypriority)<<24);	netinitconnection(myconnectnum,mycompaddr);	ecbget[8] = 1; ecbput[8] = 0;	*netinbufplc = 0; *netinbufend = 0;	for(i=MAXPLAYERS-1;i>=0;i--) netincnt[i] = 0, netoutcnt[i] = 0;	for(i=0;i<MAXPLAYERS;i++)	{		omessnum[i] = 0;		for(j=NETBACKPACKETS-1;j>=0;j--)		{			omessleng[i][j] = 0;			omessconnectindex[i][j] = 0;		}	}		//Netlisten	for(i=0;i<30;i++) ipxin[i] = 0;	for(i=0;i<48;i++) ecbget[i] = 0;	ecbget[4] = (char)(((long)rmnethandler-rmoffset32)&255), ecbget[5] = (char)(((long)rmnethandler-rmoffset32)>>8);	ecbget[6] = (char)(rmsegment16&255), ecbget[7] = (char)(rmsegment16>>8);	ecbget[10] = (socket&255), ecbget[11] = (socket>>8);	ecbget[34] = 2, ecbget[35] = 0;	ecbget[36] = (char)(((long)ipxin-rmoffset32)&255), ecbget[37] = (char)(((long)ipxin-rmoffset32)>>8);	ecbget[38] = (char)(rmsegment16&255), ecbget[39] = (char)(rmsegment16>>8);	ecbget[40] = 30, ecbget[41] = 0;	ecbget[42] = (char)(((long)messin-rmoffset32)&255), ecbget[43] = (char)(((long)messin-rmoffset32)>>8);	ecbget[44] = (char)(rmsegment16&255), ecbget[45] = (char)(rmsegment16>>8);	ecbget[46] = (MAXIPXSIZ&255), ecbget[47] = (MAXIPXSIZ>>8);	simulateint(0x7a,0L,(long)0x4,0L,0L,(long)ecbget,0L);               //Receivepacket	return(0);}int comon(){	long divisor, cnt;	short *ptr;	if ((comnum < 1) || (comnum > 4)) return(-1);	//comvect = 0xb+(comnum&1);	comvect = ((comrateoption>>4)+0x8+2);	installbicomhandlers();	*incnt = 0; outcnt = 0;	*inbufplc = 0; *inbufend = 0; *outbufplc = 0; *outbufend = 0;	ptr = (short *)(0x400L+(long)((comnum-1)<<1));	*comport = *ptr;	if (*comport == 0)	{		switch(comnum)		{			case 1: *comport = 0x3f8; break;			case 2: *comport = 0x2f8; break;			case 3: *comport = 0x3e8; break;			case 4: *comport = 0x2e8; break;		}		if ((inp((*comport)+5)&0x60) != 0x60) { *comport = 0; return(-1); }	}	if ((comspeed <= 0) || (comspeed > 115200)) return(-1);	  // Baud-Setting,?,?,Parity O/E,Parity Off/On, Stop-1/2,Bits-5/6/7/8	  // 0x0b is odd parity,1 stop bit, 8 bits#ifdef PLATFORM_DOS		_disable();#endif		koutp((*comport)+3,0x80);                  //enable latch registers	divisor = 115200 / comspeed;	koutp((*comport)+0,divisor&255);           //# = 115200 / bps	koutp((*comport)+1,divisor>>8);	koutp((*comport)+3,0x03);                  //0x03 = n,8,1	koutp((*comport)+2,0x87);   //check for a 16550   0=1,64=4,128=8,192=14	if ((kinp((*comport)+2)&0xf8) == 0xc0)	{		*comtype = 16;	}	else	{		*comtype = 1;		koutp((*comport)+2,0);	}	cnt = *comtype;                        //Clear any junk already in FIFO	while (((kinp((*comport)+5)&0x1) > 0) && (cnt > 0))		{ kinp(*comport); cnt--; }	koutp((*comport)+4,0x0b);             //setup for interrupts (modem control)	koutp((*comport)+1,0);                //com interrupt disable	koutp(0x21,kinp(0x21)&(255-(1<<(comvect&7))));          //Unmask vector	kinp((*comport)+6);	kinp((*comport)+5);	kinp((*comport)+0);	kinp((*comport)+2);	koutp((*comport)+1,0x03);             //com interrupt enable	koutp(0x20,0x20);	comescape = 0; comreset = 0;	*comerror = 0; *comresend = 0;#ifdef PLATFORM_DOS		_enable();#endif		syncbufleng = 0;	return(0);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -