ReC98/th01/formats/ptn.cpp

148 lines
3.4 KiB
C++

extern "C" {
#include "ReC98.h"
#include "th01/hardware/palette.h"
#include "th01/formats/ptn.hpp"
#include "th01/formats/pf.hpp"
extern int flag_palette_show;
// On-disk .PTN slot file header
// -----------------------------
#define PTN_MAGIC "HPTN"
#pragma option -a-
typedef struct {
char magic[sizeof(PTN_MAGIC) - 1];
int8_t unused_one;
int8_t image_count;
} ptn_header_t;
#pragma option -a.
// -----------------------------
ptn_error_t ptn_load_palette_show(int slot, const char *fn)
{
union {
Palette4 pal;
ptn_header_t header;
} h;
int y;
int i;
int image_count;
ptn_t *ptn;
arc_file_load(fn);
arc_file_get(h.header);
image_count = h.header.image_count;
// MODDERS:
/* if(image_count <= 0 || image_count > PTN_IMAGES_PER_SLOT) {
return PE_IMAGE_COUNT_INVALID;
} */
if(ptn_images[slot]) {
delete[] ptn_images[slot];
}
ptn_images[slot] = new ptn_t[image_count];
if(!ptn_images[slot]) {
return PE_OUT_OF_MEMORY;
}
arc_file_get(h.pal);
if(flag_palette_show) {
z_palette_set_all_show(h.pal);
}
ptn_image_count[slot] = image_count;
ptn = ptn_images[slot];
for(i = 0; i < image_count; i++, ptn++) {
arc_file_get(ptn->unused_zero);
arc_file_get(ptn->planes);
for(y = 0; y < PTN_H; y++) {
// Color #15 (1111) is always the transparent one, meaning that
// transparent dots are 1 in all 4 bitplanes. The alpha mask
// therefore simply is the negation of ANDing all bitplanes
// together. Nifty!
ptn->alpha[y] = ~(
ptn->planes.B[y]
& ptn->planes.R[y]
& ptn->planes.G[y]
& ptn->planes.E[y]
);
}
}
arc_file_free();
return PE_OK;
}
ptn_error_t ptn_new(int slot, int image_count)
{
if(image_count <= 0 || image_count > PTN_IMAGES_PER_SLOT) {
return PE_IMAGE_COUNT_INVALID;
}
if(ptn_images[slot]) {
delete[] ptn_images[slot];
}
ptn_image_count[slot] = image_count;
ptn_images[slot] = new ptn_t[image_count];
if(!ptn_images[slot]) {
return PE_OUT_OF_MEMORY;
}
return PE_OK;
}
void ptn_load(int slot, const char *fn)
{
flag_palette_show = false;
int ret = ptn_load_palette_show(slot, fn);
flag_palette_show = true;
ret;
}
void ptn_free(int slot)
{
if(ptn_images[slot]) {
delete[] ptn_images[slot];
ptn_images[slot] = NULL;
ptn_image_count[slot] = 0;
}
}
void ptn_put_noalpha_8(int left, int top, int ptn_id)
{
unsigned int vram_offset = vram_offset_shift(left, top);
ptn_t *ptn = ptn_with_id(ptn_id);
for(int y = 0; y < PTN_H; y++) {
#define put_noalpha(vram_offset, w, ptn) \
VRAM_CHUNK(B, vram_offset, w) = (ptn->planes.B[y]); \
VRAM_CHUNK(R, vram_offset, w) = (ptn->planes.R[y]); \
VRAM_CHUNK(G, vram_offset, w) = (ptn->planes.G[y]); \
VRAM_CHUNK(E, vram_offset, w) = (ptn->planes.E[y]);
put_noalpha(vram_offset, PTN_W, ptn);
#undef put_noalpha
vram_offset += ROW_SIZE;
}
}
void ptn_put_quarter_noalpha_8(int left, int top, int ptn_id, int quarter)
{
int y;
unsigned int vram_offset = vram_offset_muldiv(left, top);
PTNQuarter q;
ptn_t *ptn = ptn_with_id(ptn_id);
q.init(quarter);
for(y = q.y; y < (q.y + PTN_QUARTER_H); y++) {
#define put_quarter_noalpha(vram_offset, w, ptn, q_x) \
VRAM_CHUNK(B, vram_offset, w) = (ptn->planes.B[y] >> q_x); \
VRAM_CHUNK(R, vram_offset, w) = (ptn->planes.R[y] >> q_x); \
VRAM_CHUNK(G, vram_offset, w) = (ptn->planes.G[y] >> q_x); \
VRAM_CHUNK(E, vram_offset, w) = (ptn->planes.E[y] >> q_x);
put_quarter_noalpha(vram_offset, PTN_QUARTER_W, ptn, q.x);
#undef put_quarter_noalpha
vram_offset += ROW_SIZE;
}
}
}