Scaled blit, plus fix some level editor things

This commit is contained in:
elasota
2020-01-02 01:32:00 -05:00
parent 1c6ab800a7
commit 1da2851d3a
42 changed files with 571 additions and 273 deletions

View File

@@ -7,6 +7,7 @@
#include "PLButtonWidget.h"
#include "PLDialogs.h"
#include "PLIconWidget.h"
#include "PLImageWidget.h"
#include "PLInvisibleWidget.h"
#include "PLLabelWidget.h"
#include "PLPasStr.h"
@@ -276,10 +277,12 @@ namespace PortabilityLayer
case SerializedDialogItemTypeCodes::kIcon:
widget = IconWidget::Create(basicState);
break;
case SerializedDialogItemTypeCodes::kImage:
widget = ImageWidget::Create(basicState);
break;
case SerializedDialogItemTypeCodes::kCheckBox:
case SerializedDialogItemTypeCodes::kRadioButton:
case SerializedDialogItemTypeCodes::kEditBox:
case SerializedDialogItemTypeCodes::kImage:
default:
widget = InvisibleWidget::Create(basicState);
break;
@@ -443,7 +446,7 @@ namespace PortabilityLayer
//window->m_wmY = displayHeight / 3 - dialogHeight / 2;
window->m_wmY = (static_cast<int32_t>(displayHeight * 2) - static_cast<int32_t>(dialogHeight * 3)) / 6;
}
else if (dialogHeight * 2 <= displayHeight)
else if (dialogHeight * 2U <= displayHeight)
window->m_wmY = displayHeight / 4;
else
window->m_wmY = (static_cast<int32_t>(displayHeight) - static_cast<int32_t>(dialogHeight)) / 2;

View File

@@ -19,6 +19,7 @@ namespace PortabilityLayer
{
public:
bool FileExists(VirtualDirectory_t dirID, const PLPasStr &filename) override;
bool FileLocked(VirtualDirectory_t dirID, const PLPasStr &filename) override;
bool DeleteFile(VirtualDirectory_t dirID, const PLPasStr &filename) override;
PLError_t CreateFile(VirtualDirectory_t dirID, const PLPasStr &filename, const MacFileProperties &mfp) override;
@@ -53,6 +54,24 @@ namespace PortabilityLayer
return HostFileSystem::GetInstance()->FileExists(dirID, extFN);
}
bool FileManagerImpl::FileLocked(VirtualDirectory_t dirID, const PLPasStr &filename)
{
const char *exts[3] = { ".gpf", ".gpr", ".gpd" };
for (int extIndex = 0; extIndex < sizeof(exts) / sizeof(exts[0]); extIndex++)
{
ExtendedFileName_t extFN;
if (!ConstructFilename(extFN, filename, exts[extIndex]))
return true;
bool exists = false;
if (HostFileSystem::GetInstance()->FileLocked(dirID, extFN, &exists) && exists)
return true;
}
return false;
}
bool FileManagerImpl::DeleteFile(VirtualDirectory_t dirID, const PLPasStr &filename)
{
ExtendedFileName_t extFN;

View File

@@ -1,6 +1,4 @@
#pragma once
#ifndef __PL_FILE_MANAGER_H__
#define __PL_FILE_MANAGER_H__
#include "FilePermission.h"
#include "CoreDefs.h"
@@ -22,6 +20,7 @@ namespace PortabilityLayer
{
public:
virtual bool FileExists(VirtualDirectory_t dirID, const PLPasStr &filename) = 0;
virtual bool FileLocked(VirtualDirectory_t dirID, const PLPasStr &filename) = 0;
virtual bool DeleteFile(VirtualDirectory_t dirID, const PLPasStr &filename) = 0;
virtual PLError_t CreateFile(VirtualDirectory_t dirID, const PLPasStr &filename, const MacFileProperties &mfp) = 0;
@@ -37,5 +36,3 @@ namespace PortabilityLayer
static FileManager *GetInstance();
};
}
#endif

