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

📄 makemap.cpp

📁 空战游戏flacon源码
💻 CPP
字号:
//--------------------------------------

/*

  MakeMap - Terrain map tool

  Created by Erick Jap   November 5, 1996
  Copyright Spectrum Holobyte, Inc.

*/

//--------------------------------------

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <io.h>
#include <sys\stat.h>

//--------------------------------------

#define	HAS_DATA_DIMENSION		0x01
#define	HAS_WINDOW_DIMENSION		0x02

#define	HASH_ELEMENT_SIZE		4
#define	HASH_MAX_SIZE			16

//--------------------------------------

struct ElementList {
	int element, counter;
	ElementList *previous;
	ElementList *next;
};

ElementList *HashRow[HASH_MAX_SIZE], *HashCol[HASH_MAX_SIZE];

#pragma pack (push, 1)
struct PCXHEADER {
	char	manufacturer, version, encoding, bits_per_pixel;
	short	xmin, ymin, xmax, ymax, hres, vres;
	char  	palette[48], reserved, colour_planes;
	short 	bytes_per_line, palette_type;
	char  	filler[58];
};
#pragma pack (pop)

//--------------------------------------

void ConcatFileExtension (char *newfile, char *oldfile, char *ext);
void SavePCX (char *file);
int packImageRow (unsigned char *image, unsigned char *out, int total);
int countbyte (unsigned char *image, int width);
void DeleteHashTable (ElementList **hash);
void DuplicateHashTable (ElementList **hash, ElementList **duphash);
int InsertElement (ElementList **list, int element);
int DeleteElement (ElementList **list, int element);
void DuplicateListElement (ElementList **list, ElementList **duplist);
int CreateTileListElement (ElementList **list);
int InsertTileRowElement (ElementList **list, int counter, unsigned short *buff, int width);
int DeleteTileRowElement (ElementList **list, int counter, unsigned short *buff, int width);
int InsertTileColElement (ElementList **list, int counter, unsigned short *buff, int height);
int DeleteTileColElement (ElementList **list, int counter, unsigned short *buff, int height);

int	datawidth, dataheight;
int	windowwidth, windowheight;
unsigned short *databuffer;
unsigned char  *mapbuffer;
int totalimagebytes;

