mirror of
https://github.com/kevinbentley/Descent3.git
synced 2025-01-22 11:28:56 +00:00
2348 lines
76 KiB
C++
2348 lines
76 KiB
C++
/*
|
|
** mveasm.cpp
|
|
**
|
|
** Interplay Movie File (MVE) Player Library (32-Bit Linux Version)
|
|
** Written by Paul Allen Edelstein. Partial Linux port by Jeff Slutter.
|
|
**
|
|
** (c) 1997 Interplay Productions. All Rights Reserved.
|
|
** This file is confidential and consists of proprietary information
|
|
** of Interplay Productions. This file and associated libraries
|
|
** may not, in whole or in part, be disclosed to third parties,
|
|
** incorporated into any software product which is not being created
|
|
** for Interplay Productions, copied or duplicated in any form,
|
|
** without the prior written permission of Interplay Productions.
|
|
** Further, you may not reverse engineer, decompile or otherwise
|
|
** attempt to derive source code of this material.
|
|
**
|
|
*/
|
|
|
|
#include "debug.h"
|
|
#include "pstypes.h"
|
|
#include "mvelibl.h"
|
|
#include "mvelibi.h"
|
|
#include <string.h>
|
|
|
|
extern unsigned char *nf_buf_cur;
|
|
extern unsigned char *nf_buf_prv;
|
|
extern unsigned nf_new_x;
|
|
extern unsigned nf_new_y;
|
|
extern unsigned nf_new_w;
|
|
extern unsigned nf_new_h;
|
|
extern unsigned char nf_fqty; // Number of fields
|
|
extern unsigned nf_new_row0; // SHEIGHT*width*2-width
|
|
extern unsigned nf_width; // wqty * SWIDTH
|
|
extern unsigned nf_new_line; // width - SWIDTH
|
|
extern unsigned nf_back_right; // (SHEIGHT-1)*width
|
|
extern unsigned nf_hicolor;
|
|
|
|
extern unsigned short nf_trans16_lo[256];
|
|
extern unsigned short nf_trans16_hi[256];
|
|
|
|
extern signed short snd_8to16[256];
|
|
void PkDecompWorker(const bool hiColor, const unsigned char *ops, const unsigned char *comp, const unsigned x,
|
|
const unsigned y, const unsigned w, const unsigned h);
|
|
void nfHPkDecomp(unsigned char *ops, unsigned char *comp, int x, int y, int w, int h);
|
|
void nfPkDecomp(unsigned char *ops, unsigned char *comp, unsigned x, unsigned y, unsigned w, unsigned h);
|
|
void nfPkConfig(void);
|
|
unsigned sndDecompM16(unsigned short *dst, const unsigned char *src, unsigned len, unsigned prev);
|
|
unsigned sndDecompS16(unsigned short *dst, const unsigned char *src, unsigned len, unsigned prev);
|
|
|
|
void Trans16Blk(unsigned char *edi, const unsigned char *idx);
|
|
void DOnf_xycshift(const bool hiColor, const uint32_t eax, unsigned char *&edi, const int nfpk_back_right);
|
|
void DOnf_xypshift(const bool hiColor, const uint32_t eax, unsigned char *&edi, const int nfpk_back_right,
|
|
const int DiffBufPtrs);
|
|
void DOnf_shift(const bool hiColor, int eax, unsigned char *&edi, const int nfpk_back_right);
|
|
|
|
//--------------------------------------------------------------------
|
|
// Sound Management
|
|
//--------------------
|
|
|
|
// Decompresses a mono stream containing len samples
|
|
// (src is len bytes, dst is len*2 bytes)
|
|
// prev is the previous decompression state or zero.
|
|
// Returns new decompression state.
|
|
unsigned sndDecompM16(unsigned short *dst, const unsigned char *src, unsigned len, unsigned prev) {
|
|
uint32_t i, eax, ebx;
|
|
if (len == 0)
|
|
return prev;
|
|
eax = prev;
|
|
ebx = 0;
|
|
|
|
for (i = 0; i < len; i++) {
|
|
ebx = *src;
|
|
src++;
|
|
|
|
eax += snd_8to16[ebx];
|
|
*dst = eax & 0xFFFF;
|
|
dst++;
|
|
}
|
|
|
|
return eax;
|
|
}
|
|
|
|
// Decompresses a stereo stream containing len samples
|
|
// (src is len*2 bytes, dst is len*4 bytes)
|
|
// prev is the previous decompression state or zero
|
|
// (It encodes the 16-bit states of the two stereo channels
|
|
// in its low and high order 16-bit halves.)
|
|
// Returns new decompression state.
|
|
unsigned sndDecompS16(unsigned short *dst, const unsigned char *src, unsigned len, unsigned prev) {
|
|
unsigned re = 0;
|
|
uint32_t eax, edx, ebx, i;
|
|
|
|
if (len == 0) {
|
|
return prev;
|
|
}
|
|
|
|
eax = (prev & 0xFFFF);
|
|
edx = ((prev & 0xFFFF0000) >> 16);
|
|
ebx = 0;
|
|
|
|
for (i = 0; i < len; i++) {
|
|
ebx = *src;
|
|
src++;
|
|
|
|
eax += snd_8to16[ebx];
|
|
*dst = (eax & 0xFFFF);
|
|
dst++;
|
|
|
|
ebx = *src;
|
|
src++;
|
|
|
|
edx += snd_8to16[ebx];
|
|
*dst = (edx & 0xFFFF);
|
|
dst++;
|
|
}
|
|
|
|
return (eax & 0xFFFF) | ((edx & 0xFFFF) << 16);
|
|
}
|
|
|
|
typedef struct {
|
|
unsigned char *tbuf;
|
|
int new_row, DiffBufPtrs;
|
|
unsigned x, y, w, h;
|
|
} tNextFrame;
|
|
|
|
// NOTE: On exit ebx is nf_fqty
|
|
void NF_DECOMP_INIT(bool HI_COLOR_FLAG, tNextFrame *nf) {
|
|
nf->DiffBufPtrs = nf_buf_prv - nf_buf_cur;
|
|
|
|
if (HI_COLOR_FLAG) {
|
|
nf_new_x = nf->x << (LOG2_SWIDTH + 1);
|
|
nf_new_w = nf->w << (LOG2_SWIDTH + 1);
|
|
} else {
|
|
nf_new_x = nf->x << LOG2_SWIDTH;
|
|
nf_new_w = nf->w << LOG2_SWIDTH;
|
|
}
|
|
nf_new_y = (nf->y << LOG2_SHEIGHT) * nf_fqty;
|
|
nf_new_h = (nf->h << LOG2_SHEIGHT) * nf_fqty;
|
|
|
|
nf->new_row = nf_new_row0 - nf_new_w;
|
|
|
|
// Move to correct place in current buffer
|
|
nf->tbuf = nf_buf_cur;
|
|
if (nf->x || nf->y) {
|
|
nf->tbuf += nf_new_y * nf_width + nf_new_x;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// signed 8-bit y * nf_width
|
|
signed int nfpk_ShiftY[256];
|
|
|
|
// Constant tables
|
|
|
|
// 8-bit -8:7 x nf_width + -8:7
|
|
signed short nfpk_ShiftP1[256];
|
|
signed short nfpk_ShiftP2[256];
|
|
|
|
// Constant tables
|
|
// mov eax, ebx/ecx
|
|
// EBX = 0
|
|
// ECX = 1
|
|
unsigned char nfhpk_mov4l[64];
|
|
|
|
// mov ax, bx,cx
|
|
// EBX = 0
|
|
// ECX = 1
|
|
unsigned char nfpk_mov4l[64];
|
|
|
|
// mov ds:[edi+0/4/8/12], ebx/edx/ecx/ebp
|
|
// EBX = 0
|
|
// EDX = 1
|
|
// ECX = 2
|
|
// EBP = 3
|
|
unsigned char nfhpk_mov8[1024];
|
|
|
|
// mov ax, bx/dx/cx/bp
|
|
// BX = 0
|
|
// DX = 1
|
|
// CX = 2
|
|
// BP = 3
|
|
unsigned char nfpk_mov8[1024];
|
|
|
|
// mov eax, ebx/edx/ecx/ebp
|
|
// EBX = 0
|
|
// EDX = 1
|
|
// ECX = 2
|
|
// EBP = 3
|
|
unsigned char nfhpk_mov4[1024];
|
|
|
|
// mov al, bl/bh/cl/ch
|
|
// BL = 0
|
|
// BH = 1
|
|
// CL = 2
|
|
// CH = 3
|
|
unsigned char nfpk_mov4[1024];
|
|
|
|
class initme {
|
|
public:
|
|
initme() {
|
|
int x, y;
|
|
int m4, m3, m2, m1;
|
|
signed char *ptr;
|
|
unsigned char *uptr;
|
|
|
|
// Do nfhpk_mov4l
|
|
uptr = nfhpk_mov4l;
|
|
for (m4 = 0; m4 < 2; ++m4)
|
|
for (m3 = 0; m3 < 2; ++m3)
|
|
for (m2 = 0; m2 < 2; ++m2)
|
|
for (m1 = 0; m1 < 2; ++m1) {
|
|
*uptr++ = m1;
|
|
*uptr++ = m2;
|
|
*uptr++ = m3;
|
|
*uptr++ = m4;
|
|
}
|
|
|
|
// Do nfpk_mov4l
|
|
uptr = nfpk_mov4l;
|
|
for (m4 = 0; m4 < 2; ++m4)
|
|
for (m3 = 0; m3 < 2; ++m3)
|
|
for (m2 = 0; m2 < 2; ++m2)
|
|
for (m1 = 0; m1 < 2; ++m1) {
|
|
*uptr++ = m1;
|
|
*uptr++ = m2;
|
|
*uptr++ = m3;
|
|
*uptr++ = m4;
|
|
}
|
|
|
|
// Do nfhpk_mov8
|
|
uptr = nfhpk_mov8;
|
|
for (m4 = 0; m4 < 4; ++m4)
|
|
for (m3 = 0; m3 < 4; ++m3)
|
|
for (m2 = 0; m2 < 4; ++m2)
|
|
for (m1 = 0; m1 < 4; ++m1) {
|
|
*uptr++ = m1;
|
|
*uptr++ = m2;
|
|
*uptr++ = m3;
|
|
*uptr++ = m4;
|
|
}
|
|
|
|
// Do nfpk_mov8
|
|
uptr = nfpk_mov8;
|
|
for (m4 = 0; m4 < 4; ++m4)
|
|
for (m3 = 0; m3 < 4; ++m3)
|
|
for (m2 = 0; m2 < 4; ++m2)
|
|
for (m1 = 0; m1 < 4; ++m1) {
|
|
*uptr++ = m1;
|
|
*uptr++ = m2;
|
|
*uptr++ = m3;
|
|
*uptr++ = m4;
|
|
}
|
|
|
|
// Do nfhpk_mov4
|
|
uptr = nfhpk_mov4;
|
|
for (m4 = 0; m4 < 4; ++m4)
|
|
for (m3 = 0; m3 < 4; ++m3)
|
|
for (m2 = 0; m2 < 4; ++m2)
|
|
for (m1 = 0; m1 < 4; ++m1) {
|
|
*uptr++ = m1;
|
|
*uptr++ = m2;
|
|
*uptr++ = m3;
|
|
*uptr++ = m4;
|
|
}
|
|
|
|
// Do nfpk_mov4
|
|
uptr = nfpk_mov4;
|
|
for (m4 = 0; m4 < 4; ++m4)
|
|
for (m3 = 0; m3 < 4; ++m3)
|
|
for (m2 = 0; m2 < 4; ++m2)
|
|
for (m1 = 0; m1 < 4; ++m1) {
|
|
*uptr++ = m1;
|
|
*uptr++ = m2;
|
|
*uptr++ = m3;
|
|
*uptr++ = m4;
|
|
}
|
|
|
|
// do nfpk_ShiftP1
|
|
ptr = (signed char *)nfpk_ShiftP1;
|
|
for (y = -8; y != 8; y++) {
|
|
for (x = -8; x != 8; x++) {
|
|
#ifdef OUTRAGE_BIG_ENDIAN
|
|
ptr[0] = y;
|
|
ptr[1] = x;
|
|
#else
|
|
ptr[0] = x;
|
|
ptr[1] = y;
|
|
#endif
|
|
ptr += 2;
|
|
}
|
|
}
|
|
|
|
// do nfpk_ShiftP2[]
|
|
ptr = (signed char *)nfpk_ShiftP2;
|
|
for (y = 0; y != 8; y++) {
|
|
for (x = 8; x != 15; x++) {
|
|
#ifdef OUTRAGE_BIG_ENDIAN
|
|
ptr[0] = y;
|
|
ptr[1] = x;
|
|
#else
|
|
ptr[0] = x;
|
|
ptr[1] = y;
|
|
#endif
|
|
ptr += 2;
|
|
}
|
|
}
|
|
|
|
for (y = 8; y != 14; y++) {
|
|
for (x = -14; x != 0; x++) {
|
|
#ifdef OUTRAGE_BIG_ENDIAN
|
|
ptr[0] = y;
|
|
ptr[1] = x;
|
|
#else
|
|
ptr[0] = x;
|
|
ptr[1] = y;
|
|
#endif
|
|
ptr += 2;
|
|
}
|
|
|
|
for (x = 0; x != 15; x++) {
|
|
#ifdef OUTRAGE_BIG_ENDIAN
|
|
ptr[0] = y;
|
|
ptr[1] = x;
|
|
#else
|
|
ptr[0] = x;
|
|
ptr[1] = y;
|
|
#endif
|
|
ptr += 2;
|
|
}
|
|
}
|
|
for (x = -14; x != 0; x++) {
|
|
#ifdef OUTRAGE_BIG_ENDIAN
|
|
ptr[0] = 14;
|
|
ptr[1] = x;
|
|
#else
|
|
ptr[0] = x;
|
|
ptr[1] = 14;
|
|
#endif
|
|
ptr += 2;
|
|
}
|
|
for (x = 0; x != 12; x++) {
|
|
#ifdef OUTRAGE_BIG_ENDIAN
|
|
ptr[0] = 14;
|
|
ptr[1] = x;
|
|
#else
|
|
ptr[0] = x;
|
|
ptr[1] = 14;
|
|
#endif
|
|
ptr += 2;
|
|
}
|
|
}
|
|
};
|
|
|
|
initme _initme;
|
|
|
|
// nfPkConfig initializes tables used by nfPkDecomp
|
|
// which are dependent on screen size.
|
|
void nfPkConfig(void) {
|
|
// Build ShiftY table
|
|
int index = 0;
|
|
int val;
|
|
|
|
val = 0;
|
|
for (int i = 0; i < 128; ++i) {
|
|
nfpk_ShiftY[index++] = val;
|
|
val += nf_width;
|
|
}
|
|
|
|
val = -int(nf_width << 7);
|
|
for (int i = 0; i < 128; ++i) {
|
|
nfpk_ShiftY[index++] = val;
|
|
val += nf_width;
|
|
}
|
|
}
|
|
|
|
unsigned short Trans16(const unsigned char *idx) { return nf_trans16_lo[idx[0]] | nf_trans16_hi[idx[1]]; }
|
|
|
|
int SkipOpcode(int opcode_to_use, bool hiColor, const unsigned char *&esi, const unsigned char *&bcomp,
|
|
unsigned char *&edi) {
|
|
switch (opcode_to_use) {
|
|
case 0:
|
|
case 1:
|
|
case 2:
|
|
// no esi change
|
|
break;
|
|
case 3:
|
|
case 4:
|
|
if (hiColor) {
|
|
++bcomp;
|
|
} else {
|
|
++esi;
|
|
}
|
|
break;
|
|
case 5:
|
|
esi += 2;
|
|
break;
|
|
case 6:
|
|
if (hiColor) {
|
|
esi += 2;
|
|
} else {
|
|
// we can't skip this -- though I've never came across this
|
|
return opcode_to_use;
|
|
}
|
|
break;
|
|
case 7: {
|
|
bool donf23 = false;
|
|
if (hiColor) {
|
|
unsigned short val = IntelSwapper(*(unsigned short *)esi);
|
|
if (val & 0x8000) {
|
|
donf23 = true;
|
|
}
|
|
} else {
|
|
if (esi[0] > esi[1]) {
|
|
donf23 = true;
|
|
}
|
|
}
|
|
|
|
if (donf23) {
|
|
esi += (hiColor) ? 6 : 4;
|
|
} else {
|
|
esi += (hiColor) ? 12 : 10;
|
|
}
|
|
} break;
|
|
|
|
case 8: {
|
|
bool mode2 = false;
|
|
if (hiColor) {
|
|
unsigned short val = IntelSwapper(*(unsigned short *)esi);
|
|
if (val & 0x8000) {
|
|
mode2 = true;
|
|
}
|
|
} else {
|
|
if (esi[0] > esi[1]) {
|
|
mode2 = true;
|
|
}
|
|
}
|
|
|
|
if (!mode2) {
|
|
esi += (hiColor) ? 24 : 16;
|
|
} else {
|
|
esi += (hiColor) ? 16 : 12;
|
|
}
|
|
} break;
|
|
|
|
case 9: {
|
|
bool mode2 = false;
|
|
bool mode3 = false;
|
|
|
|
if (hiColor) {
|
|
unsigned short val = IntelSwapper(*(unsigned short *)esi);
|
|
if (val & 0x8000) {
|
|
mode2 = true;
|
|
} else {
|
|
val = IntelSwapper(*(unsigned short *)(esi + 4));
|
|
if (val & 0x8000) {
|
|
mode3 = true;
|
|
}
|
|
}
|
|
} else {
|
|
if (esi[0] > esi[1]) {
|
|
mode2 = true;
|
|
} else if (esi[2] > esi[3]) {
|
|
mode3 = true;
|
|
}
|
|
}
|
|
|
|
if (mode2)
|
|
esi += (hiColor) ? 16 : 12;
|
|
else if (mode3)
|
|
esi += (hiColor) ? 12 : 8;
|
|
else
|
|
esi += (hiColor) ? 24 : 20;
|
|
} break;
|
|
case 10: {
|
|
// 2x2 4x4x2 (32 bytes) or 2x1 4x8x2 (24 bytes) or 1x2 4x8x2 (24 bytes)
|
|
bool mode2 = false;
|
|
|
|
if (hiColor) {
|
|
int val1 = IntelSwapper(*(unsigned short *)esi);
|
|
if (val1 & 0x8000) {
|
|
mode2 = true;
|
|
}
|
|
} else {
|
|
if (esi[0] > esi[1]) {
|
|
mode2 = true;
|
|
}
|
|
}
|
|
|
|
if (!mode2) {
|
|
esi += (hiColor) ? 48 : 32;
|
|
} else {
|
|
esi += (hiColor) ? 32 : 24;
|
|
}
|
|
} break;
|
|
|
|
case 11: {
|
|
esi += (hiColor) ? 128 : 64;
|
|
} break;
|
|
|
|
case 12: {
|
|
esi += (hiColor) ? 32 : 16;
|
|
} break;
|
|
|
|
case 13: {
|
|
esi += (hiColor) ? 8 : 4;
|
|
} break;
|
|
|
|
case 14: {
|
|
esi += (hiColor) ? 2 : 1;
|
|
} break;
|
|
|
|
case 15: {
|
|
esi += (hiColor) ? 0 : 2;
|
|
} break;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
// HiColor version
|
|
//
|
|
void nfHPkDecomp(unsigned char *ops, unsigned char *comp, unsigned x, unsigned y, unsigned w, unsigned h) {
|
|
PkDecompWorker(true, ops, comp, x, y, w, h);
|
|
}
|
|
|
|
void nfPkDecomp(unsigned char *ops, unsigned char *comp, unsigned x, unsigned y, unsigned w, unsigned h) {
|
|
PkDecompWorker(false, ops, comp, x, y, w, h);
|
|
}
|
|
|
|
void PkDecompWorker(const bool hiColor, const unsigned char *ops, const unsigned char *comp, const unsigned x,
|
|
const unsigned y, unsigned w, unsigned h) {
|
|
#ifdef OUTRAGE_BIG_ENDIAN
|
|
typedef struct {
|
|
unsigned short hax, ax;
|
|
} reg_word;
|
|
typedef struct {
|
|
signed char hah, hal, ah, al;
|
|
} reg_byte;
|
|
#else
|
|
typedef struct {
|
|
unsigned short ax, hax;
|
|
} reg_word;
|
|
typedef struct {
|
|
signed char al, ah, hal, hah;
|
|
} reg_byte;
|
|
#endif
|
|
|
|
tNextFrame nf;
|
|
nf.w = w;
|
|
nf.h = h;
|
|
nf.x = x;
|
|
nf.y = y;
|
|
|
|
NF_DECOMP_INIT((hiColor) ? 1 : 0, &nf);
|
|
const uint32_t kSWidthScaled = (hiColor) ? SWIDTH * 2 : SWIDTH;
|
|
|
|
int nfpk_back_right = nf_back_right - kSWidthScaled;
|
|
|
|
const unsigned char *esi = comp;
|
|
unsigned char *edi = nf.tbuf;
|
|
|
|
const unsigned char *bcomp = NULL;
|
|
if (hiColor) {
|
|
uint32_t bcompOffset = IntelSwapper(*((const unsigned short *)esi));
|
|
bcomp = esi + bcompOffset;
|
|
esi += 2;
|
|
}
|
|
|
|
int wcnt = w >> 1;
|
|
do {
|
|
if (--wcnt < 0) {
|
|
edi += nf.new_row;
|
|
--h;
|
|
wcnt = w >> 1;
|
|
continue;
|
|
}
|
|
|
|
bool first_opcode = true;
|
|
bool skipNextOpCode = false;
|
|
|
|
unsigned char opcode = *ops++;
|
|
int opcode_to_use = opcode & 0xF;
|
|
|
|
do_next_opcode:
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Note: this is all you should have to tweak
|
|
bool opcodesToProcess[16] = {true, true, true, true, // 0 - 3
|
|
true, true, true, true, // 4 - 7
|
|
true, true, true, true, // 8 - 11
|
|
true, true, true, true}; // 12 - 15
|
|
if (!opcodesToProcess[opcode_to_use]) {
|
|
opcode_to_use = SkipOpcode(opcode_to_use, hiColor, esi, bcomp, edi);
|
|
}
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
switch (opcode_to_use) {
|
|
case -1: {
|
|
// DEBUG: skip processing
|
|
// Note: esi will have been adjusted above in SkipOpcode
|
|
|
|
if (hiColor) {
|
|
// Here we can set the color to exactly what we want
|
|
const unsigned short kColor = 0;
|
|
unsigned short *pDst = reinterpret_cast<unsigned short *>(edi);
|
|
for (int r = 0; r < 8; ++r) {
|
|
pDst[0] = kColor;
|
|
pDst[1] = kColor;
|
|
pDst[2] = kColor;
|
|
pDst[3] = kColor;
|
|
pDst[4] = kColor;
|
|
pDst[5] = kColor;
|
|
pDst[6] = kColor;
|
|
pDst[7] = kColor;
|
|
pDst += nf_width >> 1;
|
|
}
|
|
} else {
|
|
// Here we paint with the palette index we want
|
|
const uint32_t kPaletteIndex = 0;
|
|
|
|
uint32_t *pDst = reinterpret_cast<uint32_t *>(edi);
|
|
const uint32_t kPalIndexDWord =
|
|
(kPaletteIndex << 24) | (kPaletteIndex << 16) | (kPaletteIndex << 8) | kPaletteIndex;
|
|
for (int r = 0; r < 8; ++r) {
|
|
pDst[0] = kPalIndexDWord;
|
|
pDst[1] = kPalIndexDWord;
|
|
pDst += nf_width >> 2;
|
|
}
|
|
}
|
|
|
|
// Adjust edi
|
|
edi += kSWidthScaled;
|
|
} break;
|
|
|
|
case 0: {
|
|
// No change from previous buffer
|
|
DOnf_shift(hiColor, nf.DiffBufPtrs, edi, nfpk_back_right);
|
|
} break;
|
|
case 1: {
|
|
// No change (and copied to screen)
|
|
edi += kSWidthScaled;
|
|
} break;
|
|
case 2: {
|
|
// Near shift from older part of current buffer
|
|
uint32_t offset;
|
|
if (hiColor) {
|
|
offset = *bcomp++;
|
|
} else {
|
|
offset = *esi++;
|
|
}
|
|
DOnf_xycshift(hiColor, nfpk_ShiftP2[offset], edi, nfpk_back_right);
|
|
} break;
|
|
case 3: {
|
|
// Near shift from newer part of current buffer
|
|
union {
|
|
uint32_t eax;
|
|
reg_word word;
|
|
reg_byte byte;
|
|
} myeax;
|
|
|
|
if (hiColor) {
|
|
myeax.eax = *bcomp++;
|
|
} else {
|
|
myeax.eax = *esi++;
|
|
}
|
|
|
|
myeax.word.ax = nfpk_ShiftP2[myeax.eax];
|
|
myeax.byte.al = -myeax.byte.al;
|
|
myeax.byte.ah = -myeax.byte.ah;
|
|
|
|
DOnf_xycshift(hiColor, myeax.eax, edi, nfpk_back_right);
|
|
} break;
|
|
case 4: {
|
|
// Near shift from previous buffer
|
|
union {
|
|
uint32_t eax;
|
|
reg_word word;
|
|
reg_byte byte;
|
|
} myeax;
|
|
|
|
if (hiColor) {
|
|
myeax.eax = *bcomp++;
|
|
} else {
|
|
myeax.eax = *esi++;
|
|
}
|
|
|
|
myeax.word.ax = nfpk_ShiftP1[myeax.eax];
|
|
DOnf_xypshift(hiColor, myeax.eax, edi, nfpk_back_right, nf.DiffBufPtrs);
|
|
} break;
|
|
case 5: {
|
|
// Far shift from previous buffer
|
|
uint32_t eax = IntelSwapper(*(unsigned short *)(esi));
|
|
esi += 2;
|
|
DOnf_xypshift(hiColor, eax, edi, nfpk_back_right, nf.DiffBufPtrs);
|
|
} break;
|
|
case 6: {
|
|
if (hiColor) {
|
|
// Far shift from current buffer
|
|
uint32_t val1 = IntelSwapper(*(unsigned short *)esi);
|
|
esi += 2;
|
|
DOnf_xycshift(hiColor, val1, edi, nfpk_back_right);
|
|
} else {
|
|
// Run of no changes (must only appear in first nibble opcodes)
|
|
// Next nibble k specifies 2k+4 squares with no changes
|
|
skipNextOpCode = true; // Next nibble is not an opcode
|
|
uint32_t cnt = ((opcode >> 4) & 0xF) + 2; // (minimum of 4 squares)
|
|
|
|
while (true) {
|
|
edi += SWIDTH * 2; // Advance over two squares
|
|
if (--cnt == 0)
|
|
break; // Last pair of squares
|
|
|
|
if (--wcnt >= 0) // Same row?
|
|
continue; // Yes
|
|
|
|
edi += nf.new_row; // Advance to next row
|
|
--h; // Decrement row count (should never become zero here)
|
|
wcnt = (w >> 1) - 1; // Reset wcnt
|
|
}
|
|
}
|
|
} break;
|
|
case 7: {
|
|
bool donf23 = false;
|
|
if (hiColor) {
|
|
unsigned short val = IntelSwapper(*(unsigned short *)esi);
|
|
if (val & 0x8000) {
|
|
donf23 = true;
|
|
}
|
|
} else {
|
|
if (esi[0] > esi[1]) {
|
|
donf23 = true;
|
|
}
|
|
}
|
|
|
|
if (!donf23) {
|
|
// 8x8x1 (12/10 bytes)
|
|
uint32_t colors[4];
|
|
if (hiColor) {
|
|
uint32_t ecx = (Trans16(esi + 2) << 16) | Trans16(esi);
|
|
uint32_t edx = (ecx >> 16) | (ecx << 16);
|
|
uint32_t ebx = (edx & 0xFFFF0000) | (ecx & 0xFFFF);
|
|
uint32_t ebp = (ecx & 0xFFFF0000) | (edx & 0xFFFF);
|
|
colors[0] = ebx;
|
|
colors[1] = edx;
|
|
colors[2] = ecx;
|
|
colors[3] = ebp;
|
|
} else {
|
|
uint32_t tcLo = esi[0];
|
|
uint32_t tcHi = esi[1];
|
|
colors[0] = tcLo | (tcLo << 8);
|
|
colors[1] = tcHi | (tcLo << 8);
|
|
colors[2] = tcLo | (tcHi << 8);
|
|
colors[3] = tcHi | (tcHi << 8);
|
|
}
|
|
|
|
const unsigned char *lookupTable = (hiColor) ? nfhpk_mov8 : nfpk_mov8;
|
|
const int kOffset = (hiColor) ? 4 : 2;
|
|
const int max_repcount = 8;
|
|
for (int rep_count = 0; rep_count < max_repcount; ++rep_count) {
|
|
const unsigned char *color_idx = lookupTable + (esi[rep_count + kOffset] * 4);
|
|
#ifdef OUTRAGE_BIG_ENDIAN
|
|
uint32_t w1 = colors[color_idx[3]];
|
|
uint32_t w2 = colors[color_idx[2]];
|
|
uint32_t w3 = colors[color_idx[1]];
|
|
uint32_t w4 = colors[color_idx[0]];
|
|
#else
|
|
uint32_t w1 = colors[color_idx[0]];
|
|
uint32_t w2 = colors[color_idx[1]];
|
|
uint32_t w3 = colors[color_idx[2]];
|
|
uint32_t w4 = colors[color_idx[3]];
|
|
#endif
|
|
if (hiColor) {
|
|
*(uint32_t *)(edi + 0) = w1;
|
|
*(uint32_t *)(edi + 4) = w2;
|
|
*(uint32_t *)(edi + 8) = w3;
|
|
*(uint32_t *)(edi + 12) = w4;
|
|
} else {
|
|
*(unsigned short *)(edi + 0) = w1;
|
|
*(unsigned short *)(edi + 2) = w2;
|
|
*(unsigned short *)(edi + 4) = w3;
|
|
*(unsigned short *)(edi + 6) = w4;
|
|
}
|
|
|
|
edi += nf_width;
|
|
}
|
|
esi += hiColor ? 12 : 10;
|
|
edi -= nf_width;
|
|
edi -= nfpk_back_right;
|
|
} else {
|
|
// low 4x4x1 (6/4 bytes)
|
|
uint32_t colors[2];
|
|
if (hiColor) {
|
|
uint32_t temp = nf_trans16_lo[*(esi)] | nf_trans16_hi[*(esi + 1)];
|
|
colors[0] = (temp << 16) | temp;
|
|
temp = nf_trans16_lo[*(esi + 2)] | nf_trans16_hi[*(esi + 3)];
|
|
colors[1] = (temp << 16) | temp;
|
|
} else {
|
|
uint32_t tcLo = esi[0];
|
|
uint32_t tcHi = esi[1];
|
|
colors[0] = tcLo | (tcLo << 8);
|
|
colors[1] = tcHi | (tcHi << 8);
|
|
}
|
|
|
|
const unsigned char *esiOffset = (hiColor) ? (esi + 4) : (esi + 2);
|
|
const unsigned char *lookupTable = (hiColor) ? nfhpk_mov4l : nfpk_mov4l;
|
|
const int max_repcount = 4;
|
|
for (int rep_count = 0; rep_count < max_repcount; ++rep_count) {
|
|
int idx;
|
|
switch (rep_count) {
|
|
case 0:
|
|
idx = esiOffset[0] & 0xF;
|
|
break;
|
|
case 1:
|
|
idx = esiOffset[0] >> 4;
|
|
break;
|
|
case 2:
|
|
idx = esiOffset[1] & 0xF;
|
|
break;
|
|
case 3:
|
|
idx = esiOffset[1] >> 4;
|
|
break;
|
|
}
|
|
|
|
const unsigned char *color_idx = lookupTable + (idx * 4);
|
|
#ifdef OUTRAGE_BIG_ENDIAN
|
|
uint32_t w1 = colors[color_idx[3]];
|
|
uint32_t w2 = colors[color_idx[2]];
|
|
uint32_t w3 = colors[color_idx[1]];
|
|
uint32_t w4 = colors[color_idx[0]];
|
|
#else
|
|
uint32_t w1 = colors[color_idx[0]];
|
|
uint32_t w2 = colors[color_idx[1]];
|
|
uint32_t w3 = colors[color_idx[2]];
|
|
uint32_t w4 = colors[color_idx[3]];
|
|
#endif
|
|
|
|
if (hiColor) {
|
|
*(uint32_t *)(edi + 0) = w1;
|
|
*(uint32_t *)(edi + 4) = w2;
|
|
*(uint32_t *)(edi + 8) = w3;
|
|
*(uint32_t *)(edi + 12) = w4;
|
|
*(uint32_t *)(edi + nf_width + 0) = w1;
|
|
*(uint32_t *)(edi + nf_width + 4) = w2;
|
|
*(uint32_t *)(edi + nf_width + 8) = w3;
|
|
*(uint32_t *)(edi + nf_width + 12) = w4;
|
|
} else {
|
|
*(unsigned short *)(edi + 0) = w1;
|
|
*(unsigned short *)(edi + 2) = w2;
|
|
*(unsigned short *)(edi + 4) = w3;
|
|
*(unsigned short *)(edi + 6) = w4;
|
|
*(unsigned short *)(edi + 0 + nf_width) = w1;
|
|
*(unsigned short *)(edi + 2 + nf_width) = w2;
|
|
*(unsigned short *)(edi + 4 + nf_width) = w3;
|
|
*(unsigned short *)(edi + 6 + nf_width) = w4;
|
|
}
|
|
|
|
edi += nf_width * 2;
|
|
}
|
|
edi -= nf_width * 2;
|
|
edi += nf_width;
|
|
edi -= nfpk_back_right;
|
|
esi += (hiColor) ? 6 : 4;
|
|
}
|
|
} break;
|
|
case 8: {
|
|
bool donf24 = false;
|
|
bool donf40 = false;
|
|
|
|
if (hiColor) {
|
|
unsigned short val = IntelSwapper(*(unsigned short *)esi);
|
|
if (val & 0x8000) {
|
|
val = IntelSwapper(*(unsigned short *)(esi + 8));
|
|
if (val & 0x8000) {
|
|
donf40 = true;
|
|
} else {
|
|
donf24 = true;
|
|
}
|
|
}
|
|
} else {
|
|
if (esi[0] > esi[1]) {
|
|
if (esi[6] > esi[7]) {
|
|
donf40 = true;
|
|
} else {
|
|
donf24 = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!donf24 && !donf40) {
|
|
uint32_t colors[4];
|
|
int max_repcount = 8;
|
|
|
|
if (hiColor) {
|
|
uint32_t tempcolor;
|
|
tempcolor = nf_trans16_lo[*(esi + 2)] | nf_trans16_hi[*(esi + 3)];
|
|
tempcolor = (tempcolor << 16) | (nf_trans16_lo[*(esi + 0)] | nf_trans16_hi[*(esi + 1)]);
|
|
colors[2] = tempcolor;
|
|
tempcolor = ((tempcolor & 0xFFFF0000) >> 16) | ((tempcolor & 0xFFFF) << 16);
|
|
colors[0] = (tempcolor & 0xFFFF0000) | (colors[2] & 0xFFFF);
|
|
colors[1] = tempcolor;
|
|
colors[3] = (colors[2] & 0xFFFF0000) | (colors[1] & 0xFFFF);
|
|
} else {
|
|
uint32_t tcLo = esi[0];
|
|
uint32_t tcHi = esi[1];
|
|
colors[0] = tcLo | (tcLo << 8);
|
|
colors[1] = tcHi | (tcLo << 8);
|
|
colors[2] = tcLo | (tcHi << 8);
|
|
colors[3] = tcHi | (tcHi << 8);
|
|
}
|
|
|
|
int repLookup[8] = {4, 5, 10, 11, 16, 17, 22, 23};
|
|
if (!hiColor) {
|
|
repLookup[0] -= 2;
|
|
repLookup[1] -= 2;
|
|
repLookup[2] -= 4;
|
|
repLookup[3] -= 4;
|
|
repLookup[4] -= 6;
|
|
repLookup[5] -= 6;
|
|
repLookup[6] -= 8;
|
|
repLookup[7] -= 8;
|
|
}
|
|
const unsigned char *lookupTable = (hiColor) ? nfhpk_mov8 : nfpk_mov8;
|
|
|
|
for (int rep_count = 0; rep_count < max_repcount; ++rep_count) {
|
|
int idx = repLookup[rep_count];
|
|
const unsigned char *color_idx = lookupTable + (esi[idx] * 4);
|
|
#ifdef OUTRAGE_BIG_ENDIAN
|
|
uint32_t w1 = colors[color_idx[3]];
|
|
uint32_t w2 = colors[color_idx[2]];
|
|
uint32_t w3 = colors[color_idx[1]];
|
|
uint32_t w4 = colors[color_idx[0]];
|
|
#else
|
|
uint32_t w1 = colors[color_idx[0]];
|
|
uint32_t w2 = colors[color_idx[1]];
|
|
uint32_t w3 = colors[color_idx[2]];
|
|
uint32_t w4 = colors[color_idx[3]];
|
|
#endif
|
|
|
|
if (hiColor) {
|
|
*(uint32_t *)(edi + 0) = w1;
|
|
*(uint32_t *)(edi + 4) = w2;
|
|
edi += nf_width;
|
|
*(uint32_t *)(edi + 0) = w3;
|
|
*(uint32_t *)(edi + 4) = w4;
|
|
edi += nf_width;
|
|
} else {
|
|
*(unsigned short *)(edi + 0) = w1;
|
|
*(unsigned short *)(edi + 2) = w2;
|
|
edi += nf_width;
|
|
*(unsigned short *)(edi + 0) = w3;
|
|
*(unsigned short *)(edi + 2) = w4;
|
|
edi += nf_width;
|
|
}
|
|
|
|
if (rep_count == 1) {
|
|
if (hiColor) {
|
|
uint32_t tempcolor = nf_trans16_lo[*(esi + 8)] | nf_trans16_hi[*(esi + 9)];
|
|
tempcolor = (tempcolor << 16) | (nf_trans16_lo[*(esi + 6)] | nf_trans16_hi[*(esi + 7)]);
|
|
colors[2] = tempcolor;
|
|
tempcolor = ((tempcolor & 0xFFFF0000) >> 16) | ((tempcolor & 0xFFFF) << 16);
|
|
colors[0] = (tempcolor & 0xFFFF0000) | (colors[2] & 0xFFFF);
|
|
colors[1] = tempcolor;
|
|
colors[3] = (colors[2] & 0xFFFF0000) | (colors[1] & 0xFFFF);
|
|
} else {
|
|
uint32_t tcLo = esi[4];
|
|
uint32_t tcHi = esi[5];
|
|
colors[0] = tcLo | (tcLo << 8);
|
|
colors[1] = tcHi | (tcLo << 8);
|
|
colors[2] = tcLo | (tcHi << 8);
|
|
colors[3] = tcHi | (tcHi << 8);
|
|
}
|
|
} else if (rep_count == 3) {
|
|
if (hiColor) {
|
|
edi -= nf_width * 8 - 8;
|
|
uint32_t tempcolor = nf_trans16_lo[*(esi + 14)] | nf_trans16_hi[*(esi + 15)];
|
|
tempcolor = (tempcolor << 16) | (nf_trans16_lo[*(esi + 12)] | nf_trans16_hi[*(esi + 13)]);
|
|
colors[2] = tempcolor;
|
|
tempcolor = ((tempcolor & 0xFFFF0000) >> 16) | ((tempcolor & 0xFFFF) << 16);
|
|
colors[0] = (tempcolor & 0xFFFF0000) | (colors[2] & 0xFFFF);
|
|
colors[1] = tempcolor;
|
|
colors[3] = (colors[2] & 0xFFFF0000) | (colors[1] & 0xFFFF);
|
|
} else {
|
|
edi -= nf_width * 8 - 4;
|
|
uint32_t tcLo = esi[8];
|
|
uint32_t tcHi = esi[9];
|
|
colors[0] = tcLo | (tcLo << 8);
|
|
colors[1] = tcHi | (tcLo << 8);
|
|
colors[2] = tcLo | (tcHi << 8);
|
|
colors[3] = tcHi | (tcHi << 8);
|
|
}
|
|
} else if (rep_count == 5) {
|
|
if (hiColor) {
|
|
uint32_t tempcolor = nf_trans16_lo[*(esi + 20)] | nf_trans16_hi[*(esi + 21)];
|
|
tempcolor = (tempcolor << 16) | (nf_trans16_lo[*(esi + 18)] | nf_trans16_hi[*(esi + 19)]);
|
|
colors[2] = tempcolor;
|
|
tempcolor = ((tempcolor & 0xFFFF0000) >> 16) | ((tempcolor & 0xFFFF) << 16);
|
|
colors[0] = (tempcolor & 0xFFFF0000) | (colors[2] & 0xFFFF);
|
|
colors[1] = tempcolor;
|
|
colors[3] = (colors[2] & 0xFFFF0000) | (colors[1] & 0xFFFF);
|
|
} else {
|
|
uint32_t tcLo = esi[12];
|
|
uint32_t tcHi = esi[13];
|
|
colors[0] = tcLo | (tcLo << 8);
|
|
colors[1] = tcHi | (tcLo << 8);
|
|
colors[2] = tcLo | (tcHi << 8);
|
|
colors[3] = tcHi | (tcHi << 8);
|
|
}
|
|
}
|
|
}
|
|
|
|
edi -= nf_width;
|
|
esi += (hiColor) ? 24 : 16;
|
|
edi -= ((hiColor) ? 8 : 4) + nfpk_back_right;
|
|
}
|
|
|
|
if (donf24) {
|
|
uint32_t colors[4];
|
|
|
|
if (hiColor) {
|
|
uint32_t tempcolor = nf_trans16_lo[*(esi + 2)] | nf_trans16_hi[*(esi + 3)];
|
|
tempcolor = (tempcolor << 16) | (nf_trans16_lo[*(esi + 0)] | nf_trans16_hi[*(esi + 1)]);
|
|
colors[2] = tempcolor;
|
|
tempcolor = ((tempcolor & 0xFFFF0000) >> 16) | ((tempcolor & 0xFFFF) << 16);
|
|
colors[0] = (tempcolor & 0xFFFF0000) | (colors[2] & 0xFFFF);
|
|
colors[1] = tempcolor;
|
|
colors[3] = (colors[2] & 0xFFFF0000) | (colors[1] & 0xFFFF);
|
|
} else {
|
|
uint32_t tcLo = esi[0];
|
|
uint32_t tcHi = esi[1];
|
|
colors[0] = tcLo | (tcLo << 8);
|
|
colors[1] = tcHi | (tcLo << 8);
|
|
colors[2] = tcLo | (tcHi << 8);
|
|
colors[3] = tcHi | (tcHi << 8);
|
|
}
|
|
|
|
int repLookupTable[8] = {4, 5, 6, 7, 12, 13, 14, 15};
|
|
if (!hiColor) {
|
|
repLookupTable[0] -= 2;
|
|
repLookupTable[1] -= 2;
|
|
repLookupTable[2] -= 2;
|
|
repLookupTable[3] -= 2;
|
|
repLookupTable[4] -= 4;
|
|
repLookupTable[5] -= 4;
|
|
repLookupTable[6] -= 4;
|
|
repLookupTable[7] -= 4;
|
|
}
|
|
|
|
const unsigned char *lookupTable = (hiColor) ? nfhpk_mov8 : nfpk_mov8;
|
|
|
|
int max_repcount = 8;
|
|
for (int rep_count = 0; rep_count < max_repcount; rep_count++) {
|
|
int idx = repLookupTable[rep_count];
|
|
const unsigned char *color_idx = lookupTable + (esi[idx] * 4);
|
|
uint32_t w1 = colors[color_idx[0]];
|
|
uint32_t w2 = colors[color_idx[1]];
|
|
uint32_t w3 = colors[color_idx[2]];
|
|
uint32_t w4 = colors[color_idx[3]];
|
|
|
|
if (hiColor) {
|
|
*(uint32_t *)(edi + 0) = w1;
|
|
*(uint32_t *)(edi + 4) = w2;
|
|
edi += nf_width;
|
|
*(uint32_t *)(edi + 0) = w3;
|
|
*(uint32_t *)(edi + 4) = w4;
|
|
edi += nf_width;
|
|
} else {
|
|
*(unsigned short *)(edi + 0) = w1;
|
|
*(unsigned short *)(edi + 2) = w2;
|
|
edi += nf_width;
|
|
*(unsigned short *)(edi + 0) = w3;
|
|
*(unsigned short *)(edi + 2) = w4;
|
|
edi += nf_width;
|
|
}
|
|
|
|
if (rep_count == 3) {
|
|
if (hiColor) {
|
|
edi -= nf_width * 8 - 8;
|
|
|
|
uint32_t tempcolor = nf_trans16_lo[*(esi + 10)] | nf_trans16_hi[*(esi + 11)];
|
|
tempcolor = (tempcolor << 16) | (nf_trans16_lo[*(esi + 8)] | nf_trans16_hi[*(esi + 9)]);
|
|
colors[2] = tempcolor;
|
|
tempcolor = ((tempcolor & 0xFFFF0000) >> 16) | ((tempcolor & 0xFFFF) << 16);
|
|
colors[0] = (tempcolor & 0xFFFF0000) | (colors[2] & 0xFFFF);
|
|
colors[1] = tempcolor;
|
|
colors[3] = (colors[2] & 0xFFFF0000) | (colors[1] & 0xFFFF);
|
|
} else {
|
|
edi -= nf_width * 8 - 4;
|
|
|
|
uint32_t tcLo = esi[6];
|
|
uint32_t tcHi = esi[7];
|
|
colors[0] = tcLo | (tcLo << 8);
|
|
colors[1] = tcHi | (tcLo << 8);
|
|
colors[2] = tcLo | (tcHi << 8);
|
|
colors[3] = tcHi | (tcHi << 8);
|
|
}
|
|
}
|
|
}
|
|
|
|
esi += (hiColor) ? 16 : 12;
|
|
edi -= nf_width + ((hiColor) ? 8 : 4) + nfpk_back_right;
|
|
}
|
|
|
|
if (donf40) {
|
|
uint32_t colors[4];
|
|
|
|
if (hiColor) {
|
|
uint32_t tempcolor = nf_trans16_lo[*(esi + 2)] | nf_trans16_hi[*(esi + 3)];
|
|
tempcolor = (tempcolor << 16) | (nf_trans16_lo[*(esi + 0)] | nf_trans16_hi[*(esi + 1)]);
|
|
colors[2] = tempcolor;
|
|
tempcolor = ((tempcolor & 0xFFFF0000) >> 16) | ((tempcolor & 0xFFFF) << 16);
|
|
colors[0] = (tempcolor & 0xFFFF0000) | (colors[2] & 0xFFFF);
|
|
colors[1] = tempcolor;
|
|
colors[3] = (colors[2] & 0xFFFF0000) | (colors[1] & 0xFFFF);
|
|
} else {
|
|
uint32_t tcLo = esi[0];
|
|
uint32_t tcHi = esi[1];
|
|
colors[0] = tcLo | (tcLo << 8);
|
|
colors[1] = tcHi | (tcLo << 8);
|
|
colors[2] = tcLo | (tcHi << 8);
|
|
colors[3] = tcHi | (tcHi << 8);
|
|
}
|
|
|
|
int repLookupTable[8] = {4, 5, 6, 7, 12, 13, 14, 15};
|
|
if (!hiColor) {
|
|
repLookupTable[0] -= 2;
|
|
repLookupTable[1] -= 2;
|
|
repLookupTable[2] -= 2;
|
|
repLookupTable[3] -= 2;
|
|
repLookupTable[4] -= 4;
|
|
repLookupTable[5] -= 4;
|
|
repLookupTable[6] -= 4;
|
|
repLookupTable[7] -= 4;
|
|
}
|
|
const unsigned char *lookupTable = (hiColor) ? nfhpk_mov8 : nfpk_mov8;
|
|
|
|
int max_repcount = 8;
|
|
for (int rep_count = 0; rep_count < max_repcount; ++rep_count) {
|
|
int idx = repLookupTable[rep_count];
|
|
const unsigned char *color_idx = lookupTable + (esi[idx] * 4);
|
|
#ifdef OUTRAGE_BIG_ENDIAN
|
|
uint32_t w1 = colors[color_idx[3]];
|
|
uint32_t w2 = colors[color_idx[2]];
|
|
uint32_t w3 = colors[color_idx[1]];
|
|
uint32_t w4 = colors[color_idx[0]];
|
|
#else
|
|
uint32_t w1 = colors[color_idx[0]];
|
|
uint32_t w2 = colors[color_idx[1]];
|
|
uint32_t w3 = colors[color_idx[2]];
|
|
uint32_t w4 = colors[color_idx[3]];
|
|
#endif
|
|
if (hiColor) {
|
|
*(uint32_t *)(edi + 0) = w1;
|
|
*(uint32_t *)(edi + 4) = w2;
|
|
*(uint32_t *)(edi + 8) = w3;
|
|
*(uint32_t *)(edi + 12) = w4;
|
|
} else {
|
|
*(unsigned short *)(edi + 0) = w1;
|
|
*(unsigned short *)(edi + 2) = w2;
|
|
*(unsigned short *)(edi + 4) = w3;
|
|
*(unsigned short *)(edi + 6) = w4;
|
|
}
|
|
edi += nf_width;
|
|
|
|
if (rep_count == 3) {
|
|
if (hiColor) {
|
|
uint32_t tempcolor = nf_trans16_lo[*(esi + 10)] | nf_trans16_hi[*(esi + 11)];
|
|
tempcolor = (tempcolor << 16) | (nf_trans16_lo[*(esi + 8)] | nf_trans16_hi[*(esi + 9)]);
|
|
colors[2] = tempcolor;
|
|
tempcolor = ((tempcolor & 0xFFFF0000) >> 16) | ((tempcolor & 0xFFFF) << 16);
|
|
colors[0] = (tempcolor & 0xFFFF0000) | (colors[2] & 0xFFFF);
|
|
colors[1] = tempcolor;
|
|
colors[3] = (colors[2] & 0xFFFF0000) | (colors[1] & 0xFFFF);
|
|
} else {
|
|
uint32_t tcLo = esi[6];
|
|
uint32_t tcHi = esi[7];
|
|
colors[0] = tcLo | (tcLo << 8);
|
|
colors[1] = tcHi | (tcLo << 8);
|
|
colors[2] = tcLo | (tcHi << 8);
|
|
colors[3] = tcHi | (tcHi << 8);
|
|
}
|
|
}
|
|
}
|
|
|
|
esi += (hiColor) ? 16 : 12;
|
|
edi -= nf_width + nfpk_back_right;
|
|
}
|
|
} break;
|
|
case 9: {
|
|
bool donf41 = false;
|
|
bool donf25 = false;
|
|
bool donf57 = false;
|
|
|
|
if (hiColor) {
|
|
unsigned short val = IntelSwapper(*(unsigned short *)esi);
|
|
if (val & 0x8000) {
|
|
val = IntelSwapper(*(unsigned short *)(esi + 4));
|
|
if (val & 0x8000) {
|
|
donf57 = true;
|
|
} else {
|
|
donf41 = true;
|
|
}
|
|
|
|
} else {
|
|
val = IntelSwapper(*(unsigned short *)(esi + 4));
|
|
if (val & 0x8000) {
|
|
donf25 = true;
|
|
}
|
|
}
|
|
} else {
|
|
if (esi[0] > esi[1]) {
|
|
if (esi[2] > esi[3]) {
|
|
donf57 = true;
|
|
} else {
|
|
donf41 = true;
|
|
}
|
|
} else if (esi[2] > esi[3]) {
|
|
donf25 = true;
|
|
}
|
|
}
|
|
|
|
if (donf57) {
|
|
unsigned short colors[4];
|
|
if (hiColor) {
|
|
colors[0] = nf_trans16_lo[*(esi)] | nf_trans16_hi[*(esi + 1)];
|
|
colors[1] = nf_trans16_lo[*(esi + 2)] | nf_trans16_hi[*(esi + 3)];
|
|
colors[2] = nf_trans16_lo[*(esi + 4)] | nf_trans16_hi[*(esi + 5)];
|
|
colors[3] = nf_trans16_lo[*(esi + 6)] | nf_trans16_hi[*(esi + 7)];
|
|
} else {
|
|
colors[0] = esi[0];
|
|
colors[1] = esi[1];
|
|
colors[2] = esi[2];
|
|
colors[3] = esi[3];
|
|
}
|
|
|
|
const int max_repcount = 8;
|
|
const unsigned char *lookupTable = (hiColor) ? nfhpk_mov4 : nfpk_mov4;
|
|
for (int rep_count = 0; rep_count < max_repcount; ++rep_count) {
|
|
int idx = rep_count + ((hiColor) ? 8 : 4);
|
|
const unsigned char *color_idx = lookupTable + (esi[idx] * 4);
|
|
|
|
uint32_t w1 = colors[color_idx[0]];
|
|
uint32_t w2 = colors[color_idx[1]];
|
|
uint32_t w3 = colors[color_idx[2]];
|
|
uint32_t w4 = colors[color_idx[3]];
|
|
|
|
if (rep_count & 1) {
|
|
#ifdef OUTRAGE_BIG_ENDIAN
|
|
if (hiColor) {
|
|
*(uint32_t *)(edi + 8) = (w1 & 0xFFFF) | ((w2 & 0xFFFF) << 16);
|
|
*(uint32_t *)(edi + nf_width + 8) = (w1 & 0xFFFF) | ((w2 & 0xFFFF) << 16);
|
|
|
|
*(uint32_t *)(edi + 12) = (w3 & 0xFFFF) | ((w4 & 0xFFFF) << 16);
|
|
*(uint32_t *)(edi + nf_width + 12) = (w3 & 0xFFFF) | ((w4 & 0xFFFF) << 16);
|
|
} else {
|
|
*(unsigned char *)(edi + 4) = w4;
|
|
*(unsigned char *)(edi + 5) = w3;
|
|
*(unsigned char *)(edi + 6) = w2;
|
|
*(unsigned char *)(edi + 7) = w1;
|
|
|
|
*(unsigned char *)(edi + nf_width + 4) = w4;
|
|
*(unsigned char *)(edi + nf_width + 5) = w3;
|
|
*(unsigned char *)(edi + nf_width + 6) = w2;
|
|
*(unsigned char *)(edi + nf_width + 7) = w1;
|
|
}
|
|
#else
|
|
if (hiColor) {
|
|
*(uint32_t *)(edi + 8) = (w1 & 0xFFFF) | ((w2 & 0xFFFF) << 16);
|
|
*(uint32_t *)(edi + nf_width + 8) = (w1 & 0xFFFF) | ((w2 & 0xFFFF) << 16);
|
|
|
|
*(uint32_t *)(edi + 12) = (w3 & 0xFFFF) | ((w4 & 0xFFFF) << 16);
|
|
*(uint32_t *)(edi + nf_width + 12) = (w3 & 0xFFFF) | ((w4 & 0xFFFF) << 16);
|
|
} else {
|
|
*(unsigned char *)(edi + 4) = w1;
|
|
*(unsigned char *)(edi + 5) = w2;
|
|
*(unsigned char *)(edi + 6) = w3;
|
|
*(unsigned char *)(edi + 7) = w4;
|
|
|
|
*(unsigned char *)(edi + nf_width + 4) = w1;
|
|
*(unsigned char *)(edi + nf_width + 5) = w2;
|
|
*(unsigned char *)(edi + nf_width + 6) = w3;
|
|
*(unsigned char *)(edi + nf_width + 7) = w4;
|
|
}
|
|
#endif
|
|
edi += nf_width * 2;
|
|
} else {
|
|
if (hiColor) {
|
|
#ifdef OUTRAGE_BIG_ENDIAN
|
|
*(uint32_t *)(edi + 0) = (w4 & 0xFFFF) | ((w3 & 0xFFFF) << 16);
|
|
*(uint32_t *)(edi + nf_width) = (w4 & 0xFFFF) | ((w3 & 0xFFFF) << 16);
|
|
|
|
*(uint32_t *)(edi + 4) = (w2 & 0xFFFF) | ((w1 & 0xFFFF) << 16);
|
|
*(uint32_t *)(edi + nf_width + 4) = (w2 & 0xFFFF) | ((w1 & 0xFFFF) << 16);
|
|
#else
|
|
*(uint32_t *)(edi + 0) = (w1 & 0xFFFF) | ((w2 & 0xFFFF) << 16);
|
|
*(uint32_t *)(edi + nf_width) = (w1 & 0xFFFF) | ((w2 & 0xFFFF) << 16);
|
|
|
|
*(uint32_t *)(edi + 4) = (w3 & 0xFFFF) | ((w4 & 0xFFFF) << 16);
|
|
*(uint32_t *)(edi + nf_width + 4) = (w3 & 0xFFFF) | ((w4 & 0xFFFF) << 16);
|
|
#endif
|
|
} else {
|
|
const uint32_t value = IntelSwapper((uint32_t)(w4 << 24) | (w3 << 16) | (w2 << 8) | w1);
|
|
*(uint32_t *)(edi) = value;
|
|
*(uint32_t *)(edi + nf_width) = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
esi += (hiColor) ? 16 : 12;
|
|
edi -= nf_width * 2;
|
|
edi += nf_width;
|
|
edi -= nfpk_back_right;
|
|
} else if (donf41) {
|
|
uint32_t colors[4];
|
|
if (hiColor) {
|
|
colors[0] = nf_trans16_lo[*(esi)] | nf_trans16_hi[*(esi + 1)];
|
|
colors[0] = ((colors[0]) << 16) | colors[0];
|
|
colors[1] = nf_trans16_lo[*(esi + 2)] | nf_trans16_hi[*(esi + 3)];
|
|
colors[1] = ((colors[1]) << 16) | colors[1];
|
|
colors[2] = nf_trans16_lo[*(esi + 4)] | nf_trans16_hi[*(esi + 5)];
|
|
colors[2] = ((colors[2]) << 16) | colors[2];
|
|
colors[3] = nf_trans16_lo[*(esi + 6)] | nf_trans16_hi[*(esi + 7)];
|
|
colors[3] = ((colors[3]) << 16) | colors[3];
|
|
} else {
|
|
colors[0] = esi[0];
|
|
colors[1] = esi[1];
|
|
colors[2] = esi[2];
|
|
colors[3] = esi[3];
|
|
}
|
|
|
|
const int max_repcount = 8;
|
|
const unsigned char *lookupTable = (hiColor) ? nfhpk_mov8 : nfpk_mov4;
|
|
for (int rep_count = 0; rep_count < max_repcount; ++rep_count) {
|
|
int idx = rep_count + ((hiColor) ? 8 : 4);
|
|
const unsigned char *color_idx = lookupTable + (esi[idx] * 4);
|
|
uint32_t w1 = colors[color_idx[0]];
|
|
uint32_t w2 = colors[color_idx[1]];
|
|
uint32_t w3 = colors[color_idx[2]];
|
|
uint32_t w4 = colors[color_idx[3]];
|
|
#ifdef OUTRAGE_BIG_ENDIAN
|
|
if (hiColor) {
|
|
*(uint32_t *)(edi + 0) = w4;
|
|
*(uint32_t *)(edi + 4) = w3;
|
|
*(uint32_t *)(edi + 8) = w2;
|
|
*(uint32_t *)(edi + 12) = w1;
|
|
} else {
|
|
*(unsigned char *)(edi + 0) = w4;
|
|
*(unsigned char *)(edi + 1) = w4;
|
|
*(unsigned char *)(edi + 2) = w3;
|
|
*(unsigned char *)(edi + 3) = w3;
|
|
*(unsigned char *)(edi + 4) = w2;
|
|
*(unsigned char *)(edi + 5) = w2;
|
|
*(unsigned char *)(edi + 6) = w1;
|
|
*(unsigned char *)(edi + 7) = w1;
|
|
}
|
|
#else
|
|
if (hiColor) {
|
|
*(uint32_t *)(edi + 0) = w1;
|
|
*(uint32_t *)(edi + 4) = w2;
|
|
*(uint32_t *)(edi + 8) = w3;
|
|
*(uint32_t *)(edi + 12) = w4;
|
|
} else {
|
|
*(unsigned char *)(edi + 0) = w1;
|
|
*(unsigned char *)(edi + 1) = w1;
|
|
*(unsigned char *)(edi + 2) = w2;
|
|
*(unsigned char *)(edi + 3) = w2;
|
|
*(unsigned char *)(edi + 4) = w3;
|
|
*(unsigned char *)(edi + 5) = w3;
|
|
*(unsigned char *)(edi + 6) = w4;
|
|
*(unsigned char *)(edi + 7) = w4;
|
|
}
|
|
|
|
#endif
|
|
edi += nf_width;
|
|
}
|
|
|
|
esi += (hiColor) ? 16 : 12;
|
|
edi -= nf_width;
|
|
edi -= nfpk_back_right;
|
|
} else if (donf25) {
|
|
uint32_t colors[4];
|
|
if (hiColor) {
|
|
colors[0] = nf_trans16_lo[*(esi)] | nf_trans16_hi[*(esi + 1)];
|
|
colors[0] = ((colors[0]) << 16) | colors[0];
|
|
colors[1] = nf_trans16_lo[*(esi + 2)] | nf_trans16_hi[*(esi + 3)];
|
|
colors[1] = ((colors[1]) << 16) | colors[1];
|
|
colors[2] = nf_trans16_lo[*(esi + 4)] | nf_trans16_hi[*(esi + 5)];
|
|
colors[2] = ((colors[2]) << 16) | colors[2];
|
|
colors[3] = nf_trans16_lo[*(esi + 6)] | nf_trans16_hi[*(esi + 7)];
|
|
colors[3] = ((colors[3]) << 16) | colors[3];
|
|
} else {
|
|
colors[0] = esi[0];
|
|
colors[1] = esi[1];
|
|
colors[2] = esi[2];
|
|
colors[3] = esi[3];
|
|
}
|
|
|
|
const unsigned char *lookupTable = (hiColor) ? nfhpk_mov4 : nfpk_mov4;
|
|
const int max_repcount = 4;
|
|
for (int rep_count = 0; rep_count < max_repcount; ++rep_count) {
|
|
int idx = rep_count + (hiColor ? 8 : 4);
|
|
const unsigned char *color_idx = lookupTable + (esi[idx] * 4);
|
|
uint32_t w1 = colors[color_idx[0]];
|
|
uint32_t w2 = colors[color_idx[1]];
|
|
uint32_t w3 = colors[color_idx[2]];
|
|
uint32_t w4 = colors[color_idx[3]];
|
|
|
|
if (hiColor) {
|
|
#ifdef OUTRAGE_BIG_ENDIAN
|
|
*(uint32_t *)(edi + 0) = w4;
|
|
*(uint32_t *)(edi + nf_width) = w4;
|
|
*(uint32_t *)(edi + 4) = w3;
|
|
*(uint32_t *)(edi + nf_width + 4) = w3;
|
|
*(uint32_t *)(edi + 8) = w2;
|
|
*(uint32_t *)(edi + nf_width + 8) = w2;
|
|
*(uint32_t *)(edi + 12) = w1;
|
|
*(uint32_t *)(edi + nf_width + 12) = w1;
|
|
#else
|
|
*(uint32_t *)(edi + 0) = w1;
|
|
*(uint32_t *)(edi + nf_width) = w1;
|
|
*(uint32_t *)(edi + 4) = w2;
|
|
*(uint32_t *)(edi + nf_width + 4) = w2;
|
|
*(uint32_t *)(edi + 8) = w3;
|
|
*(uint32_t *)(edi + nf_width + 8) = w3;
|
|
*(uint32_t *)(edi + 12) = w4;
|
|
*(uint32_t *)(edi + nf_width + 12) = w4;
|
|
#endif
|
|
} else {
|
|
uint32_t c0 = IntelSwapper((uint32_t)(w2 << 24) | (w2 << 16) | (w1 << 8) | w1);
|
|
uint32_t c1 = IntelSwapper((uint32_t)(w4 << 24) | (w4 << 16) | (w3 << 8) | w3);
|
|
*(uint32_t *)(edi + 0) = c0;
|
|
*(uint32_t *)(edi + nf_width) = c0;
|
|
*(uint32_t *)(edi + 4) = c1;
|
|
*(uint32_t *)(edi + nf_width + 4) = c1;
|
|
}
|
|
|
|
edi += nf_width * 2;
|
|
}
|
|
|
|
edi -= nf_width * 2;
|
|
edi += nf_width;
|
|
esi += (hiColor) ? 12 : 8;
|
|
edi -= nfpk_back_right;
|
|
} else {
|
|
unsigned short colors[4];
|
|
if (hiColor) {
|
|
colors[0] = Trans16(esi + 0);
|
|
colors[1] = Trans16(esi + 2);
|
|
colors[2] = Trans16(esi + 4);
|
|
colors[3] = Trans16(esi + 6);
|
|
} else {
|
|
colors[0] = esi[0];
|
|
colors[1] = esi[1];
|
|
colors[2] = esi[2];
|
|
colors[3] = esi[3];
|
|
}
|
|
|
|
const unsigned char *lookupTable = (hiColor) ? nfhpk_mov4 : nfpk_mov4;
|
|
const int max_repcount = 16;
|
|
for (int rep_count = 0; rep_count < max_repcount; ++rep_count) {
|
|
int idx = rep_count + ((hiColor) ? 8 : 4);
|
|
const unsigned char *color_idx = lookupTable + (esi[idx] * 4);
|
|
|
|
uint32_t w1 = colors[color_idx[0]];
|
|
uint32_t w2 = colors[color_idx[1]];
|
|
uint32_t w3 = colors[color_idx[2]];
|
|
uint32_t w4 = colors[color_idx[3]];
|
|
|
|
if (rep_count & 1) {
|
|
if (hiColor) {
|
|
#ifdef OUTRAGE_BIG_ENDIAN
|
|
*(uint32_t *)(edi + 8) = (w4 & 0xFFFF) | ((w3 & 0xFFFF) << 16);
|
|
*(uint32_t *)(edi + 12) = (w2 & 0xFFFF) | ((w1 & 0xFFFF) << 16);
|
|
#else
|
|
*(uint32_t *)(edi + 8) = (w1 & 0xFFFF) | ((w2 & 0xFFFF) << 16);
|
|
*(uint32_t *)(edi + 12) = (w3 & 0xFFFF) | ((w4 & 0xFFFF) << 16);
|
|
#endif
|
|
} else {
|
|
*(uint32_t *)(edi + 4) = IntelSwapper((uint32_t)(w4 << 24) | (w3 << 16) | (w2 << 8) | w1);
|
|
}
|
|
|
|
edi += nf_width;
|
|
} else {
|
|
if (hiColor) {
|
|
#ifdef OUTRAGE_BIG_ENDIAN
|
|
*(uint32_t *)(edi + 0) = (w4 & 0xFFFF) | ((w3 & 0xFFFF) << 16);
|
|
*(uint32_t *)(edi + 4) = (w2 & 0xFFFF) | ((w1 & 0xFFFF) << 16);
|
|
#else
|
|
*(uint32_t *)(edi + 0) = (w1 & 0xFFFF) | ((w2 & 0xFFFF) << 16);
|
|
*(uint32_t *)(edi + 4) = (w3 & 0xFFFF) | ((w4 & 0xFFFF) << 16);
|
|
#endif
|
|
} else {
|
|
*(uint32_t *)(edi + 0) = IntelSwapper((uint32_t)(w4 << 24) | (w3 << 16) | (w2 << 8) | w1);
|
|
}
|
|
}
|
|
}
|
|
|
|
edi -= nf_width;
|
|
esi += (hiColor) ? 24 : 20;
|
|
edi -= nfpk_back_right;
|
|
}
|
|
} break;
|
|
case 10: {
|
|
// 2x2 4x4x2 (32 bytes) or 2x1 4x8x2 (24 bytes) or 1x2 4x8x2 (24 bytes)
|
|
bool do26 = false;
|
|
bool do42 = false;
|
|
|
|
if (hiColor) {
|
|
int val1 = IntelSwapper(*(unsigned short *)esi);
|
|
if (val1 & 0x8000) {
|
|
val1 = IntelSwapper(*(unsigned short *)(esi + 16));
|
|
if (val1 & 0x8000) {
|
|
do42 = true;
|
|
} else {
|
|
do26 = true;
|
|
}
|
|
}
|
|
} else {
|
|
if (esi[0] > esi[1]) {
|
|
if (esi[12] > esi[13]) {
|
|
do42 = true;
|
|
} else {
|
|
do26 = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Load bx,dx,cx,bp with four colors
|
|
unsigned short colors[4];
|
|
if (hiColor) {
|
|
colors[0] = nf_trans16_lo[*(esi)] | nf_trans16_hi[*(esi + 1)];
|
|
colors[1] = nf_trans16_lo[*(esi + 2)] | nf_trans16_hi[*(esi + 3)];
|
|
colors[2] = nf_trans16_lo[*(esi + 4)] | nf_trans16_hi[*(esi + 5)];
|
|
colors[3] = nf_trans16_lo[*(esi + 6)] | nf_trans16_hi[*(esi + 7)];
|
|
} else {
|
|
colors[0] = esi[0];
|
|
colors[1] = esi[1];
|
|
colors[2] = esi[2];
|
|
colors[3] = esi[3];
|
|
}
|
|
|
|
// build our iteration lookup table
|
|
int repLookup[16];
|
|
if (do26 || do42) {
|
|
int baseCnt1 = (hiColor) ? 8 : 4;
|
|
int baseCnt2 = (hiColor) ? 24 : 16;
|
|
for (int i = 0; i < 8; ++i) {
|
|
repLookup[i + 0] = baseCnt1 + i;
|
|
repLookup[i + 8] = baseCnt2 + i;
|
|
}
|
|
} else {
|
|
int baseCnt1 = (hiColor) ? 8 : 4;
|
|
int baseCnt2 = (hiColor) ? 20 : 12;
|
|
int baseCnt3 = (hiColor) ? 32 : 20;
|
|
int baseCnt4 = (hiColor) ? 44 : 28;
|
|
for (int i = 0; i < 4; ++i) {
|
|
repLookup[i + 0] = baseCnt1 + i;
|
|
repLookup[i + 4] = baseCnt2 + i;
|
|
repLookup[i + 8] = baseCnt3 + i;
|
|
repLookup[i + 12] = baseCnt4 + i;
|
|
}
|
|
}
|
|
|
|
const unsigned char *lookupTable = (hiColor) ? nfhpk_mov4 : nfpk_mov4;
|
|
for (int rep_count = 0; rep_count < 16; ++rep_count) {
|
|
int idx = repLookup[rep_count];
|
|
const unsigned char *color_idx = lookupTable + (esi[idx] * 4);
|
|
uint32_t w1 = colors[color_idx[0]];
|
|
uint32_t w2 = colors[color_idx[1]];
|
|
uint32_t w3 = colors[color_idx[2]];
|
|
uint32_t w4 = colors[color_idx[3]];
|
|
|
|
if (!do42) {
|
|
if (hiColor) {
|
|
#ifdef OUTRAGE_BIG_ENDIAN
|
|
*(uint32_t *)(edi + 0) = ((uint32_t)(w4 & 0xFFFF) | ((w3 & 0xFFFF) << 16));
|
|
*(uint32_t *)(edi + 4) = ((uint32_t)(w2 & 0xFFFF) | ((w1 & 0xFFFF) << 16));
|
|
#else
|
|
*(uint32_t *)(edi + 0) = ((uint32_t)(w1 & 0xFFFF) | ((w2 & 0xFFFF) << 16));
|
|
*(uint32_t *)(edi + 4) = ((uint32_t)(w3 & 0xFFFF) | ((w4 & 0xFFFF) << 16));
|
|
#endif
|
|
} else {
|
|
*(uint32_t *)(edi + 0) = IntelSwapper((uint32_t)(w4 << 24) | (w3 << 16) | (w2 << 8) | w1);
|
|
}
|
|
edi += nf_width;
|
|
} else {
|
|
// 42
|
|
if (rep_count & 1) {
|
|
if (hiColor) {
|
|
#ifdef OUTRAGE_BIG_ENDIAN
|
|
*(uint32_t *)(edi + 8) = ((uint32_t)(w4 & 0xFFFF) | ((w3 & 0xFFFF) << 16));
|
|
*(uint32_t *)(edi + 12) = ((uint32_t)(w2 & 0xFFFF) | ((w1 & 0xFFFF) << 16));
|
|
#else
|
|
|
|
*(uint32_t *)(edi + 8) = ((uint32_t)(w1 & 0xFFFF) | ((w2 & 0xFFFF) << 16));
|
|
*(uint32_t *)(edi + 12) = ((uint32_t)(w3 & 0xFFFF) | ((w4 & 0xFFFF) << 16));
|
|
#endif
|
|
} else {
|
|
*(uint32_t *)(edi + 4) = IntelSwapper((uint32_t)(w4 << 24) | (w3 << 16) | (w2 << 8) | w1);
|
|
}
|
|
edi += nf_width;
|
|
} else {
|
|
if (hiColor) {
|
|
#ifdef OUTRAGE_BIG_ENDIAN
|
|
*(uint32_t *)(edi + 0) = ((uint32_t)(w4 & 0xFFFF) | ((w3 & 0xFFFF) << 16));
|
|
*(uint32_t *)(edi + 4) = ((uint32_t)(w2 & 0xFFFF) | ((w1 & 0xFFFF) << 16));
|
|
#else
|
|
*(uint32_t *)(edi + 0) = ((uint32_t)(w1 & 0xFFFF) | ((w2 & 0xFFFF) << 16));
|
|
*(uint32_t *)(edi + 4) = ((uint32_t)(w3 & 0xFFFF) | ((w4 & 0xFFFF) << 16));
|
|
#endif
|
|
} else {
|
|
*(uint32_t *)(edi + 0) = IntelSwapper((uint32_t)(w4 << 24) | (w3 << 16) | (w2 << 8) | w1);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (rep_count == 3 && !do42 && !do26) {
|
|
if (hiColor) {
|
|
// Load bx,dx,cx,bp with four colors
|
|
colors[0] = nf_trans16_lo[*(esi + 12)] | nf_trans16_hi[*(esi + 13)];
|
|
colors[1] = nf_trans16_lo[*(esi + 14)] | nf_trans16_hi[*(esi + 15)];
|
|
colors[2] = nf_trans16_lo[*(esi + 16)] | nf_trans16_hi[*(esi + 17)];
|
|
colors[3] = nf_trans16_lo[*(esi + 18)] | nf_trans16_hi[*(esi + 19)];
|
|
} else {
|
|
colors[0] = esi[8];
|
|
colors[1] = esi[9];
|
|
colors[2] = esi[10];
|
|
colors[3] = esi[11];
|
|
}
|
|
}
|
|
|
|
if (rep_count == 7) {
|
|
if (!do42 && !do26) {
|
|
edi -= nf_width * 8 - ((hiColor) ? 8 : 4);
|
|
|
|
if (hiColor) {
|
|
// Load bx,dx,cx,bp with four colors
|
|
colors[0] = nf_trans16_lo[*(esi + 24)] | nf_trans16_hi[*(esi + 25)];
|
|
colors[1] = nf_trans16_lo[*(esi + 26)] | nf_trans16_hi[*(esi + 27)];
|
|
colors[2] = nf_trans16_lo[*(esi + 28)] | nf_trans16_hi[*(esi + 29)];
|
|
colors[3] = nf_trans16_lo[*(esi + 30)] | nf_trans16_hi[*(esi + 31)];
|
|
} else {
|
|
colors[0] = esi[16];
|
|
colors[1] = esi[17];
|
|
colors[2] = esi[18];
|
|
colors[3] = esi[19];
|
|
}
|
|
}
|
|
|
|
if (do26 || do42) {
|
|
if (do26) {
|
|
edi -= nf_width * 8 - ((hiColor) ? 8 : 4);
|
|
}
|
|
|
|
if (hiColor) {
|
|
// Load bx,dx,cx,bp with four colors
|
|
colors[0] = nf_trans16_lo[*(esi + 16)] | nf_trans16_hi[*(esi + 17)];
|
|
colors[1] = nf_trans16_lo[*(esi + 18)] | nf_trans16_hi[*(esi + 19)];
|
|
colors[2] = nf_trans16_lo[*(esi + 20)] | nf_trans16_hi[*(esi + 21)];
|
|
colors[3] = nf_trans16_lo[*(esi + 22)] | nf_trans16_hi[*(esi + 23)];
|
|
} else {
|
|
colors[0] = esi[12];
|
|
colors[1] = esi[13];
|
|
colors[2] = esi[14];
|
|
colors[3] = esi[15];
|
|
}
|
|
}
|
|
}
|
|
|
|
if (rep_count == 11 && !do42 && !do26) {
|
|
if (hiColor) {
|
|
// Load bx,dx,cx,bp with four colors
|
|
colors[0] = nf_trans16_lo[*(esi + 36)] | nf_trans16_hi[*(esi + 37)];
|
|
colors[1] = nf_trans16_lo[*(esi + 38)] | nf_trans16_hi[*(esi + 39)];
|
|
colors[2] = nf_trans16_lo[*(esi + 40)] | nf_trans16_hi[*(esi + 41)];
|
|
colors[3] = nf_trans16_lo[*(esi + 42)] | nf_trans16_hi[*(esi + 43)];
|
|
} else {
|
|
colors[0] = esi[24];
|
|
colors[1] = esi[25];
|
|
colors[2] = esi[26];
|
|
colors[3] = esi[27];
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!do42 && !do26) {
|
|
esi += (hiColor) ? 48 : 32;
|
|
} else {
|
|
esi += (hiColor) ? 32 : 24;
|
|
}
|
|
|
|
edi -= nf_width;
|
|
if (!do42) {
|
|
edi -= ((hiColor) ? 8 : 4) + nfpk_back_right;
|
|
} else {
|
|
edi -= nfpk_back_right;
|
|
}
|
|
} break;
|
|
|
|
case 11: {
|
|
// 8x8x16 (128 bytes)
|
|
if (hiColor) {
|
|
Trans16Blk(edi, esi);
|
|
edi += nf_width;
|
|
|
|
Trans16Blk(edi, esi + 16);
|
|
edi += nf_width;
|
|
|
|
Trans16Blk(edi, esi + 32);
|
|
edi += nf_width;
|
|
|
|
Trans16Blk(edi, esi + 48);
|
|
edi += nf_width;
|
|
|
|
Trans16Blk(edi, esi + 64);
|
|
edi += nf_width;
|
|
|
|
Trans16Blk(edi, esi + 80);
|
|
edi += nf_width;
|
|
|
|
Trans16Blk(edi, esi + 96);
|
|
edi += nf_width;
|
|
|
|
Trans16Blk(edi, esi + 112);
|
|
|
|
esi += 128;
|
|
} else {
|
|
// 8x8x8 (64 bytes)
|
|
uint32_t *ediW = (uint32_t *)edi;
|
|
uint32_t *esiW = (uint32_t *)esi;
|
|
const uint32_t width = nf_width >> 2;
|
|
ediW[0] = (esiW[0]);
|
|
ediW[1] = (esiW[1]);
|
|
ediW += width;
|
|
ediW[0] = (esiW[2]);
|
|
ediW[1] = (esiW[3]);
|
|
ediW += width;
|
|
ediW[0] = (esiW[4]);
|
|
ediW[1] = (esiW[5]);
|
|
ediW += width;
|
|
ediW[0] = (esiW[6]);
|
|
ediW[1] = (esiW[7]);
|
|
ediW += width;
|
|
ediW[0] = (esiW[8]);
|
|
ediW[1] = (esiW[9]);
|
|
ediW += width;
|
|
ediW[0] = (esiW[10]);
|
|
ediW[1] = (esiW[11]);
|
|
ediW += width;
|
|
ediW[0] = (esiW[12]);
|
|
ediW[1] = (esiW[13]);
|
|
ediW += width;
|
|
ediW[0] = (esiW[14]);
|
|
ediW[1] = (esiW[15]);
|
|
esi += 64;
|
|
edi = ((unsigned char *)ediW);
|
|
}
|
|
edi -= nfpk_back_right;
|
|
} break;
|
|
case 12: {
|
|
for (int i = 0; i < 4; ++i) {
|
|
if (hiColor) {
|
|
// low 4x4x16 (32 bytes)
|
|
uint32_t eax, ebx;
|
|
|
|
eax = *(unsigned char *)(esi + i * 8 + 0);
|
|
ebx = nf_trans16_lo[eax];
|
|
eax = *(unsigned char *)(esi + i * 8 + 1);
|
|
ebx |= nf_trans16_hi[eax];
|
|
eax = ((ebx & 0xFFFF) << 16) | (ebx & 0xFFFF);
|
|
*(uint32_t *)(edi + 0) = eax;
|
|
*(uint32_t *)(edi + nf_width) = eax;
|
|
|
|
eax = *(unsigned char *)(esi + i * 8 + 2);
|
|
ebx = nf_trans16_lo[eax];
|
|
eax = *(unsigned char *)(esi + i * 8 + 3);
|
|
ebx |= nf_trans16_hi[eax];
|
|
eax = ((ebx & 0xFFFF) << 16) | (ebx & 0xFFFF);
|
|
*(uint32_t *)(edi + 4) = eax;
|
|
*(uint32_t *)(edi + nf_width + 4) = eax;
|
|
|
|
eax = *(unsigned char *)(esi + i * 8 + 4);
|
|
ebx = nf_trans16_lo[eax];
|
|
eax = *(unsigned char *)(esi + i * 8 + 5);
|
|
ebx |= nf_trans16_hi[eax];
|
|
eax = ((ebx & 0xFFFF) << 16) | (ebx & 0xFFFF);
|
|
*(uint32_t *)(edi + 8) = eax;
|
|
*(uint32_t *)(edi + nf_width + 8) = eax;
|
|
|
|
eax = *(unsigned char *)(esi + i * 8 + 6);
|
|
ebx = nf_trans16_lo[eax];
|
|
eax = *(unsigned char *)(esi + i * 8 + 7);
|
|
ebx |= nf_trans16_hi[eax];
|
|
eax = ((ebx & 0xFFFF) << 16) | (ebx & 0xFFFF);
|
|
*(uint32_t *)(edi + 12) = eax;
|
|
*(uint32_t *)(edi + nf_width + 12) = eax;
|
|
} else {
|
|
// low 4x4x8 (16 bytes)
|
|
uint32_t eax, ebx;
|
|
|
|
eax = IntelSwapper(((uint32_t *)esi)[i]);
|
|
ebx = ((eax & 0xFF00) << 16) | ((eax & 0xFF00) << 8) | ((eax & 0xFF) << 8) | (eax & 0xFF);
|
|
((uint32_t *)edi)[0] = ebx;
|
|
((uint32_t *)(edi + nf_width))[0] = ebx;
|
|
|
|
eax = eax >> 16;
|
|
ebx = ((eax & 0xFF00) << 16) | ((eax & 0xFF00) << 8) | ((eax & 0xFF) << 8) | (eax & 0xFF);
|
|
((uint32_t *)edi)[1] = ebx;
|
|
((uint32_t *)(edi + nf_width))[1] = ebx;
|
|
}
|
|
|
|
edi += nf_width * 2;
|
|
}
|
|
|
|
edi -= nf_width * 2;
|
|
edi += nf_width;
|
|
edi -= nfpk_back_right;
|
|
esi += (hiColor) ? 32 : 16;
|
|
} break;
|
|
case 13: {
|
|
if (hiColor) {
|
|
// 2x2 4x4x0 (8 bytes)
|
|
for (int i = 0; i < 2; ++i) {
|
|
const unsigned char *loopEsi = esi + (i * 4);
|
|
|
|
uint32_t temp = nf_trans16_lo[loopEsi[0]] | nf_trans16_hi[loopEsi[1]];
|
|
uint32_t ebx = ((temp & 0xFFFF) << 16) | (temp & 0xFFFF);
|
|
|
|
temp = nf_trans16_lo[loopEsi[2]] | nf_trans16_hi[loopEsi[3]];
|
|
uint32_t ecx = ((temp & 0xFFFF) << 16) | (temp & 0xFFFF);
|
|
|
|
*(uint32_t *)(edi + 0) = ebx;
|
|
*(uint32_t *)(edi + 4) = ebx;
|
|
*(uint32_t *)(edi + 8) = ecx;
|
|
*(uint32_t *)(edi + 12) = ecx;
|
|
*(uint32_t *)(edi + nf_width) = ebx;
|
|
*(uint32_t *)(edi + nf_width + 4) = ebx;
|
|
*(uint32_t *)(edi + nf_width + 8) = ecx;
|
|
*(uint32_t *)(edi + nf_width + 12) = ecx;
|
|
|
|
edi += nf_width * 2;
|
|
|
|
*(uint32_t *)(edi + 0) = ebx;
|
|
*(uint32_t *)(edi + 4) = ebx;
|
|
*(uint32_t *)(edi + 8) = ecx;
|
|
*(uint32_t *)(edi + 12) = ecx;
|
|
*(uint32_t *)(edi + nf_width) = ebx;
|
|
*(uint32_t *)(edi + nf_width + 4) = ebx;
|
|
*(uint32_t *)(edi + nf_width + 8) = ecx;
|
|
*(uint32_t *)(edi + nf_width + 12) = ecx;
|
|
|
|
edi += nf_width * 2;
|
|
}
|
|
} else {
|
|
// 2x2 4x4x0 (4 bytes)
|
|
for (int i = 0; i < 2; ++i) {
|
|
uint32_t c1 = esi[(i << 1) + 0];
|
|
uint32_t eax = (c1 << 24) | (c1 << 16) | (c1 << 8) | c1;
|
|
|
|
uint32_t c2 = esi[(i << 1) + 1];
|
|
uint32_t ebx = (c2 << 24) | (c2 << 16) | (c2 << 8) | c2;
|
|
|
|
*(uint32_t *)(edi + 0) = eax;
|
|
*(uint32_t *)(edi + 4) = ebx;
|
|
*(uint32_t *)(edi + 0 + nf_width) = eax;
|
|
*(uint32_t *)(edi + 4 + nf_width) = ebx;
|
|
edi += nf_width * 2;
|
|
|
|
*(uint32_t *)(edi + 0) = eax;
|
|
*(uint32_t *)(edi + 4) = ebx;
|
|
*(uint32_t *)(edi + 0 + nf_width) = eax;
|
|
*(uint32_t *)(edi + 4 + nf_width) = ebx;
|
|
edi += nf_width * 2;
|
|
}
|
|
}
|
|
|
|
edi -= nf_width * 2;
|
|
edi += nf_width;
|
|
edi -= nfpk_back_right;
|
|
esi += (hiColor) ? 8 : 4;
|
|
} break;
|
|
case 14: {
|
|
if (hiColor) {
|
|
// 8x8x0 (2 bytes)
|
|
uint32_t ecx = nf_trans16_lo[esi[0]] | nf_trans16_hi[esi[1]];
|
|
uint32_t ebx = ((ecx & 0xFFFF) << 16) | (ecx & 0xFFFF);
|
|
esi += 2;
|
|
|
|
for (int i = 0; i < 8; ++i) {
|
|
*(uint32_t *)(edi + 0) = ebx;
|
|
*(uint32_t *)(edi + 4) = ebx;
|
|
*(uint32_t *)(edi + 8) = ebx;
|
|
*(uint32_t *)(edi + 12) = ebx;
|
|
edi += nf_width;
|
|
}
|
|
|
|
edi -= nf_width;
|
|
edi -= nfpk_back_right;
|
|
} else {
|
|
// 8x8x0 (1 byte)
|
|
uint32_t c = *esi++; // Copy color into 8 positions
|
|
uint32_t col = (c << 24) | (c << 16) | (c << 8) | c;
|
|
|
|
for (int i = 0; i < 8; ++i) {
|
|
*(uint32_t *)(edi + 0) = col;
|
|
*(uint32_t *)(edi + 4) = col;
|
|
edi += nf_width;
|
|
}
|
|
edi -= nf_width;
|
|
edi -= nfpk_back_right;
|
|
}
|
|
} break;
|
|
case 15: {
|
|
if (!hiColor) {
|
|
// mix 8x8x0 (2 bytes)
|
|
uint32_t ebx = IntelSwapper(*(unsigned short *)(esi)); // Copy 2 colors into 8 positions
|
|
esi += 2; // in a checkerboard
|
|
uint32_t eax = (ebx << 16) | ebx;
|
|
ebx = (eax << 8) | ((eax >> 24) & 0xFF);
|
|
|
|
for (int i = 0; i < 4; ++i) {
|
|
*(uint32_t *)(edi + 0) = eax;
|
|
*(uint32_t *)(edi + 4) = eax;
|
|
edi += nf_width;
|
|
|
|
*(uint32_t *)(edi + 0) = ebx;
|
|
*(uint32_t *)(edi + 4) = ebx;
|
|
edi += nf_width;
|
|
}
|
|
edi -= nf_width;
|
|
edi -= nfpk_back_right;
|
|
}
|
|
} break;
|
|
}
|
|
|
|
if (first_opcode && !skipNextOpCode) {
|
|
first_opcode = false;
|
|
opcode_to_use = (opcode >> 4);
|
|
goto do_next_opcode;
|
|
}
|
|
} while (h != 0);
|
|
}
|
|
|
|
void Trans16Blk(unsigned char *edi, const unsigned char *idx) {
|
|
*((unsigned short *)(edi + 0)) = nf_trans16_lo[*(idx + 0)] | nf_trans16_hi[*(idx + 1)];
|
|
*((unsigned short *)(edi + 2)) = nf_trans16_lo[*(idx + 2)] | nf_trans16_hi[*(idx + 3)];
|
|
*((unsigned short *)(edi + 4)) = nf_trans16_lo[*(idx + 4)] | nf_trans16_hi[*(idx + 5)];
|
|
*((unsigned short *)(edi + 6)) = nf_trans16_lo[*(idx + 6)] | nf_trans16_hi[*(idx + 7)];
|
|
*((unsigned short *)(edi + 8)) = nf_trans16_lo[*(idx + 8)] | nf_trans16_hi[*(idx + 9)];
|
|
*((unsigned short *)(edi + 10)) = nf_trans16_lo[*(idx + 10)] | nf_trans16_hi[*(idx + 11)];
|
|
*((unsigned short *)(edi + 12)) = nf_trans16_lo[*(idx + 12)] | nf_trans16_hi[*(idx + 13)];
|
|
*((unsigned short *)(edi + 14)) = nf_trans16_lo[*(idx + 14)] | nf_trans16_hi[*(idx + 15)];
|
|
}
|
|
|
|
void DOnf_xycshift(const bool hiColor, const uint32_t eax, unsigned char *&edi, const int nfpk_back_right) {
|
|
uint32_t ebx = (eax >> 8) & 0xFF;
|
|
|
|
// get the lower byte of the offset, but sign extend it
|
|
int offset = eax & 0xFF;
|
|
if (eax & 0x80) {
|
|
// extend...
|
|
offset |= 0xFFFFFF00;
|
|
}
|
|
|
|
// hiColor is multiplied by two
|
|
if (hiColor) {
|
|
offset <<= 1;
|
|
}
|
|
|
|
// factor in the table
|
|
offset += nfpk_ShiftY[ebx];
|
|
DOnf_shift(hiColor, offset, edi, nfpk_back_right);
|
|
}
|
|
|
|
void DOnf_xypshift(const bool hiColor, const uint32_t eax, unsigned char *&edi, const int nfpk_back_right,
|
|
const int DiffBufPtrs) {
|
|
uint32_t ebx = (eax >> 8) & 0xFF;
|
|
|
|
// get the lower byte of the offset, but sign extend it
|
|
int offset = eax & 0xFF;
|
|
if (eax & 0x80) {
|
|
// extend...
|
|
offset |= 0xFFFFFF00;
|
|
}
|
|
|
|
// hiColor is multiplied by two
|
|
if (hiColor) {
|
|
offset <<= 1;
|
|
}
|
|
|
|
// factor in the table
|
|
offset += nfpk_ShiftY[ebx] + DiffBufPtrs;
|
|
DOnf_shift(hiColor, offset, edi, nfpk_back_right);
|
|
}
|
|
|
|
// Copy the 128/64 bytes from an offset of edi to edi is.
|
|
void DOnf_shift(const bool hiColor, const int offset, unsigned char *&edi, const int nfpk_back_right) {
|
|
union ptr {
|
|
uint32_t *pAsInt;
|
|
unsigned char *pAsChar;
|
|
};
|
|
ptr dstBuffer;
|
|
dstBuffer.pAsChar = edi;
|
|
ptr srcBuffer;
|
|
srcBuffer.pAsChar = edi + offset;
|
|
|
|
for (int i = 0; i < 8; ++i) {
|
|
dstBuffer.pAsInt[0] = (srcBuffer.pAsInt[0]);
|
|
dstBuffer.pAsInt[1] = (srcBuffer.pAsInt[1]);
|
|
|
|
if (hiColor) {
|
|
dstBuffer.pAsInt[2] = (srcBuffer.pAsInt[2]);
|
|
dstBuffer.pAsInt[3] = (srcBuffer.pAsInt[3]);
|
|
}
|
|
|
|
dstBuffer.pAsChar += nf_width;
|
|
srcBuffer.pAsChar += nf_width;
|
|
}
|
|
|
|
// restore edi
|
|
dstBuffer.pAsChar -= nf_width;
|
|
dstBuffer.pAsChar -= nfpk_back_right;
|
|
edi = dstBuffer.pAsChar;
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
// Non-Implemented Functions
|
|
////////////////////////////////////////////////
|
|
void nfHiColorDecomp(const unsigned char *comp, unsigned x, unsigned y, unsigned w, unsigned h);
|
|
void nfHiColorDecompChg(const unsigned short *chgs, const unsigned short *parms, const unsigned char *comp, unsigned x,
|
|
unsigned y, unsigned w, unsigned h);
|
|
void nfDecomp(const unsigned char *comp, unsigned x, unsigned y, unsigned w, unsigned h);
|
|
void nfDecompChg(const unsigned short *chgs, const unsigned short *parms, const unsigned char *comp, unsigned x,
|
|
unsigned y, unsigned w, unsigned h);
|
|
void nfPkDecompH(unsigned char *ops, unsigned char *comp, unsigned x, unsigned y, unsigned w, unsigned h);
|
|
void nfPkDecompD(unsigned char *ops, unsigned char *comp, unsigned x, unsigned y, unsigned w, unsigned h);
|
|
void mve_ShowFrameField(unsigned char *buf, unsigned bufw, unsigned bufh, unsigned sx, unsigned sy, unsigned w,
|
|
unsigned h, unsigned dstx, unsigned dsty, unsigned field);
|
|
void mve_ShowFrameFieldHi(unsigned char *buf, unsigned bufw, unsigned bufh, unsigned sx, unsigned sy, unsigned w,
|
|
unsigned h, unsigned dstx, unsigned dsty, unsigned field);
|
|
void mve_sfShowFrameChg(bool prvbuf, unsigned x, unsigned y, unsigned w, unsigned h, unsigned short *chgs,
|
|
unsigned dstx, unsigned dsty);
|
|
void mve_sfHiColorShowFrameChg(bool prvbuf, unsigned x, unsigned y, unsigned w, unsigned h, unsigned short *chgs,
|
|
unsigned dstx, unsigned dsty);
|
|
void mve_sfPkShowFrameChg(bool prvbuf, unsigned x, unsigned y, unsigned w, unsigned h, unsigned char *ops,
|
|
unsigned dstx, unsigned dsty);
|
|
void mve_sfPkHiColorShowFrameChg(bool prvbuf, unsigned x, unsigned y, unsigned w, unsigned h, unsigned char *ops,
|
|
unsigned dstx, unsigned dsty);
|
|
|
|
void MVE_SetPalette(unsigned char *p, unsigned start, unsigned count);
|
|
void palLoadCompPalette(unsigned char *buf);
|
|
void gfxMode(unsigned mode);
|
|
void gfxLoadCrtc(unsigned char *crtc, unsigned char chain4, unsigned char res);
|
|
void gfxGetCrtc(unsigned char *crtc);
|
|
void gfxVres(unsigned char misc, unsigned char *crtc);
|
|
void MVE_gfxWaitRetrace(int state);
|
|
void MVE_gfxSetSplit(unsigned line);
|
|
|
|
|
|
void DECOMP_BODY(bool HI_COLOR_FLAG, const unsigned char *&comp, uint32_t _x, uint32_t _y, uint32_t _w,
|
|
uint32_t _h) {
|
|
uint32_t HI_COLOR_SCALE = (HI_COLOR_FLAG) ? 2 : 1;
|
|
|
|
tNextFrame nf;
|
|
nf.w = _w;
|
|
nf.h = _h;
|
|
nf.x = _x;
|
|
nf.y = _y;
|
|
NF_DECOMP_INIT(HI_COLOR_FLAG ? 1 : 0, &nf);
|
|
|
|
uint32_t parms_sz = (nf.w * nf.h * nf_fqty) << 1;
|
|
const unsigned char *compData = comp + parms_sz;
|
|
|
|
// New Data
|
|
//=====================
|
|
|
|
// Iterate over params and copy new hires data to appropriate sections.
|
|
unsigned char *curr_tbuf = nf.tbuf;
|
|
const unsigned short *compAsWord = (const unsigned short *)comp;
|
|
for (unsigned char fqIt = nf_fqty; fqIt != 0; --fqIt, curr_tbuf += nf_width) {
|
|
unsigned char *this_tbuf = curr_tbuf;
|
|
for (uint32_t ch = nf.h; ch != 0; --ch, this_tbuf += nf.new_row) {
|
|
for (uint32_t cl = nf.w; cl != 0; --cl) {
|
|
int flags = (int)IntelSwapper(*compAsWord++);
|
|
if (flags != 0) {
|
|
this_tbuf += SWIDTH * HI_COLOR_SCALE;
|
|
continue;
|
|
}
|
|
|
|
// Copy new data to one section
|
|
// Enter with esi(compData) pointing to source data, edi(this_tbuf) to screen section.
|
|
// Assumes SWIDTH=8 (16-bit data) and SHEIGHT=8
|
|
for (int currH = 0; currH < 8; ++currH) {
|
|
size_t amt = sizeof(uint32_t) * 2 * HI_COLOR_SCALE;
|
|
// memcpy( this_tbuf, compData, amt );
|
|
for (uint32_t ii = 0; ii < (amt / 2); ii++) {
|
|
unsigned short *destword = (unsigned short *)this_tbuf[ii];
|
|
unsigned short *srcword = (unsigned short *)compData[ii];
|
|
*destword = IntelSwapper(*srcword);
|
|
}
|
|
compData += amt;
|
|
this_tbuf += amt + nf_new_line;
|
|
}
|
|
this_tbuf -= nf_new_line;
|
|
this_tbuf -= nf_back_right;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Motion Compensation
|
|
//=====================
|
|
|
|
// Iterate over flags and motion source addresses from params
|
|
// to determine which sections to move.
|
|
// ebx indexes params.
|
|
// esi indexes source from buffer
|
|
// esi will be computed as +- 16K relative to edi.
|
|
compAsWord = (const unsigned short *)comp;
|
|
curr_tbuf = nf.tbuf;
|
|
for (unsigned char fqIt = nf_fqty; fqIt != 0; --fqIt, curr_tbuf += nf_width) {
|
|
unsigned char *this_tbuf = curr_tbuf;
|
|
for (uint32_t ch = nf.h; ch != 0; --ch, this_tbuf += nf.new_row) {
|
|
for (uint32_t cl = nf.w; cl != 0; --cl) {
|
|
int flags = (int)IntelSwapper(*compAsWord++);
|
|
if (flags == 0) {
|
|
this_tbuf += SWIDTH * HI_COLOR_SCALE;
|
|
continue;
|
|
}
|
|
|
|
// Make esi absolute
|
|
unsigned char *src = this_tbuf;
|
|
if (flags > 0) {
|
|
// jg
|
|
src += (flags - 0x4000) * HI_COLOR_SCALE;
|
|
} else {
|
|
// jl
|
|
src += (flags - 0xC000) * HI_COLOR_SCALE + nf.DiffBufPtrs;
|
|
}
|
|
|
|
for (int i = 0; i < 8; ++i) {
|
|
size_t amt = sizeof(uint32_t) * 2 * HI_COLOR_SCALE;
|
|
// memcpy( this_tbuf, src, amt );
|
|
for (uint32_t ii = 0; ii < (amt / 2); ii++) {
|
|
unsigned short *destword = (unsigned short *)this_tbuf[ii];
|
|
unsigned short *srcword = (unsigned short *)src[ii];
|
|
*destword = IntelSwapper(*srcword);
|
|
}
|
|
src += amt + nf_new_line;
|
|
this_tbuf += amt + nf_new_line;
|
|
}
|
|
|
|
this_tbuf -= nf_new_line;
|
|
this_tbuf -= nf_back_right;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void DECOMP_CHG_BODY(bool HI_COLOR_FLAG, const unsigned short *&chgs, const unsigned short *&parms,
|
|
const unsigned char *&comp, uint32_t _x, uint32_t _y, uint32_t _w, uint32_t _h) {
|
|
uint32_t HI_COLOR_SCALE = (HI_COLOR_FLAG) ? 2 : 1;
|
|
|
|
tNextFrame nf;
|
|
nf.w = _w;
|
|
nf.h = _h;
|
|
nf.x = _x;
|
|
nf.y = _y;
|
|
NF_DECOMP_INIT(HI_COLOR_FLAG ? 1 : 0, &nf);
|
|
|
|
// Iterate over params and copy new hires data to appropriate sections.
|
|
const unsigned short *pChgs = chgs;
|
|
uint32_t eax = 0;
|
|
const unsigned char *compData = comp;
|
|
unsigned char *curr_tbuf = nf.tbuf;
|
|
const unsigned short *curr_parms = parms;
|
|
for (unsigned char fqIt = nf_fqty; fqIt != 0; --fqIt, curr_tbuf += nf_width) {
|
|
unsigned char *this_tbuf = curr_tbuf;
|
|
for (uint32_t ch = nf.h; ch != 0; --ch, this_tbuf += nf.new_row) {
|
|
for (uint32_t cl = nf.w; cl != 0; --cl) {
|
|
eax *= 2;
|
|
while (eax == 0) {
|
|
eax = IntelSwapper(*pChgs++);
|
|
eax *= 2;
|
|
}
|
|
|
|
if (((int)eax) > 0) {
|
|
this_tbuf += SWIDTH * HI_COLOR_SCALE;
|
|
continue;
|
|
}
|
|
|
|
unsigned short flags = IntelSwapper(*curr_parms++);
|
|
if (flags != 0) {
|
|
this_tbuf += SWIDTH * HI_COLOR_SCALE;
|
|
continue;
|
|
}
|
|
|
|
// Copy new data to one section
|
|
// Enter with ds:si pointing to source data, es:di to screen section.
|
|
// Assumes SWIDTH=8 (16-bit data) and SHEIGHT=8
|
|
for (int i = 0; i < 8; ++i) {
|
|
size_t amt = sizeof(uint32_t) * 2 * HI_COLOR_SCALE;
|
|
// TODO: Do these bytes need swapping? Is this data shorts?
|
|
// memcpy( this_tbuf, compData, amt );
|
|
for (uint32_t ii = 0; ii < (amt / 2); ii++) {
|
|
unsigned short *dest = (unsigned short *)this_tbuf[ii];
|
|
unsigned short *src = (unsigned short *)compData[ii];
|
|
*dest = IntelSwapper(*src);
|
|
}
|
|
compData += amt;
|
|
this_tbuf += amt + nf_new_line;
|
|
}
|
|
this_tbuf -= nf_new_line;
|
|
this_tbuf -= nf_back_right;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Iterate over flags and motion source addresses from params
|
|
// to determine which sections to move.
|
|
// ebx indexes params.
|
|
// esi indexes source from buffer
|
|
// esi will be computed as +- 16K relative to edi.
|
|
curr_tbuf = nf.tbuf;
|
|
curr_parms = parms;
|
|
pChgs = chgs;
|
|
eax = 0;
|
|
|
|
for (unsigned char fqIt = nf_fqty; fqIt != 0; --fqIt, curr_tbuf += nf_width) {
|
|
unsigned char *this_tbuf = curr_tbuf;
|
|
for (uint32_t ch = nf.h; ch != 0; --ch, this_tbuf += nf.new_row) {
|
|
for (uint32_t cl = nf.w; cl != 0; --cl) {
|
|
eax *= 2;
|
|
while (eax == 0) {
|
|
eax = IntelSwapper(*pChgs++);
|
|
eax *= 2;
|
|
}
|
|
|
|
if (((int)eax) > 0) {
|
|
this_tbuf += SWIDTH * HI_COLOR_SCALE;
|
|
continue;
|
|
}
|
|
|
|
int flags = (int)IntelSwapper((*curr_parms++));
|
|
if (flags == 0) {
|
|
this_tbuf += SWIDTH * HI_COLOR_SCALE;
|
|
continue;
|
|
}
|
|
|
|
// Make esi absolute
|
|
unsigned char *src = this_tbuf;
|
|
if (flags > 0) {
|
|
src += (flags - 0x4000) * HI_COLOR_SCALE;
|
|
} else {
|
|
src += (flags - 0xC000) * HI_COLOR_SCALE;
|
|
src += nf.DiffBufPtrs; // and point to other buffer
|
|
}
|
|
|
|
for (int i = 0; i < 8; ++i) {
|
|
size_t amt = sizeof(uint32_t) * 2 * HI_COLOR_SCALE;
|
|
// memcpy( this_tbuf, src, amt );
|
|
for (uint32_t ii = 0; ii < (amt / 2); ii++) {
|
|
unsigned short *destword = (unsigned short *)this_tbuf[ii];
|
|
unsigned short *srcword = (unsigned short *)src[ii];
|
|
*destword = IntelSwapper(*srcword);
|
|
}
|
|
src += amt + nf_new_line;
|
|
this_tbuf += amt + nf_new_line;
|
|
}
|
|
this_tbuf -= nf_new_line;
|
|
this_tbuf -= nf_back_right; // (SHEIGHT-1)*width
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Decompress into subsection of current buffer specified by x,y,w,h in units of SWIDTHxSHEIGHT (8x8).
|
|
void nfHiColorDecomp(const unsigned char *comp, uint32_t x, uint32_t y, uint32_t w, uint32_t h) {
|
|
DECOMP_BODY(true, comp, x, y, w, h);
|
|
}
|
|
|
|
// Decompress into subsection of current buffer specified
|
|
// by x,y,w,h in units of SWIDTHxSHEIGHT (8x8).
|
|
// Chgs specifies which squares to update.
|
|
// Parms are motion parms for squares to update.
|
|
void nfHiColorDecompChg(const unsigned short *chgs, const unsigned short *parms, const unsigned char *comp, unsigned x,
|
|
unsigned y, unsigned w, unsigned h) {
|
|
DECOMP_CHG_BODY(true, chgs, parms, comp, x, y, w, h);
|
|
}
|
|
|
|
// Decompress into subsection of current buffer specified
|
|
// by x,y,w,h in units of SWIDTHxSHEIGHT (8x8).
|
|
void nfDecomp(const unsigned char *comp, unsigned x, unsigned y, unsigned w, unsigned h) {
|
|
if (nf_hicolor) {
|
|
nfHiColorDecomp(comp, x, y, w, h);
|
|
return;
|
|
}
|
|
|
|
DECOMP_BODY(false, comp, x, y, w, h);
|
|
}
|
|
|
|
// Decompress into subsection of current buffer specified
|
|
// by x,y,w,h in units of SWIDTHxSHEIGHT (8x8).
|
|
// Chgs specifies which squares to update.
|
|
// Parms are motion parms for squares to update.
|
|
void nfDecompChg(const unsigned short *chgs, const unsigned short *parms, const unsigned char *comp, unsigned x,
|
|
unsigned y, unsigned w, unsigned h) {
|
|
if (nf_hicolor) {
|
|
nfHiColorDecompChg(chgs, parms, comp, x, y, w, h);
|
|
return;
|
|
}
|
|
|
|
DECOMP_CHG_BODY(false, chgs, parms, comp, x, y, w, h);
|
|
}
|
|
|
|
void nfPkDecompH(unsigned char *ops, unsigned char *comp, unsigned x, unsigned y, unsigned w, unsigned h) { debug_break(); }
|
|
void nfPkDecompD(unsigned char *ops, unsigned char *comp, unsigned x, unsigned y, unsigned w, unsigned h) { debug_break(); }
|
|
void mve_ShowFrameField(unsigned char *buf, unsigned bufw, unsigned bufh, unsigned sx, unsigned sy, unsigned w,
|
|
unsigned h, unsigned dstx, unsigned dsty, unsigned field) {
|
|
debug_break();
|
|
}
|
|
void mve_ShowFrameFieldHi(unsigned char *buf, unsigned bufw, unsigned bufh, unsigned sx, unsigned sy, unsigned w,
|
|
unsigned h, unsigned dstx, unsigned dsty, unsigned field) {
|
|
debug_break();
|
|
}
|
|
void mve_sfShowFrameChg(bool prvbuf, unsigned x, unsigned y, unsigned w, unsigned h, unsigned short *chgs,
|
|
unsigned dstx, unsigned dsty) {
|
|
debug_break();
|
|
}
|
|
void mve_sfHiColorShowFrameChg(bool prvbuf, unsigned x, unsigned y, unsigned w, unsigned h, unsigned short *chgs,
|
|
unsigned dstx, unsigned dsty) {
|
|
debug_break();
|
|
}
|
|
void mve_sfPkShowFrameChg(bool prvbuf, unsigned x, unsigned y, unsigned w, unsigned h, unsigned char *ops,
|
|
unsigned dstx, unsigned dsty) {
|
|
debug_break();
|
|
}
|
|
void mve_sfPkHiColorShowFrameChg(bool prvbuf, unsigned x, unsigned y, unsigned w, unsigned h, unsigned char *ops,
|
|
unsigned dstx, unsigned dsty) {
|
|
debug_break();
|
|
}
|
|
void MVE_SetPalette(unsigned char *p, unsigned start, unsigned count) { debug_break(); }
|
|
void palLoadCompPalette(unsigned char *buf) { debug_break(); }
|
|
void gfxMode(unsigned mode) { debug_break(); }
|
|
void gfxLoadCrtc(unsigned char *crtc, unsigned char chain4, unsigned char res) { debug_break(); }
|
|
void gfxGetCrtc(unsigned char *crtc) { debug_break(); }
|
|
void gfxVres(unsigned char misc, unsigned char *crtc) { debug_break(); }
|
|
void MVE_gfxWaitRetrace(int state) { debug_break(); }
|
|
void MVE_gfxSetSplit(unsigned line) { debug_break(); }
|