File gargoyle-level9update41.patch of Package gargoyle

--- terps/level9/Glk/Makefile.glk
+++ terps/level9/Glk/Makefile.glk
@@ -27,7 +27,7 @@
 IFPHDR		= level9.hdr
 
 # Level9 version.
-VERSION		= 4.0
+VERSION		= 4.1
 
 # Common definitions.
 CC		=  gcc
@@ -89,7 +89,7 @@
 maintainer-clean: clean
 dist: distclean
 	mkdir distribution binaries
-	cd ..; zip -r Glk/distribution/Level9_4.0_Source.zip \
+	cd ..; zip -r Glk/distribution/Level9_4.1_Source.zip \
 			* -x Glk/distribution/\* Glk/binaries/
 	cp ../COPYING glk_readme.txt binaries
 	$(MAKE) -f Makefile.glk \
@@ -108,7 +108,7 @@
 			GLKLIBDIR=../../cheapglk GLKINCDIR=../../cheapglk \
 			GLKMAKEINC=../../cheapglk/Make.cheapglk glklevel9
 	mv glklevel9 binaries/cheaplevel9
-	cd binaries; tar zcvf ../distribution/Level9_4.0_Linux.tgz *
+	cd binaries; tar zcvf ../distribution/Level9_4.1_Linux.tgz *
 
 # Dependencies.
 glk.o: glk.c level9.h
--- terps/level9/Glk/glk.c
+++ terps/level9/Glk/glk.c
@@ -466,7 +466,7 @@
 		/* ...now update the status window. */
 		glk_window_clear (gln_status_window);
 		status_stream = glk_window_get_stream (gln_status_window);
-		glk_put_string_stream (status_stream, "Glk Level9 version 4.0");
+		glk_put_string_stream (status_stream, "Glk Level9 version 4.1");
 	    }
 }
 
@@ -3041,7 +3041,7 @@
 		    }
 
 		/* Print out a short banner. */
-		gln_header_string ("\nLevel 9 Interpreter, version 4.0\n");
+		gln_header_string ("\nLevel 9 Interpreter, version 4.1\n");
 		gln_banner_string ("Written by Glen Summers and David Kinder\n"
 					"Glk interface by Simon Baldwin\n\n");
 
@@ -3234,9 +3234,9 @@
 	gln_startup_called = TRUE;
 
 #ifdef GARGLK
-	garglk_set_program_name("Level 9 4.0");
+	garglk_set_program_name("Level 9 4.1");
 	garglk_set_program_info(
-		"Level 9 4.0 by Glen Summers, David Kinder\n"
+		"Level 9 4.1 by Glen Summers, David Kinder\n"
 		"Alan Staniforth, Simon Baldwin and Dieter Baron\n"
 		"Glk Graphics support by Tor Andersson\n");
 #endif
--- terps/level9/Glk/level9.hdr
+++ terps/level9/Glk/level9.hdr
@@ -33,7 +33,7 @@
 #
 IFP_ENGINE_TYPE="Level9"
 IFP_ENGINE_NAME="Level9"
-IFP_ENGINE_VERSION="4.0"
+IFP_ENGINE_VERSION="4.1"
 
 IFP_ACCEPTOR_OFFSET=0
 IFP_ACCEPTOR_LENGTH=5