void main (int argc, char *argv[])
{
	if (argc < 2) {
		puts ("\nMakeMap v1.0 by Erick Jap\n");
		puts ("Usage: MakeMap mapfile -d width height -w width height [-oOutput]");
		puts ("where: mapfile is map file data to be used");
		puts ("       -oOutput use 'Output' as the output file");
		puts ("       -d width height indicate map dimension");
		puts ("       -w width height indicate sliding window dimension");
		puts ("Note: - Sliding window dimension must be less than the data dimension");
		exit (1);
	}
	int i, j, flag;

	char output[256];
	ConcatFileExtension (output, argv[1], "PCX");

	flag = 0;
	for (i=2;i < argc;i++) {
		if (argv[i][0] == '-') {
			if (argv[i][1] == 'd' || argv[i][1] == 'D') {
				flag |= HAS_DATA_DIMENSION;
				datawidth = atoi(argv[++i]);
				dataheight = atoi(argv[++i]);
			}
			else if (argv[i][1] == 'w' || argv[i][1] == 'W') {
				flag |= HAS_WINDOW_DIMENSION;
				windowwidth = atoi(argv[++i]);
				windowheight = atoi(argv[++i]);
			}
			else if (argv[i][1] == 'o' || argv[i][1] == 'O') {
				ConcatFileExtension (output, &(argv[i][2]), "PCX");
			}
		}
	}

	if (!(flag & HAS_DATA_DIMENSION)) {
		puts ("You forget to enter the map dimension!");
		exit (1);
	}
	if (!(flag & HAS_WINDOW_DIMENSION)) {
		puts ("You forget to enter the sliding window dimension!");
		exit (1);
	}

	if (windowwidth > datawidth) {
		puts ("Sliding window width must be less than the width of the map!");
		exit (1);
	}
	if (windowheight > dataheight) {
		puts ("Sliding window height must be less than the height of the map!");
		exit (1);
	}

	if (datawidth & 1) {
		puts ("The width of the map must be an even number!");
		exit (1);
	}

	j = datawidth * dataheight;
	i = j << 1;
	mapbuffer = (unsigned char *) malloc (i+j);
	if (!mapbuffer) {
		printf ("Can not allocate memory to load map data!\n");
		exit (1);
	}
	databuffer = (unsigned short *) (mapbuffer + j);
	int infile = open (argv[1], O_BINARY | O_RDONLY);
	if (!infile) {
		printf ("Can not open map file %s\n", argv[1]);
		free (mapbuffer);
		exit (1);
	}
	read (infile, (char *) databuffer, i);
	close (infile);

	int numwidth = datawidth - windowwidth + 1;
	int numheight = dataheight - windowheight + 1;

	memset (HashRow, 0, HASH_MAX_SIZE * sizeof (ElementList *));
	int totaltile = CreateTileListElement (HashRow);
	unsigned short *buff = databuffer;
	unsigned char  *curmap = mapbuffer;
	int winheight;
	for (i=0; i< dataheight; i++) {
		if (i < (numheight - 1)) winheight = windowheight;
		else winheight = dataheight - i;
		DuplicateHashTable (HashRow, HashCol);
		int curtile = totaltile;
		for (j=0; j< datawidth; j++) {
			unsigned int k = 255;
			if (curtile <= 256) k = curtile-1;
			*curmap++ = k;
			if (j < (numwidth - 1)) {
				curtile = InsertTileColElement (HashCol, curtile, &(buff[j+windowwidth]), winheight);
				curtile = DeleteTileColElement (HashCol, curtile, &(buff[j]), winheight);
			}
			else {
				curtile = DeleteTileColElement (HashCol, curtile, &(buff[j]), winheight);
			}
		}
		if (i < (numheight - 1)) {
			totaltile = InsertTileRowElement (HashRow, totaltile, buff + datawidth*windowheight, windowwidth);
			totaltile = DeleteTileRowElement (HashRow, totaltile, buff, windowwidth);
		}
		else {
			totaltile = DeleteTileRowElement (HashRow, totaltile, buff, windowwidth);
		}
		buff += datawidth;
		DeleteHashTable (HashCol);
	}
	DeleteHashTable (HashRow);

	totalimagebytes = 0;
	curmap = mapbuffer;
	for (i=0; i< dataheight; i++) {
		unsigned char *databuf = (unsigned char *) databuffer;
		databuf += totalimagebytes;
		totalimagebytes = packImageRow (curmap, 
										(unsigned char *) databuf, 
										totalimagebytes);
		curmap += datawidth;
	}

	SavePCX (output);

	free (mapbuffer);
}

void ConcatFileExtension (char *newfile, char *oldfile, char *ext)
{
	char prevchar, currchar, nextchar;

	prevchar = '.';
	while (*oldfile != 0) {
		currchar = *oldfile++;
		nextchar = *oldfile;
		if (currchar == '.' && 
			((prevchar != '.' && prevchar != '\\') ||
			 (nextchar != '.' && nextchar != '\\'))) break;
		prevchar = currchar;
		*newfile++ = currchar;
	}
	*newfile++ = '.';
	while (*ext) *newfile++ = *ext++;
	*newfile = 0;
}

