mirror of
https://github.com/kichikuou/xsystem35-sdl2.git
synced 2026-09-28 09:48:05 +03:00
218 lines
6.3 KiB
C
218 lines
6.3 KiB
C
/*
|
|
* vsp.c extract VSP cg
|
|
*
|
|
* Copyright (C) 1997-1998 Masaki Chikama (Wren) <chikama@kasumi.ipl.mech.nagoya-u.ac.jp>
|
|
* 1998- <masaki-c@is.aist-nara.ac.jp>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
* 0.00 97/11/06 初版
|
|
* 0.01 97/11/12 TYPO
|
|
* 0.01-01 97/11/13 ヘッダ情報の返しかたの変更
|
|
* 0.01-02 97/11/27 記憶子の変更
|
|
* 0.01-03 97/12/06 ヘッダの誤認識の修正
|
|
* 0.02 98/02/26 デバッグ済み
|
|
* 0.03 98/03/20 ヘッダチェックのミス
|
|
* 0.03 98/12/19 dalkで640x401なCGがあったのでその対策
|
|
* @version 1.5 00/09/17 rewrite for changeing interface
|
|
*/
|
|
/* $Id: vsp.c,v 1.6 2000/11/25 18:31:49 chikama Exp $ */
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "portab.h"
|
|
#include "LittleEndian.h"
|
|
#include "graphics.h"
|
|
#include "cg.h"
|
|
#include "vsp.h"
|
|
|
|
/*
|
|
* static methods
|
|
*/
|
|
static vsp_header *extract_header(uint8_t *b);
|
|
static void extract(vsp_header *vsp, uint8_t *pic, uint8_t *b);
|
|
|
|
/*
|
|
* Get information from cg header
|
|
* b: raw data (pointer to header)
|
|
* return: acquired vsp information object
|
|
*/
|
|
static vsp_header *extract_header(uint8_t *b) {
|
|
vsp_header *vsp = malloc(sizeof(vsp_header));
|
|
|
|
vsp->vspX0 = LittleEndian_getW(b, 0);
|
|
vsp->vspY0 = LittleEndian_getW(b, 2);
|
|
vsp->vspXW = LittleEndian_getW(b, 4) - vsp->vspX0;
|
|
vsp->vspYW = LittleEndian_getW(b, 6) - vsp->vspY0;
|
|
vsp->vspPb = b[9];
|
|
vsp->vspPp = 0x0a;
|
|
vsp->vspDp = 0x3a;
|
|
|
|
return vsp;
|
|
}
|
|
|
|
/*
|
|
* Get palette from raw data
|
|
* b : raw data (pointer to palette)
|
|
*/
|
|
static Color *getpal(uint8_t *b) {
|
|
Color *pal = malloc(sizeof(Color) * 256);
|
|
for (int i = 0; i < 16; i++) {
|
|
pal[i].b = b[i * 3 + 0] * 17;
|
|
pal[i].r = b[i * 3 + 1] * 17;
|
|
pal[i].g = b[i * 3 + 2] * 17;
|
|
}
|
|
return pal;
|
|
}
|
|
|
|
/*
|
|
* Do extract vsp image
|
|
* vsp: vsp header information
|
|
* pic: pixel to be stored
|
|
* b : raw data (pointer to pixel)
|
|
*/
|
|
static void extract(vsp_header *vsp, uint8_t *pic, uint8_t *b) {
|
|
int c0;
|
|
uint8_t b0, b1, b2, b3, mask = 0;
|
|
uint8_t *bt;
|
|
int i, l, x, y, pl, loc;
|
|
|
|
// Extraction buffers.
|
|
uint8_t *buf = malloc(vsp->vspYW * 8);
|
|
uint8_t *bc[4];
|
|
uint8_t *bp[4];
|
|
for (int i = 0; i < 4; i++) {
|
|
bc[i] = buf + vsp->vspYW * (i * 2);
|
|
bp[i] = buf + vsp->vspYW * (i * 2 + 1);
|
|
}
|
|
|
|
for (x = 0; x < vsp->vspXW; x++) {
|
|
for (pl = 0; pl < 4; pl++) {
|
|
y = 0;
|
|
while(y < vsp->vspYW) {
|
|
c0 = *b++;
|
|
if (c0 >= 0x08) {
|
|
*(bc[pl] + y) = c0; y++;
|
|
} else if (c0 == 0x00) {
|
|
l = (*b) + 1; b++;
|
|
memcpy(bc[pl] + y, bp[pl] + y, l);
|
|
y+=l;
|
|
} else if (c0 == 0x01) {
|
|
l = (*b) + 1; b++;
|
|
b0 = *b++;
|
|
memset(bc[pl] + y, b0, l);
|
|
y+=l;
|
|
} else if (c0 == 0x02) {
|
|
l = (*b) + 1; b++;
|
|
b0 = *b++; b1 = *b++;
|
|
for (i = 0; i < l; i++) {
|
|
*(bc[pl] + y) = b0; y++;
|
|
*(bc[pl] + y) = b1; y++;
|
|
}
|
|
} else if (c0 == 0x03) {
|
|
l = (*b) + 1; b++;
|
|
for (i = 0; i < l; i++) {
|
|
*(bc[pl] + y) = (*(bc[0] + y) ^ mask); y++;
|
|
}
|
|
mask = 0;
|
|
} else if (c0 == 0x04) {
|
|
l = (*b) + 1; b++;
|
|
for (i = 0; i < l; i++) {
|
|
*(bc[pl] + y) = (*(bc[1] + y) ^ mask); y++;
|
|
}
|
|
mask = 0;
|
|
} else if (c0 == 0x05) {
|
|
l = (*b) + 1; b++;
|
|
for (i = 0; i < l; i++) {
|
|
*(bc[pl] + y) = (*(bc[2] + y) ^ mask); y++;
|
|
}
|
|
mask = 0;
|
|
} else if (c0 == 0x06) {
|
|
mask = 0xff;
|
|
} else if (c0 == 0x07) {
|
|
*(bc[pl] + y) = *b++ ; y++;
|
|
}
|
|
}
|
|
}
|
|
/* plane -> packed 展開 */
|
|
for (y = 0; y < vsp->vspYW; y++) {
|
|
loc = (y * vsp->vspXW + x) * 8;
|
|
b0 = bc[0][y]; b1 = bc[1][y];
|
|
b2 = bc[2][y]; b3 = bc[3][y];
|
|
*(pic + loc + 0) = ((b0>>7)&0x01)|((b1>>6)&0x02)|((b2>>5)&0x04)|((b3>>4)&0x08);
|
|
*(pic + loc + 1) = ((b0>>6)&0x01)|((b1>>5)&0x02)|((b2>>4)&0x04)|((b3>>3)&0x08);
|
|
*(pic + loc + 2) = ((b0>>5)&0x01)|((b1>>4)&0x02)|((b2>>3)&0x04)|((b3>>2)&0x08);
|
|
*(pic + loc + 3) = ((b0>>4)&0x01)|((b1>>3)&0x02)|((b2>>2)&0x04)|((b3>>1)&0x08);
|
|
*(pic + loc + 4) = ((b0>>3)&0x01)|((b1>>2)&0x02)|((b2>>1)&0x04)|((b3 )&0x08);
|
|
*(pic + loc + 5) = ((b0>>2)&0x01)|((b1>>1)&0x02)|((b2 )&0x04)|((b3<<1)&0x08);
|
|
*(pic + loc + 6) = ((b0>>1)&0x01)|((b1 )&0x02)|((b2<<1)&0x04)|((b3<<2)&0x08);
|
|
*(pic + loc + 7) = ((b0 )&0x01)|((b1<<1)&0x02)|((b2<<2)&0x04)|((b3<<3)&0x08);
|
|
}
|
|
/* bc -> bpにコピー */
|
|
bt = bp[0]; bp[0] = bc[0]; bc[0] = bt;
|
|
bt = bp[1]; bp[1] = bc[1]; bc[1] = bt;
|
|
bt = bp[2]; bp[2] = bc[2]; bc[2] = bt;
|
|
bt = bp[3]; bp[3] = bc[3]; bc[3] = bt;
|
|
}
|
|
free(buf);
|
|
}
|
|
|
|
/*
|
|
* Check data is vsp format cg or not
|
|
* data: raw data (pointer to data top)
|
|
* return: TRUE if data is vsp
|
|
*/
|
|
boolean vsp_checkfmt(uint8_t *data) {
|
|
int x0 = LittleEndian_getW(data, 0);
|
|
int y0 = LittleEndian_getW(data, 2);
|
|
int w = LittleEndian_getW(data, 4) - x0;
|
|
int h = LittleEndian_getW(data, 6) - y0;
|
|
|
|
if (x0 < 0 || x0 > 80 || y0 < 0 || y0 > 400) return FALSE;
|
|
/* 401: for dalk's broken cg */
|
|
if (w < 0 || w > 80 || h < 0 || h > 401) return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*
|
|
* Extract vsp, header, palette and pixel
|
|
* data: raw data (pointer to data top)
|
|
* return: extracted image data and information
|
|
*/
|
|
cgdata *vsp_extract(uint8_t *data) {
|
|
cgdata *cg = calloc(1, sizeof(cgdata));
|
|
vsp_header *vsp = extract_header(data);
|
|
|
|
cg->pal = getpal(data + vsp->vspPp);
|
|
|
|
/* +10: margin for broken cg */
|
|
cg->pic = malloc(sizeof(uint8_t) * ((vsp->vspXW * 8 + 10) * (vsp->vspYW + 10)));
|
|
extract(vsp, cg->pic, data + vsp->vspDp);
|
|
|
|
cg->type = ALCG_VSP;
|
|
cg->x = vsp->vspX0 * 8;
|
|
cg->y = vsp->vspY0;
|
|
cg->width = vsp->vspXW * 8;
|
|
cg->height = vsp->vspYW;
|
|
cg->depth = 8;
|
|
cg->vsp_bank = vsp->vspPb;
|
|
cg->alpha = NULL;
|
|
|
|
free(vsp);
|
|
|
|
return cg;
|
|
}
|