--- terps/level9/level9.c
+++ terps/level9/level9.c
@@ -1,10 +1,10 @@
 /***********************************************************************\
 *
 * Level 9 interpreter
-* Version 4.0
+* Version 4.1
 * Copyright (c) 1996 Glen Summers
 * Copyright (c) 2002,2003 Glen Summers and David Kinder
-* Copyright (c) 2005 Glen Summers, David Kinder, Alan Staniforth,
+* Copyright (c) 2005,2007 Glen Summers, David Kinder, Alan Staniforth,
 * Simon Baldwin and Dieter Baron
 *
 * This program is free software; you can redistribute it and/or modify
@@ -115,7 +115,7 @@
 int CheatWord;
 GameState CheatWorkspace;
 
-int reflectflag,scale,gintcolour,option;
+int reflectflag,scale,gintcolour,_option;
 int l9textmode=0,drawx=0,drawy=0,screencalled=0,showtitle=1;
 L9BYTE *gfxa5=NULL;
 L9BOOL scalegfx=TRUE;
@@ -152,7 +152,7 @@
 
 
 #ifdef CODEFOLLOW
-#define CODEFOLLOWFILE "c:\\temp\\output"
+#define CODEFOLLOWFILE "c:\\temp\\level9.txt"
 FILE *f;
 L9UINT16 *cfvar,*cfvar2;
 char *codes[]=
@@ -1780,8 +1780,14 @@
 
 void L9Random(void)
 {
+#ifdef CODEFOLLOW
+	fprintf(f," %d",randomseed);
+#endif
 	randomseed=(((randomseed<<8) + 0x0a - randomseed) <<2) + randomseed + 1;
 	*getvar()=randomseed & 0xff;
+#ifdef CODEFOLLOW
+	fprintf(f," %d",randomseed);
+#endif
 }
 
 void save(void)
@@ -2535,6 +2541,11 @@
 		do
 		{
 			d0=*a0;
+			if (L9GameType==L9_V4)
+			{
+				if ((d0==0) && (*(a0+1)==0))
+					goto notfn4;
+			}
 			a0+=2;
 		}
 		while ((d0&0x80)==0 || --d1);
@@ -2553,6 +2564,7 @@
 	while (((*d4)&0x80)==0);
 
 	/* notfn4 */
+notfn4:
 	d6=exitreversaltable[d6];
 	a0=absdatablock;
 	*d5=1;
@@ -2573,10 +2585,17 @@
 	L9BYTE d4,d5;
 	L9BYTE d7=(L9BYTE) *getvar();
 	L9BYTE d6=(L9BYTE) *getvar();
+#ifdef CODEFOLLOW
+	fprintf(f," d7=%d d6=%d",d7,d6);
+#endif
 	exit1(&d4,&d5,d6,d7);
 
 	*getvar()=(d4&0x70)>>4;
 	*getvar()=d5;
+#ifdef CODEFOLLOW
+	fprintf(f," Var[%d]=%d(d4=%d) Var[%d]=%d",
+		cfvar2-workspace.vartable,(d4&0x70)>>4,d4,cfvar-workspace.vartable,d5);
+#endif
 }
 
 void ifeqvt(void)
@@ -2809,11 +2828,11 @@
 
 #ifdef L9DEBUG
 	printf("gfx - sdraw (%d,%d) (%d,%d) colours %d,%d",
-		x1,y1,drawx,drawy,gintcolour&3,option&3);
+		x1,y1,drawx,drawy,gintcolour&3,_option&3);
 #endif
 
 	os_drawline(scalex(x1),scaley(y1),scalex(drawx),scaley(drawy),
-		gintcolour&3,option&3);
+		gintcolour&3,_option&3);
 }
 
 /* smove instruction plus arguments are stored in an 8 bit word.
@@ -2883,11 +2902,11 @@
 
 #ifdef L9DEBUG
 	printf("gfx - draw (%d,%d) (%d,%d) colours %d,%d",
-		x1,y1,drawx,drawy,gintcolour&3,option&3);
+		x1,y1,drawx,drawy,gintcolour&3,_option&3);
 #endif
 
 	os_drawline(scalex(x1),scaley(y1),scalex(drawx),scaley(drawy),
-		gintcolour&3,option&3);
+		gintcolour&3,_option&3);
 }
 
 /* move instruction plus arguments are stored in a 16 bit word.
@@ -2954,10 +2973,10 @@
 /* fillb */
 
 #ifdef L9DEBUG
-	printf("gfx - gintfill (%d,%d) colours %d,%d",drawx,drawy,d7&3,option&3);
+	printf("gfx - gintfill (%d,%d) colours %d,%d",drawx,drawy,d7&3,_option&3);
 #endif
 
-	os_fill(scalex(drawx),scaley(drawy),d7&3,option&3);
+	os_fill(scalex(drawx),scaley(drawy),d7&3,_option&3);
 }
 
 void gosub(int d7, L9BYTE** a5)
@@ -3021,7 +3040,7 @@
 	if (d0)
 		d0 = (d0&3)|0x80;
 /* optend */
