🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: alt.graphics.pixutils
Article #708

new version of dltogl

#708
From: George Phillips
Date: Thu, 03 Oct 1991 17:16
471 lines
10670 bytes
Here's a new version of my .DL animation to .GL animation converter.
It now converts both version 1 and version 2 .DL files (it only did
version 2 before; thanks to Neil Nelson for sending me some version
1 files to dissect).  I also minorly cleaned up the code and fixed
a stupid typo that made the program say it was "gltodl".

For you PC users who lack the C compiler or savvy to compile this,
ftp to cs.ubc.ca and grab pc/dltogl.zip which contains the source
code along with a ready-to-run dltogl.exe.  I use grasprt version
4.10beta to display the .GL files on my PC.  I've heard of some
trouble with earlier versions so beware.  Not that you'd want to
bother as there already is a .DL viewer for PCs.


#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	dltogl.c
# This archive created: Thu Oct  3 01:41:04 1991
export PATH; PATH=/bin:$PATH
if test -f 'dltogl.c'
then
	echo shar: will not over-write existing file "'dltogl.c'"
else
cat << \SHAR_EOF > 'dltogl.c'
/*
 * dltogl.c -- convert .DL animations into .GL animations.
 *
 * usage: dltogl file.dl [file.gl]
 *
 * If no .gl file is specified, the images and control file will be
 * written to separate files.  The control file will always be "dl.txt",
 * the images "clpN.clp" and a palette file called "palette.pic".
 *
 * If you compile it under Turbo C, you should use the compact memory model.
 *
 * Author:
 *	George Phillips
 *	<phillips@cs.ubc.ca>
 */

#include <stdio.h>
#ifdef __TURBOC__
#include <alloc.h>
#define FOWB	"wb"
#define FORB	"rb"
#else
extern char* malloc();
#define FOWB	"w"
#define FORB	"r"
#endif

FILE*	gl;
int		gl_fileno;

FILE* file_open();
int file_close();

#define isneg16(x)	((x) & 0x8000)
#define neg16(x)	((~(x) + 1) & 0x7fff)