void SavePCX (char *file)
{
	PCXHEADER pcx;
	memset ((char *) &pcx, 0, sizeof (PCXHEADER));
	pcx.manufacturer = 10;
	pcx.version = 5;
	pcx.encoding = 1;
	pcx.bits_per_pixel = 8;
	pcx.xmin = 0;
	pcx.ymin = 0;
	pcx.xmax = datawidth - 1;
	pcx.ymax = dataheight - 1;
	pcx.hres = 640;
	pcx.vres = 480;
	pcx.colour_planes = 1;
	pcx.bytes_per_line = datawidth;
	pcx.palette[0] = (char) 0;
	pcx.palette[1] = (char) 0;
	pcx.palette[2] = (char) 0;
	pcx.palette[3] = (char) 0;
	pcx.palette[4] = (char) 0;
	pcx.palette[5] = (char) 0xaa;
	pcx.palette[6] = (char) 0;
	pcx.palette[7] = (char) 0xaa;
	pcx.palette[8] = (char) 0;
	pcx.palette[9] = (char) 0;
	pcx.palette[10] = (char) 0xaa;
	pcx.palette[11] = (char) 0xaa;
	pcx.palette[12] = (char) 0xaa;
	pcx.palette[13] = (char) 0;
	pcx.palette[14] = (char) 0;
	pcx.palette[15] = (char) 0xaa;
	pcx.palette[16] = (char) 0;
	pcx.palette[17] = (char) 0xaa;
	pcx.palette[18] = (char) 0xaa;
	pcx.palette[19] = (char) 0xaa;
	pcx.palette[20] = (char) 0;
	pcx.palette[21] = (char) 0xaa;
	pcx.palette[22] = (char) 0xaa;
	pcx.palette[23] = (char) 0xaa;
	pcx.palette[24] = (char) 0x55;
	pcx.palette[25] = (char) 0x55;
	pcx.palette[26] = (char) 0x55;
	pcx.palette[27] = (char) 0x55;
	pcx.palette[28] = (char) 0x55;
	pcx.palette[29] = (char) 0xff;
	pcx.palette[30] = (char) 0x55;
	pcx.palette[31] = (char) 0xff;
	pcx.palette[32] = (char) 0x55;
	pcx.palette[33] = (char) 0x55;
	pcx.palette[34] = (char) 0xff;
	pcx.palette[35] = (char) 0xff;
	pcx.palette[36] = (char) 0xff;
	pcx.palette[37] = (char) 0x55;
	pcx.palette[38] = (char) 0x55;
	pcx.palette[39] = (char) 0xff;
	pcx.palette[40] = (char) 0x55;
	pcx.palette[41] = (char) 0xff;
	pcx.palette[42] = (char) 0xff;
	pcx.palette[43] = (char) 0xff;
	pcx.palette[44] = (char) 0x55;
	pcx.palette[45] = (char) 0xff;
	pcx.palette[46] = (char) 0xff;
	pcx.palette[47] = (char) 0xff;

	char palette[769];
	int  i, j;
	palette[0] = 0xc;
	j = 1;
	for (i=0; i < 256; i++) {
		palette[j++] = i;
		palette[j++] = i;
		palette[j++] = i;
	}

	int outfile = open (file, O_BINARY | O_CREAT | O_RDWR, S_IWRITE);
	write (outfile, (char *) &pcx, sizeof (PCXHEADER));
	write (outfile, (char *) databuffer, totalimagebytes);
	write (outfile, (char *) &palette, 769);
}

int countbyte (unsigned char *image, int width)
{
	int i, j;
	unsigned char c = *image;
	j = 0;
	for (i=0; i < width; i++) {
		if (c != *image) break;
		j++;
		image++;
	}
	return j;
}

int packImageRow (unsigned char *image, unsigned char *out, int total)
{
	int	i, j, k;

	i = 0;
	while (i < datawidth) {
		j = countbyte (image, datawidth-i);
		unsigned char c = *image;
		if (j > 1) {
			k = j;
			while (k > 63) {
				*out++ = 0xff;
				*out++ = c;
				k -= 63;
				total += 2;
			}
			if (k > 0) {
				*out++ = k | 0xc0;
				*out++ = c;
				total += 2;
			}
		}
		else {
			*out++ = c;
			total++;
		}
		i += j;
		image += j;
	}
	return total;
}

int CreateTileListElement (ElementList **list)
{
	int i, j;
	int counter = 0;
	unsigned short *buff = databuffer;
	for (i=0;i < windowheight; i++) {
		for (j=0;j < windowwidth; j++) {
			counter += InsertElement (list, (unsigned int) buff[j]);
		}
		buff += datawidth;
	}
	return counter;
}

int InsertTileRowElement (ElementList **list, int counter, unsigned short *buff, int winwidth)
{
	int i;
	for (i=0;i < winwidth; i++) {
		counter += InsertElement (list, (unsigned int) buff[i]);
	}
	return counter;
}