-	option = d0;
+	_option = d0;
 }
 
 void restorescale(void)
@@ -3114,7 +3133,7 @@
 		os_cleargraphics();
 /* gintinit */
 		gintcolour = 3;
-		option = 0x80;
+		_option = 0x80;
 		reflectflag = 0;
 		drawx = 0x1400;
 		drawy = 0x1400;
@@ -4605,13 +4624,31 @@
 	{0x7c, 0x70, 0xda },
 	{0xab, 0xab, 0xab }};
 
+const Colour bitmap_bbc_colours[] = {
+	{0x00, 0x00, 0x00 },
+	{0xff, 0x00, 0x00 },
+	{0x00, 0xff, 0x00 },
+	{0xff, 0xff, 0x00 },
+	{0x00, 0x00, 0xff },
+	{0xff, 0x00, 0xff },
+	{0x00, 0xff, 0xff },
+	{0xff, 0xff, 0xff }};
+
 void bitmap_c64_name(int num, char* dir, char* out)
 {
 	if (num == 0)
-	{
-		FILE* f;
-
 		sprintf(out,"%stitle mpic",dir);
+	else
+		sprintf(out,"%spic%d",dir,num);
+}
+
+void bitmap_bbc_name(int num, char* dir, char* out)
+{
+	FILE* f;
+
+	if (num == 0)
+	{
+		sprintf(out,"%sP.Title",dir);
 		f = fopen(out,"rb");
 		if (f != NULL)
 		{
@@ -4622,15 +4659,17 @@
 		sprintf(out,"%stitle",dir);
 	}
 	else
-		sprintf(out,"%spic%d",dir,num);
-}
-
-void bitmap_bbc_name(int num, char* dir, char* out)
-{
-	if (num == 0)
-		sprintf(out,"%sP.Title",dir);
-	else
+	{
 		sprintf(out,"%sP.Pic%d",dir,num);
+		f = fopen(out,"rb");
+		if (f != NULL)
+		{
+			fclose(f);
+			return;
+		}
+
+		sprintf(out,"%spic%d",dir,num);
+	}
 }
 
 void bitmap_cpc_name(int num, char* dir, char* out)
@@ -4643,6 +4682,25 @@
 		sprintf(out,"%sallpics.pic",dir);
 }
 
+BitmapType bitmap_c64_type(char* file)
+{
+	BitmapType type = C64_BITMAPS;
+
+	FILE* f = fopen(file,"rb");
+	if (f != NULL)
+	{
+		L9UINT32 size = filelength(f);
+		fclose(f);
+
+		if (size == 10048)
+			type = BBC_BITMAPS;
+		if (size == 6494)
+			type = BBC_BITMAPS;
+	}
+
+	return type;
+}
+
 /*
 	The C64 graphics file format is (loosely) based on the layout of
 	C64 graphics memory. There are in fact two formats (i) the
@@ -4656,36 +4714,6 @@
 	no "main" and "sub" images. All game graphics have the same
 	dimensions and each completely replaces its predecessor.
 
-
-	The graphics files used by the BBC B platform are virtually identical
-	to C64 graphics files. I assume that (as with the CPC and
-	Spectrum+3) this choice was made because the BBC mode 2 screen,
-	although more capable than the c64, was nearly the same size
-	(160*256) and displayed roughly the same number of colours. In
-	addition (a) the artwork already existed so no extra expense would
-	be incurred and (b) by accepting the C64's limitation of only four
-	colours in each 4*8 pixel block (but still with sixteen colours on
-	screen) they got a compressed file format allowing more pictures
-	on each disk.
-
-	The file organisation is very close to the C64. The naming system
-	can be the same eg "PIC12", but another form is also used :
-	"P.Pic12". Unlike the C64 the BBC has well defined title images,
-	called "TITLE" or P.Title. All pictures are in separate files.
-
-	The only difference seems to be:
-
-	*	There is either *no* header before the image data or a simple
-	10 byte header which I think *may* be a file system header
-	left in place by the extractor system.
-
-	*	There is an extra 32 bytes following the data at the end of
-	each file. I am almost certain this is palette information for
-	the BBC - probably a C64-BBC colour conversion table because
-	although the Beeb has 16 colours in mode 2, 8 of those are
-	flashing alternates of the other eight.
-
-	
 	The graphics files used on the Amstrad CPC and Spectrum +3 are also
 	virtually identical to C64 graphics files. This choice was presumably
 	made because although the CPC screen was more capable than the c64 it
@@ -4744,26 +4772,6 @@
 			off_bg = 6463;
 			col_comp = 1;
 		}
-		else if (size == 10048) /* BBC title picture */
-		{
-			max_x = 320;
-			max_y = 200;
-			off = 0;
-			off_scr = 8000;
-			off_bg = 9001;
-			off_col = 9016;
-			col_comp = 0;
-		}
-		else if (size == 6494) /* BBC picture */
-		{
-			max_x = 320;
-			max_y = 136;
-			off = 0;
-			off_scr = 5440;
-			off_col = 6120;
-			off_bg = 6461;
-			col_comp = 1;
-		}
 		else
 			return FALSE;
 	}
