From: Holger Schemel Date: Wed, 30 Sep 1998 20:57:50 +0000 (+0200) Subject: rnd-19980930-3 X-Git-Tag: 1.2.0^2~71 X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=commitdiff_plain;h=b2a0ff1ddd4430110b331129469dabb8ea7b6ba7 rnd-19980930-3 --- diff --git a/src/Makefile b/src/Makefile index 8b9de786..bff1b9b4 100644 --- a/src/Makefile +++ b/src/Makefile @@ -100,7 +100,7 @@ $(SERVNAME): $(SERVNAME).c $(CC) $(CFLAGS) -c $*.c clean: - $(RM) $(OBJS) + $(RM) $(PROGNAME) $(SERVNAME) $(OBJS) backup: ./make_backup.sh diff --git a/src/events.c b/src/events.c index d0684ed3..f1cd50da 100644 --- a/src/events.c +++ b/src/events.c @@ -25,7 +25,7 @@ void EventLoop(void) { while(1) { - if (XPending(display)) /* got an event */ + if (XPending(display)) /* got event from X server */ { XEvent event; @@ -693,6 +693,199 @@ void HandleKey(KeySym key, int key_status) } } + + +/* TEST STUFF -------------------------------------------------------------- */ + +#define PROT_VERS_1 1 +#define PROT_VERS_2 0 +#define PROT_VERS_3 1 + +#define OP_NICK 1 +#define OP_PLAY 2 +#define OP_FALL 3 +#define OP_DRAW 4 +#define OP_LOST 5 +#define OP_GONE 6 +#define OP_CLEAR 7 +#define OP_NEW 8 +#define OP_LINES 9 +#define OP_GROW 10 +#define OP_MODE 11 +#define OP_LEVEL 12 +#define OP_BOT 13 +#define OP_KILL 14 +#define OP_PAUSE 15 +#define OP_CONT 16 +#define OP_VERSION 17 +#define OP_BADVERS 18 +#define OP_MSG 19 +#define OP_YOUARE 20 +#define OP_LINESTO 21 +#define OP_WON 22 +#define OP_ZERO 23 + +/* server stuff */ + +#define BUFLEN 4096 + +extern int sfd; +extern unsigned char realbuf[], readbuf[], writbuf[]; +extern unsigned char *buf; +extern int nread, nwrite; + +extern void fatal(char *); +extern void flushbuf(void); +extern void sysmsg(char *); + +/* like memcpy, but guaranteed to handle overlap when s <= t */ +void copydown(char *s, char *t, int n) +{ + for (; n; n--) + *(s++) = *(t++); +} + +void handlemessages() +{ + unsigned int len; + static char msgbuf[300]; + + while (nread >= 4 && nread >= 4 + readbuf[3]) + { + len = readbuf[3]; + if (readbuf[0] || readbuf[1] || readbuf[2]) + fatal("Wrong server line length"); + + memcpy(buf, &readbuf[4], len); + nread -= 4 + len; + copydown(readbuf, readbuf + 4 + len, nread); + + switch(buf[1]) + { + case OP_YOUARE: + printf("OP_YOUARE: %d\n", buf[0]); + break; + + case OP_NEW: + printf("OP_NEW: %d\n", buf[0]); + sprintf(msgbuf, "new client %d connected", buf[0]); + sysmsg(msgbuf); + break; + + case OP_GONE: + printf("OP_GONE: %d\n", buf[0]); + sprintf(msgbuf, "client %d disconnected", buf[0]); + sysmsg(msgbuf); + break; + + case OP_BADVERS: + { + static char tmpbuf[128]; + + sprintf(tmpbuf, "Protocol version mismatch: server expects %d.%d.x instead of %d.%d.%d\n", buf[2], buf[3], PROT_VERS_1, PROT_VERS_2, PROT_VERS_3); + fatal(tmpbuf); + } + break; + + case OP_PLAY: + printf("OP_PLAY: %d\n", buf[0]); + sprintf(msgbuf, "client %d starts game", buf[0]); + sysmsg(msgbuf); + break; + + case OP_PAUSE: + printf("OP_PAUSE: %d\n", buf[0]); + sprintf(msgbuf, "client %d pauses game", buf[0]); + sysmsg(msgbuf); + break; + + case OP_CONT: + printf("OP_CONT: %d\n", buf[0]); + sprintf(msgbuf, "client %d continues game", buf[0]); + sysmsg(msgbuf); + break; + + case OP_WON: + printf("OP_WON: %d\n", buf[0]); + sprintf(msgbuf, "client %d wins the game", buf[0]); + sysmsg(msgbuf); + break; + + case OP_ZERO: + printf("OP_ZERO: %d\n", buf[0]); + sprintf(msgbuf, "client %d resets game counters", buf[0]); + sysmsg(msgbuf); + break; + + case OP_NICK: + printf("OP_NICK: %d\n", buf[0]); + sprintf(msgbuf, "client %d calls itself %s", buf[0], &buf[2]); + sysmsg(msgbuf); + break; + + case OP_MSG: + printf("OP_MSG: %d\n", buf[0]); + sprintf(msgbuf, "client %d sends message", buf[0]); + break; + + case OP_LOST: + printf("OP_MSG: %d\n", buf[0]); + sprintf(msgbuf, "client %d has lost", buf[0]); + break; + + case OP_LEVEL: + printf("OP_MSG: %d\n", buf[0]); + sprintf(msgbuf, "client %d sets level to %d", buf[0], buf[2]); + break; + } + } + + fflush(stdout); +} + + + +static void HandleNetworking() +{ + static struct timeval tv = { 0, 0 }; + fd_set rfds; + int r = 0; + + if (standalone) + return; + + flushbuf(); + + FD_ZERO(&rfds); + FD_SET(sfd, &rfds); + + r = select(sfd + 1, &rfds, NULL, NULL, &tv); + + if (r < 0 && errno != EINTR) + { + perror("select"); + fatal("fatal: select() failed"); + } + + if (r < 0) + FD_ZERO(&rfds); + + if (FD_ISSET(sfd, &rfds)) + { + int r; + + r = read(sfd, readbuf + nread, BUFLEN - nread); + + if (r < 0) + fatal("Error reading from server"); + if (r == 0) + fatal("Connection to server lost"); + nread += r; + + handlemessages(); + } +} + void HandleNoXEvent() { if (button_status && game_status != PLAYING) @@ -701,6 +894,8 @@ void HandleNoXEvent() return; } + HandleNetworking(); + switch(game_status) { case MAINMENU: diff --git a/src/gfxloader.c b/src/gfxloader.c new file mode 100644 index 00000000..9a28f435 --- /dev/null +++ b/src/gfxloader.c @@ -0,0 +1,1155 @@ +/*********************************************************** +* Rocks'n'Diamonds -- McDuffin Strikes Back! * +*----------------------------------------------------------* +* ©1995 Artsoft Development * +* Holger Schemel * +* 33659 Bielefeld-Senne * +* Telefon: (0521) 493245 * +* eMail: aeglos@valinor.owl.de * +* aeglos@uni-paderborn.de * +* q99492@pbhrzx.uni-paderborn.de * +*----------------------------------------------------------* +* gfxloader.c * +***********************************************************/ + +#include "gfxloader.h" + + + + + + +extern Window window; +extern void Delay(long); + + + + + + +#ifdef DEBUG +/* +#define DEBUG_GIF +#define DEBUG_ILBM +*/ +#endif + +struct IFF_ILBM_FORM_big_endian +{ + char magic_FORM[4]; + unsigned char chunk_size[4]; + char magic_ILBM[4]; +}; + +struct IFF_ILBM_BMHD_big_endian +{ + char Width[2], Height[2]; + char LeftEdge[2], TopEdge[2]; + char Depth; + char Mask; + char Compression; + char pad1; + char transparentColor[2]; + char xAspect, yAspect; + char pageWidth[2], pageHeight[2]; +}; + +struct IFF_ILBM_BMHD +{ + unsigned int Width, Height; + int LeftEdge, TopEdge; + unsigned int Depth; + unsigned int Mask; + unsigned int Compression; + unsigned char pad1; + unsigned int transparentColor; + unsigned int xAspect, yAspect; + int pageWidth, pageHeight; +}; + +static int ConvertXImageDepth(Display *, XImage **); +static int Read_GIF_to_Pixmap_or_Bitmap(Display *, char *, Pixmap *, int); + +#define READ_GIF_TO_BITMAP 0 +#define READ_GIF_TO_PIXMAP 1 + + +int Read_GIF_to_Bitmap(Display *display, char *filename, Pixmap *pixmap) +{ + printf("Read_GIF_to_Bitmap\n"); + + + + + return(Read_GIF_to_Pixmap_or_Bitmap(display, filename, + pixmap, READ_GIF_TO_BITMAP)); +} + +int Read_GIF_to_Pixmap(Display *display, char *filename, Pixmap *pixmap) +{ + printf("Read_GIF_to_Pixmap\n"); + + + + + return(Read_GIF_to_Pixmap_or_Bitmap(display, filename, + pixmap, READ_GIF_TO_PIXMAP)); +} + +int Read_GIF_to_Pixmap_or_Bitmap(Display *display, char *filename, + Pixmap *pixmap, int mode) +{ + XImage *image = NULL; + Pixmap new_pixmap = 0; + int return_code; + + *pixmap = 0; + return_code = Read_GIF_to_XImage(display, filename, &image); + if (return_code != GIF_Success) + return(return_code); + + if (image) + { + int screen = DefaultScreen(display); + Drawable root = RootWindow(display,screen); + int depth = DefaultDepth(display, screen); + int width = image->width; + int height = image->height; + + if (mode == READ_GIF_TO_BITMAP) + { + int i,x,y; + unsigned long black_pixel = BlackPixel(display,screen); + int bytes_per_line = (width+7) / 8; + int size = bytes_per_line * height; + char *data, *ptr; + + data = (char *)malloc(size); + if (!data) + return(GIF_NoMemory); + + ptr = data; + for(i=0;i filesize) + return(GIF_FileInvalid); + } + while(ch1); + + free(RawGIF); /* We're done with the raw data now... */ + +#ifdef DEBUG_GIF + fprintf(stderr, "done\n"); + fprintf(stderr, " Decompressing... "); +#endif + + /* Allocate the X Image */ + ImageData = (byte *) malloc(Width*Height); + if (!ImageData) + return(GIF_NoMemory); + + new_image = XCreateImage(display,visual,8,ZPixmap,0,ImageData, + Width,Height,8,Width); + if (!new_image) + return(GIF_NoMemory); + + BytesPerScanline = Width; + + + /* Decompress the file, continuing until you see the GIF EOF code. + * One obvious enhancement is to add checking for corrupt files here. + */ + + Code = ReadCode(); + while (Code != EOFCode) + { + /* Clear code sets everything back to its initial value, then reads the + * immediately subsequent code as uncompressed data. + */ + + if (Code == ClearCode) + { + CodeSize = InitCodeSize; + MaxCode = (1 << CodeSize); + ReadMask = MaxCode - 1; + FreeCode = FirstFree; + CurCode = OldCode = Code = ReadCode(); + FinChar = CurCode & BitMask; + AddToPixel(FinChar); + } + else + { + /* If not a clear code, then must be data: + * save same as CurCode and InCode + */ + + CurCode = InCode = Code; + + /* If greater or equal to FreeCode, not in the hash table yet; + * repeat the last character decoded + */ + + if (CurCode >= FreeCode) + { + CurCode = OldCode; + OutCode[OutCount++] = FinChar; + } + + /* Unless this code is raw data, pursue the chain pointed to by CurCode + * through the hash table to its end; each code in the chain puts its + * associated output code on the output queue. + */ + + while (CurCode > BitMask) + { + if (OutCount > 1024) + return(GIF_FileInvalid); + + OutCode[OutCount++] = Suffix[CurCode]; + CurCode = Prefix[CurCode]; + } + + /* The last code in the chain is treated as raw data. */ + + FinChar = CurCode & BitMask; + OutCode[OutCount++] = FinChar; + + /* Now we put the data out to the Output routine. + * It's been stacked LIFO, so deal with it that way... + */ + + for (i = OutCount - 1; i >= 0; i--) + AddToPixel(OutCode[i]); + OutCount = 0; + + /* Build the hash table on-the-fly. No table is stored in the file. */ + + Prefix[FreeCode] = OldCode; + Suffix[FreeCode] = FinChar; + OldCode = InCode; + + /* Point to the next slot in the table. If we exceed the current + * MaxCode value, increment the code size unless it's already 12. If it + * is, do nothing: the next code decompressed better be CLEAR + */ + + FreeCode++; + if (FreeCode >= MaxCode) + { + if (CodeSize < 12) + { + CodeSize++; + MaxCode *= 2; + ReadMask = (1 << CodeSize) - 1; + } + } + } + Code = ReadCode(); + } + + free(Raster); + +#ifdef DEBUG_GIF + fprintf(stderr, "done\n"); + fprintf(stderr," %d colors used\n",numused); +#endif + + if (file != stdin) + fclose(file); + + if (ColorDicking(display) != GIF_Success) + return(GIF_ColorFailed); + + *image = new_image; + return(GIF_Success); +} + + +/* Fetch the next code from the raster data stream. The codes can be + * any length from 3 to 12 bits, packed into 8-bit bytes, so we have to + * maintain our location in the Raster array as a BIT Offset. We compute + * the byte Offset into the raster array by dividing this by 8, pick up + * three bytes, compute the bit Offset into our 24-bit chunk, shift to + * bring the desired code to the bottom, then mask it off and return it. + */ + +static int ReadCode() +{ + int RawCode, ByteOffset; + + ByteOffset = BitOffset / 8; + RawCode = Raster[ByteOffset] + (0x100 * Raster[ByteOffset + 1]); + if (CodeSize >= 8) + RawCode += (0x10000 * Raster[ByteOffset + 2]); + RawCode >>= (BitOffset % 8); + BitOffset += CodeSize; + return(RawCode & ReadMask); +} + + +static void AddToPixel(byte Index) +{ + if (YC= Height) + { + Pass++; + YC = 4; + } + break; + + case 1: + YC += 8; + if (YC >= Height) + { + Pass++; + YC = 2; + } + break; + + case 2: + YC += 4; + if (YC >= Height) + { + Pass++; + YC = 1; + } + break; + + case 3: + YC += 2; + break; + + default: + break; + } + } + } +} + + +static int ColorDicking(Display *display) +{ + /* we've got the picture loaded, we know what colors are needed. get 'em */ + + register int i,j; + static byte lmasks[8] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80}; + byte lmask, *ptr; + int screen = DefaultScreen(display); + Colormap cmap = DefaultColormap(display,screen); + int dispcells = DisplayCells(display,screen); + + int strip = 0; + int nostrip = 0; + + if (!HasColormap) + return(GIF_Success); + /* no need to allocate any colors if no colormap in GIF file */ + + /* Allocate the X colors for this picture */ + + if (nostrip) + { + /* nostrip was set. try REAL hard to do it */ + for (i=j=0; i>8)) + + abs(g - (ctab[j].green>>8)) + + abs(b - (ctab[j].blue>>8)); + if (d=0; i--) + if (used[i]) + XFreeColors(display,cmap,cols+i,1,0L); + } + else + break; + } + +#ifdef DEBUG_GIF + if (j && strip<8) + fprintf(stderr,"%s: stripped %d bits\n",progname,strip); +#endif + + if (strip==8) + { + fprintf(stderr,"UTTERLY failed to allocate the desired colors.\n"); + for (i=0; idepth == %d\n", + (*image)->depth); + printf("DefaultDepth(display, screen) == %d\n", + DefaultDepth(display, screen)); + + + + + if ((*image)->depth != depth) + { + XImage *old_image, *new_image; + /* + Visual *visual = DefaultVisual(display,screen); + */ + int width = (*image)->width; + int height = (*image)->height; + register int dwx, dwy; + byte *data; + + + + + + printf("ConvertXImageDepth: ---------> CONVERTING...\n"); + + + + + + + data = (byte *)malloc(width * height * depth); + old_image = *image; + + /* + new_image = XCreateImage(display,visual,depth, + ZPixmap,0,data,width,height,8,0); + */ + + new_image = XGetImage(display,RootWindow(display,screen), + 0,0,width,height,0xffffffff,ZPixmap); + + + if (!new_image) + return(GIF_NoMemory); + + if (old_image->depth == 8 && new_image->depth == 4) + { + /* speedup for the most common format change */ + + register byte *sptr = (byte *)old_image->data; + register byte *dptr = (byte *)new_image->data; + + for (dwy=1; dwy<=height; dwy++) + { + for (dwx=1; dwx 4 bit */ + { + unsigned long pixel_value; + + for (dwx=0; dwx 0xff) + printf("pixel = %lx", pixel_value); + + XPutPixel(new_image, dwx, dwy, pixel_value); + } + } + } + + free(old_image->data); + old_image->data = NULL; + XDestroyImage(old_image); + + *image = new_image; + } + + return(GIF_Success); +} + + +static unsigned long be2long(unsigned char *be) /* big-endian -> long int */ +{ + return((be[0]<<24) | (be[1]<<16) | (be[2]<<8) | be[3]); +} + +static unsigned short be2short(unsigned char *be) /* big-endian -> short int */ +{ + return((be[0]<<8) | be[1]); +} + +static struct IFF_ILBM_BMHD *ConvertBMHD(unsigned char *header_data) +{ + struct IFF_ILBM_BMHD_big_endian *bmhd_be; + struct IFF_ILBM_BMHD *bmhd; + + bmhd_be = (struct IFF_ILBM_BMHD_big_endian *)header_data; + bmhd = (struct IFF_ILBM_BMHD *)malloc(sizeof(struct IFF_ILBM_BMHD)); + if (!bmhd) + return(NULL); + + bmhd->Width = be2short(bmhd_be->Width); + bmhd->Height = be2short(bmhd_be->Height); + bmhd->LeftEdge = be2short(bmhd_be->LeftEdge); + bmhd->TopEdge = be2short(bmhd_be->TopEdge); + bmhd->Depth = (int)bmhd_be->Depth; + bmhd->Mask = (int)bmhd_be->Mask; + bmhd->Compression = (int)bmhd_be->Compression; + bmhd->pad1 = bmhd_be->pad1; + bmhd->transparentColor = be2short(bmhd_be->transparentColor); + bmhd->xAspect = (int)bmhd_be->xAspect; + bmhd->yAspect = (int)bmhd_be->yAspect; + bmhd->pageWidth = be2short(bmhd_be->pageWidth); + bmhd->pageHeight = be2short(bmhd_be->pageHeight); + + return(bmhd); +} + +static unsigned char MSBitFirst2LSBitFirst(unsigned char msb_byte) +{ + unsigned char lsb_byte = 0; + int i; + + for(i=7;i>=0;i--) + { + lsb_byte |= (msb_byte & 1) << i; + msb_byte >>= 1; + } + + return(lsb_byte); +} + +int Read_ILBM_to_Bitmap(Display *display, char *filename, Pixmap *pixmap) +{ + Pixmap new_pixmap = 0; + int screen = DefaultScreen(display); + Drawable root = RootWindow(display,screen); + struct IFF_ILBM_FORM_big_endian *form_header; + struct IFF_ILBM_BMHD *bitmap_header; + unsigned long file_len, body_len; + unsigned char *file_data, *bitmap_data; + unsigned char *file_ptr, *bitmap_ptr, *body_ptr; + unsigned char byte_count, byte_value; + int i,x,y,z; + int width, height, depth; + int bytes_per_line, bitmap_size; + FILE *file; + + + + + + printf("Read_ILBM_to_Bitmap\n"); + + + + + if (!(file = fopen(filename,"r"))) + return(ILBM_OpenFailed); + + if (fseek(file,0,SEEK_END) < 0) + { + fclose(file); + return(ILBM_ReadFailed); + } + + file_len = ftell(file); + rewind(file); + + if (!(file_data = (unsigned char *)malloc(file_len))) + { + fclose(file); + return(ILBM_NoMemory); + } + + if (fread(file_data,1,file_len,file) != file_len) + { + free(file_data); + fclose(file); + return(ILBM_ReadFailed); + } + + fclose(file); + + form_header = (struct IFF_ILBM_FORM_big_endian *)file_data; + + if (strncmp(form_header->magic_FORM,"FORM",4) || + file_len != be2long(form_header->chunk_size)+8 || + strncmp(form_header->magic_ILBM,"ILBM",4)) + { +#ifdef DEBUG_ILBM + printf("%s: IFF chunk 'FORM' and/or 'ILBM' not found.\n",filename); +#endif + free(file_data); + return(ILBM_FileInvalid); + } + + bitmap_header = NULL; + body_ptr = NULL; + file_ptr = file_data + 12; + + while(file_ptr < (unsigned char *)(file_data + file_len)) + { + if (!strncmp(file_ptr,"BMHD",4)) + { +#ifdef DEBUG_ILBM + printf("%s: IFF chunk 'BMHD' found.\n",filename); +#endif + bitmap_header = ConvertBMHD(file_ptr + 8); + file_ptr += be2long(file_ptr + 4) + 8; + continue; + } + else if (!strncmp(file_ptr,"BODY",4)) + { +#ifdef DEBUG_ILBM + printf("%s: IFF chunk 'BODY' found.\n",filename); +#endif + body_ptr = file_ptr + 8; + body_len = be2long(file_ptr + 4); + file_ptr += be2long(file_ptr + 4) + 8; + continue; + } + else + { +#ifdef DEBUG_ILBM + printf("%s: IFF chunk '%c%c%c%c' found (but not used).\n",filename, + file_ptr[0],file_ptr[1],file_ptr[2],file_ptr[3]); +#endif + /* other chunk not recognized here */ + file_ptr += be2long(file_ptr + 4) + 8; + continue; + } + } + + if (!bitmap_header || !body_ptr) + { +#ifdef DEBUG_ILBM + printf("%s: IFF chunk 'BMHD' and/or 'BODY' not found.\n",filename); +#endif + free(file_data); + return(ILBM_FileInvalid); + } + + width = bitmap_header->Width; + height = bitmap_header->Height; + depth = bitmap_header->Depth; + +#ifdef DEBUG_ILBM + if (depth > 1) + printf("%s: %d bitplanes found; using only the first plane.\n", + filename,depth); +#endif + + bytes_per_line = ((width + 15) / 16) * 2; + bitmap_size = bytes_per_line * height; + + bitmap_data = (char *)malloc(bitmap_size); + if (!bitmap_data) + { + free(file_data); + free(bitmap_header); + return(ILBM_NoMemory); + } + + bitmap_ptr = bitmap_data; + for(i=0;iCompression) + { + while(x++ < bytes_per_line) + *bitmap_ptr++ |= MSBitFirst2LSBitFirst(*body_ptr++); + } + else + { + while(x < bytes_per_line) + { + byte_count = *body_ptr++; + + if (byte_count <= 128) + { + for(i=0;i +#include +#include +#include +#include + +#define GIF_Success 0 +#define GIF_OpenFailed -1 +#define GIF_ReadFailed -2 +#define GIF_FileInvalid -3 +#define GIF_NoMemory -4 +#define GIF_ColorFailed -5 + +#define ILBM_Success 0 +#define ILBM_OpenFailed -1 +#define ILBM_ReadFailed -2 +#define ILBM_FileInvalid -3 +#define ILBM_NoMemory -4 +#define ILBM_ColorFailed -5 + +int Read_ILBM_to_Bitmap(Display *, char *, Pixmap *); +int Read_GIF_to_Bitmap(Display *, char *, Pixmap *); +int Read_GIF_to_Pixmap(Display *, char *, Pixmap *); +int Read_GIF_to_XImage(Display *, char *, XImage **); + +#endif diff --git a/src/init.c b/src/init.c index 27247acd..2f6bb8ed 100644 --- a/src/init.c +++ b/src/init.c @@ -11,11 +11,19 @@ * init.c * ***********************************************************/ +#include +#include +#include #include +#include +#include +#include #include #include +#include #include #include +#include #include "init.h" #include "misc.h" @@ -96,9 +104,38 @@ void OpenAll(int argc, char *argv[]) int norestart = 0; int nospeedup = 0; +#define DEFAULTPORT 19503 + +#define PROT_VERS_1 1 +#define PROT_VERS_2 0 +#define PROT_VERS_3 1 + +#define OP_NICK 1 +#define OP_PLAY 2 +#define OP_FALL 3 +#define OP_DRAW 4 +#define OP_LOST 5 +#define OP_GONE 6 +#define OP_CLEAR 7 +#define OP_NEW 8 +#define OP_LINES 9 +#define OP_GROW 10 +#define OP_MODE 11 +#define OP_LEVEL 12 +#define OP_BOT 13 +#define OP_KILL 14 +#define OP_PAUSE 15 +#define OP_CONT 16 +#define OP_VERSION 17 +#define OP_BADVERS 18 +#define OP_MSG 19 +#define OP_YOUARE 20 +#define OP_LINESTO 21 +#define OP_WON 22 +#define OP_ZERO 23 + /* server stuff */ -#define DEFAULTPORT 19503 #define BUFLEN 4096 int sfd; @@ -106,6 +143,12 @@ unsigned char realbuf[512], readbuf[BUFLEN], writbuf[BUFLEN]; unsigned char *buf = realbuf + 4; int nread = 0, nwrite = 0; +void sysmsg(char *s) +{ + printf("** %s\n", s); + fflush(stdout); +} + void fatal(char *s) { fprintf(stderr, "%s.\n", s); @@ -120,6 +163,29 @@ void u_sleep(int i) select(0, NULL, NULL, NULL, &tm); } +void flushbuf() +{ + if (nwrite) + { + write(sfd, writbuf, nwrite); + nwrite = 0; + } +} + +void sendbuf(int len) +{ + if (!standalone) + { + realbuf[0] = realbuf[1] = realbuf[2] = 0; + realbuf[3] = (unsigned char)len; + buf[0] = 0; + if (nwrite + 4 + len >= BUFLEN) + fatal("Internal error: send buffer overflow"); + memcpy(writbuf + nwrite, realbuf, 4 + len); + nwrite += 4 + len; + } +} + void startserver() { char *options[2]; @@ -144,10 +210,11 @@ void startserver() fprintf(stderr, "Can't start server '%s'.\n", #ifdef XTRISPATH - XTRISPATH "/xtserv"); + XTRISPATH "/rnd_server" #else - "xtserv"); + "rnd_server" #endif + ); _exit(1); @@ -191,7 +258,7 @@ void connect2server(char *host, int port) { if (!host) { - printf("No xtris server on localhost - starting up one ...\n"); + printf("No rocksndiamonds server on localhost - starting up one ...\n"); startserver(); for (i=0; i<6; i++) { @@ -212,12 +279,34 @@ void connect2server(char *host, int port) } } +static void send_nickname(char *nickname) +{ + static char msgbuf[300]; + + buf[1] = OP_NICK; + memcpy(&buf[2], nickname, strlen(nickname)); + sendbuf(2 + strlen(nickname)); + sprintf(msgbuf, "you set your nick to %s", nickname); + sysmsg(msgbuf); +} + void InitServer() { if (server_port == 0) server_port = DEFAULTPORT; - connect2server(server_host, server_port); + standalone = FALSE; + + if (!standalone) + connect2server(server_host, server_port); + + send_nickname("dummyplayer"); + + buf[1] = OP_VERSION; + buf[2] = PROT_VERS_1; + buf[3] = PROT_VERS_2; + buf[4] = PROT_VERS_3; + sendbuf(5); } /* TEST STUFF -------------------------------------------------------------- */ diff --git a/src/main.c b/src/main.c index 4b1a8c64..1aac4c96 100644 --- a/src/main.c +++ b/src/main.c @@ -47,6 +47,8 @@ int width, height; char *server_host = NULL; int server_port = 0; +int networking = FALSE; +int standalone = TRUE; int game_status = MAINMENU; int game_emulation = EMU_NONE; @@ -66,7 +68,6 @@ int fading_on = FALSE; int autorecord_on = FALSE; int joystick_nr = 0; int quick_doors = FALSE; -int networking = FALSE; BOOL redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE]; int redraw_x1 = 0, redraw_y1 = 0; diff --git a/src/main.h b/src/main.h index d1abeccc..2aeb7709 100644 --- a/src/main.h +++ b/src/main.h @@ -14,6 +14,13 @@ #ifndef MAIN_H #define MAIN_H +#include +#include +#include +#include +#include +#include + #ifndef MSDOS #define XK_MISCELLANY #define XK_LATIN1 @@ -32,13 +39,6 @@ #include "msdos.h" #endif /* #ifndef MSDOS */ -#include -#include -#include -#include -#include -#include - typedef int BOOL; #ifndef FALSE @@ -323,6 +323,8 @@ extern int width, height; extern char *server_host; extern int server_port; +extern int networking; +extern int standalone; extern int game_status; extern int game_emulation; @@ -341,7 +343,6 @@ extern int fading_on; extern int autorecord_on; extern int joystick_nr; extern int quick_doors; -extern int networking; extern BOOL redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE]; extern int redraw_x1, redraw_y1; diff --git a/src/misc.c b/src/misc.c index 1ab116d6..253a8d7f 100644 --- a/src/misc.c +++ b/src/misc.c @@ -11,11 +11,6 @@ * misc.c * ***********************************************************/ -#include "misc.h" -#include "tools.h" -#include "sound.h" -#include "random.h" - #include #include #include @@ -23,6 +18,11 @@ #include #include +#include "misc.h" +#include "tools.h" +#include "sound.h" +#include "random.h" + static unsigned long mainCounter(int mode) { static struct timeval base_time = { 0, 0 }; diff --git a/src/sound.h b/src/sound.h index 02431c45..1822b3aa 100644 --- a/src/sound.h +++ b/src/sound.h @@ -14,8 +14,8 @@ #ifndef SOUND_H #define SOUND_H -#include "main.h" #include +#include "main.h" #ifdef linux #include diff --git a/src/tools.h b/src/tools.h index c8436d11..9ee53aa1 100644 --- a/src/tools.h +++ b/src/tools.h @@ -14,9 +14,8 @@ #ifndef TOOLS_H #define TOOLS_H -#include "main.h" - #include +#include "main.h" /* for SetDrawtoField */ #define DRAW_DIRECT 0