mirror of
https://github.com/elasota/Aerofoil.git
synced 2025-09-23 14:53:52 +00:00
Fix mirrors, poly draw (WIP), and game over screen. Temp disable high scores.
This commit is contained in:
@@ -1026,9 +1026,13 @@ OSErr PtrAndHand(const void *data, Handle handle, Size size)
|
||||
return noErr;
|
||||
}
|
||||
|
||||
void SetHandleSize(Handle hdl, Size newSize)
|
||||
OSErr SetHandleSize(Handle hdl, Size newSize)
|
||||
{
|
||||
PL_NotYetImplemented();
|
||||
PortabilityLayer::MemoryManager *mm = PortabilityLayer::MemoryManager::GetInstance();
|
||||
if (!mm->ResizeHandle(reinterpret_cast<PortabilityLayer::MMHandleBlock*>(hdl), newSize))
|
||||
return genericErr;
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
||||
void *NewPtr(Size size)
|
||||
|
@@ -370,7 +370,7 @@ void DisposeHandle(Handle handle);
|
||||
long GetHandleSize(Handle handle);
|
||||
|
||||
OSErr PtrAndHand(const void *data, Handle handle, Size size); // Appends data to the end of a handle
|
||||
void SetHandleSize(Handle hdl, Size newSize);
|
||||
OSErr SetHandleSize(Handle hdl, Size newSize);
|
||||
|
||||
void *NewPtr(Size size);
|
||||
void *NewPtrClear(Size size);
|
||||
|
@@ -1,11 +1,19 @@
|
||||
#include "PLHacks.h"
|
||||
|
||||
// Trademark issue
|
||||
bool IsMacPlusGraphicBanned()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Trademark issue
|
||||
bool IsMacPlusSoundBanned()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// High scores disabled until dialogs work
|
||||
bool IsHighScoreDisabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@@ -2,3 +2,4 @@
|
||||
|
||||
bool IsMacPlusGraphicBanned();
|
||||
bool IsMacPlusSoundBanned();
|
||||
bool IsHighScoreDisabled();
|
||||
|
@@ -15,6 +15,8 @@
|
||||
#include "ResourceManager.h"
|
||||
#include "ResTypeID.h"
|
||||
#include "RGBAColor.h"
|
||||
#include "ScanlineMask.h"
|
||||
#include "ScanlineMaskIterator.h"
|
||||
#include "QDStandardPalette.h"
|
||||
#include "WindowManager.h"
|
||||
#include "QDGraf.h"
|
||||
@@ -215,33 +217,33 @@ static void PlotLine(PortabilityLayer::QDState *qdState, PortabilityLayer::QDPor
|
||||
default:
|
||||
case PortabilityLayer::PlotDirection_Exhausted:
|
||||
return;
|
||||
|
||||
|
||||
case PortabilityLayer::PlotDirection_NegX_NegY:
|
||||
case PortabilityLayer::PlotDirection_0X_NegY:
|
||||
case PortabilityLayer::PlotDirection_PosX_NegY:
|
||||
// These should never happen, the point order is swapped so that Y is always 0 or positive
|
||||
assert(false);
|
||||
return;
|
||||
|
||||
|
||||
case PortabilityLayer::PlotDirection_NegX_PosY:
|
||||
currentPoint.m_x--;
|
||||
currentPoint.m_y++;
|
||||
plotIndex = plotIndex + pitch - pixelSize;
|
||||
break;
|
||||
break;
|
||||
case PortabilityLayer::PlotDirection_0X_PosY:
|
||||
currentPoint.m_y++;
|
||||
plotIndex = plotIndex + pitch;
|
||||
break;
|
||||
break;
|
||||
case PortabilityLayer::PlotDirection_PosX_PosY:
|
||||
currentPoint.m_x++;
|
||||
currentPoint.m_y++;
|
||||
plotIndex = plotIndex + pitch + pixelSize;
|
||||
break;
|
||||
|
||||
|
||||
case PortabilityLayer::PlotDirection_NegX_0Y:
|
||||
currentPoint.m_x--;
|
||||
plotIndex = plotIndex - pixelSize;
|
||||
break;
|
||||
break;
|
||||
case PortabilityLayer::PlotDirection_PosX_0Y:
|
||||
currentPoint.m_x++;
|
||||
plotIndex = plotIndex + pixelSize;
|
||||
@@ -572,9 +574,155 @@ void PaintOval(const Rect *rect)
|
||||
PL_NotYetImplemented_TODO("Ovals");
|
||||
}
|
||||
|
||||
void PaintRgn(RgnHandle region)
|
||||
void FillScanlineSpan(uint8_t *rowStart, size_t startCol, size_t endCol)
|
||||
{
|
||||
PL_NotYetImplemented_TODO("Polys");
|
||||
for (size_t col = startCol; col < endCol; col++)
|
||||
rowStart[col] = 255;
|
||||
}
|
||||
|
||||
void FillScanlineMask(const PortabilityLayer::ScanlineMask *scanlineMask)
|
||||
{
|
||||
if (!scanlineMask)
|
||||
return;
|
||||
|
||||
PortabilityLayer::QDManager *qdManager = PortabilityLayer::QDManager::GetInstance();
|
||||
PortabilityLayer::QDState *qdState = qdManager->GetState();
|
||||
|
||||
const PortabilityLayer::QDPort *port = qdManager->GetPort();
|
||||
PixMap *pixMap = *port->GetPixMap();
|
||||
const Rect portRect = port->GetRect();
|
||||
const Rect maskRect = scanlineMask->GetRect();
|
||||
|
||||
const Rect constrainedRect = portRect.Intersect(maskRect);
|
||||
if (!constrainedRect.IsValid())
|
||||
return;
|
||||
|
||||
const size_t firstMaskRow = static_cast<size_t>(constrainedRect.top - maskRect.top);
|
||||
const size_t firstMaskCol = static_cast<size_t>(constrainedRect.left - maskRect.left);
|
||||
const size_t firstPortRow = static_cast<size_t>(constrainedRect.top - portRect.top);
|
||||
const size_t firstPortCol = static_cast<size_t>(constrainedRect.left - portRect.left);
|
||||
const size_t pitch = pixMap->m_pitch;
|
||||
const size_t maskSpanWidth = scanlineMask->GetRect().right - scanlineMask->GetRect().left;
|
||||
|
||||
// Skip mask rows
|
||||
PortabilityLayer::ScanlineMaskIterator iter = scanlineMask->GetIterator();
|
||||
for (size_t i = 0; i < firstMaskRow; i++)
|
||||
{
|
||||
size_t spanRemaining = maskSpanWidth;
|
||||
while (spanRemaining > 0)
|
||||
spanRemaining -= iter.Next();
|
||||
}
|
||||
|
||||
uint8_t color8 = 0;
|
||||
|
||||
const GpPixelFormat_t pixelFormat = pixMap->m_pixelFormat;
|
||||
|
||||
size_t pixelSize = 0;
|
||||
switch (pixMap->m_pixelFormat)
|
||||
{
|
||||
case GpPixelFormats::k8BitStandard:
|
||||
color8 = qdState->ResolveForeColor8(nullptr, 256);
|
||||
break;
|
||||
default:
|
||||
PL_NotYetImplemented();
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t pattern8x8[8] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||
bool havePattern = false;
|
||||
if (const uint8_t *statePattern = qdState->GetPattern8x8())
|
||||
{
|
||||
memcpy(pattern8x8, statePattern, 8);
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if (pattern8x8[i] != 0xff)
|
||||
{
|
||||
havePattern = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const size_t constrainedRectWidth = static_cast<size_t>(constrainedRect.right - constrainedRect.left);
|
||||
|
||||
uint8_t *pixMapData = static_cast<uint8_t*>(pixMap->m_data);
|
||||
uint8_t *firstRowStart = pixMapData + (constrainedRect.top * pitch);
|
||||
const size_t numRows = static_cast<size_t>(constrainedRect.bottom - constrainedRect.top);
|
||||
for (size_t row = 0; row < numRows; row++)
|
||||
{
|
||||
uint8_t *thisRowStart = firstRowStart + row * pitch;
|
||||
|
||||
bool spanState = false;
|
||||
|
||||
size_t currentSpan = iter.Next();
|
||||
{
|
||||
// Skip prefix cols. If the span ends at the first col, this must not advance the iterator to it (currentSpan should be 0 instead)
|
||||
size_t prefixColsRemaining = firstMaskCol;
|
||||
|
||||
while (prefixColsRemaining > 0)
|
||||
{
|
||||
if (prefixColsRemaining <= currentSpan)
|
||||
{
|
||||
currentSpan -= prefixColsRemaining;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
prefixColsRemaining -= currentSpan;
|
||||
currentSpan = iter.Next();
|
||||
spanState = !spanState;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Paint in-bound cols. If the span ends at the end of the mask, this must not advance the iterator beyond it (currentSpan should be 0 instead)
|
||||
size_t paintColsRemaining = constrainedRectWidth;
|
||||
size_t spanStartCol = firstPortCol;
|
||||
|
||||
while (paintColsRemaining > 0)
|
||||
{
|
||||
if (paintColsRemaining <= currentSpan)
|
||||
{
|
||||
currentSpan -= paintColsRemaining;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
const size_t spanEndCol = spanStartCol + currentSpan;
|
||||
if (spanState)
|
||||
FillScanlineSpan(thisRowStart, spanStartCol, spanEndCol);
|
||||
|
||||
spanStartCol = spanEndCol;
|
||||
paintColsRemaining -= currentSpan;
|
||||
currentSpan = iter.Next();
|
||||
spanState = !spanState;
|
||||
}
|
||||
}
|
||||
|
||||
// Flush any lingering span
|
||||
if (spanState)
|
||||
{
|
||||
const size_t spanEndCol = firstPortCol + constrainedRectWidth;
|
||||
FillScanlineSpan(thisRowStart, spanStartCol, spanEndCol);
|
||||
}
|
||||
|
||||
if (row != numRows - 1)
|
||||
{
|
||||
size_t terminalColsRemaining = maskSpanWidth - constrainedRectWidth - firstMaskCol;
|
||||
|
||||
assert(currentSpan <= terminalColsRemaining);
|
||||
|
||||
terminalColsRemaining -= currentSpan;
|
||||
|
||||
while (terminalColsRemaining > 0)
|
||||
{
|
||||
currentSpan = iter.Next();
|
||||
|
||||
assert(currentSpan <= terminalColsRemaining);
|
||||
terminalColsRemaining -= currentSpan;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ClipRect(const Rect *rect)
|
||||
@@ -703,7 +851,7 @@ void GetIndPattern(Pattern *pattern, int patListID, int index)
|
||||
memcpy(pattern, patternRes + 2 + (index - 1) * 8, 8);
|
||||
}
|
||||
|
||||
static void CopyBitsComplete(const BitMap *srcBitmap, const BitMap *maskBitmap, BitMap *destBitmap, const Rect *srcRectBase, const Rect *maskRectBase, const Rect *destRectBase, RgnHandle maskRegion)
|
||||
static void CopyBitsComplete(const BitMap *srcBitmap, const BitMap *maskBitmap, BitMap *destBitmap, const Rect *srcRectBase, const Rect *maskRectBase, const Rect *destRectBase, const Rect *maskConstraintRect)
|
||||
{
|
||||
assert(srcBitmap->m_pixelFormat == destBitmap->m_pixelFormat);
|
||||
|
||||
@@ -736,7 +884,10 @@ static void CopyBitsComplete(const BitMap *srcBitmap, const BitMap *maskBitmap,
|
||||
|
||||
{
|
||||
const Rect constrainedSrcRect = srcRectBase->Intersect(srcBounds);
|
||||
const Rect constrainedDestRect = destRectBase->Intersect(destBounds);
|
||||
Rect constrainedDestRect = destRectBase->Intersect(destBounds);
|
||||
|
||||
if (maskConstraintRect)
|
||||
constrainedDestRect = constrainedDestRect.Intersect(*maskConstraintRect);
|
||||
|
||||
const int32_t leftNudge = std::max(constrainedSrcRect.left - srcRectBase->left, constrainedDestRect.left - destRectBase->left);
|
||||
const int32_t topNudge = std::max(constrainedSrcRect.top - srcRectBase->top, constrainedDestRect.top - destRectBase->top);
|
||||
@@ -792,44 +943,30 @@ static void CopyBitsComplete(const BitMap *srcBitmap, const BitMap *maskBitmap,
|
||||
assert(destRect.left >= destBounds.left);
|
||||
assert(destRect.right <= destBounds.right);
|
||||
|
||||
const Region *mask = nullptr;
|
||||
|
||||
if (maskRegion)
|
||||
mask = *maskRegion;
|
||||
|
||||
const Rect constrainedDestRect = mask ? destRect.Intersect(mask->rect) : destRect;
|
||||
if (!constrainedDestRect.IsValid())
|
||||
return;
|
||||
|
||||
Rect constrainedSrcRect = srcRect;
|
||||
constrainedSrcRect.left += constrainedDestRect.left - destRect.left;
|
||||
constrainedSrcRect.right += constrainedDestRect.right - destRect.right;
|
||||
constrainedSrcRect.top += constrainedDestRect.top - destRect.top;
|
||||
constrainedSrcRect.bottom += constrainedDestRect.bottom - destRect.bottom;
|
||||
constrainedSrcRect.left += destRect.left - destRect.left;
|
||||
constrainedSrcRect.right += destRect.right - destRect.right;
|
||||
constrainedSrcRect.top += destRect.top - destRect.top;
|
||||
constrainedSrcRect.bottom += destRect.bottom - destRect.bottom;
|
||||
|
||||
Rect constrainedMaskRect = maskRect;
|
||||
if (maskRectBase != nullptr)
|
||||
{
|
||||
constrainedMaskRect.left += constrainedDestRect.left - destRect.left;
|
||||
constrainedMaskRect.right += constrainedDestRect.right - destRect.right;
|
||||
constrainedMaskRect.top += constrainedDestRect.top - destRect.top;
|
||||
constrainedMaskRect.bottom += constrainedDestRect.bottom - destRect.bottom;
|
||||
constrainedMaskRect.left += destRect.left - destRect.left;
|
||||
constrainedMaskRect.right += destRect.right - destRect.right;
|
||||
constrainedMaskRect.top += destRect.top - destRect.top;
|
||||
constrainedMaskRect.bottom += destRect.bottom - destRect.bottom;
|
||||
}
|
||||
|
||||
const size_t srcFirstCol = constrainedSrcRect.left - srcBitmap->m_rect.left;
|
||||
const size_t srcFirstRow = constrainedSrcRect.top - srcBitmap->m_rect.top;
|
||||
|
||||
const size_t destFirstCol = constrainedDestRect.left - destBitmap->m_rect.left;
|
||||
const size_t destFirstRow = constrainedDestRect.top - destBitmap->m_rect.top;
|
||||
const size_t destFirstCol = destRect.left - destBitmap->m_rect.left;
|
||||
const size_t destFirstRow = destRect.top - destBitmap->m_rect.top;
|
||||
|
||||
const size_t maskFirstCol = maskBitmap ? constrainedMaskRect.left - maskBitmap->m_rect.left : 0;
|
||||
const size_t maskFirstRow = maskBitmap ? constrainedMaskRect.top - maskBitmap->m_rect.top : 0;
|
||||
|
||||
if (mask && mask->size != sizeof(Region))
|
||||
{
|
||||
PL_NotYetImplemented();
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t pixelSizeBytes = 0;
|
||||
|
||||
@@ -900,7 +1037,12 @@ static void CopyBitsComplete(const BitMap *srcBitmap, const BitMap *maskBitmap,
|
||||
}
|
||||
}
|
||||
|
||||
void CopyBits(const BitMap *srcBitmap, BitMap *destBitmap, const Rect *srcRectBase, const Rect *destRectBase, CopyBitsMode copyMode, RgnHandle maskRegion)
|
||||
void CopyBits(const BitMap *srcBitmap, BitMap *destBitmap, const Rect *srcRectBase, const Rect *destRectBase, CopyBitsMode copyMode)
|
||||
{
|
||||
CopyBitsConstrained(srcBitmap, destBitmap, srcRectBase, destRectBase, copyMode, nullptr);
|
||||
}
|
||||
|
||||
void CopyBitsConstrained(const BitMap *srcBitmap, BitMap *destBitmap, const Rect *srcRectBase, const Rect *destRectBase, CopyBitsMode copyMode, const Rect *constrainRect)
|
||||
{
|
||||
const BitMap *maskBitmap = nullptr;
|
||||
const Rect *maskRect = nullptr;
|
||||
@@ -910,7 +1052,12 @@ void CopyBits(const BitMap *srcBitmap, BitMap *destBitmap, const Rect *srcRectBa
|
||||
maskRect = srcRectBase;
|
||||
}
|
||||
|
||||
CopyBitsComplete(srcBitmap, maskBitmap, destBitmap, srcRectBase, maskRect, destRectBase, maskRegion);
|
||||
CopyBitsComplete(srcBitmap, maskBitmap, destBitmap, srcRectBase, maskRect, destRectBase, constrainRect);
|
||||
}
|
||||
|
||||
void CopyMaskConstrained(const BitMap *srcBitmap, const BitMap *maskBitmap, BitMap *destBitmap, const Rect *srcRectBase, const Rect *maskRectBase, const Rect *destRectBase, const Rect *constrainRect)
|
||||
{
|
||||
CopyBitsComplete(srcBitmap, maskBitmap, destBitmap, srcRectBase, maskRectBase, destRectBase, constrainRect);
|
||||
}
|
||||
|
||||
void CopyMask(const BitMap *srcBitmap, const BitMap *maskBitmap, BitMap *destBitmap, const Rect *srcRectBase, const Rect *maskRectBase, const Rect *destRectBase)
|
||||
|
@@ -6,6 +6,11 @@
|
||||
#include "QDGraf.h"
|
||||
#include "SharedTypes.h"
|
||||
|
||||
namespace PortabilityLayer
|
||||
{
|
||||
class ScanlineMask;
|
||||
}
|
||||
|
||||
struct Dialog;
|
||||
|
||||
enum IconAlignmentType
|
||||
@@ -49,7 +54,6 @@ enum SystemColorID
|
||||
enum CopyBitsMode
|
||||
{
|
||||
srcCopy,
|
||||
srcOr,
|
||||
srcXor,
|
||||
transparent,
|
||||
};
|
||||
@@ -122,7 +126,7 @@ void RGBForeColor(const RGBColor *color);
|
||||
void DrawString(const PLPasStr &str);
|
||||
void PaintRect(const Rect *rect);
|
||||
void PaintOval(const Rect *rect);
|
||||
void PaintRgn(RgnHandle region);
|
||||
void FillScanlineMask(const PortabilityLayer::ScanlineMask *scanlineMask);
|
||||
|
||||
void ClipRect(const Rect *rect); // Sets the clipping area
|
||||
void FrameRect(const Rect *rect);
|
||||
@@ -146,8 +150,10 @@ void GetIndPattern(Pattern *pattern, int patListID, int index);
|
||||
|
||||
void DebugPixMap(PixMap **pixMap, const char *outName);
|
||||
|
||||
void CopyBits(const BitMap *srcBitmap, BitMap *destBitmap, const Rect *srcRect, const Rect *destRect, CopyBitsMode copyMode, RgnHandle maskRegion);
|
||||
void CopyBits(const BitMap *srcBitmap, BitMap *destBitmap, const Rect *srcRect, const Rect *destRect, CopyBitsMode copyMode);
|
||||
void CopyBitsConstrained(const BitMap *srcBitmap, BitMap *destBitmap, const Rect *srcRect, const Rect *destRect, CopyBitsMode copyMode, const Rect *constraintRect);
|
||||
void CopyMask(const BitMap *srcBitmap, const BitMap *maskBitmap, BitMap *destBitmap, const Rect *srcRect, const Rect *maskRect, const Rect *destRect);
|
||||
void CopyMaskConstrained(const BitMap *srcBitmap, const BitMap *maskBitmap, BitMap *destBitmap, const Rect *srcRectBase, const Rect *maskRectBase, const Rect *destRectBase, const Rect *constraintRect);
|
||||
|
||||
RgnHandle NewRgn();
|
||||
void RectRgn(RgnHandle region, const Rect *rect);
|
||||
|
@@ -238,6 +238,8 @@
|
||||
<ClInclude Include="ResTypeID.h" />
|
||||
<ClInclude Include="ResTypeIDCodec.h" />
|
||||
<ClInclude Include="RGBAColor.h" />
|
||||
<ClInclude Include="ScanlineMaskDataStorage.h" />
|
||||
<ClInclude Include="ScanlineMaskIterator.h" />
|
||||
<ClInclude Include="SharedTypes.h" />
|
||||
<ClInclude Include="SimpleGraphic.h" />
|
||||
<ClInclude Include="Vec2i.h" />
|
||||
@@ -315,6 +317,7 @@
|
||||
<ClCompile Include="RandomNumberGenerator.cpp" />
|
||||
<ClCompile Include="ResourceCompiledRef.cpp" />
|
||||
<ClCompile Include="ResourceFile.cpp" />
|
||||
<ClCompile Include="ScanlineMaskIterator.cpp" />
|
||||
<ClCompile Include="SimpleGraphic.cpp" />
|
||||
<ClCompile Include="WindowDef.cpp" />
|
||||
<ClCompile Include="WindowManager.cpp" />
|
||||
|
@@ -387,6 +387,12 @@
|
||||
<ClInclude Include="PLHacks.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ScanlineMaskIterator.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ScanlineMaskDataStorage.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="CFileStream.cpp">
|
||||
@@ -587,5 +593,8 @@
|
||||
<ClCompile Include="PLHacks.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ScanlineMaskIterator.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
@@ -20,11 +20,14 @@ namespace PortabilityLayer
|
||||
, m_clipRegion(nullptr)
|
||||
, m_penInvert(false)
|
||||
, m_penMask(false)
|
||||
, m_havePattern8x8(false)
|
||||
{
|
||||
m_backUnresolvedColor.r = m_backUnresolvedColor.g = m_backUnresolvedColor.b = m_backUnresolvedColor.a = 255;
|
||||
m_foreUnresolvedColor.r = m_foreUnresolvedColor.g = m_foreUnresolvedColor.b = 0;
|
||||
m_foreUnresolvedColor.a = 255;
|
||||
m_penPos.h = m_penPos.v = 0;
|
||||
|
||||
memset(m_pattern8x8, 0, sizeof(m_pattern8x8));
|
||||
}
|
||||
|
||||
void QDState::SetForeColor(const RGBAColor &color)
|
||||
@@ -81,4 +84,39 @@ namespace PortabilityLayer
|
||||
return resolvedColor;
|
||||
}
|
||||
}
|
||||
|
||||
void QDState::SetPenPattern8x8(const uint8_t *pattern)
|
||||
{
|
||||
if (!pattern)
|
||||
{
|
||||
m_havePattern8x8 = false;
|
||||
return;
|
||||
}
|
||||
|
||||
bool isSolid = true;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if (pattern[i] != 0xff)
|
||||
{
|
||||
isSolid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isSolid)
|
||||
m_havePattern8x8 = false;
|
||||
else
|
||||
{
|
||||
m_havePattern8x8 = true;
|
||||
memcpy(m_pattern8x8, pattern, sizeof(m_pattern8x8));
|
||||
}
|
||||
}
|
||||
|
||||
const uint8_t *QDState::GetPattern8x8() const
|
||||
{
|
||||
if (m_havePattern8x8)
|
||||
return m_pattern8x8;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
@@ -28,6 +28,9 @@ namespace PortabilityLayer
|
||||
uint8_t ResolveForeColor8(const RGBAColor *palette, unsigned int numColors);
|
||||
uint8_t ResolveBackColor8(const RGBAColor *palette, unsigned int numColors);
|
||||
|
||||
void SetPenPattern8x8(const uint8_t *pattern);
|
||||
const uint8_t *GetPattern8x8() const;
|
||||
|
||||
private:
|
||||
static uint8_t ResolveColor8(const RGBAColor &color, uint8_t &cached, bool &isCached, const RGBAColor *palette, unsigned int numColors);
|
||||
|
||||
@@ -39,6 +42,9 @@ namespace PortabilityLayer
|
||||
uint8_t m_foreResolvedColor8;
|
||||
uint8_t m_backResolvedColor8;
|
||||
|
||||
uint8_t m_pattern8x8[8];
|
||||
bool m_havePattern8x8;
|
||||
|
||||
bool m_isForeResolved16;
|
||||
bool m_isForeResolved8;
|
||||
bool m_isBackResolved16;
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#include "CoreDefs.h"
|
||||
#include "ScanlineMask.h"
|
||||
#include "ScanlineMaskBuilder.h"
|
||||
#include "ScanlineMaskIterator.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <new>
|
||||
@@ -13,7 +14,17 @@ namespace PortabilityLayer
|
||||
free(this);
|
||||
}
|
||||
|
||||
ScanlineMask *ScanlineMask::Create(const ScanlineMaskBuilder &builder)
|
||||
const Rect &ScanlineMask::GetRect() const
|
||||
{
|
||||
return m_rect;
|
||||
}
|
||||
|
||||
ScanlineMaskIterator ScanlineMask::GetIterator() const
|
||||
{
|
||||
return ScanlineMaskIterator(m_data, m_dataStorage);
|
||||
}
|
||||
|
||||
ScanlineMask *ScanlineMask::Create(const Rect &rect, const ScanlineMaskBuilder &builder)
|
||||
{
|
||||
size_t alignedPrefixSize = sizeof(ScanlineMask) + PL_SYSTEM_MEMORY_ALIGNMENT - 1;
|
||||
alignedPrefixSize -= alignedPrefixSize % PL_SYSTEM_MEMORY_ALIGNMENT;
|
||||
@@ -23,18 +34,18 @@ namespace PortabilityLayer
|
||||
const size_t *spans = builder.GetSpans();
|
||||
|
||||
size_t storageSize = numSpans;
|
||||
DataStorage dataStorage = DataStorage_UInt8;
|
||||
ScanlineMaskDataStorage dataStorage = ScanlineMaskDataStorage_UInt8;
|
||||
if (longestSpan <= 0xff)
|
||||
dataStorage = DataStorage_UInt8;
|
||||
dataStorage = ScanlineMaskDataStorage_UInt8;
|
||||
else if (longestSpan <= 0xffff)
|
||||
{
|
||||
storageSize *= 2;
|
||||
dataStorage = DataStorage_UInt16;
|
||||
dataStorage = ScanlineMaskDataStorage_UInt16;
|
||||
}
|
||||
else if (longestSpan <= 0xffffffff)
|
||||
{
|
||||
storageSize *= 4;
|
||||
dataStorage = DataStorage_UInt32;
|
||||
dataStorage = ScanlineMaskDataStorage_UInt32;
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
@@ -45,19 +56,19 @@ namespace PortabilityLayer
|
||||
|
||||
void *spanStorage = static_cast<uint8_t*>(storage) + alignedPrefixSize;
|
||||
|
||||
ScanlineMask *mask = new (storage) ScanlineMask(dataStorage, spanStorage, numSpans);
|
||||
ScanlineMask *mask = new (storage) ScanlineMask(rect, dataStorage, spanStorage, numSpans);
|
||||
|
||||
for (size_t i = 0; i < numSpans; i++)
|
||||
{
|
||||
switch (dataStorage)
|
||||
{
|
||||
case DataStorage_UInt8:
|
||||
case ScanlineMaskDataStorage_UInt8:
|
||||
static_cast<uint8_t*>(spanStorage)[i] = static_cast<uint8_t>(spans[i]);
|
||||
break;
|
||||
case DataStorage_UInt16:
|
||||
case ScanlineMaskDataStorage_UInt16:
|
||||
static_cast<uint16_t*>(spanStorage)[i] = static_cast<uint16_t>(spans[i]);
|
||||
break;
|
||||
case DataStorage_UInt32:
|
||||
case ScanlineMaskDataStorage_UInt32:
|
||||
static_cast<uint32_t*>(spanStorage)[i] = static_cast<uint32_t>(spans[i]);
|
||||
break;
|
||||
}
|
||||
@@ -66,10 +77,11 @@ namespace PortabilityLayer
|
||||
return mask;
|
||||
}
|
||||
|
||||
ScanlineMask::ScanlineMask(DataStorage dataStorage, const void *data, size_t numSpans)
|
||||
ScanlineMask::ScanlineMask(const Rect &rect, ScanlineMaskDataStorage dataStorage, const void *data, size_t numSpans)
|
||||
: m_dataStorage(dataStorage)
|
||||
, m_data(data)
|
||||
, m_numSpans(numSpans)
|
||||
, m_rect(rect)
|
||||
{
|
||||
}
|
||||
|
||||
|
@@ -1,31 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "SharedTypes.h"
|
||||
#include "ScanlineMaskDataStorage.h"
|
||||
|
||||
namespace PortabilityLayer
|
||||
{
|
||||
class ScanlineMaskBuilder;
|
||||
|
||||
class ScanlineMaskIterator;
|
||||
|
||||
class ScanlineMask
|
||||
{
|
||||
public:
|
||||
void Destroy();
|
||||
const Rect &GetRect() const;
|
||||
ScanlineMaskIterator GetIterator() const;
|
||||
|
||||
static ScanlineMask *Create(const ScanlineMaskBuilder &builder);
|
||||
static ScanlineMask *Create(const Rect &rect, const ScanlineMaskBuilder &builder);
|
||||
|
||||
private:
|
||||
enum DataStorage
|
||||
{
|
||||
DataStorage_UInt8,
|
||||
DataStorage_UInt16,
|
||||
DataStorage_UInt32,
|
||||
};
|
||||
|
||||
explicit ScanlineMask(DataStorage dataStorage, const void *data, size_t numSpans);
|
||||
explicit ScanlineMask(const Rect &rect, ScanlineMaskDataStorage dataStorage, const void *data, size_t numSpans);
|
||||
~ScanlineMask();
|
||||
|
||||
const DataStorage m_dataStorage;
|
||||
const ScanlineMaskDataStorage m_dataStorage;
|
||||
const void *m_data;
|
||||
const size_t m_numSpans;
|
||||
const Rect m_rect;
|
||||
};
|
||||
}
|
||||
|
@@ -8,7 +8,7 @@
|
||||
#include <assert.h>
|
||||
#include <algorithm>
|
||||
|
||||
#define PL_SCANLINE_MASKS_DEBUGGING 1
|
||||
#define PL_SCANLINE_MASKS_DEBUGGING 0
|
||||
|
||||
#if PL_SCANLINE_MASKS_DEBUGGING
|
||||
#include "stb_image_write.h"
|
||||
@@ -240,9 +240,16 @@ namespace PortabilityLayer
|
||||
}
|
||||
}
|
||||
|
||||
#if PL_SCANLINE_MASKS_DEBUGGING
|
||||
static int debugID = 0;
|
||||
char path[256];
|
||||
sprintf_s(path, "DebugData/ScanlineMask%i.png", debugID++);
|
||||
stbi_write_png(path, width, height, 4, flagBits, width * 4);
|
||||
#endif
|
||||
|
||||
free(storage);
|
||||
|
||||
return ScanlineMask::Create(maskBuilder);
|
||||
return ScanlineMask::Create(Rect::Create(minPoint.m_y, minPoint.m_x, minPoint.m_y + static_cast<int16_t>(height), minPoint.m_x + static_cast<int16_t>(width)), maskBuilder);
|
||||
}
|
||||
|
||||
class PolyPlotter final : public IPlotter
|
||||
|
11
PortabilityLayer/ScanlineMaskDataStorage.h
Normal file
11
PortabilityLayer/ScanlineMaskDataStorage.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
namespace PortabilityLayer
|
||||
{
|
||||
enum ScanlineMaskDataStorage
|
||||
{
|
||||
ScanlineMaskDataStorage_UInt8,
|
||||
ScanlineMaskDataStorage_UInt16,
|
||||
ScanlineMaskDataStorage_UInt32,
|
||||
};
|
||||
}
|
40
PortabilityLayer/ScanlineMaskIterator.cpp
Normal file
40
PortabilityLayer/ScanlineMaskIterator.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
#include "ScanlineMaskIterator.h"
|
||||
|
||||
namespace PortabilityLayer
|
||||
{
|
||||
ScanlineMaskIterator::ScanlineMaskIterator(const void *data, ScanlineMaskDataStorage dataStorage)
|
||||
: m_loc(data)
|
||||
, m_storage(dataStorage)
|
||||
{
|
||||
}
|
||||
|
||||
size_t ScanlineMaskIterator::Next()
|
||||
{
|
||||
switch (m_storage)
|
||||
{
|
||||
case ScanlineMaskDataStorage_UInt8:
|
||||
{
|
||||
const uint8_t *loc = static_cast<const uint8_t*>(m_loc);
|
||||
uint8_t value = *loc;
|
||||
m_loc = loc + 1;
|
||||
return value;
|
||||
}
|
||||
case ScanlineMaskDataStorage_UInt16:
|
||||
{
|
||||
const uint16_t *loc = static_cast<const uint16_t*>(m_loc);
|
||||
uint16_t value = *loc;
|
||||
m_loc = loc + 1;
|
||||
return value;
|
||||
}
|
||||
case ScanlineMaskDataStorage_UInt32:
|
||||
{
|
||||
const uint32_t *loc = static_cast<const uint32_t*>(m_loc);
|
||||
uint32_t value = *loc;
|
||||
m_loc = loc + 1;
|
||||
return value;
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
19
PortabilityLayer/ScanlineMaskIterator.h
Normal file
19
PortabilityLayer/ScanlineMaskIterator.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ScanlineMaskDataStorage.h"
|
||||
|
||||
namespace PortabilityLayer
|
||||
{
|
||||
class ScanlineMaskIterator
|
||||
{
|
||||
public:
|
||||
ScanlineMaskIterator(const void *data, ScanlineMaskDataStorage dataStorage);
|
||||
size_t Next();
|
||||
|
||||
private:
|
||||
const void *m_loc;
|
||||
const ScanlineMaskDataStorage m_storage;
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user