Files
nethack/win/gem/load_img.c
Sean Hunt 97d6fade74 Reformat all C files.
I'll push a formatting guide at some point. There may still be
outstanding changes, but please feel free to resolve those as you arrive
a them.

To the best of my knowledge, there is no changes to the actual code
content, but the formatter does have the occasional bug. If you run into
an issue, please fix it!
2015-05-09 13:43:16 -04:00

323 lines
9.2 KiB
C

/*
* $NHDT-Date: 1431192775 2015/05/09 17:32:55 $ $NHDT-Branch: master $:$NHDT-Revision: 1.4 $
* $Date: 2002/03/20 03:45:03 $ $Revision: 1.2 $
*/
#define __TCC_COMPAT__
#include <stdio.h>
#include <string.h>
#include <osbind.h>
#include <memory.h>
#include <aesbind.h>
#include <vdibind.h>
#include <gemfast.h>
#include <e_gem.h>
#include "load_img.h"
#ifndef FALSE
#define FALSE 0
#define TRUE !FALSE
#endif
/* VDI <-> Device palette order conversion matrixes: */
/* Four-plane vdi-device */
int vdi2dev4[] = { 0, 15, 1, 2, 4, 6, 3, 5, 7, 8, 9, 10, 12, 14, 11, 13 };
/* Two-plane vdi-device */
int vdi2dev2[] = { 0, 3, 1, 2 };
void
get_colors(int handle, short *palette, int col)
{
int i, idx;
/* get current color palette */
for (i = 0; i < col; i++) {
/* device->vdi->device palette order */
switch (planes) {
case 1:
idx = i;
break;
case 2:
idx = vdi2dev2[i];
break;
case 4:
idx = vdi2dev4[i];
break;
default:
if (i < 16)
idx = vdi2dev4[i];
else
idx = i == 255 ? 1 : i;
}
vq_color(handle, i, 0, (int *) palette + idx * 3);
}
}
void
img_set_colors(int handle, short *palette, int col)
{
int i, idx, end;
/* set color palette */
end = min(1 << col, 1 << planes);
for (i = 0; i < end; i++) {
switch (planes) { /* MAR -- war col 10.01.2001 */
case 1:
idx = i;
break;
case 2:
idx = vdi2dev2[i];
break;
case 4:
idx = vdi2dev4[i];
break;
default:
if (i < 16)
idx = vdi2dev4[i];
else
idx = i == 255 ? 1 : i;
}
vs_color(handle, i, (int *) palette + idx * 3);
}
}
int
convert(MFDB *image, long size)
{
int plane, mplanes;
char *line_addr, *buf_addr, *new_addr, *new1_addr, *image_addr,
*screen_addr;
MFDB dev_form, tmp;
long new_size;
/* convert size from words to bytes */
size <<= 1;
/* memory for the device raster */
new_size = size * (long) planes;
if ((new_addr = (char *) calloc(1, new_size)) == NULL)
return (FALSE);
/* initialize MFDBs */
tmp = *image;
tmp.fd_nplanes = planes;
tmp.fd_addr = new_addr;
tmp.fd_stand = 1; /* standard format */
dev_form = tmp;
screen_addr = new_addr;
dev_form.fd_stand = 0; /* device format */
image_addr = (char *) image->fd_addr;
/* initialize some variables and zero temp. line buffer */
mplanes = min(image->fd_nplanes, planes);
/* convert image */
line_addr = image_addr;
buf_addr = screen_addr;
if (mplanes > 1) {
/* cut/pad color planes into temp buf */
for (plane = 0; plane < mplanes; plane++) {
memcpy(buf_addr, line_addr, size);
line_addr += size;
buf_addr += size;
}
} else {
/* fill temp line bitplanes with a b&w line */
for (plane = 0; plane < planes; plane++) {
memcpy(buf_addr, line_addr, size);
buf_addr += size;
}
}
free(image->fd_addr);
/* convert image line in temp into current device raster format */
if ((new1_addr = (char *) calloc(1, new_size)) == NULL)
return (FALSE);
dev_form.fd_addr = new1_addr;
vr_trnfm(x_handle, &tmp, &dev_form);
free(new_addr);
/* change image description */
image->fd_stand = 0; /* device format */
image->fd_addr = new1_addr;
image->fd_nplanes = planes;
return (TRUE);
}
int
transform_img(MFDB *image)
{ /* return FALSE if transform_img fails */
int success;
long size;
if (!image->fd_addr)
return (FALSE);
size = (long) ((long) image->fd_wdwidth * (long) image->fd_h);
success = convert(
image, size); /* Use vr_trfm(), which needs quite a lot memory. */
if (success)
return (TRUE);
/* else show_error(ERR_ALLOC); */
return (FALSE);
}
/* Loads & depacks IMG (0 if succeded, else error). */
/* Bitplanes are one after another in address IMG_HEADER.addr. */
int
depack_img(char *name, IMG_header *pic)
{
int b, line, plane, width, word_aligned, opcode, patt_len, pal_size,
byte_repeat, patt_repeat, scan_repeat, error = FALSE;
char *pattern, *to, *endline, *puffer, sol_pat;
long size;
FILE *fp;
if ((fp = fopen(name, "rb")) == NULL)
return (ERR_FILE);
setvbuf(fp, NULL, _IOLBF, BUFSIZ);
/* read header info (bw & ximg) into image structure */
fread((char *) &(pic->version), 2, 8 + 3, fp);
/* only 2-256 color imgs */
if (pic->planes < 1 || pic->planes > 8) {
error = ERR_COLOR;
goto end_depack;
}
/* if XIMG, read info */
if (pic->magic == XIMG && pic->paltype == 0) {
pal_size = (1 << pic->planes) * 3 * 2;
if ((pic->palette = (short *) calloc(1, pal_size))) {
fread((char *) pic->palette, 1, pal_size, fp);
}
} else {
pic->palette = NULL;
}
/* width in bytes word aliged */
word_aligned = (pic->img_w + 15) >> 4;
word_aligned <<= 1;
/* width byte aligned */
width = (pic->img_w + 7) >> 3;
/* allocate memory for the picture */
free(pic->addr);
size = (long) ((long) word_aligned * (long) pic->img_h
* (long) pic->planes); /*MAR*/
/* check for header validity & malloc long... */
if (pic->length > 7 && pic->planes < 33 && pic->img_w > 0
&& pic->img_h > 0) {
if (!(pic->addr = (char *) calloc(1, size))) {
error = ERR_ALLOC;
goto end_depack;
}
} else {
error = ERR_HEADER;
goto end_depack;
}
patt_len = pic->pat_len;
/* jump over the header and possible (XIMG) info */
fseek(fp, (long) pic->length * 2L, SEEK_SET);
for (line = 0, to = pic->addr; line < pic->img_h;
line += scan_repeat) { /* depack whole img */
for (plane = 0, scan_repeat = 1; plane < pic->planes;
plane++) { /* depack one scan line */
puffer = to =
pic->addr
+ (long) (line + plane * pic->img_h) * (long) word_aligned;
endline = puffer + width;
do { /* depack one line in one bitplane */
switch ((opcode = fgetc(fp))) {
case 0: /* pattern or scan repeat */
if ((patt_repeat = fgetc(fp))) { /* repeat a pattern */
fread(to, patt_len, 1, fp);
pattern = to;
to += patt_len;
while (--patt_repeat) { /* copy pattern */
memcpy(to, pattern, patt_len);
to += patt_len;
}
} else { /* repeat a line */
if (fgetc(fp) == 0xFF)
scan_repeat = fgetc(fp);
else {
error = ERR_DEPACK;
goto end_depack;
}
}
break;
case 0x80: /* Literal */
byte_repeat = fgetc(fp);
fread(to, byte_repeat, 1, fp);
to += byte_repeat;
break;
default: /* Solid run */
byte_repeat = opcode & 0x7F;
sol_pat = opcode & 0x80 ? 0xFF : 0x00;
while (byte_repeat--)
*to++ = sol_pat;
}
} while (to < endline);
if (to == endline) {
/* ensure that lines aren't repeated past the end of the img
*/
if (line + scan_repeat > pic->img_h)
scan_repeat = pic->img_h - line;
/* copy line to image buffer */
if (scan_repeat > 1) {
/* calculate address of a current line in a current
* bitplane */
/* to=pic->addr+(long)(line+1+plane*pic->img_h)*(long)word_aligned;*/
for (b = scan_repeat - 1; b; --b) {
memcpy(to, puffer, width);
to += word_aligned;
}
}
} else {
error = ERR_DEPACK;
goto end_depack;
}
}
}
end_depack:
fclose(fp);
return (error);
}
int
half_img(MFDB *s, MFDB *d)
{
int pxy[8], i, j;
MFDB tmp;
mfdb(&tmp, NULL, s->fd_w / 2, s->fd_h, s->fd_stand, s->fd_nplanes);
tmp.fd_w = s->fd_w / 2;
tmp.fd_addr = calloc(1, mfdb_size(&tmp));
if (!tmp.fd_addr)
return (FALSE);
pxy[1] = pxy[5] = 0;
pxy[3] = pxy[7] = s->fd_h - 1;
for (i = 0; i < s->fd_w / 2; i++) {
pxy[0] = pxy[2] = 2 * i;
pxy[4] = pxy[6] = i;
vro_cpyfm(x_handle, S_ONLY, pxy, s, &tmp);
}
pxy[0] = pxy[4] = 0;
pxy[2] = pxy[6] = s->fd_w / 2 - 1;
for (j = 0; j < s->fd_h / 2; j++) {
pxy[1] = pxy[3] = 2 * j;
pxy[5] = pxy[7] = j;
vro_cpyfm(x_handle, S_ONLY, pxy, &tmp, d);
}
free(tmp.fd_addr);
return (TRUE);
}