@@ -4779,6 +4787,16 @@
 			off_col = 9026;
 			col_comp = 0;
 		}
+		else if (size == 10048) /* BBC title picture */
+		{
+			max_x = 320;
+			max_y = 200;
+			off = 0;
+			off_scr = 8000;
+			off_bg = 9001;
+			off_col = 9016;
+			col_comp = 0;
+		}
 		else if (size == 6504) /* BBC picture */
 		{
 			max_x = 320;
@@ -4789,6 +4807,16 @@
 			off_bg = 6471;
 			col_comp = 1;
 		}
+		else if (size == 6494) /* BBC picture */
+		{
+			max_x = 320;
+			max_y = 136;
+			off = 0;
+			off_scr = 5440;
+			off_col = 6120;
+			off_bg = 6461;
+			col_comp = 1;
+		}
 		else
 			return FALSE;
 	}
@@ -4881,6 +4909,142 @@
 	return TRUE;
 }
 
+/*
+	The graphics files used by the BBC B are virtually identical
+	to C64 graphics files. I assume that (as with the CPC and
+	Spectrum+3) this choice was made because the BBC mode 2 screen,
+	was nearly the same size (160*256) and had roughly the same capability
+	as the C64 screen (displays 16 colours, although eight of those ar
+	just the first eight flashing).
+
+	In addition (a) the artwork already existed so no extra expense would
+	be incurred and (b) by accepting the C64's limitation of only four
+	colours in each 4*8 pixel block (but still with sixteen colours on
+	screen) they got a compressed file format allowing more pictures
+	on each disk.
+
+	The file organisation is very close to the C64. The naming system
+	can be the same eg "PIC12", but another form is also used :
+	"P.Pic12". Unlike the C64 the BBC has well defined title images,
+	called "TITLE" or P.Title. All pictures are in separate files.
+
+	The only difference seems to be:
+
+	* There is either *no* header before the image data or a simple
+	10 byte header which I think *may* be a file system header
+	left in place by the extractor system.
+
+	* There is an extra 32 bytes following the data at the end of
+	each file. These bytes encode a table to convert between the 16
+	C64 colours and 16, four-pixel pix-patterns used to let the BBC
+	(with only 8 colours) represent the sixteen possible C64 colours.
+
+	A pix-pattern looks like this:
+
+			 |   Even |   Odd   |
+			 | Column | Column  |
+		-----------------------------
+		Even Row |Pixel 1 | Pixel 2 |
+		---------|--------|---------|
+		Odd Row  |Pixel 3 | Pixel 4 |
+		-----------------------------
+
+	Each of the four pixel *can* be any of the eight BBC Mode 2
+	steady colours. In practice they seem either to be all the
+	same or a simple check of two colours - the pixels in the 
+	odd row being in the reverse order to those in the even row.
+
+	When converting a C64 pixel to a BBC pixel the game uses the
+	value of the C64 pixel as an index into the array of sixteen
+	BBC pix-patterns. The game looks at the selected pattern and
+	chooses the BBC pixel colour thus: if the pixel is in an even
+	numbered row and an even numbered column, it uses Pixel 1 from 
+	the pattern, if in an even row but an odd column, it uses Pixel 3
+	and so on.
+
+	The pix-pattern data is encoded thus: the first sixteen bytes 
+	encode the even row pixels for the patterns, one byte per
+	pattern, and in the same way the second sixteen bytes encode
+	the odd row pixels for each pattern. For example for the 
+	pattern representing C64 colour 0 the even row pixels are encoded 
+	in the first byte and the odd row pixels in the sixteenth byte.
+
+	Within each byte the pixels are encoded in this way:
+
+	Bit		7	6	5	4	3	2	1	0
+	-------------------------------------
+			0	0	1	0	0	1	1	1
+			|	|	|	|	|	|	|	|
+			+---|---+---|---+---|---+---|----- Even Pixel 0101 (5)
+				|		|		|		|
+				+-------+-------+-------+----- Odd Pixel 0011 (3)
+
+	This function calls the C64 decoding routines to do the actual
+	loading. See the comments to that function for details of how the
+	image is encoded and stored.
+*/
+L9BOOL bitmap_bbc_decode(char* file, BitmapType type, int num)
+{
+	unsigned char	patRowData[32];
+	unsigned char patArray[16][2][2];
+	FILE* f;
+	int i,j,k,isOddColumn,isOddRow;
+	L9BYTE pixel;
+
+	if (bitmap_c64_decode(file,type,num) == FALSE)
+		return FALSE;
+
+	f = fopen(file,"rb");
+	if (f == NULL)
+		return FALSE;
+
+	/* Seek to the offset of the pixPat data and read in the data */
+	fseek(f,filelength(f)-32,SEEK_SET);
+	fread(patRowData,sizeof (L9BYTE),32,f);
+	fclose(f);
+
+	/* Extract the patterns */
+	i = 0;
+	for (k = 0; k < 2; k++)
+	{
+		for (j = 0; j < 16; j++)
+		{
+			/* Extract the even col pixel for this pattern row */
+			patArray[j][k][0] =
+				((patRowData[i] >> 4) & 0x8) + ((patRowData[i] >> 3) & 0x4) +
+				((patRowData[i] >> 2) & 0x2) + ((patRowData[i] >> 1) & 0x1);
+			/* Extract the odd col pixel for this pattern row */
+			patArray[j][k][1] =
+				((patRowData[i] >> 3) & 0x8) + ((patRowData[i] >> 2) & 0x4) +
+				((patRowData[i] >> 1) & 0x2) + (patRowData[i] & 0x1);
+			i++;
+		}
+	}
+
+	/* Convert the image. Each BBC pixel is represented by two pixels here */
+	i = 0;
+	isOddRow = 0;
+	for (j = 0; j < bitmap->height; j++)
+	{
+		isOddColumn = 0;
+		for (k = 0; k < bitmap->width/2; k++)
+		{
+			pixel = bitmap->bitmap[i];
+			bitmap->bitmap[i] = patArray[pixel][isOddColumn][isOddRow];
+			bitmap->bitmap[i+1] = patArray[pixel][isOddColumn][isOddRow];
+			isOddColumn ^= 1;
+			i += 2;
+		}
+		isOddRow ^= 1;
+	}
+
+	bitmap->npalette = 8;
+	for (i = 0; i < 8; i++)
+		bitmap->palette[i] = bitmap_bbc_colours[i];
+
+	return TRUE;
+}
+
 BitmapType DetectBitmaps(char* dir)
 {
 	char file[MAX_PATH];
@@ -4895,7 +5059,7 @@
 
 	bitmap_c64_name(2,dir,file);
 	if (bitmap_exists(file))
-		return C64_BITMAPS;
+		return bitmap_c64_type(file);
 
 	bitmap_bbc_name(2,dir,file);
 	if (bitmap_exists(file))
@@ -4944,7 +5108,7 @@
 
 	case BBC_BITMAPS:
 		bitmap_bbc_name(num,dir,file);
-		if (bitmap_c64_decode(file,type,num)) /* Nearly identical to C64 */
+		if (bitmap_bbc_decode(file,type,num))
 			return bitmap;
 		break;
 
openSUSE Build Service is sponsored by