View File

@@ -1,6 +1,4 @@
#pragma once
#ifndef __PL_HOST_FILESYSTEM_H__
#define __PL_HOST_FILESYSTEM_H__
#include "VirtualDirectory.h"
@@ -13,6 +11,7 @@ namespace PortabilityLayer
{
public:
virtual bool FileExists(VirtualDirectory_t virtualDirectory, const char *path) = 0;
virtual bool FileLocked(VirtualDirectory_t virtualDirectory, const char *path, bool *exists) = 0;
virtual IOStream *OpenFile(VirtualDirectory_t virtualDirectory, const char *path, bool writeAccess, bool create) = 0;
virtual HostDirectoryCursor *ScanDirectory(VirtualDirectory_t virtualDirectory) = 0;
@@ -23,5 +22,3 @@ namespace PortabilityLayer
static HostFileSystem *ms_instance;
};
}
#endif

View File

@@ -91,8 +91,8 @@ struct Menu
PortabilityLayer::MMHandleBlock *stringBlobHandle;
Menu **prevMenu;
Menu **nextMenu;
THandle<Menu> prevMenu;
THandle<Menu> nextMenu;
// Refreshed on layout
size_t cumulativeOffset;
@@ -116,15 +116,19 @@ namespace PortabilityLayer
virtual void Init() override;
virtual void Shutdown() override;
Menu **DeserializeMenu(const void *resData) const override;
Menu **GetMenuByID(int id) const override;
void InsertMenuBefore(Menu **insertingMenu, Menu **existingMenu) override;
void InsertMenuAfter(Menu **insertingMenu, Menu **existingMenu) override;
void InsertMenuAtEnd(Menu **insertingMenu) override;
void InsertMenuAtBeginning(Menu **insertingMenu) override;
void SetMenuEnabled(Menu **menuHandle, bool enabled) override;
void SetItemEnabled(Menu **menu, unsigned int index, bool enabled) override;
void SetItemChecked(Menu **menu, unsigned int index, bool checked) override;
THandle<Menu> DeserializeMenu(const void *resData) const override;
THandle<Menu> GetMenuByID(int id) const override;
void InsertMenuBefore(const THandle<Menu> &insertingMenu, const THandle<Menu> &existingMenu) override;
void InsertMenuAfter(const THandle<Menu> &insertingMenu, const THandle<Menu> &existingMenu) override;
void InsertMenuAtEnd(const THandle<Menu> &insertingMenu) override;
void InsertMenuAtBeginning(const THandle<Menu> &insertingMenu) override;
void RemoveMenu(const THandle<Menu> &menu) override;
void SetMenuEnabled(const THandle<Menu> &menuHandle, bool enabled) override;
void SetItemEnabled(const THandle<Menu> &menu, unsigned int index, bool enabled) override;
void SetItemChecked(const THandle<Menu> &menu, unsigned int index, bool checked) override;
bool IsPointInMenuBar(const Vec2i &point) const override;
void MenuSelect(const Vec2i &initialPoint, int16_t *outMenu, uint16_t *outItem) override;
@@ -146,7 +150,7 @@ namespace PortabilityLayer
void HandleSelectionOfMenu(MenuManagerImpl *mm, Menu **menuHdl, bool &outNeedRedraw);
void Dismiss();
Menu **GetSelectedMenu() const;
THandle<Menu> GetSelectedMenu() const;
DrawSurface *GetRenderedMenu() const;
const unsigned int *GetSelectedItem() const;
@@ -156,7 +160,7 @@ namespace PortabilityLayer
private:
void RenderMenu(Menu *menu);
Menu **m_currentMenu;
THandle<Menu> m_currentMenu;
DrawSurface *m_menuGraf;
unsigned int m_itemIndex;
bool m_haveItem;
@@ -187,8 +191,8 @@ namespace PortabilityLayer
DrawSurface *m_menuBarGraf;
Menu **m_firstMenu;
Menu **m_lastMenu;
THandle<Menu> m_firstMenu;
THandle<Menu> m_lastMenu;
bool m_haveMenuBarLayout;
bool m_haveIcon;
bool m_menuBarVisible;
@@ -205,12 +209,10 @@ namespace PortabilityLayer
MenuManagerImpl::MenuManagerImpl()
: m_menuBarGraf(nullptr)
, m_firstMenu(nullptr)
, m_lastMenu(nullptr)
, m_haveMenuBarLayout(false)
, m_haveIcon(false)
, m_iconGraphic(nullptr)
, m_menuBarVisible(true)
, m_menuBarVisible(false)
{
}
@@ -238,7 +240,7 @@ namespace PortabilityLayer
// GP TODO: Dispose of menus properly
}
Menu **MenuManagerImpl::DeserializeMenu(const void *resData) const
THandle<Menu> MenuManagerImpl::DeserializeMenu(const void *resData) const
{
PortabilityLayer::MemoryManager *mm = PortabilityLayer::MemoryManager::GetInstance();
@@ -334,21 +336,21 @@ namespace PortabilityLayer
menu->layoutWidth = 0;
menu->layoutHeight = 0;
return reinterpret_cast<Menu**>(&menuData->m_contents);
return THandle<Menu>(menuData);
}
Menu **MenuManagerImpl::GetMenuByID(int id) const
THandle<Menu> MenuManagerImpl::GetMenuByID(int id) const
{
for (Menu **menuHandle = m_firstMenu; menuHandle; menuHandle = (*menuHandle)->nextMenu)
for (THandle<Menu> menuHandle = m_firstMenu; menuHandle; menuHandle = (*menuHandle)->nextMenu)
{
if ((*menuHandle)->menuID == id)
return menuHandle;
}
return nullptr;
return THandle<Menu>();
}
void MenuManagerImpl::InsertMenuBefore(Menu **insertingMenu, Menu **existingMenu)
void MenuManagerImpl::InsertMenuBefore(const THandle<Menu> &insertingMenu, const THandle<Menu> &existingMenu)
{
m_haveMenuBarLayout = false;
@@ -366,7 +368,7 @@ namespace PortabilityLayer
existingMenuPtr->prevMenu = insertingMenu;
}
void MenuManagerImpl::InsertMenuAfter(Menu **insertingMenu, Menu **existingMenu)
void MenuManagerImpl::InsertMenuAfter(const THandle<Menu> &insertingMenu, const THandle<Menu> &existingMenu)
{
m_haveMenuBarLayout = false;
@@ -384,7 +386,7 @@ namespace PortabilityLayer
existingMenuPtr->nextMenu = insertingMenu;
}
void MenuManagerImpl::InsertMenuAtEnd(Menu **insertingMenu)
void MenuManagerImpl::InsertMenuAtEnd(const THandle<Menu> &insertingMenu)
{
m_haveMenuBarLayout = false;
@@ -399,7 +401,7 @@ namespace PortabilityLayer
m_lastMenu = insertingMenu;
}
void MenuManagerImpl::InsertMenuAtBeginning(Menu **insertingMenu)
void MenuManagerImpl::InsertMenuAtBeginning(const THandle<Menu> &insertingMenu)
{
m_haveMenuBarLayout = false;
@@ -414,14 +416,39 @@ namespace PortabilityLayer
m_firstMenu = insertingMenu;
}
void MenuManagerImpl::SetMenuEnabled(Menu **menuHandle, bool enabled)
void MenuManagerImpl::RemoveMenu(const THandle<Menu> &menu)
{
DrawMenuBar();
Menu *menuPtr = *menu;
if (menuPtr->stringBlobHandle)
PortabilityLayer::MemoryManager::GetInstance()->ReleaseHandle(menuPtr->stringBlobHandle);
if (menuPtr->prevMenu)
(*menuPtr->prevMenu)->nextMenu = menuPtr->nextMenu;
if (menuPtr->nextMenu)
(*menuPtr->nextMenu)->prevMenu = menuPtr->prevMenu;
if (m_firstMenu == menu)
m_firstMenu = menuPtr->nextMenu;
if (m_lastMenu == menu)
m_lastMenu = menuPtr->prevMenu;
menu.Dispose();
DrawMenuBar();
}
void MenuManagerImpl::SetMenuEnabled(const THandle<Menu> &menuHandle, bool enabled)
{
Menu *menu = *menuHandle;
menu->enabled = enabled;
}
void MenuManagerImpl::SetItemEnabled(Menu **menuHandle, unsigned int index, bool enabled)
void MenuManagerImpl::SetItemEnabled(const THandle<Menu> &menuHandle, unsigned int index, bool enabled)
{
Menu *menu = *menuHandle;
@@ -431,7 +458,7 @@ namespace PortabilityLayer
menu->menuItems[index].enabled = enabled;
}
void MenuManagerImpl::SetItemChecked(Menu **menuHandle, unsigned int index, bool checked)
void MenuManagerImpl::SetItemChecked(const THandle<Menu> &menuHandle, unsigned int index, bool checked)
{
Menu *menu = *menuHandle;
@@ -710,6 +737,9 @@ namespace PortabilityLayer
void MenuManagerImpl::SetMenuVisible(bool isVisible)
{
if (isVisible && !m_menuBarVisible)
DrawMenuBar();
m_menuBarVisible = isVisible;
}
@@ -919,8 +949,7 @@ namespace PortabilityLayer
MenuManagerImpl MenuManagerImpl::ms_instance;
MenuManagerImpl::MenuSelectionState::MenuSelectionState()
: m_currentMenu(nullptr)
, m_menuGraf(nullptr)
: m_menuGraf(nullptr)
, m_haveItem(false)
, m_itemIndex(0)
{
@@ -965,7 +994,7 @@ namespace PortabilityLayer
m_haveItem = false;
}
Menu **MenuManagerImpl::MenuSelectionState::GetSelectedMenu() const
THandle<Menu> MenuManagerImpl::MenuSelectionState::GetSelectedMenu() const
{
return m_currentMenu;
}

View File

@@ -1,5 +1,8 @@
#pragma once
template<class T>
class THandle;
#include <stdint.h>
struct IGpDisplayDriver;
@@ -15,15 +18,19 @@ namespace PortabilityLayer
virtual void Init() = 0;
virtual void Shutdown() = 0;
virtual Menu **DeserializeMenu(const void *resData) const = 0;
virtual Menu **GetMenuByID(int id) const = 0;
virtual void InsertMenuBefore(Menu **insertingMenu, Menu **existingMenu) = 0;
virtual void InsertMenuAfter(Menu **insertingMenu, Menu **existingMenu) = 0;
virtual void InsertMenuAtEnd(Menu **insertingMenu) = 0;
virtual void InsertMenuAtBeginning(Menu **insertingMenu) = 0;
virtual void SetMenuEnabled(Menu **menuHandle, bool enabled) = 0;
virtual void SetItemEnabled(Menu **menu, unsigned int index, bool enabled) = 0;
virtual void SetItemChecked(Menu **menu, unsigned int index, bool checked) = 0;
virtual THandle<Menu> DeserializeMenu(const void *resData) const = 0;
virtual THandle<Menu> GetMenuByID(int id) const = 0;
virtual void InsertMenuBefore(const THandle<Menu> &insertingMenu, const THandle<Menu> &existingMenu) = 0;
virtual void InsertMenuAfter(const THandle<Menu> &insertingMenu, const THandle<Menu> &existingMenu) = 0;
virtual void InsertMenuAtEnd(const THandle<Menu> &insertingMenu) = 0;
virtual void InsertMenuAtBeginning(const THandle<Menu> &insertingMenu) = 0;
virtual void RemoveMenu(const THandle<Menu> &menu) = 0;
virtual void SetMenuEnabled(const THandle<Menu> &menuHandle, bool enabled) = 0;
virtual void SetItemEnabled(const THandle<Menu> &menu, unsigned int index, bool enabled) = 0;
virtual void SetItemChecked(const THandle<Menu> &menu, unsigned int index, bool checked) = 0;
virtual bool IsPointInMenuBar(const Vec2i &point) const = 0;

View File

@@ -287,7 +287,7 @@ void ShowWindow(WindowPtr window)
void SetWTitle(WindowPtr window, const PLPasStr &title)
{
PL_NotYetImplemented();
PL_NotYetImplemented_TODO("Editor");
}
long MenuSelect(Point point)

View File

@@ -2,10 +2,8 @@
#include "MemoryManager.h"
void THandleBase::Dispose()
void THandleBase::Dispose() const
{
if (m_hdl)
PortabilityLayer::MemoryManager::GetInstance()->ReleaseHandle(m_hdl);
m_hdl = nullptr;
}

View File

@@ -13,7 +13,7 @@ public:
PortabilityLayer::MMHandleBlock *MMBlock() const;
void Dispose();
void Dispose() const;
protected:
PortabilityLayer::MMHandleBlock *m_hdl;

View File

@@ -0,0 +1,31 @@
#include "PLImageWidget.h"
#include "PLQDraw.h"
#include "ResourceManager.h"
namespace PortabilityLayer
{
ImageWidget::ImageWidget(const WidgetBasicState &state)
: WidgetSpec<ImageWidget>(state)
{
}
ImageWidget::~ImageWidget()
{
}
bool ImageWidget::Init(const WidgetBasicState &state)
{
m_pict = PortabilityLayer::ResourceManager::GetInstance()->GetResource('PICT', state.m_resID).StaticCast<Picture>();
if (!m_pict)
return false;
return true;
}
void ImageWidget::DrawControl(DrawSurface *surface)
{
if (m_pict && m_rect.IsValid())
surface->DrawPicture(m_pict, m_rect);
}
}

View File

@@ -0,0 +1,22 @@
#pragma once
#include "PLWidgets.h"
#include "PLHandle.h"
struct Picture;
namespace PortabilityLayer
{
class ImageWidget final : public WidgetSpec<ImageWidget>
{
public:
ImageWidget(const WidgetBasicState &state);
~ImageWidget();
bool Init(const WidgetBasicState &state) override;
void DrawControl(DrawSurface *surface) override;
private:
THandle<Picture> m_pict;
};
}

View File

@@ -48,21 +48,6 @@ void InsertMenu(MenuHandle menu, int beforeID)
mm->InsertMenuAtEnd(menu);
}
void DeleteMenu(int menuID)
{
PL_NotYetImplemented();
}
void DrawMenuBar()
{
PortabilityLayer::MenuManager::GetInstance()->DrawMenuBar();
}
void HiliteMenu(int menu)
{
// Don't know what this does
}
void EnableMenuItem(MenuHandle menu, int index)
{
PortabilityLayer::MenuManager *mm = PortabilityLayer::MenuManager::GetInstance();

View File

@@ -8,9 +8,6 @@ class PLPasStr;
MenuHandle GetMenu(int resID);
void InsertMenu(MenuHandle menu, int beforeID);
void DeleteMenu(int menuID); // ???
void DrawMenuBar();
void HiliteMenu(int menu);
void EnableMenuItem(MenuHandle menu, int index);
void DisableMenuItem(MenuHandle menu, int index);

View File

@@ -36,7 +36,7 @@ PixMapHandle GetGWorldPixMap(DrawSurface *gworld)
return gworld->m_port.GetPixMap();
}
PicHandle GetPicture(short resID)
THandle<Picture> GetPicture(short resID)
{
return PortabilityLayer::ResourceManager::GetInstance()->GetResource('PICT', resID).StaticCast<Picture>();
}

