+// int16 scanlineWidth = tom_getVideoModeWidth();
+ uint8 * tom_ram_8 = tom_get_ram_pointer();
+ uint8 * paletteRAM = &tom_ram_8[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!)
+ uint16 * paletteRAM16 = (uint16 *)paletteRAM;
+
+// 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...
+// 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)
+ return;
+
+//#define OP_DEBUG_BMP
+//#ifdef OP_DEBUG_BMP
+// WriteLog("bitmap %ix%i %ibpp at %i,%i firstpix=%i data=0x%.8x pitch %i hflipped=%s dwidth=%i (linked to 0x%.8x) Transluency=%s\n",
+// 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 +
+ (!flagREFLECT ? (phraseWidthToPixels[depth] * iwidth) - 1
+ : -((phraseWidthToPixels[depth] * iwidth) + 1));
+ uint32 clippedWidth = 0, phraseClippedWidth = 0, dataClippedWidth = 0;//, phrasePixel = 0;
+ bool in24BPPMode = (((GET16(tom_ram_8, 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...
+
+ // 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]
+//There are four possibilities:
+// 1. image sits on left edge and no REFLECT; starts out of bounds but ends in bounds.
+// 2. image sits on left edge and REFLECT; starts in bounds but ends out of bounds.
+// 3. image sits on right edge and REFLECT; starts out of bounds but ends in bounds.
+// 4. image sits on right edge and no REFLECT; starts in bounds but ends out of bounds.
+//Numbers 2 & 4 can be caught by checking the LBUF clip while in the inner loop,
+// numbers 1 & 3 are of concern.
+// This *indirectly* handles only cases 2 & 4! And is WRONG is REFLECT is set...!
+// if (rightMargin < 0 || leftMargin > lbufWidth)
+
+// It might be easier to swap these (if REFLECTed) and just use XPOS down below...
+// That way, you could simply set XPOS to leftMargin if !REFLECT and to rightMargin otherwise.
+// Still have to be careful with the DATA and IWIDTH values though...
+
+// if ((!flagREFLECT && (rightMargin < 0 || leftMargin > lbufWidth))
+// || (flagREFLECT && (leftMargin < 0 || rightMargin > lbufWidth)))
+// return;
+ if ((!flagREFLECT && (endPos < 0 || startPos > lbufWidth))
+ || (flagREFLECT && (startPos < 0 || endPos > lbufWidth)))
+ return;
+
+ // Otherwise, find the clip limits and clip the phrase as well...
+ // NOTE: I'm fudging here by letting the actual blit overstep the bounds of the
+ // line buffer, but it shouldn't matter since there are two unused line
+ // buffers below and nothing above and I'll at most write 8 bytes outside
+ // the line buffer... I could use a fractional clip begin/end value, but
+ // this makes the blit a *lot* more hairy. I might fix this in the future
+ // if it becomes necessary. (JLH)
+ // Probably wouldn't be *that* hairy. Just use a delta that tells the inner loop
+ // which pixel in the phrase is being written, and quit when either end of phrases
+ // is reached or line buffer extents are surpassed.
+
+//This stuff is probably wrong as well... !!! FIX !!!
+//The strange thing is that it seems to work, but that's no guarantee that it's bulletproof!
+//Yup. Seems that JagMania doesn't work correctly with this...
+//Dunno if this is the problem, but Atari Karts is showing *some* of the road now...
+// if (!flagREFLECT)
+
+/*
+ if (leftMargin < 0)
+ clippedWidth = 0 - leftMargin,
+ phraseClippedWidth = clippedWidth / phraseWidthToPixels[depth],
+ leftMargin = 0 - (clippedWidth % phraseWidthToPixels[depth]);
+// leftMargin = 0;
+
+ if (rightMargin > lbufWidth)
+ clippedWidth = rightMargin - lbufWidth,
+ phraseClippedWidth = clippedWidth / phraseWidthToPixels[depth];//,
+// rightMargin = lbufWidth + (clippedWidth % phraseWidthToPixels[depth]);
+// rightMargin = lbufWidth;
+*/
+if (depth > 5)
+ WriteLog("OP: We're about to encounter a divide by zero error!\n");
+ // NOTE: We're just using endPos to figure out how much, if any, to clip by.
+ // ALSO: There may be another case where we start out of bounds and end out of bounds...!
+ // !!! FIX !!!
+ if (startPos < 0) // Case #1: Begin out, end in, L to R
+ clippedWidth = 0 - startPos,
+ dataClippedWidth = phraseClippedWidth = clippedWidth / phraseWidthToPixels[depth],
+ startPos = 0 - (clippedWidth % phraseWidthToPixels[depth]);
+
+ if (endPos < 0) // Case #2: Begin in, end out, R to L
+ clippedWidth = 0 - endPos,
+ phraseClippedWidth = clippedWidth / phraseWidthToPixels[depth];
+
+ if (endPos > lbufWidth) // Case #3: Begin in, end out, L to R
+ clippedWidth = endPos - lbufWidth,
+ phraseClippedWidth = clippedWidth / phraseWidthToPixels[depth];
+
+ if (startPos > lbufWidth) // Case #4: Begin out, end in, R to L
+ clippedWidth = startPos - lbufWidth,
+ dataClippedWidth = phraseClippedWidth = clippedWidth / phraseWidthToPixels[depth],
+ startPos = lbufWidth + (clippedWidth % phraseWidthToPixels[depth]);
+
+ // If the image is sitting on the line buffer left or right edge, we need to compensate
+ // by decreasing the image phrase width accordingly.
+ iwidth -= phraseClippedWidth;
+
+ // Also, if we're clipping the phrase we need to make sure we're in the correct part of
+ // the pixel data.
+// data += phraseClippedWidth * (pitch << 3);
+ data += dataClippedWidth * pitch;
+
+ // 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);
+//Why does this work right when multiplying startPos by 2 (instead of 4) for 24 BPP mode?
+//Is this a bug in the OP?
+ uint32 lbufAddress = 0x1800 + (!in24BPPMode ? startPos * 2 : startPos * 2);
+ uint8 * currentLineBuffer = &tom_ram_8[lbufAddress];
+
+ // Render.
+
+// Hmm. We check above for 24 BPP mode, but don't do anything about it below...
+// If we *were* in 24 BPP mode, how would you convert CRY to RGB24? Seems to me
+// that if you're in CRY mode then you wouldn't be able to use 24 BPP bitmaps
+// anyway.
+// This seems to be the case (at least according to the Midsummer docs)...!
+
+ if (depth == 0) // 1 BPP