main(argc, argv)
int		argc;
char*	argv[];
{
	unsigned int i, j;
	FILE* fp;
	int num_scrn;
	int ctl_len;
	int ch;
	int format;
	static char title[21];
	static char author[21];
	static unsigned char pal[256*3];
	unsigned char* screen;
	static unsigned char halfscreen[160*100];
	static char fname[32];
	int picnum;
	int images_per_screen;
	FILE* ctl;
	int fx, fy;
	int* cmd;
	int labelpos;
	int cmdnum;
	int version;

	if (argc != 2 && argc != 3)
		die("usage: dltogl file.dl [file.gl]");

	if (!(fp = fopen(argv[1], FORB))) {
		fprintf(stderr, "dltogl: can't open %s\n", argv[1]);
		exit(1);
	}

	gl = 0;
	gl_fileno = 0;
	if (argc == 3 && !(gl = fopen(argv[2], FOWB))) {
		fprintf(stderr, "dltogl: can't open %s for writing\n", argv[2]);
		exit(1);
	}

	switch (version = fgetc(fp)) {
	case 1: case 2: break;
	default:
		fprintf("dltogl: this .DL is version %d, I can only do 1 and 2.\n",
			version);
		exit(1);
	}

	if (version == 1)
		format = 1;
	else
		format = fgetc(fp);

	switch (format) {
	case 0:
		fx = fy = 0;
		images_per_screen = 1;
		break;
	case 1:
		fx = 80;
		fy = 50;
		images_per_screen = 4;
		break;
	default:
		die("dltogl: only large and medium formats are handled");
		break;
	}

	title[20] = author[20] = 0;
	for (i = 0; i < 20; i++)
		title[i] = fgetc(fp) ^ 255;

	for (i = 0; i < 20; i++)
		if (version == 2)
			author[i] = fgetc(fp) ^ 255;
		else
			author[i] = 255;

	for (i = 0; i < 20; i++) {
		if ((unsigned char)title[i] == 255) title[i] = 0;
		if ((unsigned char)author[i] == 255) author[i] = 0;
	}

	num_scrn = fgetc(fp);
	ctl_len = fgetc(fp);

	printf("%s is a version %d .DL file with %d images in a %d frame loop\n",
		argv[1], version, num_scrn * (format * 3 + 1), ctl_len);

	if (!(cmd = (int*)malloc(ctl_len * sizeof(int))))
		die("dltogl: out of memory");

	gl_numfiles(num_scrn * images_per_screen + 1 + 1);

	/* mebbe this is the border colour? */
	if (version == 2)
		for (i = 0; i < 3; i++)
			fgetc(fp);
	else
		fgetc(fp);

	for (i = 0; i < 256; i++) {
		pal[i*3] = fgetc(fp);
		pal[i*3+1] = fgetc(fp);
		pal[i*3+2] = fgetc(fp);
	}

	if (!(screen = (unsigned char*)malloc(320 * 200)))
		die("dltogl: not enough memory.");

	memset(screen, 0, 320 * 200);
	writepic(screen, 320, 200, "palette.pic", pal);

	picnum = 0;
	for (j = 0; j < num_scrn; j++) {
		fread(screen, 320 * 200, 1, fp);
		switch (format) {
		case 0: /* large */
			sprintf(fname, "clp%d.clp", picnum++);
			writepic(screen, 320, 200, fname, (unsigned char*)0);
			break;
		case 1: /* medium */
			for (i = 0; i < 4; i++) {
				unsigned char*	src;
				unsigned char*	dst;
				int				row;
				int				col;

				sprintf(fname, "clp%d.clp", picnum++);
				src = screen + (i % 2) * 160 + (i / 2) * 100 * 320;
				dst = halfscreen;
				for (row = 0; row < 100; row++) {
					for (col = 0; col < 160; col++)
						*dst++ = *src++;
					src += 160;
				}
				writepic(halfscreen, 160, 100, fname, (unsigned char*)0);
			}
		}
	}

	ctl = file_open("dl.txt", FOWB);

	fprintf(ctl, "; This GL file was converted from DL format by dltogl\r\n");
	fprintf(ctl, "; Title:  %s\r\n", title);
	fprintf(ctl, "; Author: %s\r\n", author);
	/* could print all the other keeno information */

	fprintf(ctl, "video l\r\n");
	fprintf(ctl, "pload palette,1\r\n");
	fprintf(ctl, "palette 1\r\n");
	fprintf(ctl, "pfree 1\r\n");
	for (i = 0; i < num_scrn * images_per_screen; i++)
		fprintf(ctl, "cload clp%d,%d\r\n", i, i + 1);

	for (i = 0; i < ctl_len; i++) {
		if (version == 2) {
			j = fgetc(fp);
			j += fgetc(fp) << 8;
			cmd[i] = j;
		}
		else {
			j = fgetc(fp);
			cmd[i] = (j % 10) - 1 + ((j / 10) - 1) * 4;
		}
	}

	labelpos = 0;
	if (isneg16(cmd[ctl_len - 1])) {
		labelpos = neg16(cmd[ctl_len - 1]) + 1;
		ctl_len--;	/* ignore that last command */
	}

	for (i = 0, cmdnum = 0; i < ctl_len; i++, cmdnum++) {
		if (cmdnum == labelpos)
			fprintf(ctl, "forever:\r\n");
		if (isneg16(cmd[i])) {
			i++;
			fprintf(ctl, "waitkey %d\r\n", cmd[i]);
		}
		else
			fprintf(ctl, "putup %d,%d,%d,10\r\n", fx, fy, cmd[i] + 1);
	}
	fprintf(ctl, "goto forever\r\n");
	fputc(26, ctl);
	file_close(ctl);

	fclose(fp);

	if (gl)
		fclose(gl);

	exit(0);
}

die(s)char*s;{fprintf(stderr,"%s\n",s);exit(1);}

#define BLOCKSIZE	(8192)

writepic(pixel, width, height, filename, cmap)
unsigned char* pixel;
int	width;
int	height;
char* filename;
unsigned char* cmap;
{
	FILE*	fp;
	unsigned int i;
	static unsigned char buf[BLOCKSIZE];
	unsigned char* p;
	int row, col;

	fp = file_open(filename, FOWB);

	/* write header */
	writeshort(fp, 0x1234);	/* magic number */
	writeshort(fp, width);
	writeshort(fp, height);
	writeshort(fp, 0);
	writeshort(fp, 0);
	fputc(8, fp);						/* bits per pixel */
	fputc(0xff, fp);					/* byte here is always 255 */
	fputc('L', fp);						/* video mode */
	if (cmap) {
		writeshort(fp, 4);		/* extra information descriptor */
		writeshort(fp, 768);	/* extra information length */
		fwrite(cmap, 768, 1, fp);
	}
	else {
		writeshort(fp, 0);
		writeshort(fp, 0);
	}

	/* number of packed blocks in file */
	writeshort(fp, ((long)width * height + BLOCKSIZE - 1) / BLOCKSIZE);

	i = 0;
	for (row = height - 1; row >= 0; row--) {
		p = pixel + row * width;
		for (col = 0; col < width; col++) {
			buf[i++] = *p++;
			if (i == BLOCKSIZE) {
				outpackblock(fp, buf, i);
				i = 0;
			}
		}
	}
	if (i > 0)
		outpackblock(fp, buf, i);

	file_close(fp);
}