View File

@@ -17,20 +17,12 @@ typedef CTabPtr *CTabHandle;
typedef PixMap *PixMapPtr;
typedef PixMapPtr *PixMapHandle;
typedef Picture *PicPtr;
typedef THandle<Picture> PicHandle;
enum QDFlags
{
useTempMem = 1,
};
PLError_t NewGWorld(DrawSurface **gworld, GpPixelFormat_t pixelFormat, const Rect *bounds, CTabHandle colorTable);
void DisposeGWorld(DrawSurface *gworld);
PixMapHandle GetGWorldPixMap(DrawSurface *gworld);
PicHandle GetPicture(short resID);
THandle<Picture> GetPicture(short resID);
void OffsetRect(Rect *rect, int right, int down);

View File

@@ -655,6 +655,9 @@ void DrawSurface::DrawPicture(THandle<Picture> pictHdl, const Rect &bounds)
if (!pictHdl)
return;
if (!bounds.IsValid() || bounds.Width() == 0 || bounds.Height() == 0)
return;
Picture *picPtr = *pictHdl;
if (!picPtr)
return;
@@ -663,8 +666,27 @@ void DrawSurface::DrawPicture(THandle<Picture> pictHdl, const Rect &bounds)
if (bounds.right - bounds.left != picRect.right - picRect.left || bounds.bottom - bounds.top != picRect.bottom - picRect.top)
{
// Scaled pict draw (not supported)
assert(false);
PL_NotYetImplemented_TODO("Palette");
DrawSurface *scaleSurface = nullptr;
if (PortabilityLayer::QDManager::GetInstance()->NewGWorld(&scaleSurface, this->m_port.GetPixelFormat(), picRect, nullptr) != PLErrors::kNone)
return;
scaleSurface->DrawPicture(pictHdl, picRect);
const uint16_t newWidth = bounds.Width();
const uint16_t newHeight = bounds.Height();
THandle<PortabilityLayer::PixMapImpl> scaled = static_cast<PortabilityLayer::PixMapImpl*>(*scaleSurface->m_port.GetPixMap())->ScaleTo(newWidth, newHeight);
PortabilityLayer::QDManager::GetInstance()->DisposeGWorld(scaleSurface);
if (scaled)
CopyBits(*scaled, *this->m_port.GetPixMap(), &(*scaled)->m_rect, &bounds, srcCopy);
PortabilityLayer::PixMapImpl::Destroy(scaled);
m_port.SetDirty(PortabilityLayer::QDPortDirtyFlag_Contents);
return;
}
@@ -697,6 +719,8 @@ void DrawSurface::DrawPicture(THandle<Picture> pictHdl, const Rect &bounds)
assert(false);
return;
};
m_port.SetDirty(PortabilityLayer::QDPortDirtyFlag_Contents);
}

