282 lines · 5.5 KB · C
RawDownload
/***********************************************************************\
*
* Level 9 interpreter
* Version 5.1
* Copyright (c) 1996-2011 Glen Summers and contributors.
* Contributions from David Kinder, Alan Staniforth, Simon Baldwin,
* Dieter Baron and Andreas Scherrer.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
*
\***********************************************************************/

#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include "level9.h"

#define TEXTBUFFER_SIZE 10240
char TextBuffer[TEXTBUFFER_SIZE+1];
int TextBufferPtr = 0;

int Column = 0;
#define SCREENWIDTH 76

void os_printchar(char c)
{
	if (c == '\r')
	{
		os_flush();
		putchar('\n');
		Column = 0;
	}
	else if (isprint(c) != 0)
	{
		if (TextBufferPtr >= TEXTBUFFER_SIZE)
			os_flush();
		*(TextBuffer + (TextBufferPtr++)) = c;
	}
}

L9BOOL os_input(char *ibuff, int size)
{
char *nl;

	os_flush();
	fgets(ibuff, size, stdin);
	nl = strchr(ibuff, '\n');
	if (nl)
		*nl = 0;
	return TRUE;
}

char os_readchar(int millis)
{
	static int count = 0;
	char c;

	os_flush();
	if (millis == 0)
		return 0;

	/* Some of the Level 9 games expect to be able to wait for
	   a character for a short while as a way of pausing, and
	   expect 0 to be returned, while the multiple-choice games
	   (such as The Archers) expect 'proper' keys from this
	   routine.

	   To get round this, we return 0 for the first 1024 calls,
	   and 'proper' keys thereafter. Since The Archers and
	   similar games ignore the returned zeros, this works quite
	   well. A 'correct' port would solve this properly by
	   implementing a timed wait for a key, but this is not
	   possible using only C stdio-functions.
	*/
	if (++count < 1024)
		return 0;
	count = 0;

	c = getc(stdin); /* will require enter key as well */
	if (c != '\n')
	{
		while (getc(stdin) != '\n')
		{
			/* unbuffer input until enter key */
		}
	}

	return c;
}

L9BOOL os_stoplist(void)
{
	return FALSE;
}

void os_flush(void)
{
int ptr, space, lastspace, searching;

	if (TextBufferPtr < 1)
		return;

	*(TextBuffer+TextBufferPtr) = ' ';
	ptr = 0;
	while (TextBufferPtr + Column > SCREENWIDTH)
	{
		space = ptr;
		lastspace = space;
		searching = 1;
		while (searching)
		{
			while (TextBuffer[space] != ' ')
				space++;
			if (space - ptr + Column > SCREENWIDTH)
			{
				space = lastspace;
				printf("%.*s\n", space - ptr, TextBuffer + ptr);
				Column = 0;
				space++;
				if (TextBuffer[space] == ' ')
					space++;
				TextBufferPtr -= (space - ptr);
				ptr = space;
				searching = 0;
			}
			else
				lastspace = space;
			space++;
		}
	}
	if (TextBufferPtr > 0)
	{
		printf("%.*s", TextBufferPtr, TextBuffer + ptr);
		Column += TextBufferPtr;
	}
	TextBufferPtr = 0;
}

L9BOOL os_save_file(L9BYTE * Ptr, int Bytes)
{
char name[256];
char *nl;
FILE *f;

	os_flush();
	printf("Save file: ");
	fgets(name, 256, stdin);
	nl = strchr(name, '\n');
	if (nl)
		*nl = 0;
	f = fopen(name, "wb");
	if (!f)
		return FALSE;
	fwrite(Ptr, 1, Bytes, f);
	fclose(f);
	return TRUE;
}

L9BOOL os_load_file(L9BYTE *Ptr,int *Bytes,int Max)
{
char name[256];
char *nl;
FILE *f;

	os_flush();
	printf("Load file: ");
	fgets(name, 256, stdin);
	nl = strchr(name, '\n');
	if (nl)
		*nl = 0;
	f = fopen(name, "rb");
	if (!f)
		return FALSE;
	*Bytes = fread(Ptr, 1, Max, f);
	fclose(f);
	return TRUE;
}

L9BOOL os_get_game_file(char *NewName,int Size)
{
char *nl;

	os_flush();
	printf("Load next game: ");
	fgets(NewName, Size, stdin);
	nl = strchr(NewName, '\n');
	if (nl)
		*nl = 0;
	return TRUE;
}

void os_set_filenumber(char *NewName,int Size,int n)
{
char *p;
int i;

#if defined(_Windows) || defined(__MSDOS__) || defined (_WIN32) || defined (__WIN32__)
	p = strrchr(NewName,'\\');
#else
	p = strrchr(NewName,'/');
#endif
	if (p == NULL)
		p = NewName;
	for (i = strlen(p)-1; i >= 0; i--)
	{
		if (isdigit(p[i]))
		{
			p[i] = '0'+n;
			return;
		}
	}
}

void os_graphics(int mode)
{
}

void os_cleargraphics(void)
{
}

void os_setcolour(int colour, int index)
{
}

void os_drawline(int x1, int y1, int x2, int y2, int colour1, int colour2)
{
}

void os_fill(int x, int y, int colour1, int colour2)
{
}

void os_show_bitmap(int pic, int x, int y)
{
}

FILE* os_open_script_file(void)
{
char name[256];
char *nl;

	os_flush();
	printf("Script file: ");
	fgets(name, 256, stdin);
	nl = strchr(name, '\n');
	if (nl)
		*nl = 0;
	return fopen(name, "rt");
}

int main(int argc, char **argv)
{
	printf("Level 9 Interpreter\n\n");
	if (argc != 2)
	{
		printf("Use: %s <gamefile>\n",argv[0]);
		return 0;
	}
	if (!LoadGame(argv[1],NULL))
	{
		printf("Error: Unable to open game file\n");
		return 0;
	}
	while (RunGame());
	StopGame();
	FreeMemory();
	return 0;
}