Fix mirrors, poly draw (WIP), and game over screen. Temp disable high scores.

This commit is contained in:
elasota
2019-12-28 19:50:29 -05:00
parent d9e61cffac
commit 08fac98637
42 changed files with 666 additions and 333 deletions

View File

@@ -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)

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -2,3 +2,4 @@
bool IsMacPlusGraphicBanned();
bool IsMacPlusSoundBanned();
bool IsHighScoreDisabled();

View File

@@ -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)

View File

@@ -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);

View File

@@ -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" />

View File

@@ -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>

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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)
{
}

View File

@@ -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;
};
}

View File

@@ -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

View File

@@ -0,0 +1,11 @@
#pragma once
namespace PortabilityLayer
{
enum ScanlineMaskDataStorage
{
ScanlineMaskDataStorage_UInt8,
ScanlineMaskDataStorage_UInt16,
ScanlineMaskDataStorage_UInt32,
};
}

View 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;
}
}
}

View 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;
};
}