View File

@@ -40,6 +40,11 @@ namespace PortabilityLayer
(void)style;
}
void Widget::SetString(const PLPasStr &str)
{
(void)str;
}
const Rect &Widget::GetRect() const
{
return m_rect;

View File

@@ -44,6 +44,7 @@ namespace PortabilityLayer
void SetEnabled(bool enabled);
void SetState(int16_t state);
virtual void SetString(const PLPasStr &str);
virtual void SetHighlightStyle(int16_t style);
const Rect &GetRect() const;

View File

@@ -200,6 +200,7 @@
<ClInclude Include="PLHacks.h" />
<ClInclude Include="PLHandle.h" />
<ClInclude Include="PLIconWidget.h" />
<ClInclude Include="PLImageWidget.h" />
<ClInclude Include="PLInvisibleWidget.h" />
<ClInclude Include="PLLabelWidget.h" />
<ClInclude Include="PLWidgets.h" />
@@ -310,6 +311,7 @@
<ClCompile Include="PLEventQueue.cpp" />
<ClCompile Include="PLHacks.cpp" />
<ClCompile Include="PLIconWidget.cpp" />
<ClCompile Include="PLImageWidget.cpp" />
<ClCompile Include="PLInvisibleWidget.cpp" />
<ClCompile Include="PLLabelWidget.cpp" />
<ClCompile Include="PLMenus.cpp" />

View File

@@ -435,6 +435,9 @@
<ClInclude Include="PLLabelWidget.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PLImageWidget.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="CFileStream.cpp">
@@ -671,5 +674,8 @@
<ClCompile Include="PLLabelWidget.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="PLImageWidget.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@@ -4,6 +4,175 @@
#include <assert.h>
class PixMapSampler_8BitStandard
{
public:
inline static uint8_t ReadAs8BitStandard(const void *rowData, size_t index)
{
return static_cast<const uint8_t*>(rowData)[index];
}
};
template<class TSampler>
class PixMapCopier_8BitStandard
{
public:
inline static void Copy(const void *inData, size_t inIndex, void *outData, size_t outIndex)
{
static_cast<uint8_t*>(outData)[outIndex] = TSampler::ReadAs8BitStandard(inData, inIndex);
}
};
template<class TCopier>
class PixMapColBlitter
{
public:
static void BlitRow(const void *inData, size_t inSize, void *outData, size_t outSize)
{
if (inSize == outSize)
{
for (size_t i = 0; i < inSize; i++)
TCopier::Copy(inData, i, outData, i);
}
else if (inSize < outSize)
{
size_t remainder = 0;
size_t inIndex = 0;
for (size_t i = 0; i < outSize; i++)
{
TCopier::Copy(inData, inIndex, outData, i);
remainder += inSize;
if (remainder >= outSize)
{
remainder -= outSize;
inIndex++;
}
}
}
else //if (outSize < inSize)
{
size_t remainder = 0;
size_t outIndex = 0;
for (size_t i = 0; i < inSize; i++)
{
remainder += outSize;
if (remainder >= inSize)
{
TCopier::Copy(inData, i, outData, outIndex);
remainder -= inSize;
outIndex++;
}
}
}
}
};
template<class TCopier>
class PixMapRowBlitter
{
public:
static void Blit(const void *inData, size_t inPitch, size_t inColCount, size_t inRowCount, void *outData, size_t outPitch, size_t outColCount, size_t outRowCount)
{
if (inRowCount == outRowCount)
{
for (size_t i = 0; i < inRowCount; i++)
{
PixMapColBlitter<TCopier>::BlitRow(inData, inColCount, outData, outColCount);
inData = static_cast<const uint8_t*>(inData) + inPitch;
outData = static_cast<uint8_t*>(outData) + outPitch;
}
}
else if (inRowCount < outRowCount)
{
size_t remainder = 0;
size_t inIndex = 0;
for (size_t i = 0; i < outRowCount; i++)
{
PixMapColBlitter<TCopier>::BlitRow(inData, inColCount, outData, outColCount);
remainder += inRowCount;
if (remainder >= outRowCount)
{
remainder -= outRowCount;
inData = static_cast<const uint8_t*>(inData) + inPitch;
}
outData = static_cast<uint8_t*>(outData) + outPitch;
}
}
else //if(outRowCount < inRowCount)
{
size_t remainder = 0;
size_t outIndex = 0;
for (size_t i = 0; i < inRowCount; i++)
{
remainder += outRowCount;
if (remainder >= inRowCount)
{
PixMapColBlitter<TCopier>::BlitRow(inData, inColCount, outData, outColCount);
remainder -= inRowCount;
outData = static_cast<uint8_t*>(outData) + outPitch;
}
inData = static_cast<const uint8_t*>(inData) + inPitch;
}
}
}
};
template<class TSampler>
class PixMapBlitTargetDisambiguator
{
public:
static void Blit(const void *inData, size_t inPitch, size_t inColCount, size_t inRowCount, void *outData, size_t outPitch, size_t outColCount, size_t outRowCount, GpPixelFormat_t destFormat)
{
void(*blitFunc)(const void *inData, size_t inPitch, size_t inColCount, size_t inRowCount, void *outData, size_t outPitch, size_t outColCount, size_t outRowCount);
blitFunc = nullptr;
switch (destFormat)
{
case GpPixelFormats::k8BitStandard:
blitFunc = PixMapRowBlitter<PixMapCopier_8BitStandard<TSampler> >::Blit;
break;
default:
PL_NotYetImplemented();
break;
}
if (blitFunc != nullptr)
blitFunc(inData, inPitch, inColCount, inRowCount, outData, outPitch, outColCount, outRowCount);
}
};
class PixMapBlitSourceDisambiguator
{
public:
static void Blit(const void *inData, size_t inPitch, size_t inColCount, size_t inRowCount, GpPixelFormat_t srcFormat, void *outData, size_t outPitch, size_t outColCount, size_t outRowCount, GpPixelFormat_t destFormat)
{
void(*blitFunc)(const void *inData, size_t inPitch, size_t inColCount, size_t inRowCount, void *outData, size_t outPitch, size_t outColCount, size_t outRowCount, GpPixelFormat_t srcFormat);
blitFunc = nullptr;
switch (srcFormat)
{
case GpPixelFormats::k8BitStandard:
blitFunc = PixMapBlitTargetDisambiguator<PixMapSampler_8BitStandard>::Blit;
break;
default:
PL_NotYetImplemented();
break;
}
if (blitFunc != nullptr)
blitFunc(inData, inPitch, inColCount, inRowCount, outData, outPitch, outColCount, outRowCount, srcFormat);
}
};
namespace PortabilityLayer
{
void PixMapImpl::Destroy(THandle<PixMapImpl> &hdl)
@@ -102,6 +271,30 @@ namespace PortabilityLayer
return THandle<PixMapImpl>(pmBlock);
}
THandle<PixMapImpl> PixMapImpl::ScaleTo(uint16_t width, uint16_t height)
{
// Stupid stuff to cover the entire numeric range
Rect scaledRect;
scaledRect.right = static_cast<int16_t>(width / 2);
scaledRect.bottom = static_cast<int16_t>(height / 2);
scaledRect.top = static_cast<int16_t>(scaledRect.bottom - height);
scaledRect.left = static_cast<int16_t>(scaledRect.right - width);
THandle<PixMapImpl> scaled = PixMapImpl::Create(scaledRect, m_pixelFormat);
if (!scaled)
return THandle<PixMapImpl>();
PixMapImpl *destPixMap = *scaled;
const uint16_t oldWidth = m_rect.Width();
const uint16_t oldHeight = m_rect.Height();
PixMapBlitSourceDisambiguator::Blit(GetPixelData(), m_pitch, m_rect.Width(), m_rect.Height(), m_pixelFormat, destPixMap->GetPixelData(), destPixMap->GetPitch(), width, height, m_pixelFormat);
return scaled;
}
}
void PixMap::Init(const Rect &rect, GpPixelFormat_t pixelFormat, size_t pitch, void *dataPtr)

View File

@@ -24,6 +24,8 @@ namespace PortabilityLayer
const void *GetPixelData() const;
size_t GetDataCapacity() const;
THandle<PixMapImpl> ScaleTo(uint16_t width, uint16_t height);
static THandle<PixMapImpl> Create(const Rect &rect, GpPixelFormat_t pixelFormat);
static size_t SizeForDimensions(uint16_t width, uint16_t height, GpPixelFormat_t pixelFormat);