If an old port is resurrected to work with current version code, its files can be relocated to the appropriate sys or win folder as required. In the meantime, the burden of upkeep can be avoided for the stuff in the outdated folder for now.
322 lines
9.1 KiB
C
322 lines
9.1 KiB
C
/*
|
|
* $NHDT-Date: 1432512809 2015/05/25 00:13:29 $ $NHDT-Branch: master $:$NHDT-Revision: 1.5 $
|
|
*/
|
|
#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);
|
|
}
|