mirror of
https://github.com/Garhoogin/NitroPaint.git
synced 2025-06-18 14:25:31 -04:00
Simplify IS-CAD file output code
This commit is contained in:
parent
3c9fc49df4
commit
5a120b2f44
@ -809,12 +809,13 @@ int ChrWriteNcg(NCGR *ncgr, BSTREAM *stream) {
|
||||
}
|
||||
|
||||
static int ChriIsCommonWrite(NCGR *ncgr, BSTREAM *stream) {
|
||||
int attrSize = ncgr->tilesX * ncgr->tilesY;
|
||||
|
||||
ChrWriteChars(ncgr, stream);
|
||||
IscadStream cadStream;
|
||||
IscadStreamCreate(&cadStream);
|
||||
ChrWriteChars(ncgr, &cadStream.stream);
|
||||
|
||||
//write attribute for ACG
|
||||
for (int i = 0; i < attrSize; i++) {
|
||||
unsigned int attrSize = ncgr->tilesX * ncgr->tilesY;
|
||||
for (unsigned int i = 0; i < attrSize; i++) {
|
||||
unsigned char a = 0;
|
||||
if (ncgr->attr != NULL) {
|
||||
a = ncgr->attr[i];
|
||||
@ -825,17 +826,9 @@ static int ChriIsCommonWrite(NCGR *ncgr, BSTREAM *stream) {
|
||||
a |= (ncgr->nBits == 8) ? 0x10 : 0x00;
|
||||
}
|
||||
|
||||
bstreamWrite(stream, &a, sizeof(a));
|
||||
IscadStreamWrite(&cadStream, &a, sizeof(a));
|
||||
}
|
||||
|
||||
//footer
|
||||
unsigned char linkFooter[] = { 'L', 'I', 'N', 'K', 2, 0, 0, 0, 1, 0 };
|
||||
unsigned char cmntFooter[] = { 'C', 'M', 'N', 'T', 2, 0, 0, 0, 1, 0 };
|
||||
unsigned char modeFooter[] = { 'M', 'O', 'D', 'E', 4, 0, 0, 0, 1, 0, 0, 0 };
|
||||
unsigned char sizeFooter[] = { 'S', 'I', 'Z', 'E', 4, 0, 0, 0, 0, 0, 0, 0 };
|
||||
unsigned char verFooter[] = { 'V', 'E', 'R', ' ', 0, 0, 0, 0 };
|
||||
unsigned char endFooter[] = { 'E', 'N', 'D', ' ', 0, 0, 0, 0 };
|
||||
|
||||
char *version = "";
|
||||
switch (ncgr->header.format) {
|
||||
case NCGR_TYPE_AC:
|
||||
@ -844,10 +837,7 @@ static int ChriIsCommonWrite(NCGR *ncgr, BSTREAM *stream) {
|
||||
version = "IS-ICG01"; break;
|
||||
}
|
||||
|
||||
int linkLen = (ncgr->header.fileLink == NULL) ? 0 : strlen(ncgr->header.fileLink);
|
||||
int commentLen = (ncgr->header.comment == NULL) ? 0 : strlen(ncgr->header.comment);
|
||||
|
||||
int mode = 0;
|
||||
uint32_t mode = 0;
|
||||
if (ncgr->header.format == NCGR_TYPE_AC) {
|
||||
//3: 8bpp, 1: 4bpp
|
||||
if (ncgr->nBits == 8) mode = 3;
|
||||
@ -859,24 +849,26 @@ static int ChriIsCommonWrite(NCGR *ncgr, BSTREAM *stream) {
|
||||
else mode = 8;
|
||||
}
|
||||
|
||||
*(uint32_t *) (linkFooter + 4) = linkLen + 2;
|
||||
linkFooter[9] = (unsigned char) linkLen;
|
||||
*(uint32_t *) (cmntFooter + 4) = commentLen + 2;
|
||||
cmntFooter[9] = (unsigned char) commentLen;
|
||||
*(uint32_t *) (modeFooter + 8) = mode;
|
||||
*(uint16_t *) (sizeFooter + 8) = ncgr->tilesX;
|
||||
*(uint16_t *) (sizeFooter + 10) = ncgr->tilesY;
|
||||
*(uint32_t *) (verFooter + 4) = strlen(version);
|
||||
uint16_t sizeFooter[2];
|
||||
sizeFooter[0] = ncgr->tilesX;
|
||||
sizeFooter[1] = ncgr->tilesY;
|
||||
|
||||
bstreamWrite(stream, linkFooter, sizeof(linkFooter));
|
||||
bstreamWrite(stream, ncgr->header.fileLink, linkLen);
|
||||
bstreamWrite(stream, cmntFooter, sizeof(cmntFooter));
|
||||
bstreamWrite(stream, ncgr->header.comment, commentLen);
|
||||
bstreamWrite(stream, modeFooter, sizeof(modeFooter));
|
||||
bstreamWrite(stream, sizeFooter, sizeof(sizeFooter));
|
||||
bstreamWrite(stream, verFooter, sizeof(verFooter));
|
||||
bstreamWrite(stream, version, strlen(version));
|
||||
bstreamWrite(stream, endFooter, sizeof(endFooter));
|
||||
IscadStreamStartBlock(&cadStream, "LINK");
|
||||
IscadStreamWriteCountedString(&cadStream, ncgr->header.fileLink);
|
||||
IscadStreamEndBlock(&cadStream);
|
||||
|
||||
IscadStreamStartBlock(&cadStream, "CMNT");
|
||||
IscadStreamWriteCountedString(&cadStream, ncgr->header.comment);
|
||||
IscadStreamEndBlock(&cadStream);
|
||||
|
||||
IscadWriteBlock(&cadStream, "MODE", &mode, sizeof(mode));
|
||||
IscadWriteBlock(&cadStream, "SIZE", sizeFooter, sizeof(sizeFooter));
|
||||
IscadWriteBlock(&cadStream, "VER ", version, strlen(version));
|
||||
IscadWriteBlock(&cadStream, "END ", NULL, 0);
|
||||
|
||||
IscadStreamFinalize(&cadStream);
|
||||
IscadStreamFlushOut(&cadStream, stream);
|
||||
IscadStreamFree(&cadStream);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -690,3 +690,60 @@ void NnsStreamFree(NnsStream *stream) {
|
||||
bstreamFree(&stream->blockStream);
|
||||
bstreamFree(&stream->currentStream);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ----- ISCAD functions
|
||||
|
||||
void IscadStreamCreate(IscadStream *stream) {
|
||||
stream->inFooter = 0;
|
||||
bstreamCreate(&stream->stream, NULL, 0);
|
||||
}
|
||||
|
||||
void IscadStreamFree(IscadStream *stream) {
|
||||
bstreamFree(&stream->stream);
|
||||
}
|
||||
|
||||
void IscadStreamStartBlock(IscadStream *stream, const char *signature) {
|
||||
stream->inFooter = 1;
|
||||
stream->blockStart = stream->stream.pos;
|
||||
|
||||
uint32_t tmpSize = 0;
|
||||
bstreamWrite(&stream->stream, signature, 4);
|
||||
bstreamWrite(&stream->stream, &tmpSize, sizeof(tmpSize));
|
||||
}
|
||||
|
||||
void IscadStreamEndBlock(IscadStream *stream) {
|
||||
unsigned int blockSize = stream->stream.pos - stream->blockStart;
|
||||
blockSize -= 8; // block header size
|
||||
*(uint32_t *) (stream->stream.buffer + stream->blockStart + 4) = blockSize;
|
||||
}
|
||||
|
||||
void IscadStreamFinalize(IscadStream *stream) {
|
||||
//tbd
|
||||
(void) stream;
|
||||
}
|
||||
|
||||
void IscadStreamWrite(IscadStream *stream, const void *data, unsigned int len) {
|
||||
bstreamWrite(&stream->stream, (void *) data, len);
|
||||
}
|
||||
|
||||
void IscadStreamWriteCountedString(IscadStream *stream, const char *str) {
|
||||
unsigned char header[2];
|
||||
unsigned int len = 0;
|
||||
if (str != NULL) len = strlen(str);
|
||||
header[0] = 1;
|
||||
header[1] = len;
|
||||
IscadStreamWrite(stream, header, sizeof(header));
|
||||
IscadStreamWrite(stream, str, len);
|
||||
}
|
||||
|
||||
void IscadWriteBlock(IscadStream *stream, const char *signature, const void *data, unsigned int len) {
|
||||
IscadStreamStartBlock(stream, signature);
|
||||
IscadStreamWrite(stream, data, len);
|
||||
IscadStreamEndBlock(stream);
|
||||
}
|
||||
|
||||
void IscadStreamFlushOut(IscadStream *stream, BSTREAM *out) {
|
||||
bstreamWrite(out, stream->stream.buffer, stream->stream.size);
|
||||
}
|
||||
|
@ -70,3 +70,22 @@ void NnsStreamFinalize(NnsStream *stream);
|
||||
void NnsStreamFlushOut(NnsStream *stream, BSTREAM *out);
|
||||
|
||||
void NnsStreamFree(NnsStream *stream);
|
||||
|
||||
|
||||
// ----- ISCAD stream functions
|
||||
|
||||
typedef struct IscadStream_ {
|
||||
BSTREAM stream; // file stream
|
||||
int inFooter; // in footer
|
||||
unsigned int blockStart; // current block starting offset
|
||||
} IscadStream;
|
||||
|
||||
void IscadStreamCreate(IscadStream *stream);
|
||||
void IscadStreamFree(IscadStream *stream);
|
||||
void IscadStreamStartBlock(IscadStream *stream, const char *signature);
|
||||
void IscadStreamEndBlock(IscadStream *stream);
|
||||
void IscadStreamFinalize(IscadStream *stream);
|
||||
void IscadStreamWrite(IscadStream *stream, const void *data, unsigned int len);
|
||||
void IscadStreamWriteCountedString(IscadStream *stream, const char *str);
|
||||
void IscadWriteBlock(IscadStream *stream, const char *signature, const void *data, unsigned int len);
|
||||
void IscadStreamFlushOut(IscadStream *stream, BSTREAM *out);
|
||||
|
@ -713,23 +713,20 @@ int ScrWriteNsc(NSCR *nscr, BSTREAM *stream) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ScriIsCommonWrite(NSCR *nscr, BSTREAM *stream) {
|
||||
bstreamWrite(stream, nscr->data, nscr->dataSize);
|
||||
|
||||
unsigned char clrfFooter[] = { 'C', 'L', 'R', 'F', 0, 0, 0, 0 };
|
||||
unsigned char linkFooter[] = { 'L', 'I', 'N', 'K', 0, 0, 0, 0 };
|
||||
unsigned char cmntFooter[] = { 'C', 'M', 'N', 'T', 0, 0, 0, 0, 1, 0 };
|
||||
unsigned char clrcFooter[] = { 'C', 'L', 'R', 'C', 2, 0, 0, 0, 0, 0 };
|
||||
unsigned char modeFooter[] = { 'M', 'O', 'D', 'E', 4, 0, 0, 0, 0, 0, 0, 0 };
|
||||
unsigned char sizeFooter[] = { 'S', 'I', 'Z', 'E', 4, 0, 0, 0, 0, 0, 0, 0 };
|
||||
unsigned char verFooter[] = { 'V', 'E', 'R', ' ', 0, 0, 0, 0 };
|
||||
unsigned char endFooter[] = { 'E', 'N', 'D', ' ', 0, 0, 0, 0 };
|
||||
|
||||
static int ScriIsCommonWrite(NSCR *nscr, BSTREAM *stream) {
|
||||
IscadStream cadStream;
|
||||
IscadStreamCreate(&cadStream);
|
||||
IscadStreamWrite(&cadStream, nscr->data, nscr->dataSize);
|
||||
|
||||
unsigned char clrcFooter[2];
|
||||
unsigned char modeFooter[4];
|
||||
|
||||
//expects null terminated for ISC/ASC LINK specifically (not the others for some reason)
|
||||
int linkLen = (nscr->header.fileLink == NULL) ? 0 : (strlen(nscr->header.fileLink) + 1);
|
||||
int commentLen = (nscr->header.comment == NULL) ? 0 : strlen(nscr->header.comment);
|
||||
|
||||
char *ver = "";
|
||||
const char *ver = "";
|
||||
switch (nscr->header.format) {
|
||||
case NSCR_TYPE_AC:
|
||||
ver = "IS-ASC03"; break;
|
||||
@ -737,43 +734,53 @@ static int ScriIsCommonWrite(NSCR *nscr, BSTREAM *stream) {
|
||||
ver = "IS-ISC01"; break;
|
||||
}
|
||||
|
||||
*(uint32_t *) (clrfFooter + 0x4) = (nscr->dataSize + 15) / 16;
|
||||
*(uint32_t *) (linkFooter + 0x4) = linkLen;
|
||||
*(uint32_t *) (cmntFooter + 0x4) = commentLen + 2;
|
||||
*(uint16_t *) (clrcFooter + 0x8) = nscr->clearValue;
|
||||
*(uint16_t *) (sizeFooter + 0x8) = nscr->tilesX;
|
||||
*(uint16_t *) (sizeFooter + 0xA) = nscr->tilesY;
|
||||
cmntFooter[0x09] = commentLen;
|
||||
modeFooter[0x8] = nscr->tilesX;
|
||||
modeFooter[0x9] = nscr->tilesY;
|
||||
modeFooter[0xA] = (nscr->fmt == SCREENFORMAT_AFFINE) ? 1 : 0;
|
||||
modeFooter[0xB] = 0x02 | (nscr->colorMode = SCREENCOLORMODE_256x1 || nscr->colorMode == SCREENCOLORMODE_256x16);
|
||||
*(uint32_t *) (verFooter + 0x4) = strlen(ver);
|
||||
*(uint16_t *) (clrcFooter + 0x0) = nscr->clearValue;
|
||||
|
||||
bstreamWrite(stream, clrfFooter, sizeof(clrfFooter));
|
||||
for (unsigned int i = 0; i < (nscr->dataSize + 15) / 16; i++) {
|
||||
unsigned char f = 0x00; //not clear character
|
||||
bstreamWrite(stream, &f, sizeof(f));
|
||||
modeFooter[0] = nscr->tilesX;
|
||||
modeFooter[1] = nscr->tilesY;
|
||||
modeFooter[2] = (nscr->fmt == SCREENFORMAT_AFFINE) ? 1 : 0;
|
||||
modeFooter[3] = 0x02 | (nscr->colorMode = SCREENCOLORMODE_256x1 || nscr->colorMode == SCREENCOLORMODE_256x16);
|
||||
|
||||
IscadStreamStartBlock(&cadStream, "CLRF");
|
||||
{
|
||||
//write zeroed CLRF (no tile marked "unused")
|
||||
unsigned int clrfSize = (nscr->dataSize + 15) / 16;
|
||||
unsigned char *clrf = (unsigned char *) calloc(clrfSize, 1);
|
||||
IscadStreamWrite(&cadStream, clrf, clrfSize);
|
||||
free(clrf);
|
||||
}
|
||||
bstreamWrite(stream, linkFooter, sizeof(linkFooter));
|
||||
bstreamWrite(stream, nscr->header.fileLink, linkLen);
|
||||
bstreamWrite(stream, cmntFooter, sizeof(cmntFooter));
|
||||
bstreamWrite(stream, nscr->header.comment, commentLen);
|
||||
bstreamWrite(stream, clrcFooter, sizeof(clrcFooter));
|
||||
IscadStreamEndBlock(&cadStream);
|
||||
|
||||
IscadWriteBlock(&cadStream, "LINK", nscr->header.fileLink, linkLen);
|
||||
|
||||
IscadStreamStartBlock(&cadStream, "CMNT");
|
||||
IscadStreamWriteCountedString(&cadStream, nscr->header.comment);
|
||||
IscadStreamEndBlock(&cadStream);
|
||||
|
||||
IscadWriteBlock(&cadStream, "CLRC", clrcFooter, sizeof(clrcFooter));
|
||||
|
||||
if (nscr->header.format == NSCR_TYPE_AC) {
|
||||
//ASC: MODE footer contains the size
|
||||
bstreamWrite(stream, modeFooter, sizeof(modeFooter));
|
||||
IscadWriteBlock(&cadStream, "MODE", modeFooter, sizeof(modeFooter));
|
||||
} else if (nscr->header.format == NSCR_TYPE_IC) {
|
||||
//ISC: MODE footer does not contain the size, has separate SIZE footer
|
||||
unsigned char iscModeFooter[] = { 'M', 'O', 'D', 'E', 2, 0, 0, 0, 0, 0 };
|
||||
iscModeFooter[0x8] = (nscr->fmt == SCREENFORMAT_AFFINE) ? 1 : 0;
|
||||
bstreamWrite(stream, iscModeFooter, sizeof(iscModeFooter));
|
||||
bstreamWrite(stream, sizeFooter, sizeof(sizeFooter));
|
||||
}
|
||||
bstreamWrite(stream, verFooter, sizeof(verFooter));
|
||||
bstreamWrite(stream, ver, strlen(ver));
|
||||
bstreamWrite(stream, endFooter, sizeof(endFooter));
|
||||
unsigned char iscModeFooter[] = { 0, 0 };
|
||||
iscModeFooter[0] = (nscr->fmt == SCREENFORMAT_AFFINE) ? 1 : 0;
|
||||
|
||||
unsigned char sizeFooter[] = { 0, 0, 0, 0 };
|
||||
*(uint16_t *) (sizeFooter + 0x0) = nscr->tilesX;
|
||||
*(uint16_t *) (sizeFooter + 0x2) = nscr->tilesY;
|
||||
|
||||
IscadWriteBlock(&cadStream, "MODE", iscModeFooter, sizeof(iscModeFooter));
|
||||
IscadWriteBlock(&cadStream, "SIZE", sizeFooter, sizeof(sizeFooter));
|
||||
}
|
||||
|
||||
IscadWriteBlock(&cadStream, "VER ", ver, strlen(ver));
|
||||
IscadWriteBlock(&cadStream, "END ", NULL, 0);
|
||||
|
||||
IscadStreamFinalize(&cadStream);
|
||||
IscadStreamFlushOut(&cadStream, stream);
|
||||
IscadStreamFree(&cadStream);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user