int DeleteTileRowElement (ElementList **list, int counter, unsigned short *buff, int winwidth)
{
	int i;
	for (i=0;i < winwidth; i++) {
		counter -= DeleteElement (list, (unsigned int) buff[i]);
	}
	return counter;
}

int InsertTileColElement (ElementList **list, int counter, unsigned short *buff, int winheight)
{
	int i;
	for (i=0;i < winheight; i++) {
		counter += InsertElement (list, (unsigned int) *buff);
		buff += datawidth;
	}
	return counter;
}

int DeleteTileColElement (ElementList **list, int counter, unsigned short *buff, int winheight)
{
	int i;
	for (i=0;i < winheight; i++) {
		counter -= DeleteElement (list, (unsigned int) *buff);
		buff += datawidth;
	}
	return counter;
}

void DeleteHashTable (ElementList **hash)
{
	int i;
	for (i=0; i < HASH_MAX_SIZE;i++) {
		ElementList *listElement = hash[i];
		while (listElement) {
			ElementList *curList = listElement;
			listElement = listElement -> next;
			free (curList);
		}
	}
}

void DuplicateHashTable (ElementList **hash, ElementList **duphash)
{
	int i;
	for (i=0; i < HASH_MAX_SIZE;i++) {
		duphash[i] = 0;
		if (hash[i]) DuplicateListElement (&(hash[i]), &(duphash[i]));
	}
}

void DuplicateListElement (ElementList **list, ElementList **duplist)
{
	ElementList *listElement = *list;
	ElementList *curElement = 0;
	while (listElement) {
		ElementList *newList = (ElementList *) malloc (sizeof(ElementList));
		if (!newList) {
			puts ("Unable to allocate memory for a new element");
			exit (1);
		}
		newList -> element = listElement -> element;
		newList -> counter = listElement -> counter;
		newList -> next = 0;
		newList -> previous = curElement;
		if (curElement) curElement -> next = newList;
		else *duplist = newList;
		curElement = newList;
		listElement = listElement -> next;
	}
}

inline int GetHashIndex (int element)
{
	int hashindex = element >> HASH_ELEMENT_SIZE;
	if (hashindex >= HASH_MAX_SIZE) hashindex = HASH_MAX_SIZE-1;
	return hashindex;
}

int InsertElement (ElementList **list, int element)
{
	int hashindex = GetHashIndex (element);

	ElementList *listElement = list[hashindex];
	ElementList *prevElement = 0;
	while (listElement) {
		if (listElement -> element == element) {
			listElement -> counter++;
			return 0;
		}
		else if (listElement -> element > element) break;
		prevElement = listElement;
		listElement = listElement -> next;
	}
	ElementList *newElement = (ElementList *) malloc (sizeof(ElementList));
	if (!newElement) {
		puts ("Unable to allocate memory for a new element");
		exit (1);
	}
	newElement -> element = element;
	newElement -> counter = 1;
	newElement -> previous = 0;
	newElement -> next = 0;

	if (listElement) {
		if (prevElement) {
			newElement -> previous = prevElement;
			prevElement -> next = newElement;
		}
		else list[hashindex] = newElement;
		listElement -> previous = newElement;
		newElement -> next = listElement;
	}
	else {
		if (prevElement) {
			prevElement -> next = newElement;
			newElement -> previous = prevElement;
		}
		else list[hashindex] = newElement;
	}

	return 1;
}

int DeleteElement (ElementList **list, int element)
{
	int hashindex = GetHashIndex (element);

	ElementList *listElement = list[hashindex];
	while (listElement) {
		if (listElement -> element == element) {
			listElement -> counter--;
			if (listElement -> counter) return 0;
			else {
				if (listElement -> previous) {
					listElement -> previous -> next = listElement -> next;
					if (listElement -> next)
						listElement -> next -> previous = listElement -> previous;
				}
				else {
					list[hashindex] = listElement -> next;
					if (listElement -> next) listElement -> next -> previous = 0;
				}
				free (listElement);
				return 1;
			}
		}
		listElement = listElement -> next;
	}
	puts ("Unable to remove the element from the list");
	exit (1);
	return 0;
}

⌨️ 快捷键说明

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