Article View: alt.graphics.pixutils
Article #708new version of dltogl
From: George Phillips
Date: Thu, 03 Oct 1991 17:16
Date: Thu, 03 Oct 1991 17:16
471 lines
10670 bytes
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!phillipsShow 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