//
// Original source by David Raingeard (Cal2)
// GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS)
//
// Original source by David Raingeard (Cal2)
// GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS)
-#define BLEND_Y(dst, src) op_blend_y[(((uint16)dst<<8)) | ((uint16)(src))]
-#define BLEND_CR(dst, src) op_blend_cr[(((uint16)dst)<<8) | ((uint16)(src))]
+#define BLEND_Y(dst, src) op_blend_y[(((uint16_t)dst<<8)) | ((uint16_t)(src))]
+#define BLEND_CR(dst, src) op_blend_cr[(((uint16_t)dst)<<8) | ((uint16_t)(src))]
-#define CONDITION_EQUAL 0
-#define CONDITION_LESS_THAN 1
-#define CONDITION_GREATER_THAN 2
+#define CONDITION_EQUAL 0 // VC == YPOS
+#define CONDITION_LESS_THAN 1 // VC < YPOS
+#define CONDITION_GREATER_THAN 2 // VC > YPOS
#define OPFLAG_RELEASE 8 // Bus release bit
#define OPFLAG_TRANS 4 // Transparency bit
#define OPFLAG_RMW 2 // Read-Modify-Write bit
#define OPFLAG_REFLECT 1 // Horizontal mirror bit
#define OPFLAG_RELEASE 8 // Bus release bit
#define OPFLAG_TRANS 4 // Transparency bit
#define OPFLAG_RMW 2 // Read-Modify-Write bit
#define OPFLAG_REFLECT 1 // Horizontal mirror bit
-void OPProcessFixedBitmap(uint64 p0, uint64 p1, bool render);
-void OPProcessScaledBitmap(uint64 p0, uint64 p1, uint64 p2, bool render);
-void OPDiscoverObjects(uint32 address);
+void OPProcessFixedBitmap(uint64_t p0, uint64_t p1, bool render);
+void OPProcessScaledBitmap(uint64_t p0, uint64_t p1, uint64_t p2, bool render);
+void OPDiscoverObjects(uint32_t address);
-void DumpScaledObject(uint64 p0, uint64 p1, uint64 p2);
-void DumpFixedObject(uint64 p0, uint64 p1);
-void DumpBitmapCore(uint64 p0, uint64 p1);
-uint64 OPLoadPhrase(uint32 offset);
+void DumpScaledObject(uint64_t p0, uint64_t p1, uint64_t p2);
+void DumpFixedObject(uint64_t p0, uint64_t p1);
+void DumpBitmapCore(uint64_t p0, uint64_t p1);
+uint64_t OPLoadPhrase(uint32_t offset);
// There may be a problem with this "RAM" overlapping (and thus being independent of)
// some of the regular TOM RAM...
//#warning objectp_ram is separated from TOM RAM--need to fix that!
// There may be a problem with this "RAM" overlapping (and thus being independent of)
// some of the regular TOM RAM...
//#warning objectp_ram is separated from TOM RAM--need to fix that!
-static uint8 op_bitmap_bit_depth[8] = { 1, 2, 4, 8, 16, 24, 32, 0 };
-//static uint32 op_bitmap_bit_size[8] =
-// { (uint32)(0.125*65536), (uint32)(0.25*65536), (uint32)(0.5*65536), (uint32)(1*65536),
-// (uint32)(2*65536), (uint32)(1*65536), (uint32)(1*65536), (uint32)(1*65536) };
-static uint32 op_pointer;
+static uint8_t op_bitmap_bit_depth[8] = { 1, 2, 4, 8, 16, 24, 32, 0 };
+//static uint32_t op_bitmap_bit_size[8] =
+// { (uint32_t)(0.125*65536), (uint32_t)(0.25*65536), (uint32_t)(0.5*65536), (uint32_t)(1*65536),
+// (uint32_t)(2*65536), (uint32_t)(1*65536), (uint32_t)(1*65536), (uint32_t)(1*65536) };
+static uint32_t op_pointer;
-int32 phraseWidthToPixels[8] = { 64, 32, 16, 8, 4, 2, 0, 0 };
+int32_t phraseWidthToPixels[8] = { 64, 32, 16, 8, 4, 2, 0, 0 };
static const char * opType[8] =
{ "(BITMAP)", "(SCALED BITMAP)", "(GPU INT)", "(BRANCH)", "(STOP)", "???", "???", "???" };
static const char * ccType[8] =
static const char * opType[8] =
{ "(BITMAP)", "(SCALED BITMAP)", "(GPU INT)", "(BRANCH)", "(STOP)", "???", "???", "???" };
static const char * ccType[8] =
- { "\"==\"", "\"<\"", "\">\"", "(opflag set)", "(second half line)", "?", "?", "?" };
-static uint32 object[8192];
-static uint32 numberOfObjects;
-//static uint32 objectLink[8192];
-//static uint32 numberOfLinks;
+ { "==", "<", ">", "(opflag set)", "(second half line)", "?", "?", "?" };
+static uint32_t object[8192];
+static uint32_t numberOfObjects;
+//static uint32_t objectLink[8192];
+//static uint32_t numberOfLinks;
+
// const char * ccType[8] =
// { "\"==\"", "\"<\"", "\">\"", "(opflag set)", "(second half line)", "?", "?", "?" };
// const char * ccType[8] =
// { "\"==\"", "\"<\"", "\">\"", "(opflag set)", "(second half line)", "?", "?", "?" };
WriteLog("\nOP: OLP = $%08X\n", olp);
WriteLog("OP: Phrase dump\n ----------\n");
#if 0
WriteLog("\nOP: OLP = $%08X\n", olp);
WriteLog("OP: Phrase dump\n ----------\n");
#if 0
- uint32 hi = JaguarReadLong(olp + i, OP), lo = JaguarReadLong(olp + i + 4, OP);
+ uint32_t hi = JaguarReadLong(olp + i, OP), lo = JaguarReadLong(olp + i + 4, OP);
WriteLog("\t%08X: %08X %08X %s", olp + i, hi, lo, opType[lo & 0x07]);
if ((lo & 0x07) == 3)
{
WriteLog("\t%08X: %08X %08X %s", olp + i, hi, lo, opType[lo & 0x07]);
if ((lo & 0x07) == 3)
{
- uint16 ypos = (lo >> 3) & 0x7FF;
- uint8 cc = (lo >> 14) & 0x03;
- uint32 link = ((hi << 11) | (lo >> 21)) & 0x3FFFF8;
+ uint16_t ypos = (lo >> 3) & 0x7FF;
+ uint8_t cc = (lo >> 14) & 0x03;
+ uint32_t link = ((hi << 11) | (lo >> 21)) & 0x3FFFF8;
WriteLog(" YPOS=%u, CC=%s, link=%08X", ypos, ccType[cc], link);
}
WriteLog(" YPOS=%u, CC=%s, link=%08X", ypos, ccType[cc], link);
}
- // Check to see if we've already seen this object
- for(uint32 i=0; i<numberOfObjects; i++)
+ // Yes, we really do a linear search, every time. :-/
+ for(uint32_t i=0; i<numberOfObjects; i++)
- uint32 hi = JaguarReadLong(address + 0, OP);
- uint32 lo = JaguarReadLong(address + 4, OP);
+ // If we've seen this object already, bail out!
+ // Otherwise, add it to the list
+ if (OPObjectExists(address))
+ return;
+
+ object[numberOfObjects++] = address;
+
+ // Get the object & decode its type, link address
+ uint32_t hi = JaguarReadLong(address + 0, OP);
+ uint32_t lo = JaguarReadLong(address + 4, OP);
- uint16 ypos = (lo >> 3) & 0x7FF;
- uint8 cc = (lo >> 14) & 0x07; // Proper # of bits == 3
-
- // Recursion needed to follow all links!
+ // Recursion needed to follow all links! This does depth-first recursion
+ // on the not-taken objects
-
- // Check to see if we've already seen this object, and add it if not
- bool seenObject = false;
-
- for(uint32 i=0; i<numberOfObjects; i++)
- {
- if (address == object[i])
- {
- seenObject = true;
- break;
- }
- }
-
- if (!seenObject)
- object[numberOfObjects++] = address;
- uint32 hi = JaguarReadLong(address + 0, OP);
- uint32 lo = JaguarReadLong(address + 4, OP);
- uint8 objectType = lo & 0x07;
- uint32 link = ((hi << 11) | (lo >> 21)) & 0x3FFFF8;
- WriteLog("%08X: %08X %08X %s", address, hi, lo, opType[objectType]);
+ uint32_t hi = JaguarReadLong(address + 0, OP);
+ uint32_t lo = JaguarReadLong(address + 4, OP);
+ uint8_t objectType = lo & 0x07;
+ uint32_t link = ((hi << 11) | (lo >> 21)) & 0x3FFFF8;
+ WriteLog("%08X: %08X %08X %s -> $08X", address, hi, lo, opType[objectType], link);
- uint16 ypos = (lo >> 3) & 0x7FF;
- uint8 cc = (lo >> 14) & 0x07; // Proper # of bits == 3
- WriteLog(" YPOS=%u, CC=%s, link=$%08X", ypos, ccType[cc], link);
+ uint16_t ypos = (lo >> 3) & 0x7FF;
+ uint8_t cc = (lo >> 14) & 0x07; // Proper # of bits == 3
+ WriteLog(" YPOS %s %u", ccType[cc], ypos);
{
// Note: This register is LO / HI WORD, hence the funky look of this...
return GET16(tomRam8, 0x20) | (GET16(tomRam8, 0x22) << 16);
}
{
// Note: This register is LO / HI WORD, hence the funky look of this...
return GET16(tomRam8, 0x20) | (GET16(tomRam8, 0x22) << 16);
}
{
//Not sure this is right... Wouldn't it just be stored 64 bit BE?
// Stored as least significant 32 bits first, ms32 last in big endian
{
//Not sure this is right... Wouldn't it just be stored 64 bit BE?
// Stored as least significant 32 bits first, ms32 last in big endian
{
offset &= ~0x07; // 8 byte alignment
JaguarWriteLong(offset, p >> 32, OP);
JaguarWriteLong(offset + 4, p & 0xFFFFFFFF, OP);
}
{
offset &= ~0x07; // 8 byte alignment
JaguarWriteLong(offset, p >> 32, OP);
JaguarWriteLong(offset + 4, p & 0xFFFFFFFF, OP);
}
- WriteLog(" %08X %08X\n", (uint32)(p1>>32), (uint32)(p1&0xFFFFFFFF));
- WriteLog(" %08X %08X\n", (uint32)(p2>>32), (uint32)(p2&0xFFFFFFFF));
+ WriteLog(" %08X %08X\n", (uint32_t)(p1>>32), (uint32_t)(p1&0xFFFFFFFF));
+ WriteLog(" %08X %08X\n", (uint32_t)(p2>>32), (uint32_t)(p2&0xFFFFFFFF));
- uint32 hscale = p2 & 0xFF;
- uint32 vscale = (p2 >> 8) & 0xFF;
- uint32 remainder = (p2 >> 16) & 0xFF;
+ uint32_t hscale = p2 & 0xFF;
+ uint32_t vscale = (p2 >> 8) & 0xFF;
+ uint32_t remainder = (p2 >> 16) & 0xFF;
WriteLog(" [hsc: %02X, vsc: %02X, rem: %02X]\n", hscale, vscale, remainder);
}
WriteLog(" [hsc: %02X, vsc: %02X, rem: %02X]\n", hscale, vscale, remainder);
}
- uint32 bdMultiplier[8] = { 64, 32, 16, 8, 4, 2, 1, 1 };
- uint8 bitdepth = (p1 >> 12) & 0x07;
-//WAS: int16 ypos = ((p0 >> 3) & 0x3FF); // ??? What if not interlaced (/2)?
- int16 ypos = ((p0 >> 3) & 0x7FF); // ??? What if not interlaced (/2)?
- int32 xpos = p1 & 0xFFF;
+ uint32_t bdMultiplier[8] = { 64, 32, 16, 8, 4, 2, 1, 1 };
+ uint8_t bitdepth = (p1 >> 12) & 0x07;
+//WAS: int16_t ypos = ((p0 >> 3) & 0x3FF); // ??? What if not interlaced (/2)?
+ int16_t ypos = ((p0 >> 3) & 0x7FF); // ??? What if not interlaced (/2)?
+ int32_t xpos = p1 & 0xFFF;
- uint32 iwidth = ((p1 >> 28) & 0x3FF);
- uint32 dwidth = ((p1 >> 18) & 0x3FF); // Unsigned!
- uint16 height = ((p0 >> 14) & 0x3FF);
- uint32 link = ((p0 >> 24) & 0x7FFFF) << 3;
- uint32 ptr = ((p0 >> 43) & 0x1FFFFF) << 3;
- uint32 firstPix = (p1 >> 49) & 0x3F;
- uint8 flags = (p1 >> 45) & 0x0F;
- uint8 idx = (p1 >> 38) & 0x7F;
- uint32 pitch = (p1 >> 15) & 0x07;
- WriteLog(" [%u x %u @ (%i, %u) (iw:%u, dw:%u) (%u bpp), l:%08X, p:%08X fp:%02X, fl:%s%s%s%s, idx:%02X, pt:%02X]\n",
+ uint32_t iwidth = ((p1 >> 28) & 0x3FF);
+ uint32_t dwidth = ((p1 >> 18) & 0x3FF); // Unsigned!
+ uint16_t height = ((p0 >> 14) & 0x3FF);
+ uint32_t link = ((p0 >> 24) & 0x7FFFF) << 3;
+ uint32_t ptr = ((p0 >> 43) & 0x1FFFFF) << 3;
+ uint32_t firstPix = (p1 >> 49) & 0x3F;
+ uint8_t flags = (p1 >> 45) & 0x0F;
+ uint8_t idx = (p1 >> 38) & 0x7F;
+ uint32_t pitch = (p1 >> 15) & 0x07;
+ WriteLog(" [%u x %u @ (%i, %u) (iw:%u, dw:%u) (%u bpp), p:%08X fp:%02X, fl:%s%s%s%s, idx:%02X, pt:%02X]\n",
- height, xpos, ypos, iwidth, dwidth, op_bitmap_bit_depth[bitdepth], link,
+ height, xpos, ypos, iwidth, dwidth, op_bitmap_bit_depth[bitdepth],
ptr, firstPix, (flags&OPFLAG_REFLECT ? "REFLECT " : ""),
(flags&OPFLAG_RMW ? "RMW " : ""), (flags&OPFLAG_TRANS ? "TRANS " : ""),
(flags&OPFLAG_RELEASE ? "RELEASE" : ""), idx, pitch);
}
ptr, firstPix, (flags&OPFLAG_REFLECT ? "REFLECT " : ""),
(flags&OPFLAG_RMW ? "RMW " : ""), (flags&OPFLAG_TRANS ? "TRANS " : ""),
(flags&OPFLAG_RELEASE ? "RELEASE" : ""), idx, pitch);
}
//
// Object Processor main routine
//
#warning "Need to fix this so that when an GPU object IRQ happens, we can pick up OP processing where we left off. !!! FIX !!!"
void OPProcessList(int halfline, bool render)
{
//
// Object Processor main routine
//
#warning "Need to fix this so that when an GPU object IRQ happens, we can pick up OP processing where we left off. !!! FIX !!!"
void OPProcessList(int halfline, bool render)
{
WriteLog("\n%08X --> phrase %08X %08X ", op_pointer, (int)(p1>>32), (int)(p1&0xFFFFFFFF));
WriteLog("\n%08X --> phrase %08X %08X ", op_pointer, (int)(p1>>32), (int)(p1&0xFFFFFFFF));
- uint8 bitdepth = (p1 >> 12) & 0x07;
-//WAS: int16 ypos = ((p0 >> 3) & 0x3FF); // ??? What if not interlaced (/2)?
- int16 ypos = ((p0 >> 3) & 0x7FF); // ??? What if not interlaced (/2)?
-int32 xpos = p1 & 0xFFF;
+ uint8_t bitdepth = (p1 >> 12) & 0x07;
+//WAS: int16_t ypos = ((p0 >> 3) & 0x3FF); // ??? What if not interlaced (/2)?
+ int16_t ypos = ((p0 >> 3) & 0x7FF); // ??? What if not interlaced (/2)?
+int32_t xpos = p1 & 0xFFF;
- uint32 iwidth = ((p1 >> 28) & 0x3FF);
- uint32 dwidth = ((p1 >> 18) & 0x3FF); // Unsigned!
- uint16 height = ((p0 >> 14) & 0x3FF);
- uint32 link = ((p0 >> 24) & 0x7FFFF) << 3;
- uint32 ptr = ((p0 >> 43) & 0x1FFFFF) << 3;
- uint32 firstPix = (p1 >> 49) & 0x3F;
- uint8 flags = (p1 >> 45) & 0x0F;
- uint8 idx = (p1 >> 38) & 0x7F;
- uint32 pitch = (p1 >> 15) & 0x07;
+ uint32_t iwidth = ((p1 >> 28) & 0x3FF);
+ uint32_t dwidth = ((p1 >> 18) & 0x3FF); // Unsigned!
+ uint16_t height = ((p0 >> 14) & 0x3FF);
+ uint32_t link = ((p0 >> 24) & 0x7FFFF) << 3;
+ uint32_t ptr = ((p0 >> 43) & 0x1FFFFF) << 3;
+ uint32_t firstPix = (p1 >> 49) & 0x3F;
+ uint8_t flags = (p1 >> 45) & 0x0F;
+ uint8_t idx = (p1 >> 38) & 0x7F;
+ uint32_t pitch = (p1 >> 15) & 0x07;
WriteLog("\n [%u (%u) x %u @ (%i, %u) (%u bpp), l: %08X, p: %08X fp: %02X, fl:%s%s%s%s, idx:%02X, pt:%02X]\n",
iwidth, dwidth, height, xpos, ypos, op_bitmap_bit_depth[bitdepth], link, ptr, firstPix, (flags&OPFLAG_REFLECT ? "REFLECT " : ""), (flags&OPFLAG_RMW ? "RMW " : ""), (flags&OPFLAG_TRANS ? "TRANS " : ""), (flags&OPFLAG_RELEASE ? "RELEASE" : ""), idx, pitch);
}
if ((p0 & 0x07) == OBJECT_TYPE_SCALE)
{
WriteLog(" (SCALED BITMAP)");
WriteLog("\n [%u (%u) x %u @ (%i, %u) (%u bpp), l: %08X, p: %08X fp: %02X, fl:%s%s%s%s, idx:%02X, pt:%02X]\n",
iwidth, dwidth, height, xpos, ypos, op_bitmap_bit_depth[bitdepth], link, ptr, firstPix, (flags&OPFLAG_REFLECT ? "REFLECT " : ""), (flags&OPFLAG_RMW ? "RMW " : ""), (flags&OPFLAG_TRANS ? "TRANS " : ""), (flags&OPFLAG_RELEASE ? "RELEASE" : ""), idx, pitch);
}
if ((p0 & 0x07) == OBJECT_TYPE_SCALE)
{
WriteLog(" (SCALED BITMAP)");
WriteLog("\n%08X --> phrase %08X %08X ", op_pointer, (int)(p1>>32), (int)(p1&0xFFFFFFFF));
WriteLog("\n%08X --> phrase %08X %08X ", op_pointer+8, (int)(p2>>32), (int)(p2&0xFFFFFFFF));
WriteLog("\n%08X --> phrase %08X %08X ", op_pointer, (int)(p1>>32), (int)(p1&0xFFFFFFFF));
WriteLog("\n%08X --> phrase %08X %08X ", op_pointer+8, (int)(p2>>32), (int)(p2&0xFFFFFFFF));
- uint8 bitdepth = (p1 >> 12) & 0x07;
-//WAS: int16 ypos = ((p0 >> 3) & 0x3FF); // ??? What if not interlaced (/2)?
- int16 ypos = ((p0 >> 3) & 0x7FF); // ??? What if not interlaced (/2)?
-int32 xpos = p1 & 0xFFF;
+ uint8_t bitdepth = (p1 >> 12) & 0x07;
+//WAS: int16_t ypos = ((p0 >> 3) & 0x3FF); // ??? What if not interlaced (/2)?
+ int16_t ypos = ((p0 >> 3) & 0x7FF); // ??? What if not interlaced (/2)?
+int32_t xpos = p1 & 0xFFF;
- uint32 iwidth = ((p1 >> 28) & 0x3FF);
- uint32 dwidth = ((p1 >> 18) & 0x3FF); // Unsigned!
- uint16 height = ((p0 >> 14) & 0x3FF);
- uint32 link = ((p0 >> 24) & 0x7FFFF) << 3;
- uint32 ptr = ((p0 >> 43) & 0x1FFFFF) << 3;
- uint32 firstPix = (p1 >> 49) & 0x3F;
- uint8 flags = (p1 >> 45) & 0x0F;
- uint8 idx = (p1 >> 38) & 0x7F;
- uint32 pitch = (p1 >> 15) & 0x07;
+ uint32_t iwidth = ((p1 >> 28) & 0x3FF);
+ uint32_t dwidth = ((p1 >> 18) & 0x3FF); // Unsigned!
+ uint16_t height = ((p0 >> 14) & 0x3FF);
+ uint32_t link = ((p0 >> 24) & 0x7FFFF) << 3;
+ uint32_t ptr = ((p0 >> 43) & 0x1FFFFF) << 3;
+ uint32_t firstPix = (p1 >> 49) & 0x3F;
+ uint8_t flags = (p1 >> 45) & 0x0F;
+ uint8_t idx = (p1 >> 38) & 0x7F;
+ uint32_t pitch = (p1 >> 15) & 0x07;
WriteLog("\n [%u (%u) x %u @ (%i, %u) (%u bpp), l: %08X, p: %08X fp: %02X, fl:%s%s%s%s, idx:%02X, pt:%02X]\n",
iwidth, dwidth, height, xpos, ypos, op_bitmap_bit_depth[bitdepth], link, ptr, firstPix, (flags&OPFLAG_REFLECT ? "REFLECT " : ""), (flags&OPFLAG_RMW ? "RMW " : ""), (flags&OPFLAG_TRANS ? "TRANS " : ""), (flags&OPFLAG_RELEASE ? "RELEASE" : ""), idx, pitch);
WriteLog("\n [%u (%u) x %u @ (%i, %u) (%u bpp), l: %08X, p: %08X fp: %02X, fl:%s%s%s%s, idx:%02X, pt:%02X]\n",
iwidth, dwidth, height, xpos, ypos, op_bitmap_bit_depth[bitdepth], link, ptr, firstPix, (flags&OPFLAG_REFLECT ? "REFLECT " : ""), (flags&OPFLAG_RMW ? "RMW " : ""), (flags&OPFLAG_TRANS ? "TRANS " : ""), (flags&OPFLAG_RELEASE ? "RELEASE" : ""), idx, pitch);
- uint32 hscale = p2 & 0xFF;
- uint32 vscale = (p2 >> 8) & 0xFF;
- uint32 remainder = (p2 >> 16) & 0xFF;
+ uint32_t hscale = p2 & 0xFF;
+ uint32_t vscale = (p2 >> 8) & 0xFF;
+ uint32_t remainder = (p2 >> 16) & 0xFF;
WriteLog(" [hsc: %02X, vsc: %02X, rem: %02X]\n", hscale, vscale, remainder);
}
if ((p0 & 0x07) == OBJECT_TYPE_GPU)
WriteLog(" [hsc: %02X, vsc: %02X, rem: %02X]\n", hscale, vscale, remainder);
}
if ((p0 & 0x07) == OBJECT_TYPE_GPU)
// This is only theory implied by Rayman...!
// It seems that if the YPOS is zero, then bump the YPOS value so that it coincides with
// the VDB value. With interlacing, this would be slightly more tricky.
// This is only theory implied by Rayman...!
// It seems that if the YPOS is zero, then bump the YPOS value so that it coincides with
// the VDB value. With interlacing, this would be slightly more tricky.
// Actually, this is incorrect. It seems that VDB value is wrong somewhere and that's
// what's causing things to fuck up. Still no idea why.
// Actually, this is incorrect. It seems that VDB value is wrong somewhere and that's
// what's causing things to fuck up. Still no idea why.
// *** BEGIN OP PROCESSOR TESTING ONLY ***
if (inhibit && op_start_log)
WriteLog("!!! ^^^ This object is INHIBITED! ^^^ !!!\n");
// *** BEGIN OP PROCESSOR TESTING ONLY ***
if (inhibit && op_start_log)
WriteLog("!!! ^^^ This object is INHIBITED! ^^^ !!!\n");
op_pointer += 8;
//WriteLog("OP: Writing halfline %d with ypos == %d...\n", halfline, ypos);
//WriteLog("--> Writing %u BPP bitmap...\n", op_bitmap_bit_depth[(p1 >> 12) & 0x07]);
op_pointer += 8;
//WriteLog("OP: Writing halfline %d with ypos == %d...\n", halfline, ypos);
//WriteLog("--> Writing %u BPP bitmap...\n", op_bitmap_bit_depth[(p1 >> 12) & 0x07]);
//???Does this really happen??? Doesn't seem to work if you do this...!
//Probably not. Must be a bug in the documentation...!
//???Does this really happen??? Doesn't seem to work if you do this...!
//Probably not. Must be a bug in the documentation...!
// SET16(tom_ram_8, 0x20, link & 0xFFFF); // OLP
// SET16(tom_ram_8, 0x22, link >> 16);
// SET16(tom_ram_8, 0x20, link & 0xFFFF); // OLP
// SET16(tom_ram_8, 0x22, link >> 16);
- op_pointer = (p0 & 0x000007FFFF000000LL) >> 21;
+// NOTE: The link address only replaces bits 3-21 in the OLP, and this replaces
+// EVERYTHING. !!! FIX !!! [DONE]
+#warning "!!! Link address is not linked properly for all object types !!!"
+#warning "!!! Only BITMAP is properly handled !!!"
+ op_pointer &= 0xFFC00007;
+ op_pointer |= (p0 & 0x000007FFFF000000LL) >> 21;
-//WAS: uint16 ypos = (p0 >> 3) & 0x3FF;
- uint16 ypos = (p0 >> 3) & 0x7FF;
- uint32 height = (p0 & 0xFFC000) >> 14;
- uint32 oldOPP = op_pointer - 8;
+//WAS: uint16_t ypos = (p0 >> 3) & 0x3FF;
+ uint16_t ypos = (p0 >> 3) & 0x7FF;
+ uint32_t height = (p0 & 0xFFC000) >> 14;
+ uint32_t oldOPP = op_pointer - 8;
//WriteLog("OP: Scaled Object (ypos=%04X, height=%04X", ypos, height);
// *** BEGIN OP PROCESSOR TESTING ONLY ***
if (inhibit && op_start_log)
//WriteLog("OP: Scaled Object (ypos=%04X, height=%04X", ypos, height);
// *** BEGIN OP PROCESSOR TESTING ONLY ***
if (inhibit && op_start_log)
-//WriteLog("OP: %08X (%d) %08X%08X %08X%08X %08X%08X\n", oldOPP, halfline, (uint32)(p0>>32), (uint32)(p0&0xFFFFFFFF), (uint32)(p1>>32), (uint32)(p1&0xFFFFFFFF), (uint32)(p2>>32), (uint32)(p2&0xFFFFFFFF));
+//WriteLog("OP: %08X (%d) %08X%08X %08X%08X %08X%08X\n", oldOPP, halfline, (uint32_t)(p0>>32), (uint32_t)(p0&0xFFFFFFFF), (uint32_t)(p1>>32), (uint32_t)(p1&0xFFFFFFFF), (uint32_t)(p2>>32), (uint32_t)(p2&0xFFFFFFFF));
OPProcessScaledBitmap(p0, p1, p2, render);
// OP write-backs
OPProcessScaledBitmap(p0, p1, p2, render);
// OP write-backs
- uint16 remainder = (p2 >> 16) & 0xFF;//, vscale = p2 >> 8;
- uint8 /*remainder = p2 >> 16,*/ vscale = p2 >> 8;
+ uint16_t remainder = (p2 >> 16) & 0xFF;//, vscale = p2 >> 8;
+ uint8_t /*remainder = p2 >> 16,*/ vscale = p2 >> 8;
//Actually, we should skip this object if it has a vscale of zero.
//Or do we? Not sure... Atari Karts has a few lines that look like:
// (SCALED BITMAP)
//Actually, we should skip this object if it has a vscale of zero.
//Or do we? Not sure... Atari Karts has a few lines that look like:
// (SCALED BITMAP)
- p2 |= (uint64)remainder << 16;
-//WriteLog("%08X%08X]\n", (uint32)(p2>>32), (uint32)(p2&0xFFFFFFFF));
+ p2 |= (uint64_t)remainder << 16;
+//WriteLog("%08X%08X]\n", (uint32_t)(p2>>32), (uint32_t)(p2&0xFFFFFFFF));
//WriteLog(" [after]: rem=%02X, vscale=%02X\n", remainder, vscale);
}
//WriteLog(" [after]: rem=%02X, vscale=%02X\n", remainder, vscale);
}
// NOTE: The JTRM sez there are only 2 bits used for the CC, but lists *five*
// conditions! Need at least one more bit for that! :-P
// NOTE: The JTRM sez there are only 2 bits used for the CC, but lists *five*
// conditions! Need at least one more bit for that! :-P
// if ((ypos!=507)&&(ypos!=25))
// WriteLog("\t%i%s%i link=0x%.8x\n",halfline,condition_to_str[cc],ypos>>1,link);
// if ((ypos!=507)&&(ypos!=25))
// WriteLog("\t%i%s%i link=0x%.8x\n",halfline,condition_to_str[cc],ypos>>1,link);
{
// Need to make sure that when writing that it stays within the line buffer...
// LBUF ($F01800 - $F01D9E) 360 x 32-bit RAM
{
// Need to make sure that when writing that it stays within the line buffer...
// LBUF ($F01800 - $F01D9E) 360 x 32-bit RAM
- uint8 depth = (p1 >> 12) & 0x07; // Color depth of image
- int32 xpos = ((int16)((p1 << 4) & 0xFFFF)) >> 4;// Image xpos in LBUF
- uint32 iwidth = (p1 >> 28) & 0x3FF; // Image width in *phrases*
- uint32 data = (p0 >> 40) & 0xFFFFF8; // Pixel data address
+ uint8_t depth = (p1 >> 12) & 0x07; // Color depth of image
+ int32_t xpos = ((int16_t)((p1 << 4) & 0xFFFF)) >> 4;// Image xpos in LBUF
+ uint32_t iwidth = (p1 >> 28) & 0x3FF; // Image width in *phrases*
+ uint32_t data = (p0 >> 40) & 0xFFFFF8; // Pixel data address
// "The LSB is significant only for scaled objects..." -JTRM
// "In 1 BPP mode, all five bits are significant. In 2 BPP mode, the top four are significant..."
firstPix &= 0x3E;
//#endif
// We can ignore the RELEASE (high order) bit for now--probably forever...!
// "The LSB is significant only for scaled objects..." -JTRM
// "In 1 BPP mode, all five bits are significant. In 2 BPP mode, the top four are significant..."
firstPix &= 0x3E;
//#endif
// We can ignore the RELEASE (high order) bit for now--probably forever...!
-// uint8 flags = (p1 >> 45) & 0x0F; // REFLECT, RMW, TRANS, RELEASE
+// uint8_t flags = (p1 >> 45) & 0x0F; // REFLECT, RMW, TRANS, RELEASE
bool flagREFLECT = (flags & OPFLAG_REFLECT ? true : false),
flagRMW = (flags & OPFLAG_RMW ? true : false),
flagTRANS = (flags & OPFLAG_TRANS ? true : false);
// "For images with 1 to 4 bits/pixel the top 7 to 4 bits of the index
// provide the most significant bits of the palette address."
bool flagREFLECT = (flags & OPFLAG_REFLECT ? true : false),
flagRMW = (flags & OPFLAG_RMW ? true : false),
flagTRANS = (flags & OPFLAG_TRANS ? true : false);
// "For images with 1 to 4 bits/pixel the top 7 to 4 bits of the index
// provide the most significant bits of the palette address."
- uint8 index = (p1 >> 37) & 0xFE; // CLUT index offset (upper pix, 1-4 bpp)
- uint32 pitch = (p1 >> 15) & 0x07; // Phrase pitch
+ uint8_t index = (p1 >> 37) & 0xFE; // CLUT index offset (upper pix, 1-4 bpp)
+ uint32_t pitch = (p1 >> 15) & 0x07; // Phrase pitch
-// int16 scanlineWidth = tom_getVideoModeWidth();
- uint8 * tomRam8 = TOMGetRamPointer();
- uint8 * paletteRAM = &tomRam8[0x400];
+// int16_t scanlineWidth = tom_getVideoModeWidth();
+ uint8_t * tomRam8 = TOMGetRamPointer();
+ uint8_t * paletteRAM = &tomRam8[0x400];
// This is OK as long as it's used correctly: For 16-bit RAM to RAM direct copies--NOT
// for use when using endian-corrected data (i.e., any of the *_word_read functions!)
// This is OK as long as it's used correctly: For 16-bit RAM to RAM direct copies--NOT
// for use when using endian-corrected data (i.e., any of the *_word_read functions!)
// WriteLog("bitmap %ix? %ibpp at %i,? firstpix=? data=0x%.8x pitch %i hflipped=%s dwidth=? (linked to ?) RMW=%s Tranparent=%s\n",
// iwidth, op_bitmap_bit_depth[bitdepth], xpos, ptr, pitch, (flags&OPFLAG_REFLECT ? "yes" : "no"), (flags&OPFLAG_RMW ? "yes" : "no"), (flags&OPFLAG_TRANS ? "yes" : "no"));
// WriteLog("bitmap %ix? %ibpp at %i,? firstpix=? data=0x%.8x pitch %i hflipped=%s dwidth=? (linked to ?) RMW=%s Tranparent=%s\n",
// iwidth, op_bitmap_bit_depth[bitdepth], xpos, ptr, pitch, (flags&OPFLAG_REFLECT ? "yes" : "no"), (flags&OPFLAG_RMW ? "yes" : "no"), (flags&OPFLAG_TRANS ? "yes" : "no"));
// Is it OK to have a 0 for the data width??? (i.e., undocumented?)
// Seems to be... Seems that dwidth *can* be zero (i.e., reuse same line) as well.
// Pitch == 0 is OK too...
// Is it OK to have a 0 for the data width??? (i.e., undocumented?)
// Seems to be... Seems that dwidth *can* be zero (i.e., reuse same line) as well.
// Pitch == 0 is OK too...
// if (!render || op_pointer == 0 || ptr == 0 || pitch == 0)
//I'm not convinced that we need to concern ourselves with data & op_pointer here either!
if (!render || iwidth == 0)
// if (!render || op_pointer == 0 || ptr == 0 || pitch == 0)
//I'm not convinced that we need to concern ourselves with data & op_pointer here either!
if (!render || iwidth == 0)
// iwidth, height, op_bitmap_bit_depth[bitdepth], xpos, ypos, firstPix, ptr, pitch, (flags&OPFLAG_REFLECT ? "yes" : "no"), dwidth, op_pointer, (flags&OPFLAG_RMW ? "yes" : "no"));
//#endif
// iwidth, height, op_bitmap_bit_depth[bitdepth], xpos, ypos, firstPix, ptr, pitch, (flags&OPFLAG_REFLECT ? "yes" : "no"), dwidth, op_pointer, (flags&OPFLAG_RMW ? "yes" : "no"));
//#endif
-// int32 leftMargin = xpos, rightMargin = (xpos + (phraseWidthToPixels[depth] * iwidth)) - 1;
- int32 startPos = xpos, endPos = xpos +
+// int32_t leftMargin = xpos, rightMargin = (xpos + (phraseWidthToPixels[depth] * iwidth)) - 1;
+ int32_t startPos = xpos, endPos = xpos +
(!flagREFLECT ? (phraseWidthToPixels[depth] * iwidth) - 1
: -((phraseWidthToPixels[depth] * iwidth) + 1));
(!flagREFLECT ? (phraseWidthToPixels[depth] * iwidth) - 1
: -((phraseWidthToPixels[depth] * iwidth) + 1));
- uint32 clippedWidth = 0, phraseClippedWidth = 0, dataClippedWidth = 0;//, phrasePixel = 0;
+ uint32_t clippedWidth = 0, phraseClippedWidth = 0, dataClippedWidth = 0;//, phrasePixel = 0;
bool in24BPPMode = (((GET16(tomRam8, 0x0028) >> 1) & 0x03) == 1 ? true : false); // VMODE
// Not sure if this is Jaguar Two only location or what...
// From the docs, it is... If we want to limit here we should think of something else.
bool in24BPPMode = (((GET16(tomRam8, 0x0028) >> 1) & 0x03) == 1 ? true : false); // VMODE
// Not sure if this is Jaguar Two only location or what...
// From the docs, it is... If we want to limit here we should think of something else.
-// int32 limit = GET16(tom_ram_8, 0x0008); // LIMIT
-// int32 limit = 720;
-// int32 lbufWidth = (!in24BPPMode ? limit - 1 : (limit / 2) - 1); // Zero based limit...
+// int32_t limit = GET16(tom_ram_8, 0x0008); // LIMIT
+// int32_t limit = 720;
+// int32_t lbufWidth = (!in24BPPMode ? limit - 1 : (limit / 2) - 1); // Zero based limit...
//printf("[OP:xpos=%i,spos=%i,epos=%i>", xpos, startPos, endPos);
// This is correct, the OP line buffer is a constant size...
//printf("[OP:xpos=%i,spos=%i,epos=%i>", xpos, startPos, endPos);
// This is correct, the OP line buffer is a constant size...
// If the image is completely to the left or right of the line buffer, then bail.
//If in REFLECT mode, then these values are swapped! !!! FIX !!! [DONE]
// If the image is completely to the left or right of the line buffer, then bail.
//If in REFLECT mode, then these values are swapped! !!! FIX !!! [DONE]
// NOTE: When the bitmap is in REFLECT mode, the XPOS marks the *right* side of the
// bitmap! This makes clipping & etc. MUCH, much easier...!
// NOTE: When the bitmap is in REFLECT mode, the XPOS marks the *right* side of the
// bitmap! This makes clipping & etc. MUCH, much easier...!
//Why does this work right when multiplying startPos by 2 (instead of 4) for 24 BPP mode?
//Is this a bug in the OP?
//It's because in 24bpp mode, each pixel takes *4* bytes, instead of the usual 2.
//Though it looks like we're doing it here no matter what...
//Why does this work right when multiplying startPos by 2 (instead of 4) for 24 BPP mode?
//Is this a bug in the OP?
//It's because in 24bpp mode, each pixel takes *4* bytes, instead of the usual 2.
//Though it looks like we're doing it here no matter what...
- uint32 lbufAddress = 0x1800 + (startPos * 2);
- uint8 * currentLineBuffer = &tomRam8[lbufAddress];
+ uint32_t lbufAddress = 0x1800 + (startPos * 2);
+ uint8_t * currentLineBuffer = &tomRam8[lbufAddress];
//Note that firstPix should only be honored *if* we start with the 1st phrase of the bitmap
//i.e., we didn't clip on the margin... !!! FIX !!!
pixels <<= firstPix; // Skip first N pixels (N=firstPix)...
//Note that firstPix should only be honored *if* we start with the 1st phrase of the bitmap
//i.e., we didn't clip on the margin... !!! FIX !!!
pixels <<= firstPix; // Skip first N pixels (N=firstPix)...
//Won't optimize RMW case though...
// This is the *only* correct use of endian-dependent code
// (i.e., mem-to-mem direct copying)!
//Won't optimize RMW case though...
// This is the *only* correct use of endian-dependent code
// (i.e., mem-to-mem direct copying)!
WriteLog("OP: Fixed bitmap @ 2 BPP requesting FIRSTPIX! (fp=%u)\n", firstPix);
index &= 0xFC; // Top six bits form CLUT index
// The LSB is OPFLAG_REFLECT, so sign extend it and or 2 into it.
WriteLog("OP: Fixed bitmap @ 2 BPP requesting FIRSTPIX! (fp=%u)\n", firstPix);
index &= 0xFC; // Top six bits form CLUT index
// The LSB is OPFLAG_REFLECT, so sign extend it and or 2 into it.
// This only works for the palettized modes (1 - 8 BPP), since we actually have to
// copy data from memory in 16 BPP mode (or does it? Isn't this the same as the CLUT case?)
// No, it isn't because we read the memory in an endian safe way--this *won't* work...
// This only works for the palettized modes (1 - 8 BPP), since we actually have to
// copy data from memory in 16 BPP mode (or does it? Isn't this the same as the CLUT case?)
// No, it isn't because we read the memory in an endian safe way--this *won't* work...
WriteLog("OP: Fixed bitmap @ 4 BPP requesting FIRSTPIX! (fp=%u)\n", firstPix);
index &= 0xF0; // Top four bits form CLUT index
// The LSB is OPFLAG_REFLECT, so sign extend it and or 2 into it.
WriteLog("OP: Fixed bitmap @ 4 BPP requesting FIRSTPIX! (fp=%u)\n", firstPix);
index &= 0xF0; // Top four bits form CLUT index
// The LSB is OPFLAG_REFLECT, so sign extend it and or 2 into it.
// This only works for the palettized modes (1 - 8 BPP), since we actually have to
// copy data from memory in 16 BPP mode (or does it? Isn't this the same as the CLUT case?)
// No, it isn't because we read the memory in an endian safe way--this *won't* work...
// This only works for the palettized modes (1 - 8 BPP), since we actually have to
// copy data from memory in 16 BPP mode (or does it? Isn't this the same as the CLUT case?)
// No, it isn't because we read the memory in an endian safe way--this *won't* work...
else if (depth == 3) // 8 BPP
{
// The LSB is OPFLAG_REFLECT, so sign extend it and or 2 into it.
else if (depth == 3) // 8 BPP
{
// The LSB is OPFLAG_REFLECT, so sign extend it and or 2 into it.
//Note that firstPix should only be honored *if* we start with the 1st phrase of the bitmap
//i.e., we didn't clip on the margin... !!! FIX !!!
firstPix &= 0x30; // Only top two bits are valid for 8 BPP
//Note that firstPix should only be honored *if* we start with the 1st phrase of the bitmap
//i.e., we didn't clip on the margin... !!! FIX !!!
firstPix &= 0x30; // Only top two bits are valid for 8 BPP
// This only works for the palettized modes (1 - 8 BPP), since we actually have to
// copy data from memory in 16 BPP mode (or does it? Isn't this the same as the CLUT case?)
// No, it isn't because we read the memory in an endian safe way--this *won't* work...
// This only works for the palettized modes (1 - 8 BPP), since we actually have to
// copy data from memory in 16 BPP mode (or does it? Isn't this the same as the CLUT case?)
// No, it isn't because we read the memory in an endian safe way--this *won't* work...
if (firstPix)
WriteLog("OP: Fixed bitmap @ 16 BPP requesting FIRSTPIX! (fp=%u)\n", firstPix);
// The LSB is OPFLAG_REFLECT, so sign extend it and or 2 into it.
if (firstPix)
WriteLog("OP: Fixed bitmap @ 16 BPP requesting FIRSTPIX! (fp=%u)\n", firstPix);
// The LSB is OPFLAG_REFLECT, so sign extend it and or 2 into it.
// This only works for the palettized modes (1 - 8 BPP), since we actually have to
// copy data from memory in 16 BPP mode (or does it? Isn't this the same as the CLUT case?)
// No, it isn't because we read the memory in an endian safe way--it *won't* work...
// This only works for the palettized modes (1 - 8 BPP), since we actually have to
// copy data from memory in 16 BPP mode (or does it? Isn't this the same as the CLUT case?)
// No, it isn't because we read the memory in an endian safe way--it *won't* work...
WriteLog("OP: Fixed bitmap @ 24 BPP requesting FIRSTPIX! (fp=%u)\n", firstPix);
// Not sure, but I think RMW only works with 16 BPP and below, and only in CRY mode...
// The LSB of flags is OPFLAG_REFLECT, so sign extend it and OR 4 into it.
WriteLog("OP: Fixed bitmap @ 24 BPP requesting FIRSTPIX! (fp=%u)\n", firstPix);
// Not sure, but I think RMW only works with 16 BPP and below, and only in CRY mode...
// The LSB of flags is OPFLAG_REFLECT, so sign extend it and OR 4 into it.
bits1 = pixels >> 40, bits0 = pixels >> 32;
if (flagTRANS && (bits3 | bits2 | bits1 | bits0) == 0)
bits1 = pixels >> 40, bits0 = pixels >> 32;
if (flagTRANS && (bits3 | bits2 | bits1 | bits0) == 0)
-void OPProcessScaledBitmap(uint64 p0, uint64 p1, uint64 p2, bool render)
+void OPProcessScaledBitmap(uint64_t p0, uint64_t p1, uint64_t p2, bool render)
{
// Need to make sure that when writing that it stays within the line buffer...
// LBUF ($F01800 - $F01D9E) 360 x 32-bit RAM
{
// Need to make sure that when writing that it stays within the line buffer...
// LBUF ($F01800 - $F01D9E) 360 x 32-bit RAM
- uint8 depth = (p1 >> 12) & 0x07; // Color depth of image
- int32 xpos = ((int16)((p1 << 4) & 0xFFFF)) >> 4;// Image xpos in LBUF
- uint32 iwidth = (p1 >> 28) & 0x3FF; // Image width in *phrases*
- uint32 data = (p0 >> 40) & 0xFFFFF8; // Pixel data address
+ uint8_t depth = (p1 >> 12) & 0x07; // Color depth of image
+ int32_t xpos = ((int16_t)((p1 << 4) & 0xFFFF)) >> 4;// Image xpos in LBUF
+ uint32_t iwidth = (p1 >> 28) & 0x3FF; // Image width in *phrases*
+ uint32_t data = (p0 >> 40) & 0xFFFFF8; // Pixel data address
//#ifdef OP_DEBUG_BMP
// Prolly should use this... Though not sure exactly how.
//Use the upper bits as an offset into the phrase depending on the BPP. That's how!
//#ifdef OP_DEBUG_BMP
// Prolly should use this... Though not sure exactly how.
//Use the upper bits as an offset into the phrase depending on the BPP. That's how!
//This is WEIRD! I'm sure I saw Atari Karts request 8 BPP FIRSTPIX! What happened???
if (firstPix)
WriteLog("OP: FIRSTPIX != 0! (Scaled BM)\n");
//#endif
// We can ignore the RELEASE (high order) bit for now--probably forever...!
//This is WEIRD! I'm sure I saw Atari Karts request 8 BPP FIRSTPIX! What happened???
if (firstPix)
WriteLog("OP: FIRSTPIX != 0! (Scaled BM)\n");
//#endif
// We can ignore the RELEASE (high order) bit for now--probably forever...!
-// uint8 flags = (p1 >> 45) & 0x0F; // REFLECT, RMW, TRANS, RELEASE
+// uint8_t flags = (p1 >> 45) & 0x0F; // REFLECT, RMW, TRANS, RELEASE
bool flagREFLECT = (flags & OPFLAG_REFLECT ? true : false),
flagRMW = (flags & OPFLAG_RMW ? true : false),
flagTRANS = (flags & OPFLAG_TRANS ? true : false);
bool flagREFLECT = (flags & OPFLAG_REFLECT ? true : false),
flagRMW = (flags & OPFLAG_RMW ? true : false),
flagTRANS = (flags & OPFLAG_TRANS ? true : false);
- uint8 index = (p1 >> 37) & 0xFE; // CLUT index offset (upper pix, 1-4 bpp)
- uint32 pitch = (p1 >> 15) & 0x07; // Phrase pitch
+ uint8_t index = (p1 >> 37) & 0xFE; // CLUT index offset (upper pix, 1-4 bpp)
+ uint32_t pitch = (p1 >> 15) & 0x07; // Phrase pitch
// This is OK as long as it's used correctly: For 16-bit RAM to RAM direct copies--NOT
// for use when using endian-corrected data (i.e., any of the *ReadWord functions!)
// This is OK as long as it's used correctly: For 16-bit RAM to RAM direct copies--NOT
// for use when using endian-corrected data (i.e., any of the *ReadWord functions!)
// Hmm. It seems that fixing the horizontal scale necessitated re-fixing this. Not sure why,
// but seems to be consistent with the vertical scaling now (and it may turn out to be wrong!)...
// Hmm. It seems that fixing the horizontal scale necessitated re-fixing this. Not sure why,
// but seems to be consistent with the vertical scaling now (and it may turn out to be wrong!)...
- uint16 horizontalRemainder = hscale; // Not sure if it starts full, but seems reasonable [It's not!]
-// uint8 horizontalRemainder = 0; // Let's try zero! Seems to work! Yay! [No, it doesn't!]
- int32 scaledWidthInPixels = (iwidth * phraseWidthToPixels[depth] * hscale) >> 5;
- uint32 scaledPhrasePixels = (phraseWidthToPixels[depth] * hscale) >> 5;
+ uint16_t horizontalRemainder = hscale; // Not sure if it starts full, but seems reasonable [It's not!]
+// uint8_t horizontalRemainder = 0; // Let's try zero! Seems to work! Yay! [No, it doesn't!]
+ int32_t scaledWidthInPixels = (iwidth * phraseWidthToPixels[depth] * hscale) >> 5;
+ uint32_t scaledPhrasePixels = (phraseWidthToPixels[depth] * hscale) >> 5;
// WriteLog("bitmap %ix? %ibpp at %i,? firstpix=? data=0x%.8x pitch %i hflipped=%s dwidth=? (linked to ?) RMW=%s Tranparent=%s\n",
// iwidth, op_bitmap_bit_depth[bitdepth], xpos, ptr, pitch, (flags&OPFLAG_REFLECT ? "yes" : "no"), (flags&OPFLAG_RMW ? "yes" : "no"), (flags&OPFLAG_TRANS ? "yes" : "no"));
// WriteLog("bitmap %ix? %ibpp at %i,? firstpix=? data=0x%.8x pitch %i hflipped=%s dwidth=? (linked to ?) RMW=%s Tranparent=%s\n",
// iwidth, op_bitmap_bit_depth[bitdepth], xpos, ptr, pitch, (flags&OPFLAG_REFLECT ? "yes" : "no"), (flags&OPFLAG_RMW ? "yes" : "no"), (flags&OPFLAG_TRANS ? "yes" : "no"));
// iwidth, height, op_bitmap_bit_depth[bitdepth], xpos, ypos, firstPix, ptr, pitch, (flags&OPFLAG_REFLECT ? "yes" : "no"), dwidth, op_pointer, (flags&OPFLAG_RMW ? "yes" : "no"));
//#endif
// iwidth, height, op_bitmap_bit_depth[bitdepth], xpos, ypos, firstPix, ptr, pitch, (flags&OPFLAG_REFLECT ? "yes" : "no"), dwidth, op_pointer, (flags&OPFLAG_RMW ? "yes" : "no"));
//#endif
bool in24BPPMode = (((GET16(tomRam8, 0x0028) >> 1) & 0x03) == 1 ? true : false); // VMODE
// Not sure if this is Jaguar Two only location or what...
// From the docs, it is... If we want to limit here we should think of something else.
bool in24BPPMode = (((GET16(tomRam8, 0x0028) >> 1) & 0x03) == 1 ? true : false); // VMODE
// Not sure if this is Jaguar Two only location or what...
// From the docs, it is... If we want to limit here we should think of something else.
-// int32 limit = GET16(tom_ram_8, 0x0008); // LIMIT
- int32 limit = 720;
-// int32 lbufWidth = (!in24BPPMode ? limit - 1 : (limit / 2) - 1); // Zero based limit...
- int32 lbufWidth = 719; // Zero based limit...
+// int32_t limit = GET16(tom_ram_8, 0x0008); // LIMIT
+ int32_t limit = 720;
+// int32_t lbufWidth = (!in24BPPMode ? limit - 1 : (limit / 2) - 1); // Zero based limit...
+ int32_t lbufWidth = 719; // Zero based limit...
// If the image is completely to the left or right of the line buffer, then bail.
//If in REFLECT mode, then these values are swapped! !!! FIX !!! [DONE]
// If the image is completely to the left or right of the line buffer, then bail.
//If in REFLECT mode, then these values are swapped! !!! FIX !!! [DONE]
// start position (14 * 27.75), we get -6.5... NOT -17!
//Now it seems we're working OK, at least for the first case...
// start position (14 * 27.75), we get -6.5... NOT -17!
//Now it seems we're working OK, at least for the first case...
// NOTE: When the bitmap is in REFLECT mode, the XPOS marks the *right* side of the
// bitmap! This makes clipping & etc. MUCH, much easier...!
// NOTE: When the bitmap is in REFLECT mode, the XPOS marks the *right* side of the
// bitmap! This makes clipping & etc. MUCH, much easier...!
-// uint32 lbufAddress = 0x1800 + (!in24BPPMode ? leftMargin * 2 : leftMargin * 4);
-// uint32 lbufAddress = 0x1800 + (!in24BPPMode ? startPos * 2 : startPos * 4);
- uint32 lbufAddress = 0x1800 + startPos * 2;
- uint8 * currentLineBuffer = &tomRam8[lbufAddress];
-//uint8 * lineBufferLowerLimit = &tom_ram_8[0x1800],
+// uint32_t lbufAddress = 0x1800 + (!in24BPPMode ? leftMargin * 2 : leftMargin * 4);
+// uint32_t lbufAddress = 0x1800 + (!in24BPPMode ? startPos * 2 : startPos * 4);
+ uint32_t lbufAddress = 0x1800 + startPos * 2;
+ uint8_t * currentLineBuffer = &tomRam8[lbufAddress];
+//uint8_t * lineBufferLowerLimit = &tom_ram_8[0x1800],
if (firstPix != 0)
WriteLog("OP: Scaled bitmap @ 1 BPP requesting FIRSTPIX!\n");
// The LSB of flags is OPFLAG_REFLECT, so sign extend it and or 2 into it.
if (firstPix != 0)
WriteLog("OP: Scaled bitmap @ 1 BPP requesting FIRSTPIX!\n");
// The LSB of flags is OPFLAG_REFLECT, so sign extend it and or 2 into it.
if (!flagRMW)
// This is the *only* correct use of endian-dependent code
// (i.e., mem-to-mem direct copying)!
if (!flagRMW)
// This is the *only* correct use of endian-dependent code
// (i.e., mem-to-mem direct copying)!
/*
The reason we subtract the horizontalRemainder *after* the test is because we had too few
bytes for horizontalRemainder to properly recognize a negative number. But now it's 16 bits
/*
The reason we subtract the horizontalRemainder *after* the test is because we had too few
bytes for horizontalRemainder to properly recognize a negative number. But now it's 16 bits
*/
/* horizontalRemainder -= 0x20; // Subtract 1.0f in [3.5] fixed point format
while (horizontalRemainder & 0x80)
*/
/* horizontalRemainder -= 0x20; // Subtract 1.0f in [3.5] fixed point format
while (horizontalRemainder & 0x80)
int phrasesToSkip = pixCount / 64, pixelShift = pixCount % 64;
data += (pitch << 3) * phrasesToSkip;
int phrasesToSkip = pixCount / 64, pixelShift = pixCount % 64;
data += (pitch << 3) * phrasesToSkip;
WriteLog("OP: Scaled bitmap @ 2 BPP requesting FIRSTPIX!\n");
index &= 0xFC; // Top six bits form CLUT index
// The LSB is OPFLAG_REFLECT, so sign extend it and or 2 into it.
WriteLog("OP: Scaled bitmap @ 2 BPP requesting FIRSTPIX!\n");
index &= 0xFC; // Top six bits form CLUT index
// The LSB is OPFLAG_REFLECT, so sign extend it and or 2 into it.
if (!flagRMW)
// This is the *only* correct use of endian-dependent code
// (i.e., mem-to-mem direct copying)!
if (!flagRMW)
// This is the *only* correct use of endian-dependent code
// (i.e., mem-to-mem direct copying)!
int phrasesToSkip = pixCount / 32, pixelShift = pixCount % 32;
data += (pitch << 3) * phrasesToSkip;
int phrasesToSkip = pixCount / 32, pixelShift = pixCount % 32;
data += (pitch << 3) * phrasesToSkip;
WriteLog("OP: Scaled bitmap @ 4 BPP requesting FIRSTPIX!\n");
index &= 0xF0; // Top four bits form CLUT index
// The LSB is OPFLAG_REFLECT, so sign extend it and or 2 into it.
WriteLog("OP: Scaled bitmap @ 4 BPP requesting FIRSTPIX!\n");
index &= 0xF0; // Top four bits form CLUT index
// The LSB is OPFLAG_REFLECT, so sign extend it and or 2 into it.
if (!flagRMW)
// This is the *only* correct use of endian-dependent code
// (i.e., mem-to-mem direct copying)!
if (!flagRMW)
// This is the *only* correct use of endian-dependent code
// (i.e., mem-to-mem direct copying)!
int phrasesToSkip = pixCount / 16, pixelShift = pixCount % 16;
data += (pitch << 3) * phrasesToSkip;
int phrasesToSkip = pixCount / 16, pixelShift = pixCount % 16;
data += (pitch << 3) * phrasesToSkip;
if (firstPix)
WriteLog("OP: Scaled bitmap @ 8 BPP requesting FIRSTPIX! (fp=%u)\n", firstPix);
// The LSB is OPFLAG_REFLECT, so sign extend it and or 2 into it.
if (firstPix)
WriteLog("OP: Scaled bitmap @ 8 BPP requesting FIRSTPIX! (fp=%u)\n", firstPix);
// The LSB is OPFLAG_REFLECT, so sign extend it and or 2 into it.
if (!flagRMW)
// This is the *only* correct use of endian-dependent code
// (i.e., mem-to-mem direct copying)!
if (!flagRMW)
// This is the *only* correct use of endian-dependent code
// (i.e., mem-to-mem direct copying)!
int phrasesToSkip = pixCount / 8, pixelShift = pixCount % 8;
data += (pitch << 3) * phrasesToSkip;
int phrasesToSkip = pixCount / 8, pixelShift = pixCount % 8;
data += (pitch << 3) * phrasesToSkip;
if (firstPix != 0)
WriteLog("OP: Scaled bitmap @ 16 BPP requesting FIRSTPIX!\n");
// The LSB is OPFLAG_REFLECT, so sign extend it and OR 2 into it.
if (firstPix != 0)
WriteLog("OP: Scaled bitmap @ 16 BPP requesting FIRSTPIX!\n");
// The LSB is OPFLAG_REFLECT, so sign extend it and OR 2 into it.
//This doesn't seem right... Let's try the encoded black value ($8800):
//Apparently, CRY 0 maps to $8800...
//This doesn't seem right... Let's try the encoded black value ($8800):
//Apparently, CRY 0 maps to $8800...
int phrasesToSkip = pixCount / 4, pixelShift = pixCount % 4;
data += (pitch << 3) * phrasesToSkip;
int phrasesToSkip = pixCount / 4, pixelShift = pixCount % 4;
data += (pitch << 3) * phrasesToSkip;
WriteLog("OP: Scaled bitmap @ 24 BPP requesting FIRSTPIX!\n");
// Not sure, but I think RMW only works with 16 BPP and below, and only in CRY mode...
// The LSB is OPFLAG_REFLECT, so sign extend it and or 4 into it.
WriteLog("OP: Scaled bitmap @ 24 BPP requesting FIRSTPIX!\n");
// Not sure, but I think RMW only works with 16 BPP and below, and only in CRY mode...
// The LSB is OPFLAG_REFLECT, so sign extend it and or 4 into it.
bits1 = pixels >> 40, bits0 = pixels >> 32;
if (flagTRANS && (bits3 | bits2 | bits1 | bits0) == 0)
bits1 = pixels >> 40, bits0 = pixels >> 32;
if (flagTRANS && (bits3 | bits2 | bits1 | bits0) == 0)