Icon resource extractors

This commit is contained in:
Iliyas Jorio 2021-07-18 15:33:01 +02:00
parent ebea9d03cd
commit 46599c1780
7 changed files with 181 additions and 59 deletions

View File

@ -69,6 +69,7 @@ if (NOT(POMME_NO_GRAPHICS))
${POMME_SRCDIR}/Graphics/Color.cpp
${POMME_SRCDIR}/Graphics/ColorManager.cpp
${POMME_SRCDIR}/Graphics/Graphics.cpp
${POMME_SRCDIR}/Graphics/Icons.cpp
${POMME_SRCDIR}/Graphics/PICT.cpp
${POMME_SRCDIR}/Graphics/SysFont.h
${POMME_SRCDIR}/Graphics/SystemPalettes.cpp

View File

@ -1,6 +1,6 @@
#include "Pomme.h"
#include "PommeFiles.h"
#include "Memory/BlockDescriptor.h"
#include "PommeMemory.h"
#include "Utilities/bigendianstreams.h"
#include <algorithm>

View File

@ -1,13 +1,13 @@
#include "Pomme.h"
#include "PommeFiles.h"
#include "PommeGraphics.h"
#include "PommeMemory.h"
#include "SysFont.h"
#include "Utilities/memstream.h"
#include <iostream>
#include <memory>
#include <SDL.h>
#include <SDL_opengl.h>
#include <PommeFiles.h>
#include <cstring>
using namespace Pomme;
using namespace Pomme::Graphics;
@ -674,55 +674,3 @@ void DrawChar(char c)
penX += glyph.width;
}
// ----------------------------------------------------------------------------
// Icons
void Pomme::Graphics::SetWindowIconFromIcl8Resource(SDL_Window* window, short icl8ID)
{
Handle colorIcon = GetResource('icl8', icl8ID);
Handle bwIcon = GetResource('ICN#', icl8ID);
if (1024 != GetHandleSize(colorIcon))
{
DisposeHandle(colorIcon);
DisposeHandle(bwIcon);
throw std::invalid_argument("icl8 resource has incorrect size");
}
if (256 != GetHandleSize(bwIcon))
{
DisposeHandle(colorIcon);
DisposeHandle(bwIcon);
throw std::invalid_argument("ICN# resource has incorrect size");
}
uint32_t* maskScanlines = (uint32_t*)(*bwIcon + 128); // mask starts 128 bytes into ICN# resource
ByteswapInts(4, 32, maskScanlines);
const int width = 32;
const int height = 32;
SDL_Surface* icon = SDL_CreateRGBSurface(0, width, height, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
for (int y = 0; y < height; y++)
{
uint32_t* out = (uint32_t*) ((char*) icon->pixels + icon->pitch * y);
for (int x = 0; x < width; x++)
{
uint8_t paletteEntry = (*colorIcon)[y * width + x];
uint32_t argb = Pomme::Graphics::clut8[paletteEntry];
bool masked = maskScanlines[y] & (1 << (width - 1 - x));
if (!masked)
{
argb &= 0x00FFFFFF;
}
*out++ = argb;
}
}
SDL_SetWindowIcon(window, icon);
SDL_FreeSurface(icon);
DisposeHandle(colorIcon);
DisposeHandle(bwIcon);
}

154
src/Graphics/Icons.cpp Normal file
View File

@ -0,0 +1,154 @@
#include "Pomme.h"
#include "PommeGraphics.h"
#include "PommeMemory.h"
#include "Utilities/structpack.h"
#include <iostream>
#include <cstring>
// ----------------------------------------------------------------------------
// Icons
static Handle Get4bitIconAsARGB(Handle colorIcon, Ptr bwMask, int width)
{
int height = width;
if (!colorIcon || !bwMask)
return nil;
if (width*height/2 != GetHandleSize(colorIcon))
return nil;
Handle icon = NewHandle(width * height * 4);
for (int y = 0; y < height; y++)
{
uint32_t* out = (uint32_t*) (*icon + y * width * 4);
uint32_t scanlineMask = 0xFFFFFFFF;
if (!bwMask)
;
else if (width == 32)
scanlineMask = Byteswap32(bwMask + y*4);
else if (width == 16)
scanlineMask = Byteswap16(bwMask + y*2);
for (int x = 0; x < width; x++)
{
uint8_t paletteEntry = (*colorIcon)[y * (width>>1) + (x>>1)];
if (!(x & 1))
paletteEntry >>= 4;
paletteEntry &= 0x0F;
uint32_t argb = Pomme::Graphics::clut4[paletteEntry];
bool masked = scanlineMask & (1 << (width - 1 - x));
if (!masked)
argb &= 0x00FFFFFF;
*out++ = argb;
}
}
return icon;
}
static Handle Get8bitIconAsARGB(Handle colorIcon, Ptr bwMask, int width)
{
int height = width;
if (!colorIcon || !bwMask)
return nil;
if (width*height != GetHandleSize(colorIcon))
return nil;
Handle icon = NewHandle(width * height * 4);
for (int y = 0; y < height; y++)
{
uint32_t* out = (uint32_t*) (*icon + y * width * 4);
uint32_t scanlineMask = 0xFFFFFFFF;
if (!bwMask)
;
else if (width == 32)
scanlineMask = Byteswap32(bwMask + y*4);
else if (width == 16)
scanlineMask = Byteswap16(bwMask + y*2);
for (int x = 0; x < width; x++)
{
uint8_t paletteEntry = (*colorIcon)[y * width + x];
uint32_t argb = Pomme::Graphics::clut8[paletteEntry];
bool masked = scanlineMask & (1 << (width - 1 -x));
if (!masked)
argb &= 0x00FFFFFF;
*out++ = argb;
}
}
return icon;
}
Handle Pomme::Graphics::GetIcl8AsARGB(short id)
{
Handle colorIcon = GetResource('icl8', id);
Handle bwIcon = GetResource('ICN#', id);
Pomme::Memory::DisposeHandleGuard autoDisposeColorIcon(colorIcon);
Pomme::Memory::DisposeHandleGuard autoDisposeBwIcon(bwIcon);
Ptr mask = nil;
if (bwIcon && 256 == GetHandleSize(bwIcon))
mask = *bwIcon + 128; // Mask data for icl8 starts 128 bytes into ICN#
return Get8bitIconAsARGB(colorIcon, mask, 32);
}
Handle Pomme::Graphics::GetIcs8AsARGB(short id)
{
Handle colorIcon = GetResource('ics8', id);
Handle bwIcon = GetResource('ics#', id);
Pomme::Memory::DisposeHandleGuard autoDisposeColorIcon(colorIcon);
Pomme::Memory::DisposeHandleGuard autoDisposeBwIcon(bwIcon);
Ptr mask = nil;
if (bwIcon && 64 == GetHandleSize(bwIcon))
mask = *bwIcon + 32; // Mask data for ics8 starts 32 bytes into ics#
return Get8bitIconAsARGB(colorIcon, mask, 16);
}
Handle Pomme::Graphics::GetIcl4AsARGB(short id)
{
Handle colorIcon = GetResource('icl4', id);
Handle bwIcon = GetResource('ICN#', id);
Pomme::Memory::DisposeHandleGuard autoDisposeColorIcon(colorIcon);
Pomme::Memory::DisposeHandleGuard autoDisposeBwIcon(bwIcon);
Ptr mask = nil;
if (bwIcon && 256 == GetHandleSize(bwIcon))
mask = *bwIcon + 128; // Mask data for icl8 starts 128 bytes into ICN#
return Get4bitIconAsARGB(colorIcon, mask, 32);
}
Handle Pomme::Graphics::GetIcs4AsARGB(short id)
{
Handle colorIcon = GetResource('ics4', id);
Handle bwIcon = GetResource('ics#', id);
Pomme::Memory::DisposeHandleGuard autoDisposeColorIcon(colorIcon);
Pomme::Memory::DisposeHandleGuard autoDisposeBwIcon(bwIcon);
Ptr mask = nil;
if (bwIcon && 64 == GetHandleSize(bwIcon))
mask = *bwIcon + 32; // Mask data for ics8 starts 32 bytes into ics#
return Get4bitIconAsARGB(colorIcon, mask, 16);
}

View File

@ -3,7 +3,7 @@
#include <cstring>
#include "Pomme.h"
#include "Memory/BlockDescriptor.h"
#include "PommeMemory.h"
using namespace Pomme;
using namespace Pomme::Memory;

View File

@ -3,7 +3,6 @@
#include "PommeTypes.h"
#include <istream>
#include <vector>
#include <SDL_video.h>
namespace Pomme::Graphics
{
@ -54,7 +53,10 @@ namespace Pomme::Graphics
CGrafPtr GetScreenPort(void);
void SetWindowIconFromIcl8Resource(SDL_Window* sdlWindow, short i);
Handle GetIcl8AsARGB(short i);
Handle GetIcs8AsARGB(short i);
Handle GetIcl4AsARGB(short i);
Handle GetIcs4AsARGB(short i);
inline int Width(const Rect& r)
{ return r.right - r.left; }

View File

@ -21,4 +21,21 @@ namespace Pomme::Memory
static BlockDescriptor* HandleToBlock(Handle h);
};
class DisposeHandleGuard
{
public:
DisposeHandleGuard(Handle theHandle)
: h(theHandle)
{}
~DisposeHandleGuard()
{
if (h)
DisposeHandle(h);
}
private:
Handle h;
};
}