outpackblock(fp, buf, len)
FILE*	fp;
char*	buf;
int	len;
{
	static char	packbuf[BLOCKSIZE * 4 - 1];	/* overkill */
	int	packlen;

	packlen = packblock(buf, packbuf, len);
	fwrite(packbuf, packlen, 1, fp);
}

packblock(src, dest, len)
unsigned char*	src;
unsigned char*	dest;
int				len;
{
	unsigned char*	s;
	unsigned char*	r;
	unsigned char*	d;
	static int	overhead[256];
	int	i;
	int	esc;
	int	escpresent;
	int	minover;
	int	packlen;

	for (i = 0; i < 256; i++)
		overhead[i] = 0;

	/* do first pass to find optimal esc byte */
	for (s = src; s < src + len; s = r) {
		for (r = s; *r == *s && r < src + len; r++)
			;
		if (r - s < 4)
			overhead[*s]++;
	}

	minover = len + 1;
	for (i = 0; i < 256; i++) {
		if (overhead[i] < minover) {
			minover = overhead[i];
			esc = i;
		}
	}
	escpresent = overhead[esc] == 0;

	/* now run-length encode on the second pass */

	d = dest + 5;
	for (s = src; s < src + len; s = r) {
		for (r = s; *r == *s && r < src + len; r++)
			;
		if (r - s < 4 && (!escpresent || *s != esc)) {
			while (s < r)
				*d++ = *s++;
		}
		else {
			if (r - s > 255) {
				*d++ = esc;
				*d++ = 0;
				*d++ = (r - s) & 0xff;
				*d++ = ((r - s) >> 8) & 0xff;
				*d++ = *s++;
			}
			else {
				*d++ = esc;
				*d++ = r - s;
				*d++ = *s++;
			}
		}
	}

	packlen = d - dest;

	/* fill in the block header */

	*dest++ = packlen & 0xff;			/* packed block size */
	*dest++ = ((packlen) >> 8) & 0xff;
	*dest++ = len & 0xff;
	*dest++ = (len >> 8) & 0xff;		/* unpacked block size */
	*dest++ = esc;						/* escape byte */

	return packlen;
}

writeshort(fp, s)
FILE*	fp;
int		s;
{
	fputc(s & 255, fp);
	fputc((s >> 8) & 255, fp);
}

writelong(fp, l)
FILE*	fp;
long	l;
{
	fputc(l & 255, fp);
	fputc((l >> 8) & 255, fp);
	fputc((l >> 16) & 255, fp);
	fputc((l >> 24) & 255, fp);
}

long gl_eof;
long gl_filestart;

gl_numfiles(n)
int	n;
{
	if (gl) {
		fseek(gl, 0, 0);
		writeshort(gl, n * 17);
		gl_eof = 2 + n * 17;
	}
}

FILE* file_open(name, mode)
char*	name;
char*	mode;
{
	FILE*	fp;
	char	fname[14];

	if (!gl) {
		if (!(fp = fopen(name, mode))) {
			fprintf(stderr, "dltogl: can't open %s\n", name);
			exit(1);
		}
		return fp;
	}

	fseek(gl, 2 + gl_fileno++ * 17, 0);
	writelong(gl, gl_eof);
	memset(fname, 0, 13);
	strcpy(fname, name);
	fwrite(fname, 13, 1, gl);
	fseek(gl, gl_filestart = gl_eof + 4, 0);
	return gl;
}

int file_close(fp)
FILE*	fp;
{
	if (!gl)
		return fclose(fp);

	gl_eof = ftell(gl);
	fseek(gl, gl_filestart - 4, 0);
	writelong(gl, gl_eof - gl_filestart);
}
SHAR_EOF
fi # end of overwriting check
#	End of shell archive
exit 0
Technical Details
Message-ID: <1991Oct3.171650.1965@cs.ubc.ca>
Path: arc1-ca.pugleaf.net!wupost!tulane!ukma!aunro!alberta!ubc-cs!phillips

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!wupost!tulane!ukma!aunro!alberta!ubc-cs!phillips
From: phillips@cs.ubc.ca (George Phillips)
Newsgroups: alt.graphics.pixutils,alt.sources
Subject: new version of dltogl
Message-ID: <1991Oct3.171650.1965@cs.ubc.ca>
Date: 3 Oct 91 17:16:50 GMT
Sender: phillips@cs.ubc.ca (George Phillips)
Organization: Computer Science, University of B.C., Vancouver, B.C., Canada
Lines: 471