2
3
mirror of https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git synced 2025-07-14 02:27:40 -04:00

CWE Directory Reorganization

Rearrange directory structure of CWE to be loosely equivalent to
the H'uru Plasma repository.

Part 1: Movement of directories and files.
This commit is contained in:
rarified
2021-05-15 12:49:46 -06:00
parent c3f4a640a3
commit 96903e8dca
4002 changed files with 159 additions and 644 deletions

View File

@ -0,0 +1,235 @@
struct HS_RECT_NAME {
HS_RECT_TYPE fLeft, fTop, fRight, fBottom;
HS_RECT_TYPE Width() const { return fRight - fLeft; }
HS_RECT_TYPE Height() const { return fBottom - fTop; }
hsBool IsEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
void SetEmpty() { fLeft = fTop = fRight = fBottom = 0; }
HS_RECT_NAME* Set(HS_RECT_TYPE left, HS_RECT_TYPE top, HS_RECT_TYPE right, HS_RECT_TYPE bottom)
{
fLeft = left; fTop = top; fRight = right; fBottom = bottom;
return this;
}
HS_RECT_NAME* Set(const HS_RECT_POINT* p1, const HS_RECT_POINT* p2)
{
if (p1->fX < p2->fX)
{ fLeft = p1->fX;
fRight = p2->fX;
} else
{ fLeft = p2->fX;
fRight = p1->fX;
}
if (p1->fY < p2->fY)
{ fTop = p1->fY;
fBottom = p2->fY;
} else
{ fTop = p2->fY;
fBottom = p1->fY;
}
return this;
}
HS_RECT_NAME* Set(UInt32 count, const HS_RECT_POINT pts[])
{
if (count > 0)
{ fLeft = fRight = pts[0].fX;
fTop = fBottom = pts[0].fY;
(void)this->Union(count - 1, &pts[1]);
}
return this;
}
hsBool Contains(HS_RECT_TYPE x, HS_RECT_TYPE y) const
{
return x >= fLeft && x < fRight && y >= fTop && y < fBottom;
}
hsBool Contains(const HS_RECT_POINT* p) const
{
return this->Contains(p->fX, p->fY);
}
hsBool Contains(const HS_RECT_NAME* r) const
{
return fLeft <= r->fLeft && fTop <= r->fTop && fRight >= r->fRight && fBottom >= r->fBottom;
}
hsBool Contains(HS_RECT_TYPE left, HS_RECT_TYPE top, HS_RECT_TYPE right, HS_RECT_TYPE bottom) const
{
return fLeft <= left && fTop <= top && fRight >= right && fBottom >= bottom;
}
HS_RECT_NAME* Offset(HS_RECT_TYPE dx, HS_RECT_TYPE dy)
{
fLeft += dx; fTop += dy; fRight += dx; fBottom += dy;
return this;
}
HS_RECT_NAME* MoveTo(HS_RECT_TYPE x, HS_RECT_TYPE y)
{
this->fRight += x - this->fLeft;
this->fBottom += y - this->fTop;
this->fLeft = x;
this->fTop = y;
return this;
}
HS_RECT_NAME* Inset(HS_RECT_TYPE dx, HS_RECT_TYPE dy)
{
fLeft += dx; fRight -= dx;
fTop += dy; fBottom -= dy;
return this;
}
HS_RECT_NAME* UnionX(HS_RECT_TYPE x)
{
if (x < fLeft) fLeft = x; else
if (x > fRight) fRight = x;
return this;
}
HS_RECT_NAME* UnionY(HS_RECT_TYPE y)
{
if (y < fTop) fTop = y; else
if (y > fBottom) fBottom = y;
return this;
}
HS_RECT_NAME* Union(const HS_RECT_NAME* r)
{
if (r->fLeft < fLeft) fLeft = r->fLeft;
if (r->fTop < fTop) fTop = r->fTop;
if (r->fRight > fRight) fRight = r->fRight;
if (r->fBottom > fBottom) fBottom = r->fBottom;
return this;
}
HS_RECT_NAME* Union(const HS_RECT_POINT* p)
{
if (p->fX < fLeft) fLeft = p->fX;
if (p->fX > fRight) fRight = p->fX;
if (p->fY < fTop) fTop = p->fY;
if (p->fY> fBottom) fBottom = p->fY;
return this;
}
HS_RECT_NAME* Union(UInt32 count, const HS_RECT_POINT p[])
{
HS_RECT_TYPE left = this->fLeft;
HS_RECT_TYPE top = this->fTop;
HS_RECT_TYPE right = this->fRight;
HS_RECT_TYPE bottom = this->fBottom;
for (; count > 0; ++p, --count)
{ HS_RECT_TYPE value = p->fX;
if (value < left) left = value;
else if (value > right) right = value;
value = p->fY;
if (value < top) top = value;
else if (value > bottom) bottom = value;
}
return this->Set(left, top, right, bottom);
}
#if 0 // Havok reeks
friend int operator==(const HS_RECT_NAME& a, const HS_RECT_NAME& b)
{
return a.fLeft == b.fLeft && a.fTop == b.fTop &&
a.fRight == b.fRight && a.fBottom == b.fBottom;
}
friend int operator!=(const HS_RECT_NAME& a, const HS_RECT_NAME& b)
{
return !(a == b);
}
#else // Havok reeks
int operator==(const HS_RECT_NAME& aa) const
{
return aa.fLeft == fLeft && aa.fTop == fTop &&
aa.fRight == fRight && aa.fBottom == fBottom;
}
int operator!=(const HS_RECT_NAME& aa) const
{
return !(aa == *this);
}
#endif // Havok reeks
// Intersect Test
friend int operator&&(const HS_RECT_NAME& a, const HS_RECT_NAME& b)
{
return a.fLeft < b.fRight && a.fRight > b.fLeft &&
a.fTop < b.fBottom && a.fBottom > b.fTop;
}
hsBool Intersect(const HS_RECT_NAME* r)
{
return this->Intersect(r->fLeft, r->fTop, r->fRight, r->fBottom);
}
hsBool Intersect(HS_RECT_TYPE left, HS_RECT_TYPE top, HS_RECT_TYPE right, HS_RECT_TYPE bottom)
{
if (left < fRight && top < fBottom && fLeft < right && fTop < bottom)
{ if (left > fLeft) fLeft = left;
if (top > fTop) fTop = top;
if (right < fRight) fRight = right;
if (bottom < fBottom) fBottom = bottom;
return true;
}
return false;
}
hsBool Intersect(const HS_RECT_NAME* a, const HS_RECT_NAME* b)
{
if (a->fLeft < b->fRight && a->fTop < b->fBottom && b->fLeft < a->fRight && b->fTop < a->fBottom)
{ *this = *b;
if (a->fLeft > fLeft) fLeft = a->fLeft;
if (a->fTop > fTop) fTop = a->fTop;
if (a->fRight < fRight) fRight = a->fRight;
if (a->fBottom < fBottom) fBottom = a->fBottom;
return true;
}
return false; // "this" is not changed
}
HS_RECT_POINT* ToQuad(HS_RECT_POINT quad[4]) const
{
quad[0].fX = fLeft; quad[0].fY = fTop;
quad[1].fX = fRight; quad[1].fY = fTop;
quad[2].fX = fRight; quad[2].fY = fBottom;
quad[3].fX = fLeft; quad[3].fY = fBottom;
return quad;
}
hsBool CornerTest(const HS_RECT_NAME* area,
HS_RECT_POINT* hitPt = nil, HS_RECT_POINT* oppositePt = nil) const
{
if (area->Contains(fLeft, fTop))
{ if (hitPt) hitPt->Set(fLeft, fTop);
if (oppositePt) oppositePt->Set(fRight, fBottom);
return true;
}
if (area->Contains(fLeft, fBottom))
{ if (hitPt) hitPt->Set(fLeft, fBottom);
if (oppositePt) oppositePt->Set(fRight, fTop);
return true;
}
if (area->Contains(fRight, fTop))
{ if (hitPt) hitPt->Set(fRight, fTop);
if (oppositePt) oppositePt->Set(fLeft, fBottom);
return true;
}
if (area->Contains(fRight, fBottom))
{ if (hitPt) hitPt->Set(fRight, fBottom);
if (oppositePt) oppositePt->Set(fLeft, fTop);
return true;
}
return false;
}
hsBool CornerTest(HS_RECT_POINT* pt, HS_RECT_TYPE tolerance,
HS_RECT_POINT* hitPt = nil, HS_RECT_POINT* oppositePt = nil) const
{
HS_RECT_NAME area = { pt->fX - tolerance, pt->fY - tolerance,
pt->fX + tolerance, pt->fY + tolerance };
return this->CornerTest(&area, hitPt, oppositePt);
}
#if !(HS_RECT_EXTEND)
};
#endif
#undef HS_RECT_NAME
#undef HS_RECT_POINT
#undef HS_RECT_TYPE
#undef HS_RECT_EXTEND

View File

@ -0,0 +1,55 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef hsCodec_inc
#define hsCodec_inc
class plMipmap;
class hsCodec
{
public:
virtual plMipmap *CreateCompressedMipmap( plMipmap *uncompressed ) = 0;
virtual plMipmap *CreateUncompressedMipmap( plMipmap *compressed, UInt8 bitDepth = 0 ) = 0;
virtual hsBool ColorizeCompMipmap( plMipmap *bMap, const UInt8 *colorMask ) = 0;
};
#endif // hsCodec_inc

View File

@ -0,0 +1,178 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#include "hsCodecManager.h"
#include "plMipmap.h"
#include "hsDXTSoftwareCodec.h"
#if HS_BUILD_FOR_WIN32
#include "hsDXTDirectXCodec.h"
#endif
hsCodecManager& hsCodecManager::Instance()
{
static hsCodecManager the_instance;
static hsBool initialized = false;
if (!initialized)
{
initialized = true;
hsDXTSoftwareCodec::Init();
#if HS_BUILD_FOR_WIN32
hsDXTDirectXCodec::Init();
#endif
}
return the_instance;
}
hsCodecManager::hsCodecManager()
{
}
plMipmap *hsCodecManager::CreateCompressedMipmap(UInt32 compressionFormat, plMipmap *uncompressed)
{
Int32 i, j;
for (i = 0; i < fCodecTable.Count(); i++)
{
if (fCodecTable[i].fCompressionFormat == compressionFormat)
{
for (j = 0; j < fCodecTable[i].fCodecList.Count(); j++)
{
hsAssert(fCodecTable[i].fCodecList[j].fCodec != 0,
"Nil codec in hsCodecManager::CreateCompressedMipmap.");
plMipmap *bm =
fCodecTable[i].fCodecList[j].fCodec->CreateCompressedMipmap(uncompressed);
if (bm)
{
return bm;
}
}
return nil;
}
}
return nil;
}
plMipmap *hsCodecManager::CreateUncompressedMipmap(plMipmap *compressed, UInt8 bitDepth)
{
Int32 i, j;
for (i = 0; i < fCodecTable.Count(); i++)
{
if( fCodecTable[i].fCompressionFormat == compressed->fCompressionType )
{
for (j = 0; j < fCodecTable[i].fCodecList.Count(); j++)
{
hsAssert(fCodecTable[i].fCodecList[j].fCodec != 0,
"Nil codec in hsCodecManager::CreateUncompressedMipmap.");
plMipmap *bm =
fCodecTable[i].fCodecList[j].fCodec->CreateUncompressedMipmap(compressed, bitDepth);
if (bm)
{
return bm;
}
}
return nil;
}
}
return nil;
}
hsBool hsCodecManager::ColorizeCompMipmap( plMipmap *bMap, const UInt8 *colorMask )
{
Int32 i, j;
for( i = 0; i < fCodecTable.Count(); i++ )
{
if( fCodecTable[ i ].fCompressionFormat == bMap->fCompressionType )
{
for( j = 0; j < fCodecTable[ i ].fCodecList.Count(); j++ )
{
hsAssert( fCodecTable[ i ].fCodecList[ j ].fCodec != 0,
"Nil codec in hsCodecManager::CreateUncompressedMipmap." );
if( fCodecTable[ i ].fCodecList[ j ].fCodec->ColorizeCompMipmap( bMap, colorMask ) )
return true;
}
return false;
}
}
return false;
}
hsBool hsCodecManager::Register(hsCodec *codec, UInt32 compressionFormat, hsScalar priority)
{
Int32 i, j;
for (i = 0; i < fCodecTable.Count(); i++)
{
if (fCodecTable[i].fCompressionFormat == compressionFormat)
{
j = 0;
while ((j < fCodecTable[i].fCodecList.Count()) &&
fCodecTable[i].fCodecList[j].fPriority > priority)
++j;
hsCodecEntry tempCodecEntry(priority, codec);
fCodecTable[i].fCodecList.InsertAtIndex(j, tempCodecEntry);
return true;
}
}
hsCodecList tempCodecList(compressionFormat);
fCodecTable.Append(tempCodecList);
hsCodecEntry tempCodecEntry(priority, codec);
fCodecTable[fCodecTable.Count() - 1].fCodecList.Append(tempCodecEntry);
return true;
}

View File

@ -0,0 +1,113 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// hsCodecManager Class Header //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 6.7.2001 mcn - Updated for new bitmap classes. //
// //
///////////////////////////////////////////////////////////////////////////////
#ifndef hsCodecManager_inc
#define hsCodecManager_inc
#include "HeadSpin.h"
#include "hsTemplates.h"
class hsCodec;
class plMipmap;
class hsCodecManager
{
private:
hsCodecManager();
public:
~hsCodecManager() { }
static hsCodecManager& Instance();
plMipmap *CreateCompressedMipmap( UInt32 compressionFormat, plMipmap *uncompressed );
plMipmap *CreateUncompressedMipmap( plMipmap *compressed, UInt8 bitDepth = 0 );
hsBool ColorizeCompMipmap( plMipmap *bMap, const UInt8 *colorMask );
hsBool Register(hsCodec *codec, UInt32 compressionFormat, hsScalar priority);
/// Decompression flags
enum {
kBitDepthMask = 0x0003,
kCompOrderMask = 0x0004
};
enum { /// Bit depths
kDontCareDepth = 0x0000,
k16BitDepth = 0x0001,
k32BitDepth = 0x0002
};
enum { /// Byte orders
kNormalCompOrder = 0x0000, // DirectX, Glide
kWeirdCompOrder = 0x0004 // OpenGL
};
private:
struct hsCodecEntry
{
hsCodecEntry() : fPriority(0), fCodec(nil) { }
hsCodecEntry(hsScalar p, hsCodec *c) : fPriority(p), fCodec(c) { }
hsScalar fPriority;
hsCodec *fCodec;
};
struct hsCodecList
{
hsCodecList() : fCompressionFormat(0) { }
hsCodecList(UInt32 f) : fCompressionFormat(f) { }
UInt32 fCompressionFormat;
hsTArray<hsCodecEntry> fCodecList;
};
hsTArray<hsCodecList> fCodecTable;
};
#endif // hsCodecManager_inc

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,107 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// hsDXTDirectXCodec Class Functions //
// DirectX-based codec functions //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 6.8.2001 mcn - Got a much-needed Plasma 2.0/DX8 update. //
// //
///////////////////////////////////////////////////////////////////////////////
#ifndef hsDXTDirectXCodec_inc
#define hsDXTDirectXCodec_inc
#include "hsWindows.h"
#include "hsCodec.h"
class plMipmap;
struct IDirect3DDevice8;
struct IDirectDrawSurface7;
struct IDirectDraw7;
class hsDXTDirectXCodec : public hsCodec
{
private:
hsDXTDirectXCodec();
public:
~hsDXTDirectXCodec();
static hsDXTDirectXCodec& Instance();
static void Init() { fRegistered = Register(); }
plMipmap *CreateCompressedMipmap(plMipmap *uncompressed);
plMipmap *CreateUncompressedMipmap(plMipmap *compressed, UInt8 bitDepth = 0);
// Colorize a compressed mipmap
hsBool ColorizeCompMipmap( plMipmap *bMap, const UInt8 *colorMask );
void Initialize( IDirect3DDevice8 *directDraw );
hsBool Initialized() { return (fFlags & kInitialized) != 0; }
private:
UInt32 ICompressedFormat(const plMipmap *uncompressed);
IDirectDrawSurface7 *IMakeDirect3DSurface( UInt32 formatType, UInt32 mipMapLevels, UInt32 width, UInt32 height );
void IFillSurface( hsRGBAColor32* src, UInt32 mmlvs, IDirectDrawSurface7 *pddsDest );
void IFillFromSurface( hsRGBAColor32* dest, UInt32 mmlvs, IDirectDrawSurface7 *pddsSrc );
void ICopySurface( IDirectDrawSurface7 *dest, IDirectDrawSurface7 *src, Int32 mipMapLevels );
void CheckErrorCode(HRESULT res);
hsBool IInitialize();
IDirectDraw7 *fDirectDraw;
HINSTANCE fDDLibraryInstance;
UInt32 fFlags;
enum
{
kInitialized = 0x1,
kExternalInit = 0x2
};
static hsBool Register();
static hsBool fRegistered;
};
#endif // hsDXTDirectXCodec_inc

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,158 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef __HSDXTSOFTWARECODEC_H
#define __HSDXTSOFTWARECODEC_H
#include "HeadSpin.h"
#include "hsCodec.h"
class plMipmap;
class hsDXTSoftwareCodec : public hsCodec
{
private:
hsDXTSoftwareCodec();
public:
~hsDXTSoftwareCodec();
static hsDXTSoftwareCodec& Instance();
static void Init() { fRegistered = Register(); }
plMipmap *CreateCompressedMipmap(plMipmap *uncompressed);
// Uncompresses the given source into a new destination mipmap
plMipmap *CreateUncompressedMipmap( plMipmap *compressed, UInt8 flags = 0 );
// Colorize a compressed mipmap
hsBool ColorizeCompMipmap( plMipmap *bMap, const UInt8 *colorMask );
private:
enum {
kFourColorEncoding,
kThreeColorEncoding
};
void CompressMipmapLevel( plMipmap *uncompressed, plMipmap *compressed );
UInt16 BlendColors16(UInt16 weight1, UInt16 color1, UInt16 weight2, UInt16 color2);
hsRGBAColor32 BlendColors32(UInt32 weight1, hsRGBAColor32 color1, UInt32 weight2, hsRGBAColor32 color2);
Int32 ColorDistanceARGBSquared(hsRGBAColor32 color1, hsRGBAColor32 color2);
UInt16 Color32To16(hsRGBAColor32 color);
// Calculates the DXT format based on a mipmap
UInt8 ICalcCompressedFormat( plMipmap *bMap );
// Copy over a block from a mipmap level to a destination mipmap, converting if necessary
void IXlateColorBlock( plMipmap *destBMap, UInt32 *srcBlock, UInt8 flags = 0 );
// Creates an uncompressed mipmap with the settings to match
plMipmap *ICreateUncompressedMipmap( plMipmap *compressed, UInt8 flags );
// Dispatcher for all the decompression functions
void inline UncompressMipmap( plMipmap *uncompressed, plMipmap *compressed,
UInt8 flags = 0 );
// Decompresses a DXT5 compressed mipmap into a RGB4444 mipmap
void IUncompressMipmapDXT5To16( plMipmap *destBMap, plMipmap *srcBMap );
// Decompresses a DXT5 compressed mipmap into a RGB4444 reversed mipmap
void IUncompressMipmapDXT5To16Weird( plMipmap *destBMap, plMipmap *srcBMap );
// Decompresses a DXT5 compressed mipmap into a RGB8888 mipmap
void IUncompressMipmapDXT5To32( plMipmap *destBMap, plMipmap *srcBMap );
// Decompresses a DXT1 compressed mipmap into a RGB1555 mipmap
void IUncompressMipmapDXT1To16( plMipmap *destBMap, plMipmap *srcBMap );
// Decompresses a DXT1 compressed mipmap into a RGB5551 mipmap
void IUncompressMipmapDXT1To16Weird( plMipmap *destBMap, plMipmap *srcBMap );
// Decompresses a DXT1 compressed mipmap into a RGB8888 mipmap
void IUncompressMipmapDXT1To32( plMipmap *destBMap, plMipmap *srcBMap );
// Decompresses a DXT1 compressed mipmap into an intensity map
void IUncompressMipmapDXT1ToInten( plMipmap *destBMap, plMipmap *srcBMap );
// Decompresses a DXT5 compressed mipmap into an alpha-intensity map
void IUncompressMipmapDXT5ToAInten( plMipmap *destBMap, plMipmap *srcBMap );
// Mixes two RGB8888 colors equally
UInt32 inline IMixEqualRGB32( UInt32 color1, UInt32 color2 );
// Mixes two-thirds of the first RGB8888 color and one-third of the second
UInt32 inline IMixTwoThirdsRGB32( UInt32 twoThirds, UInt32 oneThird );
// Mixes two RGB1555 colors equally
UInt16 inline IMixEqualRGB1555( UInt16 color1, UInt16 color2 );
// Mixes two-thirds of the first RGB1555 color and one-third of the second
UInt16 inline IMixTwoThirdsRGB1555( UInt16 twoThirds, UInt16 oneThird );
// Mixes two RGB5551 colors equally
UInt16 inline IMixEqualRGB5551( UInt16 color1, UInt16 color2 );
// Mixes two-thirds of the first RGB5551 color and one-third of the second
UInt16 inline IMixTwoThirdsRGB5551( UInt16 twoThirds, UInt16 oneThird );
// Mixes two RGB4444 colors equally
UInt16 inline IMixEqualRGB4444( UInt16 color1, UInt16 color2 );
// Mixes two-thirds of the first RGB4444 color and one-third of the second
UInt16 inline IMixTwoThirdsRGB4444( UInt16 twoThirds, UInt16 oneThird );
// Mixes two intensity values equally
UInt8 inline IMixEqualInten( UInt8 color1, UInt8 color2 );
// Mixes two-thirds of the first intensity and one-third of the second
UInt8 inline IMixTwoThirdsInten( UInt8 twoThirds, UInt8 oneThird );
// Converts a color from RGB565 to RGB8888 format, with alpha=0
UInt32 inline IRGB16To32Bit( UInt16 color );
// Converts a color from RGB565 to RGB4444 format, with alpha=0
UInt16 inline IRGB565To4444( UInt16 color );
// Converts a color from RGB565 to RGB1555 format, with alpha=0
UInt16 inline IRGB565To1555( UInt16 color );
// Converts a color from RGB565 to RGB5551 format, with alpha=0
UInt16 inline IRGB565To5551( UInt16 color );
// Converts a color from RGB565 to RGB4444 reversed format, with alpha=0
UInt16 inline IRGB565To4444Rev( UInt16 color );
// Swaps the bytes in a doubleword
UInt32 inline ISwapDwordOrder( UInt32 color );
// Swaps the bytes in a word
UInt16 inline ISwapWordOrder( UInt16 color );
static hsBool Register();
static hsBool fRegistered;
};
#endif // __HSDXTSOFTWARECODEC_H

View File

@ -0,0 +1,167 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef hsRect_Defined
#define hsRect_Defined
#include "hsPoint2.h"
#if HS_BUILD_FOR_MAC
// This guy disables MetroWerks' desire to only include a file once, which obviously gets
// in the way of our little HS_RECT.inc trick
#pragma once off
#endif
#define HS_RECT_NAME hsIntRect
#define HS_RECT_POINT hsIntPoint2
#define HS_RECT_TYPE Int32
#define HS_RECT_EXTEND 1
#include "HS_RECT.inc"
#if HS_BUILD_FOR_MAC
Rect* ToRect(Rect* r) const
{
r->left = (Int16)this->fLeft;
r->top = (Int16)this->fTop;
r->right = (Int16)this->fRight;
r->bottom = (Int16)this->fBottom;
return r;
}
hsIntRect* Set(const Rect* r)
{
return this->Set(r->left, r->top, r->right, r->bottom);
}
#endif
#ifdef _WINDOWS_
RECT* ToRECT(RECT* r) const
{
r->left = this->fLeft;
r->top = this->fTop;
r->right = this->fRight;
r->bottom = this->fBottom;
return r;
}
hsIntRect* Set(const RECT* r)
{
return this->Set(r->left, r->top, r->right, r->bottom);
}
#endif
};
#define HS_RECT_NAME hsFixedRect
#define HS_RECT_POINT hsFixedPoint2
#define HS_RECT_TYPE hsFixed
#define HS_RECT_EXTEND 1
#include "HS_RECT.inc"
hsFixedRect* Set(const hsIntRect* src)
{
this->fLeft = hsIntToFixed(src->fLeft);
this->fTop = hsIntToFixed(src->fTop);
this->fRight = hsIntToFixed(src->fRight);
this->fBottom = hsIntToFixed(src->fBottom);
return this;
}
hsFixed CenterX(void) const { return (fLeft + fRight) >> 1; }
hsFixed CenterY(void) const { return (fTop + fBottom) >> 1; }
hsFixedPoint2* Center(hsFixedPoint2* center) const
{
(void)center->Set(this->CenterX(), this->CenterY());
return center;
}
hsIntRect* Truncate(hsIntRect* dst) const
{
return (hsIntRect*)dst->Set( hsFixedToInt(fLeft), hsFixedToInt(fTop),
hsFixedToInt(fRight), hsFixedToInt(fBottom));
}
hsIntRect* Round(hsIntRect* dst) const
{
return (hsIntRect*)dst->Set( hsFixedRound(fLeft), hsFixedRound(fTop),
hsFixedRound(fRight), hsFixedRound(fBottom));
}
hsIntRect* RoundOut(hsIntRect* dst) const
{
return (hsIntRect*)dst->Set( hsFixedToFloorInt(fLeft),
hsFixedToFloorInt(fTop),
hsFixedToCeilingInt(fRight),
hsFixedToCeilingInt(fBottom));
}
};
#if HS_SCALAR_IS_FLOAT
#define HS_RECT_NAME hsFloatRect
#define HS_RECT_POINT hsFloatPoint2
#define HS_RECT_TYPE float
#define HS_RECT_EXTEND 1
#include "HS_RECT.inc"
hsFloatRect* Set(const hsIntRect* src)
{
this->fLeft = float(src->fLeft);
this->fTop = float(src->fTop);
this->fRight = float(src->fRight);
this->fBottom = float(src->fBottom);
return this;
}
float CenterX(void) const { return (fLeft + fRight) / float(2); }
float CenterY(void) const { return (fTop + fBottom) / float(2); }
hsFloatPoint2* Center(hsFloatPoint2* center) const
{
(void)center->Set(this->CenterX(), this->CenterY());
return center;
}
float Area() const { return this->Width() * this->Height(); }
hsIntRect* Round(hsIntRect* r) const;
hsIntRect* RoundOut(hsIntRect* r) const;
hsIntRect* Truncate(hsIntRect* r) const;
};
#endif
#if HS_SCALAR_IS_FIXED
typedef hsFixedRect hsRect;
#else
typedef hsFloatRect hsRect;
#endif
#endif

View File

@ -0,0 +1,2 @@
Moving hsRect here since it doesn't have a lot to do with transforms. mf

View File

@ -0,0 +1,310 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#include "plAVIWriter.h"
#include "hsTypes.h"
#include "hsWindows.h"
#include <vfw.h>
#include "hsTimer.h"
#include "plMipmap.h"
#include "../plMessage/plRenderMsg.h"
#include "plPipeline.h"
#include "../pnDispatch/plDispatch.h"
#include "../pnKeyedObject/plFixedKey.h"
bool plAVIWriter::fInitialized = false;
class plAVIWriterImp : public plAVIWriter
{
protected:
PAVIFILE fFileHandle;
PAVISTREAM fStreamHandle;
PAVISTREAM fCompressedHandle;
BITMAPINFOHEADER fBitmapInfo;
hsBool fOldRealTime;
hsScalar fOldFrameTimeInc;
double fStartTime;
void IFillStreamInfo(AVISTREAMINFO* inf, plPipeline* pipeline);
void IFillBitmapInfo(BITMAPINFOHEADER* inf, plPipeline* pipeline);
bool ICaptureFrame(plPipeline* pipeline);
public:
plAVIWriterImp();
virtual ~plAVIWriterImp();
virtual hsBool MsgReceive(plMessage* msg);
virtual void Shutdown();
virtual bool Open(const char* fileName, plPipeline* pipeline);
virtual void Close();
};
plAVIWriter::~plAVIWriter()
{
}
plAVIWriter& plAVIWriter::Instance()
{
static plAVIWriterImp theInstance;
if (!fInitialized)
{
theInstance.RegisterAs(kAVIWriter_KEY);
fInitialized = true;
}
return theInstance;
}
////////////////////////////////////////////////////////////////////////////////
plAVIWriterImp::plAVIWriterImp() :
fStartTime(0),
fOldRealTime(false),
fStreamHandle(nil),
fCompressedHandle(nil),
fFileHandle(nil)
{
AVIFileInit();
}
plAVIWriterImp::~plAVIWriterImp()
{
}
void plAVIWriterImp::Shutdown()
{
Close();
UnRegisterAs(kAVIWriter_KEY);
SetKey(nil);
}
#include "plProfile.h"
plProfile_CreateTimer("AviCapture", "RenderSetup", AviCapture);
hsBool plAVIWriterImp::MsgReceive(plMessage* msg)
{
plRenderMsg* renderMsg = plRenderMsg::ConvertNoRef(msg);
if (renderMsg)
{
plProfile_BeginTiming(AviCapture);
ICaptureFrame(renderMsg->Pipeline());
plProfile_EndTiming(AviCapture);
}
return hsKeyedObject::MsgReceive(msg);
}
static const int kFramesPerSec = 30;
bool plAVIWriterImp::Open(const char* fileName, plPipeline* pipeline)
{
// Already writing, fail
if (fStreamHandle)
return false;
fStartTime = hsTimer::GetSysSeconds();
// If we're running in real time, set to frame time
fOldRealTime = hsTimer::IsRealTime();
if (fOldRealTime)
{
hsTimer::SetRealTime(false);
hsTimer::SetFrameTimeInc(1.f / kFramesPerSec);
}
// Open AVI file
HRESULT err;
err = AVIFileOpen( &fFileHandle, // returned file pointer
fileName, // file name
OF_WRITE | OF_CREATE, // mode to open file with
NULL); // use handler determined
hsAssert(err == AVIERR_OK, "Error creating AVI file in plAVIWriter::Open");
if (err != AVIERR_OK)
{
Close();
return false;
}
AVISTREAMINFO streamInfo;
IFillStreamInfo(&streamInfo, pipeline);
// Create a video stream in the file
err = AVIFileCreateStream( fFileHandle, // file pointer
&fStreamHandle, // returned stream pointer
&streamInfo ); // stream header
hsAssert(err == AVIERR_OK, "Error creating video stream in plAVIWriter::Open");
if (err != AVIERR_OK)
{
Close();
return false;
}
do
{
AVICOMPRESSOPTIONS opts;
AVICOMPRESSOPTIONS FAR * aopts[1] = {&opts};
memset(&opts, 0, sizeof(opts));
BOOL bErr = AVISaveOptions(NULL, ICMF_CHOOSE_DATARATE, 1, &fStreamHandle, (LPAVICOMPRESSOPTIONS FAR*)&aopts);
hsAssert(bErr, "Error saving stream options in plAVIWriter::Open");
if (!bErr)
{
Close();
return false;
}
err = AVIMakeCompressedStream(&fCompressedHandle, fStreamHandle, &opts, NULL);
hsAssert(err == AVIERR_OK, "Error creating compressed stream in plAVIWriter::Open");
if (err != AVIERR_OK)
{
Close();
return false;
}
IFillBitmapInfo(&fBitmapInfo, pipeline);
err = AVIStreamSetFormat( fCompressedHandle, 0,
&fBitmapInfo, // stream format
fBitmapInfo.biSize);
} while (err != AVIERR_OK &&
hsMessageBox("Codec unavailable, try again?", "AVI Writer", hsMessageBoxYesNo) == hsMBoxYes);
if (err != AVIERR_OK)
{
Close();
return false;
}
plgDispatch::Dispatch()->RegisterForExactType(plRenderMsg::Index(), GetKey());
return true;
}
void plAVIWriterImp::Close()
{
plgDispatch::Dispatch()->UnRegisterForExactType(plRenderMsg::Index(), GetKey());
hsTimer::SetRealTime(fOldRealTime);
if (fStreamHandle)
{
AVIStreamClose(fStreamHandle);
fStreamHandle = nil;
}
if (fCompressedHandle)
{
AVIStreamClose(fCompressedHandle);
fCompressedHandle = nil;
}
if (fFileHandle)
{
AVIFileClose(fFileHandle);
fFileHandle = nil;
}
AVIFileExit();
}
void plAVIWriterImp::IFillStreamInfo(AVISTREAMINFO* inf, plPipeline* pipeline)
{
memset(inf, 0, sizeof(AVISTREAMINFO));
inf->fccType = streamtypeVIDEO;
inf->fccHandler = 0;
inf->dwScale = 1;
inf->dwRate = kFramesPerSec;
SetRect(&inf->rcFrame,
0,0,
pipeline->Width(),
pipeline->Height());
}
void plAVIWriterImp::IFillBitmapInfo(BITMAPINFOHEADER* inf, plPipeline* pipeline)
{
memset(inf,0,sizeof(BITMAPINFOHEADER));
inf->biSize = sizeof(BITMAPINFOHEADER);
inf->biPlanes = 1;
inf->biBitCount = 32;
inf->biCompression = BI_RGB;
inf->biSizeImage = 0;
inf->biXPelsPerMeter = 0;
inf->biYPelsPerMeter = 0;
inf->biClrUsed = 0;
inf->biClrImportant = 0;
inf->biWidth = pipeline->Width();
inf->biHeight = pipeline->Height();
}
bool plAVIWriterImp::ICaptureFrame(plPipeline* pipeline)
{
plMipmap frame;
pipeline->CaptureScreen(&frame, true);
double time = hsTimer::GetSysSeconds() - fStartTime;
time *= kFramesPerSec;
HRESULT err;
err = AVIStreamWrite( fCompressedHandle,
int(time),
1,
(LPBYTE)frame.GetAddr32(0,0),
frame.GetTotalSize(),
AVIIF_KEYFRAME,
NULL,
NULL);
return (err == AVIERR_OK);
}

View File

@ -0,0 +1,71 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef plAVIWriter_h_inc
#define plAVIWriter_h_inc
#include "../pnKeyedObject/hsKeyedObject.h"
class plPipeline;
class plAVIWriter : public hsKeyedObject
{
protected:
static bool fInitialized;
virtual ~plAVIWriter();
public:
static plAVIWriter& Instance();
// If IsInitialized returns true, you need to call Shutdown before clearing
// the registry (dang key).
static bool IsInitialized() { return fInitialized; }
virtual void Shutdown()=0;
CLASSNAME_REGISTER(plAVIWriter);
GETINTERFACE_ANY(plAVIWriter, hsKeyedObject);
virtual bool Open(const char* fileName, plPipeline* pipeline)=0;
virtual void Close()=0;
};
#endif // plAVIWriter_h_inc

View File

@ -0,0 +1,182 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// plBitmap Class Functions //
// Base bitmap class for all the types of bitmaps (mipmaps, cubic envmaps, //
// etc. //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 6.7.2001 mcn - Created. //
// //
///////////////////////////////////////////////////////////////////////////////
#include "hsTypes.h"
#include "plBitmap.h"
#include "hsResMgr.h"
#include "hsStream.h"
#include "../pnKeyedObject/plKey.h"
#include "../plPipeline/hsGDeviceRef.h"
//// Static Members ///////////////////////////////////////////////////////////
UInt8 plBitmap::fGlobalNumLevelsToChop = 0;
//// Constructor & Destructor /////////////////////////////////////////////////
plBitmap::plBitmap()
{
fPixelSize = 0;
fSpace = kNoSpace;
fFlags = 0;
fCompressionType = kUncompressed;
fUncompressedInfo.fType = UncompressedInfo::kRGB8888;
fDeviceRef = nil;
fLowModifiedTime = fHighModifiedTime = 0;
}
plBitmap::~plBitmap()
{
if( fDeviceRef != nil )
hsRefCnt_SafeUnRef( fDeviceRef );
}
bool plBitmap::IsSameModifiedTime(UInt32 lowTime, UInt32 highTime)
{
return (fLowModifiedTime == lowTime && fHighModifiedTime == highTime);
}
void plBitmap::SetModifiedTime(UInt32 lowTime, UInt32 highTime)
{
fLowModifiedTime = lowTime;
fHighModifiedTime = highTime;
}
//// Read /////////////////////////////////////////////////////////////////////
static UInt8 sBitmapVersion = 2;
UInt32 plBitmap::Read( hsStream *s )
{
UInt8 version = s->ReadByte();
UInt32 read = 6;
hsAssert( version == sBitmapVersion, "Invalid bitamp version on Read()" );
fPixelSize = s->ReadByte();
fSpace = s->ReadByte();
fFlags = s->ReadSwap16();
fCompressionType = s->ReadByte();
if( fCompressionType == kUncompressed || fCompressionType == kJPEGCompression ||
fCompressionType == kPNGCompression )
{
fUncompressedInfo.fType = s->ReadByte();
read++;
}
else
{
fDirectXInfo.fBlockSize = s->ReadByte();
fDirectXInfo.fCompressionType = s->ReadByte();
read += 2;
}
fLowModifiedTime = s->ReadSwap32();
fHighModifiedTime = s->ReadSwap32();
return read;
}
//// Write ////////////////////////////////////////////////////////////////////
UInt32 plBitmap::Write( hsStream *s )
{
UInt32 written = 6;
s->WriteByte( sBitmapVersion );
s->WriteByte( fPixelSize );
s->WriteByte( fSpace );
s->WriteSwap16( fFlags );
s->WriteByte( fCompressionType );
if( fCompressionType == kUncompressed || fCompressionType == kJPEGCompression ||
fCompressionType == kPNGCompression )
{
s->WriteByte( fUncompressedInfo.fType );
written++;
}
else
{
s->WriteByte( fDirectXInfo.fBlockSize );
s->WriteByte( fDirectXInfo.fCompressionType );
written += 2;
}
s->WriteSwap32(fLowModifiedTime);
s->WriteSwap32(fHighModifiedTime);
return written;
}
//// SetDeviceRef /////////////////////////////////////////////////////////////
void plBitmap::SetDeviceRef( hsGDeviceRef *const devRef )
{
if( fDeviceRef == devRef )
return;
hsRefCnt_SafeAssign( fDeviceRef, devRef );
}
void plBitmap::MakeDirty()
{
if( fDeviceRef )
fDeviceRef->SetDirty(true);
}

View File

@ -0,0 +1,205 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// plBitmap Class Header //
// Base bitmap class for all the types of bitmaps (mipmaps, cubic envmaps, //
// etc. //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 6.7.2001 mcn - Created. //
// //
///////////////////////////////////////////////////////////////////////////////
#ifndef _plBitmap_h
#define _plBitmap_h
#include "../pnKeyedObject/hsKeyedObject.h"
class hsResMgr;
class plFilterMask;
class hsGDeviceRef;
//// Class Definition /////////////////////////////////////////////////////////
class plBitmap : public hsKeyedObject
{
public:
//// Public Flags ////
enum {
kNoSpace,
kDirectSpace,
kGraySpace,
kIndexSpace
};
enum Flags {
kNoFlag = 0x0000,
kAlphaChannelFlag = 0x0001,
kAlphaBitFlag = 0x0002,
kBumpEnvMap = 0x0004,
kForce32Bit = 0x0008,
kDontThrowAwayImage = 0x0010, // We can delete the image, but the pipeline can't
kForceOneMipLevel = 0x0020,
kNoMaxSize = 0x0040,
kIntensityMap = 0x0080,
kHalfSize = 0x0100,
kUserOwnsBitmap = 0x0200,
kForceRewrite = 0x0400,
kForceNonCompressed = 0x0800,
// For renderTargets:
kIsTexture = 0x1000,
kIsOffscreen = 0x2000,
kMainScreen = 0x0000, // Exclusive, i.e. no renderTarget flags
kIsProjected = 0x4000,
kIsOrtho = 0x8000
};
//// Public Data /////
enum // Compression format
{
kUncompressed = 0x0,
kDirectXCompression = 0x1,
kJPEGCompression = 0x2,
kPNGCompression = 0x3
};
struct DirectXInfo
{
enum // Compression type
{
kError = 0x0,
kDXT1 = 0x1,
//kDXT2 = 0x2,
//kDXT3 = 0x3,
//kDXT4 = 0x4,
kDXT5 = 0x5
};
UInt8 fCompressionType;
UInt8 fBlockSize; // In bytes
};
struct UncompressedInfo
{
enum
{
kRGB8888 = 0x00, /// 32-bit 8888 ARGB format
kRGB4444 = 0x01, /// 16-bit 4444 ARGB format
kRGB1555 = 0x02, /// 16-bit 555 RGB format w/ alpha bit
kInten8 = 0x03, /// 8-bit intensity channel (monochrome)
kAInten88 = 0x04 /// 8-bit intensity channel w/ 8-bit alpha
};
UInt8 fType;
};
//// Public Data /////
UInt8 fCompressionType;
union
{
DirectXInfo fDirectXInfo;
UncompressedInfo fUncompressedInfo;
};
//// Public Members ////
plBitmap();
virtual ~plBitmap();
CLASSNAME_REGISTER( plBitmap );
GETINTERFACE_ANY( plBitmap, hsKeyedObject );
// Get the total size in bytes
virtual UInt32 GetTotalSize( void ) const = 0;
// Read and write
virtual void Read( hsStream *s, hsResMgr *mgr ) { hsKeyedObject::Read( s, mgr ); this->Read( s ); }
virtual void Write( hsStream *s, hsResMgr *mgr ) { hsKeyedObject::Write( s, mgr ); this->Write( s ); }
UInt16 GetFlags( void ) const { return fFlags; }
void SetFlags( UInt16 flags ) { fFlags = flags; }
UInt8 GetPixelSize( void ) const { return fPixelSize; }
hsBool IsCompressed( void ) const { return ( fCompressionType == kDirectXCompression ); }
virtual void MakeDirty();
virtual hsGDeviceRef *GetDeviceRef( void ) const { return fDeviceRef; }
virtual void SetDeviceRef( hsGDeviceRef *const devRef );
static void SetGlobalLevelChopCount( UInt8 count ) { fGlobalNumLevelsToChop = count; }
static UInt8 GetGlobalLevelChopCount() { return fGlobalNumLevelsToChop; }
// Compares and sets the modified time for the source texture
bool IsSameModifiedTime(UInt32 lowTime, UInt32 highTime);
void SetModifiedTime(UInt32 lowTime, UInt32 highTime);
protected:
//// Protected Members ////
UInt8 fPixelSize; // 1, 2, 4, 8, 16, (24), 32, 64
UInt8 fSpace; // no, direct, gray, index
UInt16 fFlags; // alphachannel | alphabit
mutable hsGDeviceRef *fDeviceRef;
static UInt8 fGlobalNumLevelsToChop;
// The modification time of the source texture.
// Used to determine if we can reuse an already converted copy.
UInt32 fLowModifiedTime;
UInt32 fHighModifiedTime;
virtual UInt32 Read( hsStream *s );
virtual UInt32 Write( hsStream *s );
};
#endif // _plBitmap_h

View File

@ -0,0 +1,314 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#include "hsTypes.h"
#include "plBumpMapGen.h"
#include "plMipmap.h"
#include "hsFastMath.h"
#include "hsCodecManager.h"
plMipmap* plBumpMapGen::MakeCompatibleBlank(const plMipmap* src)
{
return TRACKED_NEW plMipmap(src->GetWidth(), src->GetHeight(), plMipmap::kARGB32Config, 1, plMipmap::kUncompressed, plMipmap::UncompressedInfo::kRGB8888);
}
plMipmap* plBumpMapGen::TwosCompToBias(plMipmap* dst)
{
UInt8* pDst = (UInt8*)dst->GetAddr32(0, 0);
const int width = dst->GetWidth();
const int height = dst->GetHeight();
int i;
int j;
for( j = 0; j < height; j++ )
{
for( i = 0; i < width; i++ )
{
*pDst++ += 128;
*pDst++ += 128;
*pDst++ += 128;
pDst++;
}
}
return dst;
}
plMipmap* plBumpMapGen::QikBumpMap(plMipmap* dst, const plMipmap* origSrc, UInt32 mask, UInt32 flags)
{
const plMipmap* src = origSrc;
if( !dst )
{
dst = MakeCompatibleBlank(src);
}
else if( (src->GetWidth() != dst->GetWidth()) || (src->GetHeight() != dst->GetHeight()) )
{
plMipmap* newSrc = src->Clone();
// Note here that ResizeNicely currently does a point sample if scaling up (and about
// as expensive a point sample as possible without using transcendental functions).
// This might be correctable by calling plMipmap::Filter after the upscale. Or I
// could just assert that dst dimensions match src dimensions.
newSrc->ResizeNicely((UInt16)(dst->GetWidth()), (UInt16)(dst->GetHeight()), plMipmap::kDefaultFilter);
src = newSrc;
}
if( src->IsCompressed() )
{
plMipmap* newSrc = hsCodecManager::Instance().CreateUncompressedMipmap(const_cast<plMipmap*>(src), hsCodecManager::k32BitDepth);
src = newSrc;
}
dst->SetCurrLevel(0);
const Int32 divis = ((mask >> 0) & 0xff)
+((mask >> 8) & 0xff)
+((mask >> 16) & 0xff);
const int width = src->GetWidth();
const int height = src->GetHeight();
const int stride = src->GetRowBytes(); // Should be width * 4;
const UInt32 alphaOr = flags & kScaleHgtByAlpha ? 0 : 0xff;
UInt32* pDst = dst->GetAddr32(0, 0);
UInt32* pBase = src->GetAddr32(0, 0);
UInt32* pSrc = pBase;
int i;
int j;
for( j = 0; j < height; j++ )
{
UInt32* pUp = j ? pSrc - width : pBase;
UInt32* pDn = j < height-1 ? pSrc + width : pBase;
for( i = 0; i < width; i++ )
{
UInt32* pLf = i ? pSrc - 1 : pSrc + width-1;
UInt32* pRt = i < width-1 ? pSrc + 1 : pSrc - width + 1;
UInt32 up = (((*pUp & mask) >> 0) & 0xff)
+ (((*pUp & mask) >> 8) & 0xff)
+ (((*pUp & mask) >> 16) & 0xff);
UInt32 dn = (((*pDn & mask) >> 0) & 0xff)
+ (((*pDn & mask) >> 8) & 0xff)
+ (((*pDn & mask) >> 16) & 0xff);
UInt32 rt = (((*pRt & mask) >> 0) & 0xff)
+ (((*pRt & mask) >> 8) & 0xff)
+ (((*pRt & mask) >> 16) & 0xff);
UInt32 lf = (((*pLf & mask) >> 0) & 0xff)
+ (((*pLf & mask) >> 8) & 0xff)
+ (((*pLf & mask) >> 16) & 0xff);
UInt32 hgt = (((*pSrc & mask) >> 0) & 0xff)
+ (((*pSrc & mask) >> 8) & 0xff)
+ (((*pSrc & mask) >> 16) & 0xff);
if( hgt )
hgt *= 1;
// Multiply by alpha, divide by 255 (so *= float(alpha/255))
// If we aren't scaling by alpha, we just force alpha to be 255.
hgt *= ((*pSrc >> 24) & 0xff) | alphaOr; // scale by alpha
hgt /= 255;
// divis has an implicit 255. For example, all three channels
// are on, so divis = 0xff+0xff+0xff = 3*255.
// So we muliply by 255 and divide by divis, so in this example,
// that means divide by 3.
Int32 delUpDn = dn - up;
delUpDn *= 255;
delUpDn /= divis;
Int32 delRtLf = lf - rt;
delRtLf *= 255;
delRtLf /= divis;
hgt *= 255;
hgt /= divis;
// hgt = 0xff;
*pDst = ((delRtLf & 0xff) << 16)
|((delUpDn & 0xff) << 8)
|((0xff) << 0)
|((hgt & 0xff) << 24);
if( delRtLf )
hgt *= 1;
if( delUpDn )
hgt *= 1;
pUp++;
pDn++;
pSrc++;
pDst++;
}
}
if( flags & kBias )
TwosCompToBias(dst);
if( origSrc != src )
delete src;
return dst;
}
plMipmap* plBumpMapGen::QikNormalMap(plMipmap* dst, const plMipmap* src, UInt32 mask, UInt32 flags, hsScalar smooth)
{
dst = QikBumpMap(dst, src, mask, flags & ~kBias);
const int width = src->GetWidth();
const int height = src->GetHeight();
if( flags & kBubbleTest )
{
Int8* pDst = (Int8*)dst->GetAddr32(0, 0);
Int32 nZ = Int32(smooth * 255.99f);
int i;
int j;
for( j = 0; j < height; j++ )
{
for( i = 0; i < width; i++ )
{
hsScalar x = hsScalar(i) / hsScalar(width-1) * 2.f - 1.f;
hsScalar y = hsScalar(j) / hsScalar(height-1) * 2.f - 1.f;
hsScalar z = 1.f - x*x - y*y;
if( z > 0 )
z = hsSquareRoot(z);
else
{
x = 0;
y = 0;
z = 1.f;
}
z *= smooth;
hsScalar invLen = hsFastMath::InvSqrt(x*x + y*y + z*z) * 127.00f;
pDst[2] = Int8(x * invLen);
pDst[1] = Int8(y * invLen);
pDst[0] = Int8(z * invLen);
pDst += 4;
}
}
}
else
if( flags & kNormalize )
{
Int8* pDst = (Int8*)dst->GetAddr32(0, 0);
Int32 nZ = Int32(smooth * 127.00f);
int i;
int j;
for( j = 0; j < height; j++ )
{
for( i = 0; i < width; i++ )
{
Int32 x = pDst[2];
Int32 y = pDst[1];
if( x )
x *= 1;
if( y )
y *= 1;
hsScalar invLen = hsFastMath::InvSqrt((hsScalar)(x*x + y*y + nZ*nZ)) * 127.0f;
pDst[2] = Int8(x * invLen);
pDst[1] = Int8(y * invLen);
pDst[0] = Int8(nZ * invLen);
pDst += 4;
}
}
}
else if( smooth != 1.f )
{
Int32 divis = 127;
Int32 nZ = 127;
if( (smooth > 1.f) )
{
divis = (Int32)(smooth * 127);
}
else
{
nZ = UInt32(smooth * 127.5f);
}
Int8* pDst = (Int8*)dst->GetAddr32(0, 0);
int i;
int j;
for( j = 0; j < height; j++ )
{
for( i = 0; i < width; i++ )
{
Int32 v;
*pDst = (Int8)nZ;
pDst++;
v = *pDst * 127;
v /= divis;
*pDst = (Int8)(v & 0xff);
pDst++;
v = *pDst * 127;
v /= divis;
*pDst = (Int8)(v & 0xff);
pDst += 2;
}
}
}
if( flags & kBias )
TwosCompToBias(dst);
return dst;
}

View File

@ -0,0 +1,67 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef plBumpMapGen_inc
#define plBumpMapGen_inc
class plMipmap;
class plBumpMapGen
{
public:
enum {
// output signed values with 0=>-1 and 255=>1, 127=>0, default is 2's complement, 0=>0, 255=>-1, 127=>1
kBias = 0x1,
kMaximize = 0x2,
kNormalize = 0x4,
kScaleHgtByAlpha = 0x8,
kBubbleTest = 0x10
};
static plMipmap* QikBumpMap(plMipmap* dst, const plMipmap* src, UInt32 mask, UInt32 flags);
static plMipmap* QikNormalMap(plMipmap* dst, const plMipmap* src, UInt32 mask, UInt32 flags, hsScalar smooth=1.f); // higher smooth means less bumpy, valid range [0..inf].
static plMipmap* TwosCompToBias(plMipmap* dst);
static plMipmap* MakeCompatibleBlank(const plMipmap* src);
};
#endif // plBumpMapGen_inc

View File

@ -0,0 +1,195 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// plCubicEnvironmap Class Functions //
// Derived bitmap class representing a collection of mipmaps to be used for //
// cubic environment mapping. //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 6.7.2001 mcn - Created. //
// //
///////////////////////////////////////////////////////////////////////////////
#include "hsTypes.h"
#include "plCubicEnvironmap.h"
#include "plMipmap.h"
//// Constructor & Destructor /////////////////////////////////////////////////
plCubicEnvironmap::plCubicEnvironmap()
{
int i;
for( i = 0; i < 6; i++ )
fFaces[ i ] = TRACKED_NEW plMipmap;
fInitialized = false;
}
plCubicEnvironmap::~plCubicEnvironmap()
{
int i;
for( i = 0; i < 6; i++ )
delete fFaces[ i ];
}
//// GetTotalSize /////////////////////////////////////////////////////////////
// Get the total size in bytes
UInt32 plCubicEnvironmap::GetTotalSize( void ) const
{
UInt32 size, i;
for( size = 0, i = 0; i < 6; i++ )
{
hsAssert( fFaces[ i ] != nil, "Nil face in GetTotalSize()" );
size += fFaces[ i ]->GetTotalSize();
}
return size;
}
//// Read /////////////////////////////////////////////////////////////////////
UInt32 plCubicEnvironmap::Read( hsStream *s )
{
UInt32 i, tr = plBitmap::Read( s );
for( i = 0; i < 6; i++ )
tr += fFaces[ i ]->Read( s );
fInitialized = true;
return tr;
}
//// Write ////////////////////////////////////////////////////////////////////
UInt32 plCubicEnvironmap::Write( hsStream *s )
{
UInt32 i, tw = plBitmap::Write( s );
for( i = 0; i < 6; i++ )
tw += fFaces[ i ]->Write( s );
return tw;
}
//// CopyToFace ///////////////////////////////////////////////////////////////
// Export-only: Copy the mipmap given into a face
void plCubicEnvironmap::CopyToFace( plMipmap *mip, UInt8 face )
{
hsAssert( face < 6, "Invalid face index in CopyToFace()" );
hsAssert( fFaces[ face ] != nil, "nil face in CopyToFace()" );
hsAssert( mip != nil, "nil source in CopyToFace()" );
if( !fInitialized )
{
// Make sure our stuff matches
fCompressionType = mip->fCompressionType;
if( fCompressionType != kDirectXCompression )
fUncompressedInfo.fType = mip->fUncompressedInfo.fType;
else
{
fDirectXInfo.fBlockSize = mip->fDirectXInfo.fBlockSize;
fDirectXInfo.fCompressionType = mip->fDirectXInfo.fCompressionType;
}
fPixelSize = mip->GetPixelSize();
fSpace = kDirectSpace;
fFlags = mip->GetFlags();
fInitialized = true;
}
else
{
// Check to make sure their stuff matches
if( IsCompressed() != mip->IsCompressed() )
{
hsAssert( false, "Compression types do not match in CopyToFace()" );
return;
}
if( !IsCompressed() )
{
if( fUncompressedInfo.fType != mip->fUncompressedInfo.fType )
{
hsAssert( false, "Compression formats do not match in CopyToFace()" );
return;
}
}
else
{
if( fDirectXInfo.fBlockSize != mip->fDirectXInfo.fBlockSize ||
fDirectXInfo.fCompressionType != mip->fDirectXInfo.fCompressionType )
{
hsAssert( false, "Compression formats do not match in CopyToFace()" );
return;
}
}
if( fPixelSize != mip->GetPixelSize() )
{
hsAssert( false, "Bitdepths do not match in CopyToFace()" );
return;
}
if( fFlags != mip->GetFlags() )
{
hsAssert( false, "Flags do not match in CopyToFace()" );
}
}
// Copy the mipmap data
fFaces[ face ]->CopyFrom( mip );
}

View File

@ -0,0 +1,114 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// plCubicEnvironmap Class Header //
// Derived bitmap class representing a collection of mipmaps to be used for //
// cubic environment mapping. //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 6.7.2001 mcn - Created. //
// //
///////////////////////////////////////////////////////////////////////////////
#ifndef _plCubicEnvironmap_h
#define _plCubicEnvironmap_h
#include "plBitmap.h"
class plMipmap;
//// Class Definition /////////////////////////////////////////////////////////
class plCubicEnvironmap : public plBitmap
{
public:
//// Public Data ////
enum Faces
{
kLeftFace = 0,
kRightFace,
kFrontFace,
kBackFace,
kTopFace,
kBottomFace
};
//// Public Members ////
plCubicEnvironmap();
virtual ~plCubicEnvironmap();
CLASSNAME_REGISTER( plCubicEnvironmap );
GETINTERFACE_ANY( plCubicEnvironmap, plBitmap );
// Get the total size in bytes
virtual UInt32 GetTotalSize( void ) const;
virtual void Read( hsStream *s, hsResMgr *mgr ) { hsKeyedObject::Read( s, mgr ); this->Read( s ); }
virtual void Write( hsStream *s, hsResMgr *mgr ) { hsKeyedObject::Write( s, mgr ); this->Write( s ); }
plMipmap *GetFace( UInt8 face ) const { return fFaces[ face ]; }
// Export-only: Copy the mipmap given into a face
void CopyToFace( plMipmap *mip, UInt8 face );
protected:
//// Protected Members ////
plMipmap *fFaces[ 6 ];
hsBool fInitialized;
virtual UInt32 Read( hsStream *s );
virtual UInt32 Write( hsStream *s );
};
#endif // plCubicEnvironmap_h

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,221 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// plDynSurfaceWriter Class Header //
// Abstract class wrapping around Windows GDI functionality for writing to //
// a generic RGBA surface. Allows us to create one writer per DTMap or a //
// single shared writer to conserve OS resources on 98/ME. //
// //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 10.28.2002 mcn - Created. //
// //
///////////////////////////////////////////////////////////////////////////////
#ifndef _plDynSurfaceWriter_h
#define _plDynSurfaceWriter_h
#include "hsColorRGBA.h"
#include "hsWindows.h" // EVIL
struct hsMatrix44;
class plDynamicTextMap;
//// Class Definition /////////////////////////////////////////////////////////
class plDynSurfaceWriter
{
public:
//// Public Flags ////
enum Justify
{
kLeftJustify = 0,
kCenter,
kRightJustify
};
enum Flags
{
kSupportAlpha = 0x00000001,
kFontBold = 0x00000002,
kFontItalic = 0x00000004,
kFontShadowed = 0x00000008,
kFontMask = 0x0000000e,
kDiscardOnFlush = 0x00000010
};
//// Public Data /////
//// Public Members ////
plDynSurfaceWriter();
plDynSurfaceWriter( plDynamicTextMap *target, UInt32 flags = 0 );
virtual ~plDynSurfaceWriter();
/// Operations to perform on the text block
void ClearToColor( hsColorRGBA &color );
void SetFont( const char *face, UInt16 size, UInt8 fontFlags = 0, hsBool antiAliasRGB = true );
void SetTextColor( hsColorRGBA &color, hsBool blockRGB = false );
void SetJustify( Justify j );
void DrawString( UInt16 x, UInt16 y, const char *text );
void DrawClippedString( Int16 x, Int16 y, const char *text, UInt16 width, UInt16 height );
void DrawClippedString( Int16 x, Int16 y, const char *text, UInt16 clipX, UInt16 clipY, UInt16 width, UInt16 height );
void DrawWrappedString( UInt16 x, UInt16 y, const char *text, UInt16 width, UInt16 height );
UInt16 CalcStringWidth( const char *text, UInt16 *height = nil );
void CalcWrappedStringSize( const char *text, UInt16 *width, UInt16 *height );
void FillRect( UInt16 x, UInt16 y, UInt16 width, UInt16 height, hsColorRGBA &color );
void FrameRect( UInt16 x, UInt16 y, UInt16 width, UInt16 height, hsColorRGBA &color );
// void DrawImage( UInt16 x, UInt16 y, plMipmap *image, hsBool respectAlpha = false );
// void DrawClippedImage( UInt16 x, UInt16 y, plMipmap *image, UInt16 srcClipX, UInt16 srcClipY,
// UInt16 srcClipWidth, UInt16 srcClipHeight, hsBool respectAlpha = false );
// Copy the raw data from the given buffer.
// void SetBitsFromBuffer( UInt32 *clearBuffer, UInt16 width, UInt16 height )
/// Target switching operations
// Flushes all ops to the target.
void FlushToTarget( void );
// Switches targets. Will flush to old target before switching. Also, if kDiscard isn't specified, will copy contents of new target to working surface
void SwitchTarget( plDynamicTextMap *target ); // Will force a flush
// Clears and resets everything. Does NOT flush.
void Reset( void );
hsBool IsValid( void ) const;
static hsBool CanHandleLotsOfThem( void );
protected:
//// Protected Members ////
void IInit( void );
void IEnsureSurfaceUpdated( void );
void IRefreshOSJustify( void );
void ISetTextColor( hsColorRGBA &color, hsBool blockRGB );
void ISetFont( const char *face, UInt16 size, UInt8 fontFlags = 0, hsBool antiAliasRGB = true );
plDynamicTextMap *fCurrTarget;
UInt32 fFlags;
Justify fJustify;
hsBool fFlushed;
char *fFontFace;
UInt16 fFontSize;
UInt8 fFontFlags;
hsBool fFontAntiAliasRGB;
hsBool fFontBlockedRGB;
static hsBool fForceSharedSurfaces;
static hsBool fOSDetected;
static hsBool fOSCanShareSurfaces;
#if HS_BUILD_FOR_WIN32
class plWinSurface
{
protected:
void *fBits;
virtual UInt8 IBitsPerPixel( void ) const = 0;
public:
HDC fDC;
HBITMAP fBitmap;
HFONT fFont;
COLORREF fTextColor;
int fSaveNum;
UInt16 fWidth, fHeight;
char *fFontFace;
UInt16 fFontSize;
UInt8 fFontFlags;
hsBool fFontAntiAliasRGB, fFontBlockedRGB;
plWinSurface();
~plWinSurface();
void Allocate( UInt16 w, UInt16 h );
void Release( void );
hsBool WillFit( UInt16 w, UInt16 h );
hsBool FontMatches( const char *face, UInt16 size, UInt8 flags, hsBool aaRGB );
void SetFont( const char *face, UInt16 size, UInt8 flags, hsBool aaRGB );
};
class plWinRGBSurface : public plWinSurface
{
virtual UInt8 IBitsPerPixel( void ) const { return 32; }
public:
UInt32 *GetBits( void ) const { return (UInt32 *)fBits; }
};
class plWinAlphaSurface : public plWinSurface
{
virtual UInt8 IBitsPerPixel( void ) const { return 8; }
public:
UInt8 *GetBits( void ) const { return (UInt8 *)fBits; }
};
plWinRGBSurface fRGBSurface;
plWinAlphaSurface fAlphaSurface;
#endif
};
#endif // _plDynSurfaceWriter_h

View File

@ -0,0 +1,933 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// plDynamicTextMap Class Functions //
// Derived bitmap class representing a single mipmap. //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 6.7.2001 mcn - Created. //
// //
///////////////////////////////////////////////////////////////////////////////
#include "hsTypes.h"
#include "plDynamicTextMap.h"
#include "hsStream.h"
#include "hsExceptions.h"
#include "hsUtils.h"
#include "hsMatrix44.h"
#include "../plPipeline/hsGDeviceRef.h"
#include "../plMessage/plDynamicTextMsg.h"
#include "../pnKeyedObject/plKey.h"
#include "plProfile.h"
#include "../plStatusLog/plStatusLog.h"
#include "plFont.h"
#include "plFontCache.h"
#include "../plResMgr/plLocalization.h"
plProfile_CreateMemCounter("DynaTextMem", "PipeC", DynaTextMem);
plProfile_CreateCounterNoReset("DynaTexts", "PipeC", DynaTexts);
plProfile_Extern(MemMipmaps);
//// Constructor & Destructor /////////////////////////////////////////////////
plDynamicTextMap::plDynamicTextMap()
: fVisWidth(0), fVisHeight(0), fHasAlpha(false), fPremultipliedAlpha(false), fJustify(kLeftJustify),
fInitBuffer(nil), fFontFace(nil), fFontSize(0), fFontFlags(0),
fFontAntiAliasRGB(false), fFontBlockRGB(false), fHasCreateBeenCalled(false)
{
fFontColor.Set(0, 0, 0, 1);
}
plDynamicTextMap::~plDynamicTextMap()
{
Reset();
}
plDynamicTextMap::plDynamicTextMap( UInt32 width, UInt32 height, hsBool hasAlpha, UInt32 extraWidth, UInt32 extraHeight, hsBool premultipliedAlpha )
: fInitBuffer(nil), fFontFace(nil)
{
Create( width, height, hasAlpha, extraWidth, extraHeight, premultipliedAlpha );
}
//// SetNoCreate //////////////////////////////////////////////////////////////
// For export time, we want to set up the config to write to disk, but we
// don't want to actually be creating OS surfaces. So we call this function
// instead, which does just that. It basically does all the setup work that
// Create() does, or enough for us to write out later.
void plDynamicTextMap::SetNoCreate( UInt32 width, UInt32 height, hsBool hasAlpha )
{
// OK, so it really isn't that much work...
fVisWidth = (UInt16)width;
fVisHeight = (UInt16)height;
fHasAlpha = hasAlpha;
fImage = nil; // So we know we haven't actually done anything yet
delete [] fInitBuffer;
fInitBuffer = nil;
}
//// Create ///////////////////////////////////////////////////////////////////
void plDynamicTextMap::Create( UInt32 width, UInt32 height, hsBool hasAlpha, UInt32 extraWidth, UInt32 extraHeight, hsBool premultipliedAlpha )
{
SetConfig( hasAlpha ? kARGB32Config : kRGB32Config );
fVisWidth = (UInt16)width;
fVisHeight = (UInt16)height;
fHasAlpha = hasAlpha;
fPremultipliedAlpha = premultipliedAlpha;
for( fWidth = 1; fWidth < width + extraWidth; fWidth <<= 1 );
for( fHeight = 1; fHeight < height + extraHeight; fHeight <<= 1 );
// instead of allocating the fImage here, we'll wait for the first draw operation to be called (in IIsValid)
fHasCreateBeenCalled = true;
fRowBytes = fWidth << 2;
fNumLevels = 1;
fFlags |= plMipmap::kDontThrowAwayImage;
fCompressionType = plMipmap::kUncompressed;
fUncompressedInfo.fType = plMipmap::UncompressedInfo::kRGB8888;
// Destroy the old texture ref, if we have one. This should force the
// pipeline to recreate one more suitable for our use
SetDeviceRef( nil );
// Some init color
SetFont( "Arial", 12 );
hsColorRGBA color;
color.Set( 0,0,1,1);
SetTextColor( color );
SetCurrLevel( 0 );
plProfile_Inc(DynaTexts);
}
//// Reset ////////////////////////////////////////////////////////////////////
void plDynamicTextMap::Reset( void )
{
IDestroyOSSurface();
plMipmap::Reset();
// they need to call create again to undo the affects of call Reset()
fHasCreateBeenCalled = false;
delete [] fInitBuffer;
fInitBuffer = nil;
delete [] fFontFace;
fFontFace = nil;
// Destroy the old texture ref, since we're no longer using it
SetDeviceRef( nil );
}
///////////////////////////////////////////////////////////////////////////////
//// OS-Specific Functions ////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
hsBool plDynamicTextMap::IIsValid( void )
{
if( GetImage() == nil && fHasCreateBeenCalled )
{
// we are going to allocate the fImage at this point... when someone is looking for it
fImage = (void *)IAllocateOSSurface( (UInt16)fWidth, (UInt16)fHeight );
hsColorRGBA color;
if( fInitBuffer != nil )
{
IClearFromBuffer( fInitBuffer );
}
else
{
color.Set( 0.f, 0.f, 0.f, 1.f );
ClearToColor( color );
FlushToHost();
}
IBuildLevelSizes();
fTotalSize = GetLevelSize( 0 );
SetCurrLevel( 0 );
// Destroy the old texture ref, if we have one. This should force the
// pipeline to recreate one more suitable for our use
SetDeviceRef( nil );
plProfile_NewMem(MemMipmaps, fTotalSize);
plProfile_NewMem(DynaTextMem, fTotalSize);
#ifdef MEMORY_LEAK_TRACER
IAddToMemRecord( this, plRecord::kViaCreate );
#endif
}
if( GetImage() == nil )
return false;
return true;//fWriter->IsValid();
}
// allow the user of the DynaTextMap that they are done with the image... for now
// ... the fImage will be re-created on the next operation that requires the image
void plDynamicTextMap::PurgeImage()
{
IDestroyOSSurface();
fTotalSize = 0;
SetCurrLevel( 0 );
// Destroy the old texture ref, if we have one. This should force the
// pipeline to recreate one more suitable for our use
SetDeviceRef( nil );
}
//// IAllocateOSSurface ///////////////////////////////////////////////////////
// OS-specific. Allocates a rectangular bitmap of the given dimensions that
// the OS can draw text into. Returns a pointer to the pixels.
UInt32* plDynamicTextMap::IAllocateOSSurface( UInt16 width, UInt16 height )
{
UInt32* pixels = TRACKED_NEW UInt32[ width * height ];
return pixels;
}
//// IDestroyOSSurface ////////////////////////////////////////////////////////
// Opposite of allocate. DUH!
void plDynamicTextMap::IDestroyOSSurface( void )
{
#ifdef MEMORY_LEAK_TRACER
if( fImage != nil )
IRemoveFromMemRecord( (UInt8 *)fImage );
#endif
delete [] fImage;
fImage = nil;
plProfile_Dec(DynaTexts);
plProfile_DelMem(DynaTextMem, fTotalSize);
plProfile_DelMem(MemMipmaps, fTotalSize);
}
///////////////////////////////////////////////////////////////////////////////
//// Virtual Functions ////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//// Read /////////////////////////////////////////////////////////////////////
UInt32 plDynamicTextMap::Read( hsStream *s )
{
UInt32 totalRead = plBitmap::Read( s );
// The funny thing is that we don't read anything like a mipmap; we just
// keep the width and height and call Create() after we read those in
fVisWidth = (UInt16)(s->ReadSwap32());
fVisHeight = (UInt16)(s->ReadSwap32());
fHasAlpha = s->ReadBool();
totalRead += 2 * 4;
UInt32 initSize = s->ReadSwap32();
totalRead += 4;
if( initSize > 0 )
{
fInitBuffer = TRACKED_NEW UInt32[ initSize ];
s->ReadSwap32( initSize, fInitBuffer );
totalRead += initSize * 4;
}
else
fInitBuffer = nil;
Create( fVisWidth, fVisHeight, fHasAlpha );
delete [] fInitBuffer;
fInitBuffer = nil;
return totalRead;
}
//// Write ////////////////////////////////////////////////////////////////////
UInt32 plDynamicTextMap::Write( hsStream *s )
{
UInt32 totalWritten = plBitmap::Write( s );
s->WriteSwap32( fVisWidth );
s->WriteSwap32( fVisHeight );
s->WriteBool( fHasAlpha );
s->WriteSwap32( fInitBuffer != nil ? fVisWidth * fVisHeight * sizeof( UInt32 ) : 0 );
if( fInitBuffer != nil )
{
s->WriteSwap32( fVisWidth * fVisHeight, fInitBuffer );
}
return totalWritten;
}
///////////////////////////////////////////////////////////////////////////////
//// Some More Functions //////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//// SetInitBuffer ////////////////////////////////////////////////////////////
// Sets an initial buffer, which is written to disk and read in to use for
// initializing the color buffer upon creation. If not specified, we init to
// black. ASSUMES the buffer is of dimensions fVisWidth x fVisHeight.
void plDynamicTextMap::SetInitBuffer( UInt32 *buffer )
{
delete [] fInitBuffer;
if( buffer == nil )
{
fInitBuffer = nil;
return;
}
fInitBuffer = TRACKED_NEW UInt32[ fVisWidth * fVisHeight ];
memcpy( fInitBuffer, buffer, fVisWidth * fVisHeight * sizeof( UInt32 ) );
}
//// CopyFrom /////////////////////////////////////////////////////////////////
void plDynamicTextMap::CopyFrom( plMipmap *source )
{
hsAssert( false, "Copying plDynamicTextMaps is not supported." );
}
//// Clone ////////////////////////////////////////////////////////////////////
plMipmap *plDynamicTextMap::Clone( void )
{
static bool alreadyWarned = false;
if( !alreadyWarned )
{
hsAssert( false, "Cloning plDynamicTextMaps is not supported." );
alreadyWarned = true;
}
return nil;
}
///////////////////////////////////////////////////////////////////////////////
//// Rendering Functions //////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//// IClearFromBuffer /////////////////////////////////////////////////////////
void plDynamicTextMap::IClearFromBuffer( UInt32 *clearBuffer )
{
int y;
UInt32 *data = (UInt32 *)fImage, *srcData = clearBuffer;
UInt8 *destAlpha = nil;
if( !IIsValid() )
return;
// Clear *all* to zero
memset( data, 0, fWidth * fHeight * sizeof( UInt32 ) );
// Buffer is of size fVisWidth x fVisHeight, so we need a bit of work to do this right
for( y = 0; y < fVisHeight; y++ )
{
memcpy( data, srcData, fVisWidth * sizeof( UInt32 ) );
data += fWidth;
srcData += fVisWidth;
}
}
//// IPropagateFlags //////////////////////////////////////////////////////////
void plDynamicTextMap::IPropagateFlags()
{
SetJustify(fJustify);
fCurrFont->SetRenderFlag(plFont::kRenderShadow, fFontFlags & kFontShadowed);
fCurrFont->SetRenderFlag(plFont::kRenderIntoAlpha, fFontBlockRGB);
fCurrFont->SetRenderFlag(plFont::kRenderAlphaPremultiplied, fPremultipliedAlpha);
fCurrFont->SetRenderColor(fFontColor.ToARGB32());
}
//// ClearToColor /////////////////////////////////////////////////////////////
void plDynamicTextMap::ClearToColor( hsColorRGBA &color )
{
if( !IIsValid() )
return;
UInt32 i, hex = fPremultipliedAlpha ? color.ToARGB32Premultiplied() : color.ToARGB32();
UInt32 *data = (UInt32 *)fImage;
// Buffer is of size fVisWidth x fVisHeight, so we need a bit of work to do this right
for( i = 0; i < fHeight * fWidth; i++ )
data[ i ] = hex;
}
//// SetJustify ///////////////////////////////////////////////////////////////
void plDynamicTextMap::SetJustify( Justify j )
{
// ===> Don't need to validate creation
// if( !IIsValid() )
// return;
fJustify = j;
switch( fJustify )
{
case kLeftJustify: fCurrFont->SetRenderXJustify( plFont::kRenderJustXForceLeft ); break;
case kCenter: fCurrFont->SetRenderXJustify( plFont::kRenderJustXCenter ); break;
case kRightJustify: fCurrFont->SetRenderXJustify( plFont::kRenderJustXRight ); break;
}
}
//// SetFont //////////////////////////////////////////////////////////////////
void plDynamicTextMap::SetFont( const char *face, UInt16 size, UInt8 fontFlags, hsBool antiAliasRGB )
{
// ===> Don't need to validate creation
// if( !IIsValid() )
// return;
delete [] fFontFace;
if (plLocalization::UsingUnicode())
{
// unicode has a bunch of chars that most fonts don't have, so we override the font choice with one
// that will work with the desired language
hsStatusMessageF("We are using a unicode language, overriding font choice of %s", face ? face : "nil");
fFontFace = hsStrcpy( "Unicode" );
}
else
fFontFace = ( face != nil ) ? hsStrcpy( face ) : nil;
fFontSize = size;
fFontFlags = fontFlags;
fFontAntiAliasRGB = antiAliasRGB;
fCurrFont = plFontCache::GetInstance().GetFont( fFontFace, (UInt8)fFontSize,
( ( fFontFlags & kFontBold ) ? plFont::kFlagBold : 0 ) |
( ( fFontFlags & kFontItalic ) ? plFont::kFlagItalic : 0 ) );
if ( fCurrFont == nil )
{
if (!fCurrFont)
hsStatusMessageF("Font missing - %s. Using Arial", fFontFace ? fFontFace : "nil");
if ( fFontFace )
delete [] fFontFace;
fFontFace = hsStrcpy( "Arial" );
// lets try again with Arial
fCurrFont = plFontCache::GetInstance().GetFont( fFontFace, (UInt8)fFontSize,
( ( fFontFlags & kFontBold ) ? plFont::kFlagBold : 0 ) |
( ( fFontFlags & kFontItalic ) ? plFont::kFlagItalic : 0 ) );
}
// This will be nil if we're just running the page optimizer.
if (fCurrFont)
{
if (fFontFlags & kFontShadowed)
fCurrFont->SetRenderFlag(plFont::kRenderShadow, true);
fCurrFont->SetRenderYJustify( plFont::kRenderJustYTop );
SetJustify( fJustify );
}
}
void plDynamicTextMap::SetFont( const wchar_t *face, UInt16 size, UInt8 fontFlags , hsBool antiAliasRGB )
{
char *sFace = hsWStringToString(face);
SetFont(sFace,size,fontFlags,antiAliasRGB);
delete [] sFace;
}
//// SetLineSpacing ///////////////////////////////////////////////////////////
void plDynamicTextMap::SetLineSpacing( Int16 spacing )
{
// ===> Don't need to validate creation
// if( !IIsValid() )
// return;
fLineSpacing = spacing;
fCurrFont->SetRenderLineSpacing(spacing);
}
//// SetTextColor /////////////////////////////////////////////////////////////
void plDynamicTextMap::SetTextColor( hsColorRGBA &color, hsBool blockRGB )
{
// ===> Don't need to validate creation
// if( !IIsValid() )
// return;
fFontColor = color;
fFontBlockRGB = blockRGB;
if (fCurrFont)
fCurrFont->SetRenderColor( fFontColor.ToARGB32() );
}
//// DrawString ///////////////////////////////////////////////////////////////
void plDynamicTextMap::DrawString( UInt16 x, UInt16 y, const char *text )
{
wchar_t *wText = hsStringToWString(text);
DrawString(x,y,wText);
delete [] wText;
}
void plDynamicTextMap::DrawString( UInt16 x, UInt16 y, const wchar_t *text )
{
if( !IIsValid() )
return;
IPropagateFlags();
fCurrFont->SetRenderFlag( plFont::kRenderWrap | plFont::kRenderClip, false );
fCurrFont->SetRenderClipRect( 0, 0, fVisWidth, fVisHeight );
fCurrFont->RenderString( this, x, y, text );
}
//// DrawClippedString ////////////////////////////////////////////////////////
void plDynamicTextMap::DrawClippedString( Int16 x, Int16 y, const char *text, UInt16 width, UInt16 height )
{
wchar_t *wText = hsStringToWString(text);
DrawClippedString(x,y,wText,width,height);
delete [] wText;
}
void plDynamicTextMap::DrawClippedString( Int16 x, Int16 y, const wchar_t *text, UInt16 width, UInt16 height )
{
if( !IIsValid() )
return;
IPropagateFlags();
fCurrFont->SetRenderClipping( x, y, width, height );
fCurrFont->RenderString( this, x, y, text );
}
//// DrawClippedString ////////////////////////////////////////////////////////
void plDynamicTextMap::DrawClippedString( Int16 x, Int16 y, const char *text, UInt16 clipX, UInt16 clipY, UInt16 width, UInt16 height )
{
wchar_t *wText = hsStringToWString(text);
DrawClippedString(x,y,wText,clipX,clipY,width,height);
delete [] wText;
}
void plDynamicTextMap::DrawClippedString( Int16 x, Int16 y, const wchar_t *text, UInt16 clipX, UInt16 clipY, UInt16 width, UInt16 height )
{
if( !IIsValid() )
return;
IPropagateFlags();
fCurrFont->SetRenderClipping( clipX, clipY, width, height );
fCurrFont->RenderString( this, x, y, text );
}
//// DrawWrappedString ////////////////////////////////////////////////////////
void plDynamicTextMap::DrawWrappedString( UInt16 x, UInt16 y, const char *text, UInt16 width, UInt16 height, UInt16 *lastX, UInt16 *lastY )
{
wchar_t *wText = hsStringToWString(text);
DrawWrappedString(x,y,wText,width,height,lastX,lastY);
delete [] wText;
}
void plDynamicTextMap::DrawWrappedString( UInt16 x, UInt16 y, const wchar_t *text, UInt16 width, UInt16 height, UInt16 *lastX, UInt16 *lastY )
{
if( !IIsValid() )
return;
IPropagateFlags();
fCurrFont->SetRenderWrapping( x, y, width, height );
fCurrFont->RenderString( this, x, y, text, lastX, lastY );
}
//// CalcStringWidth //////////////////////////////////////////////////////////
UInt16 plDynamicTextMap::CalcStringWidth( const char *text, UInt16 *height )
{
wchar_t *wText = hsStringToWString(text);
UInt16 w = CalcStringWidth(wText,height);
delete [] wText;
return w;
}
UInt16 plDynamicTextMap::CalcStringWidth( const wchar_t *text, UInt16 *height )
{
// ===> Don't need to validate creation
// if( !IIsValid() )
// return 0;
SetJustify( fJustify );
UInt16 w, h, a, lastX, lastY;
UInt32 firstClipped;
fCurrFont->SetRenderFlag( plFont::kRenderClip | plFont::kRenderWrap, false );
fCurrFont->CalcStringExtents( text, w, h, a, firstClipped, lastX, lastY );
if( height != nil )
*height = h;
return w;
}
//// SetFirstLineIndent ///////////////////////////////////////////////////////
void plDynamicTextMap::SetFirstLineIndent( Int16 indent )
{
// ===> Don't need to validate creation
// if( !IIsValid() )
// return;
fCurrFont->SetRenderFirstLineIndent( indent );
}
//// CalcWrappedStringSize ////////////////////////////////////////////////////
void plDynamicTextMap::CalcWrappedStringSize( const char *text, UInt16 *width, UInt16 *height, UInt32 *firstClippedChar, UInt16 *maxAscent, UInt16 *lastX, UInt16 *lastY )
{
wchar_t *wText = hsStringToWString(text);
CalcWrappedStringSize(wText,width,height,firstClippedChar,maxAscent,lastX,lastY);
delete [] wText;
}
void plDynamicTextMap::CalcWrappedStringSize( const wchar_t *text, UInt16 *width, UInt16 *height, UInt32 *firstClippedChar, UInt16 *maxAscent, UInt16 *lastX, UInt16 *lastY )
{
// ===> Don't need to validate creation
// if( !IIsValid() )
// return;
SetJustify( fJustify );
UInt16 w, h, a, lX, lY;
UInt32 firstClipped;
fCurrFont->SetRenderWrapping( 0, 0, *width, *height );
fCurrFont->CalcStringExtents( text, w, h, a, firstClipped, lX, lY );
*width = w;
*height = h;
if( firstClippedChar != nil )
*firstClippedChar = firstClipped;
if( maxAscent != nil )
*maxAscent = a;
if( lastX != nil )
*lastX = lX;
if( lastY != nil )
*lastY = lY;
}
//// FillRect /////////////////////////////////////////////////////////////////
void plDynamicTextMap::FillRect( UInt16 x, UInt16 y, UInt16 width, UInt16 height, hsColorRGBA &color )
{
if( !IIsValid() )
return;
if( x + width > fWidth )
width = (UInt16)(fWidth - x);
// Gee, how hard can it REALLY be?
UInt32 i, hex = fPremultipliedAlpha ? color.ToARGB32Premultiplied() : color.ToARGB32();
height += y;
if( height > fHeight )
height = (UInt16)fHeight;
for( ; y < height; y++ )
{
UInt32 *destPtr = GetAddr32( x, y );
for( i = 0; i < width; i++ )
destPtr[ i ] = hex;
}
}
//// FrameRect ////////////////////////////////////////////////////////////////
void plDynamicTextMap::FrameRect( UInt16 x, UInt16 y, UInt16 width, UInt16 height, hsColorRGBA &color )
{
if( !IIsValid() )
return;
if( x + width > fWidth )
width = (UInt16)(fWidth - x);
if( y + height > fHeight )
height = (UInt16)(fHeight - y);
// Shouldn't be much harder
UInt32 i, hex = fPremultipliedAlpha ? color.ToARGB32Premultiplied() : color.ToARGB32();
UInt32 *dest1, *dest2;
dest1 = GetAddr32( x, y );
dest2 = GetAddr32( x, y + height - 1 );
for( i = 0; i < width; i++ )
dest1[ i ] = dest2[ i ] = hex;
for( i = 0; i < height; i++ )
{
dest1[ 0 ] = dest1[ width - 1 ] = hex;
dest1 += fWidth;
}
}
//// DrawImage ////////////////////////////////////////////////////////////////
void plDynamicTextMap::DrawImage( UInt16 x, UInt16 y, plMipmap *image, DrawMethods method )
{
if( !IIsValid() )
return;
plMipmap::CompositeOptions opts;
if( method == kImgNoAlpha )
{
if( fHasAlpha )
opts.fFlags = plMipmap::kForceOpaque;
else
opts.fFlags = plMipmap::kCopySrcAlpha; // Don't care, this is fastest
}
else if( method == kImgBlend )
opts.fFlags = 0; // Default opts
else if( method == kImgSprite )
opts.fFlags = plMipmap::kCopySrcAlpha;
if( fPremultipliedAlpha )
opts.fFlags |= plMipmap::kDestPremultiplied;
Composite( image, x, y, &opts );
/// HACK for now, since the alpha in the mipmap gets copied straight into the
/// 32-bit color buffer, but our separate hacked alpha buffer hasn't been updated
/* if( fHasAlpha && !respectAlpha )
{
HBRUSH brush = ::CreateSolidBrush( RGB( 255, 255, 255 ) );
RECT rc;
::SetRect( &rc, x, y, x + image->GetWidth(), y + image->GetHeight() );
::FillRect( fWinAlphaDC, &rc, brush );
::DeleteObject( brush );
}
*/
}
//// DrawClippedImage /////////////////////////////////////////////////////////
void plDynamicTextMap::DrawClippedImage( UInt16 x, UInt16 y, plMipmap *image,
UInt16 srcClipX, UInt16 srcClipY,
UInt16 srcClipWidth, UInt16 srcClipHeight,
DrawMethods method )
{
if( !IIsValid() )
return;
plMipmap::CompositeOptions opts;
if( method == kImgNoAlpha )
{
if( fHasAlpha )
opts.fFlags = plMipmap::kForceOpaque;
else
opts.fFlags = plMipmap::kCopySrcAlpha; // Don't care, this is fastest
}
else if( method == kImgBlend )
opts.fFlags = 0; // Default opts
else if( method == kImgSprite )
opts.fFlags = plMipmap::kCopySrcAlpha;
if( fPremultipliedAlpha )
opts.fFlags |= plMipmap::kDestPremultiplied;
opts.fSrcClipX = srcClipX;
opts.fSrcClipY = srcClipY;
opts.fSrcClipWidth = srcClipWidth;
opts.fSrcClipHeight = srcClipHeight;
Composite( image, x, y, &opts );
/// HACK for now, since the alpha in the mipmap gets copied straight into the
/// 32-bit color buffer, but our separate hacked alpha buffer hasn't been updated
/* if( fHasAlpha && !respectAlpha )
{
HBRUSH brush = ::CreateSolidBrush( RGB( 255, 255, 255 ) );
RECT rc;
::SetRect( &rc, x, y, x + ( srcClipWidth > 0 ? srcClipWidth : image->GetWidth() ),
y + ( srcClipHeight > 0 ? srcClipHeight : image->GetHeight() ) );
::FillRect( fWinAlphaDC, &rc, brush );
::DeleteObject( brush );
}
*/
}
//// FlushToHost //////////////////////////////////////////////////////////////
void plDynamicTextMap::FlushToHost( void )
{
if( !IIsValid() )
return;
// Dirty the mipmap's deviceRef, if there is one
if( GetDeviceRef() != nil )
GetDeviceRef()->SetDirty( true );
}
//// GetLayerTransform ////////////////////////////////////////////////////////
// Since the textGen can actually create a texture bigger than you were expecting,
// you want to be able to apply a layer texture transform that will compensate. This
// function will give you that transform. Just feed it into plLayer->SetTransform().
hsMatrix44 plDynamicTextMap::GetLayerTransform( void )
{
hsMatrix44 xform;
hsVector3 scale;
scale.Set( (float)GetVisibleWidth() / (float)GetWidth(),
(float)GetVisibleHeight() / (float)GetHeight(), 1.f );
xform.MakeScaleMat( &scale );
return xform;
}
//// MsgReceive ///////////////////////////////////////////////////////////////
hsBool plDynamicTextMap::MsgReceive( plMessage *msg )
{
plDynamicTextMsg *textMsg = plDynamicTextMsg::ConvertNoRef( msg );
if( textMsg != nil )
{
if( textMsg->fCmd & plDynamicTextMsg::kClear )
ClearToColor( textMsg->fClearColor );
if( textMsg->fCmd & plDynamicTextMsg::kSetTextColor )
SetTextColor( textMsg->fColor, textMsg->fBlockRGB );
if( (textMsg->fCmd & plDynamicTextMsg::kSetFont ) && textMsg->fString)
SetFont( textMsg->fString, textMsg->fX, (UInt8)(textMsg->fFlags) );
if( textMsg->fCmd & plDynamicTextMsg::kSetLineSpacing )
SetLineSpacing( textMsg->fLineSpacing );
if( textMsg->fCmd & plDynamicTextMsg::kSetJustify )
SetJustify( (Justify)textMsg->fFlags );
if( textMsg->fCmd & plDynamicTextMsg::kFillRect )
FillRect( textMsg->fLeft, textMsg->fTop, textMsg->fRight - textMsg->fLeft + 1,
textMsg->fBottom - textMsg->fTop + 1, textMsg->fColor );
if( textMsg->fCmd & plDynamicTextMsg::kFrameRect )
FrameRect( textMsg->fLeft, textMsg->fTop, textMsg->fRight - textMsg->fLeft + 1,
textMsg->fBottom - textMsg->fTop + 1, textMsg->fColor );
if( (textMsg->fCmd & plDynamicTextMsg::kDrawString ) && textMsg->fString)
DrawString( textMsg->fX, textMsg->fY, textMsg->fString );
if( (textMsg->fCmd & plDynamicTextMsg::kDrawClippedString ) && textMsg->fString)
DrawClippedString( textMsg->fX, textMsg->fY, textMsg->fString,
textMsg->fLeft, textMsg->fTop, textMsg->fRight - textMsg->fLeft + 1,
textMsg->fBottom - textMsg->fTop + 1 );
if( (textMsg->fCmd & plDynamicTextMsg::kDrawWrappedString ) && textMsg->fString)
DrawWrappedString( textMsg->fX, textMsg->fY, textMsg->fString, textMsg->fRight, textMsg->fBottom );
if( textMsg->fCmd & plDynamicTextMsg::kDrawImage )
{
plMipmap *mip = plMipmap::ConvertNoRef( textMsg->fImageKey ? textMsg->fImageKey->ObjectIsLoaded() : nil);
if( mip != nil )
DrawImage( textMsg->fX, textMsg->fY, mip, textMsg->fFlags ? kImgBlend : kImgNoAlpha );
}
if( textMsg->fCmd & plDynamicTextMsg::kDrawClippedImage )
{
plMipmap *mip = plMipmap::ConvertNoRef( textMsg->fImageKey ? textMsg->fImageKey->ObjectIsLoaded() : nil);
if( mip != nil )
DrawClippedImage( textMsg->fX, textMsg->fY, mip, textMsg->fLeft, textMsg->fTop,
textMsg->fRight, textMsg->fBottom, textMsg->fFlags ? kImgBlend : kImgNoAlpha );
}
if( textMsg->fCmd & plDynamicTextMsg::kFlush )
FlushToHost();
if( textMsg->fCmd & plDynamicTextMsg::kPurgeImage )
PurgeImage();
return true;
}
return plMipmap::MsgReceive( msg );
}
//// Swap /////////////////////////////////////////////////////////////////////
// Swapping is an evil little trick. It's also something that should probably
// be exposed at the mipmap level eventually, but there's no need for it yet.
// Basically, it lets you take the contents of two DTMaps and swap them, as
// if you had swapped pointers, but you didn't. This is so you can, well, swap
// DTMaps without swapping pointers! (Like, say, you don't have access to them)
#define SWAP_ME( Type, a, b ) { Type temp; temp = a; a = b; b = temp; }
void plDynamicTextMap::Swap( plDynamicTextMap *other )
{
// We only do this if the two are the same size, color depth, etc
if( other->GetWidth() != GetWidth() || other->GetHeight() != GetHeight() ||
other->GetPixelSize() != GetPixelSize() )
return;
// Swap image pointers
void *ptr = other->fImage;
other->fImage = fImage;
fImage = ptr;
// Invalidate both device refs (don't risk swapping THOSE)
if( GetDeviceRef() != nil )
GetDeviceRef()->SetDirty( true );
if( other->GetDeviceRef() != nil )
other->GetDeviceRef()->SetDirty( true );
// Swap DTMap info
SWAP_ME( hsBool, fHasAlpha, other->fHasAlpha );
SWAP_ME( hsBool, fPremultipliedAlpha, other->fPremultipliedAlpha );
SWAP_ME( hsBool, fShadowed, other->fShadowed );
SWAP_ME( Justify, fJustify, other->fJustify );
SWAP_ME( char *, fFontFace, other->fFontFace );
SWAP_ME( UInt16, fFontSize, other->fFontSize );
SWAP_ME( UInt8, fFontFlags, other->fFontFlags );
SWAP_ME( hsBool, fFontAntiAliasRGB, other->fFontAntiAliasRGB );
SWAP_ME( hsColorRGBA, fFontColor, other->fFontColor );
SWAP_ME( hsBool, fFontBlockRGB, other->fFontBlockRGB );
SWAP_ME( hsBool, fFontBlockRGB, other->fFontBlockRGB );
SWAP_ME( hsBool, fFontBlockRGB, other->fFontBlockRGB );
SWAP_ME( hsBool, fFontBlockRGB, other->fFontBlockRGB );
SWAP_ME( plFont *, fCurrFont, other->fCurrFont );
SWAP_ME( UInt32 *, fInitBuffer, other->fInitBuffer );
}

View File

@ -0,0 +1,246 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// plDynamicTextMap Class Header //
// I derived from plMipmap not because I inherit a lot of the functionality,//
// but because this acts very very much like a mipmap with one mip level. //
// The only difference is that the actual data gets generated on the fly, //
// instead of converted at export time. However, to the outside world, //
// we're just a plain old mipmap, and I'd like to keep it that way. //
// //
// Note that we are also of a fixed format--ARGB8888. Keeps things nice and //
// simple that way. //
// //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 1.14.2002 mcn - Created. //
// 10.28.2002 mcn - Changing the arrangement a bit. Now we have a single //
// writable "creation" surface that actually generates //
// data, which then copies out on a flush to the actual //
// mipmap data. This is slower because it requires two //
// copies (second one when we prepare to write to a new //
// surface, unless kDiscard is specified as a flush option)//
// but it lets us allocate only one OS surface, which saves//
// us on Win98/ME where we're very limited in terms of //
// available OS surfaces. //
// To facilitate this, we create a new abstract class to //
// encapsulate the actual GDI functionality of Windows. //
// This way, we have two options when creating DTMaps: //
// allocate an OS writer per surface, which lets us avoid //
// the copy problem mentioned above, or allocate one to //
// share. This will also let us optimize by switching to //
// non-shared writers once we write a non-OS-reliant //
// writer/text renderer. //
// //
///////////////////////////////////////////////////////////////////////////////
#ifndef _plDynamicTextMap_h
#define _plDynamicTextMap_h
#include "plMipmap.h"
#include "hsColorRGBA.h"
struct hsMatrix44;
//// Class Definition /////////////////////////////////////////////////////////
class plFont;
class plDynamicTextMap : public plMipmap
{
protected:
UInt16 fVisWidth, fVisHeight;
virtual UInt32 Read( hsStream *s );
virtual UInt32 Write( hsStream *s );
public:
//// Public Flags ////
enum Justify
{
kLeftJustify = 0,
kCenter,
kRightJustify
};
//// Public Data /////
//// Public Members ////
plDynamicTextMap();
plDynamicTextMap( UInt32 width, UInt32 height, hsBool hasAlpha = false, UInt32 extraWidth = 0, UInt32 extraHeight = 0, hsBool premultipliedAlpha = false );
virtual ~plDynamicTextMap();
CLASSNAME_REGISTER( plDynamicTextMap );
GETINTERFACE_ANY( plDynamicTextMap, plMipmap );
void Create( UInt32 width, UInt32 height, hsBool hasAlpha, UInt32 extraWidth = 0, UInt32 extraHeight = 0, hsBool premultipliedAlpha = false );
void SetNoCreate( UInt32 width, UInt32 height, hsBool hasAlpha );
virtual void Reset( void );
virtual void Read( hsStream *s, hsResMgr *mgr ) { hsKeyedObject::Read( s, mgr ); this->Read( s ); }
virtual void Write( hsStream *s, hsResMgr *mgr ) { hsKeyedObject::Write( s, mgr ); this->Write( s ); }
virtual UInt8 GetNumLevels( void ) const { return 1; }
virtual void Colorize( void ) { ; }
virtual plMipmap *Clone( void );
virtual void CopyFrom( plMipmap *source );
/// Operations to perform on the text block
hsBool IsValid() { return IIsValid(); }
// allow the user of the DynaTextMap that they are done with the image... for now
// ... the fImage will be re-created on the next operation that requires the image
void PurgeImage();
void ClearToColor( hsColorRGBA &color );
enum FontFlags
{
kFontBold = 0x01,
kFontItalic = 0x02,
kFontShadowed = 0x04
};
void SetFont( const char *face, UInt16 size, UInt8 fontFlags = 0, hsBool antiAliasRGB = true );
void SetFont( const wchar_t *face, UInt16 size, UInt8 fontFlags = 0, hsBool antiAliasRGB = true );
void SetLineSpacing( Int16 spacing );
void SetTextColor( hsColorRGBA &color, hsBool blockRGB = false );
void SetJustify( Justify j );
void DrawString( UInt16 x, UInt16 y, const char *text );
void DrawString( UInt16 x, UInt16 y, const wchar_t *text );
void DrawClippedString( Int16 x, Int16 y, const char *text, UInt16 width, UInt16 height );
void DrawClippedString( Int16 x, Int16 y, const wchar_t *text, UInt16 width, UInt16 height );
void DrawClippedString( Int16 x, Int16 y, const char *text, UInt16 clipX, UInt16 clipY, UInt16 width, UInt16 height );
void DrawClippedString( Int16 x, Int16 y, const wchar_t *text, UInt16 clipX, UInt16 clipY, UInt16 width, UInt16 height );
void DrawWrappedString( UInt16 x, UInt16 y, const char *text, UInt16 width, UInt16 height, UInt16 *lastX = nil, UInt16 *lastY = nil );
void DrawWrappedString( UInt16 x, UInt16 y, const wchar_t *text, UInt16 width, UInt16 height, UInt16 *lastX = nil, UInt16 *lastY = nil );
UInt16 CalcStringWidth( const char *text, UInt16 *height = nil );
UInt16 CalcStringWidth( const wchar_t *text, UInt16 *height = nil );
void CalcWrappedStringSize( const char *text, UInt16 *width, UInt16 *height, UInt32 *firstClippedChar = nil, UInt16 *maxAscent = nil, UInt16 *lastX = nil, UInt16 *lastY = nil );
void CalcWrappedStringSize( const wchar_t *text, UInt16 *width, UInt16 *height, UInt32 *firstClippedChar = nil, UInt16 *maxAscent = nil, UInt16 *lastX = nil, UInt16 *lastY = nil );
void FillRect( UInt16 x, UInt16 y, UInt16 width, UInt16 height, hsColorRGBA &color );
void FrameRect( UInt16 x, UInt16 y, UInt16 width, UInt16 height, hsColorRGBA &color );
void SetFirstLineIndent( Int16 indent );
enum DrawMethods
{
kImgNoAlpha, // Just copy color data, force alpha to full if present
kImgBlend, // Blend color onto dest using src alpha, keep dest alpha
kImgSprite // Copy color data and alphas
};
void DrawImage( UInt16 x, UInt16 y, plMipmap *image, DrawMethods method = kImgNoAlpha );
void DrawClippedImage( UInt16 x, UInt16 y, plMipmap *image, UInt16 srcClipX, UInt16 srcClipY,
UInt16 srcClipWidth, UInt16 srcClipHeight, DrawMethods method = kImgNoAlpha );
void FlushToHost( void );
hsBool MsgReceive( plMessage *msg );
UInt16 GetVisibleWidth( void ) { return fVisWidth; }
UInt16 GetVisibleHeight( void ) { return fVisHeight; }
// Since the dynamic text can actually create a texture bigger than you were expecting,
// you want to be able to apply a layer texture transform that will compensate. This
// function will give you that transform. Just feed it into plLayer->SetTransform().
hsMatrix44 GetLayerTransform( void );
void SetInitBuffer( UInt32 *buffer );
// Gets for font values
Justify GetFontJustify( void ) const { return fJustify; }
const char *GetFontFace( void ) const { return fFontFace; }
UInt16 GetFontSize( void ) const { return fFontSize; }
hsBool GetFontAARGB( void ) const { return fFontAntiAliasRGB; }
hsColorRGBA GetFontColor( void ) const { return fFontColor; }
hsBool GetFontBlockRGB( void ) const { return fFontBlockRGB; }
Int16 GetLineSpacing( void ) const { return fLineSpacing; }
plFont *GetCurrFont( void ) const { return fCurrFont; }
virtual void Swap( plDynamicTextMap *other );
protected:
//// Protected Members ////
hsBool IIsValid( void );
void IClearFromBuffer( UInt32 *clearBuffer );
UInt32 *IAllocateOSSurface( UInt16 width, UInt16 height );
void IDestroyOSSurface( void );
void IPropagateFlags();
hsBool fHasAlpha, fPremultipliedAlpha, fShadowed;
Justify fJustify;
char *fFontFace;
UInt16 fFontSize;
UInt8 fFontFlags;
hsBool fFontAntiAliasRGB;
hsColorRGBA fFontColor;
hsBool fFontBlockRGB;
Int16 fLineSpacing;
plFont *fCurrFont;
UInt32 *fInitBuffer;
hsBool fHasCreateBeenCalled;
};
#endif // _plDynamicTextMap_h

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,308 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// plFont Class Header //
// Seems like we've come full circle again. This is our generic Plasma //
// bitmap font class/format. Quick list of things it supports, or needs to: //
// - Antialiasing, either in the font def or at rendertime //
// - Doublebyte character sets //
// - Platform independence, of course //
// - Render to reasonably arbitrary mipmap //
// - Character-level kerning, both before and after, as well as //
// negative kerning (for ligatures) //
// //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 5.4.2003 mcn - Created. //
// //
///////////////////////////////////////////////////////////////////////////////
#ifndef _plFont_h
#define _plFont_h
#include "hsTypes.h"
#include "hsColorRGBA.h"
#include "hsTemplates.h"
#include "pcSmallRect.h"
#include "../pnKeyedObject/hsKeyedObject.h"
#include <wchar.h>
class plBDFConvertCallback
{
public:
virtual void NumChars( UInt16 chars ) {}
virtual void CharDone( void ) {}
};
//// Class Definition /////////////////////////////////////////////////////////
class plMipmap;
class plBDFHeaderParser;
class plBDFPropertiesParser;
class plBDFCharsParser;
class plFont : public hsKeyedObject
{
public:
enum RenderFlags
{
kRenderItalic = 0x00000001,
kRenderBold = 0x00000002,
kRenderScaleAA = 0x00000004,
kRenderClip = 0x00000008,
kRenderWrap = 0x00000010,
kRenderJustXLeft = 0,
kRenderJustXRight = 0x00000020, // X right justify
kRenderJustXCenter = 0x00000040, // X center justify (left default)
kRenderJustXForceLeft=0x00000080, // Force left (no kerning)
kRenderJustXMask = 0x000000e0,
kRenderJustYBaseline = 0,
kRenderJustYTop = 0x00000100, // Y top justify
kRenderJustYCenter = 0x00000200, // Y center justify
kRenderJustYBottom = 0x00000400, // Y bottom justify (baseline is default)
kRenderJustYMask = 0x00000700,
kRenderIntoAlpha = 0x00000800, // This option causes grayscale (AA) fonts to
// render into the alpha channel instead of the color
// channel, so that the resulting pixels touched always
// have the renderColor and the alpha = to the font pixel.
// By default, we use the font pixel as an alpha blending
// value between the renderColor and the destColor and
// leave the alpha as-is
// This flag has no effect on monochrome fonts
kRenderAlphaPremultiplied = 0x00001000, // Destination has color values premultiplied by alpha
kRenderShadow = 0x00002000, // Render text shadows
};
enum Flags
{
kFlagBold = 0x00000001,
kFlagItalic = 0x00000002
};
protected:
friend class plBDFHeaderParser;
friend class plBDFPropertiesParser;
friend class plBDFCharsParser;
// Font face and size. This is just used for IDing purposes, not for rendering
char fFace[ 256 ];
UInt8 fSize;
UInt32 fFlags;
// Size of the whole font bitmap. Fonts are stored vertically, one
// character at a time, so fWidth is really the max width of any one
// character bitmap, with of course the proper padding
UInt32 fWidth, fHeight;
// Bpp of our font bitmap. We're grayscale, remember...
UInt8 fBPP;
// Bitmap data!
UInt8 *fBMapData;
// Our character class, for per-char info
class plCharacter
{
public:
UInt32 fBitmapOff; // Offset in the font bitmap in bytes
// to the first byte of the character
UInt32 fHeight; // Height in pixels of this character
Int32 fBaseline; // Number of pixels down from the top of
// the char bitmap to the baseline.
hsScalar fLeftKern; // Kerning values for this char, in pixels
hsScalar fRightKern; // Note that the right kern is relative to
// the right side of the bitmap area, which
// is the width of the font bitmap, so
// basically each character is the same width,
// just kerned back!
// (left kerning currently unsupported, just
// in here in case we need to eventually)
plCharacter& operator=(const int zero)
{
fBitmapOff=0;
fHeight = 0;
fBaseline = 0;
fLeftKern = 0;
fRightKern = 0;
return *this;
}
plCharacter();
void Read( hsStream *s );
void Write( hsStream *s );
};
// First character we encode--everything below this we don't render
UInt16 fFirstChar;
// Our characters, stored in an hsTArray for easy construction
hsTArray<plCharacter> fCharacters;
// Max character bitmap height and max ascent for any character
UInt32 fMaxCharHeight;
Int32 fFontAscent, fFontDescent;
typedef void (plFont::*CharRenderFunc)( const plCharacter &c );
// Render info
class plRenderInfo
{
public:
Int16 fFirstLineIndent;
Int16 fX, fY, fNumCols, fFarthestX, fLastX, fLastY;
Int16 fMaxWidth, fMaxHeight, fMaxAscent, fMaxDescent;
Int16 fLineSpacing;
UInt8 *fDestPtr;
UInt32 fDestStride;
UInt8 fDestBPP;
UInt32 fColor;
plMipmap *fMipmap;
UInt32 fFlags;
pcSmallRect fClipRect;
hsScalar fFloatWidth;
const wchar_t *fVolatileStringPtr; // Just so we know where we clipped
CharRenderFunc fRenderFunc;
};
plRenderInfo fRenderInfo;
void IClear( bool onConstruct = false );
void ICalcFontAscent( void );
UInt8 *IGetFreeCharData( UInt32 &newOffset );
void IRenderLoop( const wchar_t *string, Int32 maxCount );
void IRenderString( plMipmap *mip, UInt16 x, UInt16 y, const wchar_t *string, hsBool justCalc );
// Various render functions
void IRenderChar1To32( const plCharacter &c );
void IRenderChar1To32AA( const plCharacter &c );
void IRenderChar8To32( const plCharacter &c );
void IRenderChar8To32Alpha( const plCharacter &c );
void IRenderChar8To32FullAlpha( const plCharacter &c );
void IRenderChar8To32AlphaPremultiplied( const plCharacter &c );
void IRenderChar8To32AlphaPremShadow( const plCharacter &c );
void IRenderCharNull( const plCharacter &c );
UInt32 IGetCharPixel( const plCharacter &c, Int32 x, Int32 y )
{
// only for 8-bit characters
return (x < 0 || y < 0 || (UInt32)x >= fWidth || (UInt32)y >= c.fHeight) ? 0 : *(fBMapData + c.fBitmapOff + y*fWidth + x);
}
public:
plFont();
virtual ~plFont();
CLASSNAME_REGISTER( plFont );
GETINTERFACE_ANY( plFont, hsKeyedObject );
virtual void Read( hsStream *s, hsResMgr *mgr );
virtual void Write( hsStream *s, hsResMgr *mgr );
const char *GetFace( void ) const { return fFace; }
UInt8 GetSize( void ) const { return fSize; }
UInt16 GetFirstChar( void ) const { return fFirstChar; }
UInt16 GetNumChars( void ) const { return fCharacters.GetCount(); }
UInt32 GetFlags( void ) const { return fFlags; }
hsScalar GetDescent( void ) const { return (hsScalar)fFontDescent; }
hsScalar GetAscent( void ) const { return (hsScalar)fFontAscent; }
UInt32 GetBitmapWidth( void ) const { return fWidth; }
UInt32 GetBitmapHeight( void ) const { return fHeight; }
UInt8 GetBitmapBPP( void ) const { return fBPP; }
void SetFace( const char *face );
void SetSize( UInt8 size );
void SetFlags( UInt32 flags ) { fFlags = flags; }
void SetFlag( UInt32 flag, hsBool on ) { if( on ) fFlags |= flag; else fFlags &= ~flag; }
hsBool IsFlagSet( UInt32 flag ) { if( fFlags & flag ) return true; return false; }
void SetRenderColor( UInt32 color );
void SetRenderFlag( UInt32 flag, hsBool on ) { if( on ) fRenderInfo.fFlags |= flag; else fRenderInfo.fFlags &= ~flag; }
hsBool IsRenderFlagSet( UInt32 flag ) { return ( fRenderInfo.fFlags & flag ) ? true : false; }
void SetRenderClipRect( Int16 x, Int16 y, Int16 width, Int16 height );
void SetRenderXJustify( UInt32 j ) { fRenderInfo.fFlags &= ~kRenderJustXMask; fRenderInfo.fFlags |= j; }
void SetRenderYJustify( UInt32 j ) { fRenderInfo.fFlags &= ~kRenderJustYMask; fRenderInfo.fFlags |= j; }
void SetRenderFirstLineIndent( Int16 indent ) { fRenderInfo.fFirstLineIndent = indent; }
void SetRenderLineSpacing( Int16 spacing ) { fRenderInfo.fLineSpacing = spacing; }
// Sets flags too
void SetRenderClipping( Int16 x, Int16 y, Int16 width, Int16 height );
void SetRenderWrapping( Int16 x, Int16 y, Int16 width, Int16 height );
void RenderString( plMipmap *mip, UInt16 x, UInt16 y, const char *string, UInt16 *lastX = nil, UInt16 *lastY = nil );
void RenderString( plMipmap *mip, UInt16 x, UInt16 y, const wchar_t *string, UInt16 *lastX = nil, UInt16 *lastY = nil );
UInt16 CalcStringWidth( const char *string );
UInt16 CalcStringWidth( const wchar_t *string );
void CalcStringExtents( const char *string, UInt16 &width, UInt16 &height, UInt16 &ascent, UInt32 &firstClippedChar, UInt16 &lastX, UInt16 &lastY );
void CalcStringExtents( const wchar_t *string, UInt16 &width, UInt16 &height, UInt16 &ascent, UInt32 &firstClippedChar, UInt16 &lastX, UInt16 &lastY );
hsBool LoadFromFNT( const char *path );
hsBool LoadFromFNTStream( hsStream *stream );
hsBool LoadFromBDF( const char *path, plBDFConvertCallback *callback );
hsBool LoadFromBDFStream( hsStream *stream, plBDFConvertCallback *callback );
hsBool LoadFromP2FFile( const char *path );
hsBool ReadRaw( hsStream *stream );
hsBool WriteRaw( hsStream *stream );
};
#endif // _plFont_h

View File

@ -0,0 +1,219 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// plFontCache Class Header //
// Generic cache lib for our plFonts. Basically just a simple plFont //
// manager. //
// //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 3.12.2003 mcn - Created. //
// //
///////////////////////////////////////////////////////////////////////////////
#include "plFontCache.h"
#include "plFont.h"
#include "../plStatusLog/plStatusLog.h"
#include "../plFile/hsFiles.h"
#include "../pnMessage/plRefMsg.h"
#include "hsResMgr.h"
#include "../pnKeyedObject/plUoid.h"
char *plFontCache::kCustFontExtension = ".prf";
plFontCache *plFontCache::fInstance = nil;
plFontCache::plFontCache()
{
fCustFontDir = nil;
RegisterAs( kFontCache_KEY );
fInstance = this;
}
plFontCache::~plFontCache()
{
Clear();
delete [] fCustFontDir;
fInstance = nil;
}
plFontCache &plFontCache::GetInstance( void )
{
return *fInstance;
}
void plFontCache::Clear( void )
{
}
plFont *plFontCache::GetFont( const char *face, UInt8 size, UInt32 fontFlags )
{
UInt32 i, currIdx = (UInt32)-1;
int currDeltaSize = 100000;
char toFind[ 256 ];
strcpy( toFind, face );
strlwr( toFind );
for( i = 0; i < fCache.GetCount(); i++ )
{
char thisOne[ 256 ];
strcpy( thisOne, fCache[ i ]->GetFace() );
strlwr( thisOne );
if( strncmp( thisOne, toFind, strlen( toFind ) ) == 0 &&
( fCache[ i ]->GetFlags() == fontFlags ) )
{
int delta = fCache[ i ]->GetSize() - size;
if( delta < 0 )
delta = -delta;
if( delta < currDeltaSize )
{
currDeltaSize = delta;
currIdx = i;
}
}
}
if( currIdx != (UInt32)-1 )
{
//if( currDeltaSize > 0 )
// plStatusLog::AddLineS( "pipeline.log", "Warning: plFontCache is matching %s %d (requested %s %d)", fCache[ currIdx ]->GetFace(), fCache[ currIdx ]->GetSize(), face, size );
return fCache[ currIdx ];
}
// If we failed, it's possible we have a face saved as "Times", for example, and someone's
// asking for "Times New Roman", so strip all but the first word from our font and try the search again
char *c = strchr( toFind, ' ' );
if( c != nil )
{
*c = 0;
return GetFont( toFind, size, fontFlags );
}
else if( fontFlags != 0 )
{
// Hmm, well ok, just to be nice, try without our flags
plFont *f = GetFont( toFind, size, 0 );
if( f != nil )
{
//plStatusLog::AddLineS( "pipeline.log", "Warning: plFontCache is substituting %s %d regular (flags 0x%x could not be matched)", f->GetFace(), f->GetSize(), fontFlags );
return f;
}
}
//plStatusLog::AddLineS( "pipeline.log", "Warning: plFontCache was unable to match %s %d (0x%x)", face, size, fontFlags );
return nil;
}
void plFontCache::LoadCustomFonts( const char *dir )
{
delete [] fCustFontDir;
fCustFontDir = ( dir != nil ) ? hsStrcpy( dir ) : nil;
ILoadCustomFonts();
}
void plFontCache::ILoadCustomFonts( void )
{
if( fCustFontDir == nil )
return;
// Iterate through all the custom fonts in our dir
hsFolderIterator iter( fCustFontDir );
char fileName[ kFolderIterator_MaxPath ];
hsFolderIterator iter2( fCustFontDir );
while( iter2.NextFileSuffix( ".p2f" ) )
{
iter2.GetPathAndName( fileName );
plFont *font = TRACKED_NEW plFont;
if( !font->LoadFromP2FFile( fileName ) )
delete font;
else
{
char keyName[ 512 ];
if( font->GetKey() == nil )
{
sprintf( keyName, "%s-%d", font->GetFace(), font->GetSize() );
hsgResMgr::ResMgr()->NewKey( keyName, font, plLocation::kGlobalFixedLoc );
}
hsgResMgr::ResMgr()->AddViaNotify( font->GetKey(),
TRACKED_NEW plGenRefMsg( GetKey(), plRefMsg::kOnCreate, 0, -1 ),
plRefFlags::kActiveRef );
//plStatusLog::AddLineS( "pipeline.log", "FontCache: Added custom font %s", keyName );
}
}
}
hsBool plFontCache::MsgReceive( plMessage* pMsg )
{
plGenRefMsg *ref = plGenRefMsg::ConvertNoRef( pMsg );
if( ref != nil )
{
if( ref->GetContext() & ( plRefMsg::kOnCreate | plRefMsg::kOnRequest | plRefMsg::kOnReplace ) )
{
fCache.Append( plFont::ConvertNoRef( ref->GetRef() ) );
}
else
{
plFont *font = plFont::ConvertNoRef( ref->GetRef() );
UInt32 idx = fCache.Find( font );
if( idx != fCache.kMissingIndex )
fCache.Remove( idx );
}
return true;
}
return hsKeyedObject::MsgReceive( pMsg );
}

View File

@ -0,0 +1,106 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// plFontCache Class Header //
// Generic cache lib for our plFonts. Basically just a simple plFont //
// manager. //
// //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 3.12.2003 mcn - Created. //
// //
///////////////////////////////////////////////////////////////////////////////
#ifndef _plFontCache_h
#define _plFontCache_h
#include "hsTypes.h"
#include "hsTemplates.h"
#include "../pnKeyedObject/hsKeyedObject.h"
//// Class Definition /////////////////////////////////////////////////////////
class plFont;
class plFontCache : public hsKeyedObject
{
protected:
hsTArray<plFont *> fCache;
char *fCustFontDir;
static plFontCache *fInstance;
void ILoadCustomFonts( void );
public:
CLASSNAME_REGISTER( plFontCache );
GETINTERFACE_ANY( plFontCache, hsKeyedObject );
plFontCache();
virtual ~plFontCache();
virtual void Read( hsStream *s, hsResMgr *mgr ) {}
virtual void Write( hsStream *s, hsResMgr *mgr ) {}
virtual hsBool MsgReceive( plMessage* pMsg );
static plFontCache &GetInstance( void );
plFont *GetFont( const char *face, UInt8 size, UInt32 fontFlags );
// HFONT GetMeAFont( const char *face, int height, int weight, hsBool italic, UInt32 quality );
// void FreeFont( HFONT font );
void Clear( void );
void LoadCustomFonts( const char *dir );
// Our custom font extension
static char *kCustFontExtension;
};
#endif // _plFontCache_h

View File

@ -0,0 +1,88 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef plGImageCreatable_inc
#define plGImageCreatable_inc
#include "../pnFactory/plCreator.h"
/*
#include "hsGMipmap.h"
REGISTER_CREATABLE( hsGBitmapClass );
REGISTER_CREATABLE( hsGMipmapClass );
*/
#include "plBitmap.h"
REGISTER_NONCREATABLE( plBitmap );
#include "plMipmap.h"
REGISTER_CREATABLE( plMipmap );
#include "plCubicEnvironmap.h"
REGISTER_CREATABLE( plCubicEnvironmap );
#include "plDynamicTextMap.h"
REGISTER_CREATABLE( plDynamicTextMap );
#include "plAVIWriter.h"
REGISTER_NONCREATABLE( plAVIWriter );
#include "plFont.h"
REGISTER_CREATABLE( plFont );
#include "plFontCache.h"
REGISTER_CREATABLE( plFontCache );
#include "plLODMipmap.h"
REGISTER_CREATABLE( plLODMipmap );
#endif // plGImageCreatable_inc

View File

@ -0,0 +1,59 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
class plImageConvert : public hsRefCnt
{
public:
// Fill in dst according to src's image and dst's format/size
hsGBitmap* Convert(hsGBitmap* src, hsGBitmap* dst);
hsGBitmap* Create(
// Fill dst with normals from height map src. May take additional
// parameters, like scale and which channel of src to use as height
hsGBitmap* CreateBumpMap(hsGBitmap* src, hsGBitmap* dst);
hsGBitmap* Filter(hsGBitmap* src, hsGBitmap* dst, plFilterFunc func); ?
};

View File

@ -0,0 +1,300 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#include "hsTypes.h"
#include "plLODMipmap.h"
#include "hsResMgr.h"
#include "../pnKeyedObject/plKey.h"
#include "../pnKeyedObject/plUoid.h"
#include "../pnMessage/plRefMsg.h"
#include "../plPipeline/hsGDeviceRef.h"
plLODMipmap::plLODMipmap()
: fBase(nil),
fLOD(0)
{
int i;
for( i = 0; i < kNumLODs; i++ )
fDeviceRefs[i] = nil;
}
plLODMipmap::plLODMipmap(plMipmap* mip)
: fBase(nil),
fLOD(0)
{
int i;
for( i = 0; i < kNumLODs; i++ )
fDeviceRefs[i] = nil;
hsgResMgr::ResMgr()->NewKey(mip->GetKey()->GetName(), this, mip->GetKey()->GetUoid().GetLocation());
// Need some kind of reffing assignment for the mipmap here
fBase = mip;
fLevelSizes = TRACKED_NEW UInt32[fBase->GetNumLevels()];
ISetup();
hsgResMgr::ResMgr()->AddViaNotify(mip->GetKey(), TRACKED_NEW plGenRefMsg(GetKey(), plRefMsg::kOnCreate, -1, kRefBase), plRefFlags::kActiveRef);
}
plLODMipmap::~plLODMipmap()
{
// And matching unreffing of the mipmap here.
fImage = nil;
int i;
for( i = 0; i < kNumLODs; i++ )
{
hsRefCnt_SafeUnRef(fDeviceRefs[i]);
fDeviceRefs[i] = nil;
}
}
hsGDeviceRef* plLODMipmap::GetDeviceRef() const
{
return fDeviceRefs[GetLOD()];
}
void plLODMipmap::SetDeviceRef( hsGDeviceRef *const devRef )
{
hsRefCnt_SafeAssign(fDeviceRefs[GetLOD()], devRef);
}
void plLODMipmap::SetLOD(int lod)
{
hsAssert(fBase, "UnInitialized");
const int kMaxLOD = 5;
if( lod > kMaxLOD )
lod = kMaxLOD;
if( lod >= fBase->GetNumLevels() )
lod = fBase->GetNumLevels() - 1;
if( fLOD != lod )
{
fLOD = lod;
ISetup();
}
}
void plLODMipmap::ISetup()
{
hsAssert(fBase, "UnInitialized");
hsAssert(fBase->GetNumLevels() > GetLOD(), "Skipping all mip levels");
fBase->SetCurrLevel(GetLOD());
// plBitmap
fPixelSize = fBase->GetPixelSize();
// fSpace = fBase->fSpace;
fFlags = fBase->GetFlags();
fCompressionType = fBase->fCompressionType;
if( !fBase->IsCompressed() )
{
fUncompressedInfo = fBase->fUncompressedInfo;
}
else
{
fDirectXInfo = fBase->fDirectXInfo;
}
// plMipmap
fImage = fBase->GetCurrLevelPtr();
fWidth = fBase->GetCurrWidth();
fHeight = fBase->GetCurrHeight();
fRowBytes = fBase->GetRowBytes();
if( !fLevelSizes )
fLevelSizes = TRACKED_NEW UInt32[fBase->GetNumLevels()];
fNumLevels = fBase->GetNumLevels() - GetLOD();
fNumLevels = 1;
fTotalSize = 0;
int i;
for( i = 0; i < fNumLevels; i++ )
{
fLevelSizes[i] = fBase->GetLevelSize(i + GetLOD());
fTotalSize += fBase->GetLevelSize(i + GetLOD());
}
ISetupCurrLevel();
IMarkDirty();
}
void plLODMipmap::ISetupCurrLevel()
{
fCurrLevelPtr = fBase->GetCurrLevelPtr();
fCurrLevel = (UInt8)(fBase->GetCurrLevel());
fCurrLevelWidth = fBase->GetCurrWidth();
fCurrLevelHeight = fBase->GetCurrHeight();
fCurrLevelRowBytes = fBase->GetRowBytes();
}
void plLODMipmap::INilify()
{
fBase = nil;
fPixelSize = 0;
fSpace = kNoSpace;
fFlags = 0;
fCompressionType = kUncompressed;
fUncompressedInfo.fType = UncompressedInfo::kRGB8888;
// plMipmap
fImage = nil;
fWidth = 0;
fHeight = 0;
fRowBytes = 0;
fNumLevels = 0;
fTotalSize = 0;
fCurrLevelPtr = nil;
fCurrLevel = 0;
fCurrLevelWidth = 0;
fCurrLevelHeight = 0;
fCurrLevelRowBytes = 0;
delete [] fLevelSizes;
fLevelSizes = nil;
int i;
for( i = 0; i < kNumLODs; i++ )
{
hsRefCnt_SafeUnRef(fDeviceRefs[i]);
fDeviceRefs[i] = nil;
}
}
void plLODMipmap::IMarkDirty()
{
int i;
for( i = 0; i < kNumLODs; i++ )
{
if( fDeviceRefs[i] )
fDeviceRefs[i]->SetDirty(true);
}
}
void plLODMipmap::SetCurrLevel(UInt8 level)
{
fBase->SetCurrLevel(level + GetLOD());
ISetupCurrLevel();
}
void plLODMipmap::Reset()
{
fBase->Reset();
ISetup();
}
void plLODMipmap::ScaleNicely(UInt32 *destPtr, UInt16 destWidth, UInt16 destHeight,
UInt16 destStride, plMipmap::ScaleFilter filter) const
{
fBase->ScaleNicely(destPtr, destWidth, destHeight, destStride, filter);
}
hsBool plLODMipmap::ResizeNicely(UInt16 newWidth, UInt16 newHeight, plMipmap::ScaleFilter filter)
{
hsBool retVal = fBase->ResizeNicely(newWidth, newHeight, filter);
ISetup();
return retVal;
}
void plLODMipmap::CopyFrom(const plMipmap *source)
{
fBase->CopyFrom(source);
ISetup();
}
void plLODMipmap::Composite(plMipmap *source, UInt16 x, UInt16 y, CompositeOptions *options)
{
fBase->Composite(source, x, y, options);
IMarkDirty();
}
hsBool plLODMipmap::MsgReceive(plMessage *msg)
{
plGenRefMsg* ref = plGenRefMsg::ConvertNoRef(msg);
if( ref )
{
if( ref->fType == kRefBase )
{
INilify();
if( ref->GetContext() & (plRefMsg::kOnCreate|plRefMsg::kOnRequest|plRefMsg::kOnReplace) )
{
fBase = plMipmap::ConvertNoRef(ref->GetRef());
ISetup();
}
return true;
}
}
return plMipmap::MsgReceive(msg);
}
void plLODMipmap::Read(hsStream *s, hsResMgr *mgr)
{
INilify();
hsKeyedObject::Read(s, mgr);
mgr->ReadKeyNotifyMe(s, TRACKED_NEW plGenRefMsg(GetKey(), plRefMsg::kOnCreate, -1, kRefBase), plRefFlags::kActiveRef); // fBase
}
void plLODMipmap::Write(hsStream *s, hsResMgr *mgr)
{
hsKeyedObject::Write(s, mgr);
mgr->WriteKey(s, fBase);
}

View File

@ -0,0 +1,108 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef plLODMipmap_inc
#define plLODMipmap_inc
#include "plMipmap.h"
class plLODMipmap : public plMipmap
{
protected:
const enum
{
kRefBase = 0
};
const enum
{
kNumLODs = 5
};
plMipmap* fBase;
int fLOD;
hsGDeviceRef* fDeviceRefs[kNumLODs];
void ISetup();
void ISetupCurrLevel();
void IMarkDirty();
void INilify();
public:
plLODMipmap();
plLODMipmap(plMipmap* mip);
virtual ~plLODMipmap();
CLASSNAME_REGISTER( plLODMipmap );
GETINTERFACE_ANY( plLODMipmap, plMipmap );
virtual hsBool MsgReceive(plMessage *msg);
void SetLOD(int lod);
int GetLOD() const { return fLOD; }
virtual hsGDeviceRef* GetDeviceRef() const;
virtual void SetDeviceRef( hsGDeviceRef *const devRef );
virtual void Reset();
virtual void Read(hsStream *s, hsResMgr *mgr);
virtual void Write(hsStream *s, hsResMgr *mgr);
virtual plMipmap* Clone() const { return fBase->Clone(); }
virtual void CopyFrom(const plMipmap *source);
virtual void Composite(plMipmap *source, UInt16 x, UInt16 y, CompositeOptions *options = nil);
virtual void ScaleNicely(UInt32 *destPtr, UInt16 destWidth, UInt16 destHeight,
UInt16 destStride, plMipmap::ScaleFilter filter) const;
virtual hsBool ResizeNicely(UInt16 newWidth, UInt16 newHeight, plMipmap::ScaleFilter filter);
virtual void SetCurrLevel(UInt8 level);
const plMipmap* GetBase() const { return fBase; }
};
#endif // plLODMipmap_inc

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,391 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// plMipmap Class Header //
// Derived bitmap class representing a single mipmap. //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 6.7.2001 mcn - Created. //
// //
///////////////////////////////////////////////////////////////////////////////
#ifndef _plMipmap_h
#define _plMipmap_h
#include "plBitmap.h"
#ifdef HS_DEBUGGING
#define ASSERT_PIXELSIZE(bitmap, pixelsize) hsAssert((bitmap)->fPixelSize == (pixelsize), "pixelSize mismatch")
#define ASSERT_XY(bitmap, x, y) hsAssert(x < (bitmap)->fWidth && y < (bitmap)->fHeight, "bad XY")
#define ASSERT_UNCOMPRESSED() hsAssert(fCompressionType!=kDirectXCompression, "Can't operate on compressed map.")
// Define the following konstant to enable mipmap leak checking. This is because our normal
// memory manager sucks when trying to track down these problems
#define MEMORY_LEAK_TRACER
#else
#define ASSERT_PIXELSIZE(bitmap, pixelsize)
#define ASSERT_XY(bitmap, x, y)
#define ASSERT_UNCOMPRESSED()
#endif
//// Class Definition /////////////////////////////////////////////////////////
class plBitmapCreator;
class plTextGenerator;
class plMipmap : public plBitmap
{
friend class plBitmapCreator;
friend class plTextGenerator;
public:
//// Public Flags ////
//// Public Data /////
//// Public Members ////
plMipmap();
plMipmap( UInt32 width, UInt32 height, unsigned config, UInt8 numLevels = 0, UInt8 compType = kUncompressed, UInt8 format = UncompressedInfo::kRGB8888 );
plMipmap( plMipmap *bm, hsScalar sig, UInt32 createFlags,
hsScalar detailDropoffStart, hsScalar detailDropoffStop,
hsScalar detailMax, hsScalar detailMin );
virtual ~plMipmap();
CLASSNAME_REGISTER( plMipmap );
GETINTERFACE_ANY( plMipmap, plBitmap );
void Create( UInt32 width, UInt32 height, unsigned config, UInt8 numLevels, UInt8 compType = kUncompressed, UInt8 format = UncompressedInfo::kRGB8888 );
virtual void Reset();
// Get the total size in bytes
virtual UInt32 GetTotalSize() const;
virtual void Read( hsStream *s, hsResMgr *mgr ) { hsKeyedObject::Read( s, mgr ); this->Read( s ); }
virtual void Write( hsStream *s, hsResMgr *mgr ) { hsKeyedObject::Write( s, mgr ); this->Write( s ); }
virtual UInt8 GetNumLevels() const { return fNumLevels; }
virtual UInt32 GetLevelSize( UInt8 level ); // 0 is the largest
virtual void Colorize();
virtual plMipmap *Clone() const;
virtual void CopyFrom( const plMipmap *source );
inline UInt32 GetWidth() const { return fWidth; }
inline UInt32 GetHeight() const { return fHeight; }
inline UInt32 GetRowBytes() const { return fRowBytes; }
void *GetImage() const { return fImage; }
void SetImagePtr( void *ptr ) { fImage = ptr; }
UInt8 *GetLevelPtr( UInt8 level, UInt32 *width = nil, UInt32 *height = nil, UInt32 *rowBytes = nil );
// Sets the current level pointer for use with GetAddr*
virtual void SetCurrLevel(UInt8 level);
void *GetCurrLevelPtr() const { return fCurrLevelPtr; }
UInt32 GetCurrWidth() const { return fCurrLevelWidth; }
UInt32 GetCurrHeight() const { return fCurrLevelHeight; }
UInt32 GetCurrLevelSize() const { return fLevelSizes[ fCurrLevel ]; }
UInt32 GetCurrLevel() const { return fCurrLevel; }
// These methods return the address of the pixel specified by x and y
// They are meant to be fast, therefore they are inlined and do not check
// the fPixelSize field at runtime (except when debugging)
UInt8* GetAddr8(unsigned x, unsigned y) const
{
ASSERT_PIXELSIZE(this, 8);
ASSERT_XY(this, x, y);
ASSERT_UNCOMPRESSED();
return (UInt8*)((char*)fCurrLevelPtr + y * fCurrLevelRowBytes + x);
}
UInt16* GetAddr16(unsigned x, unsigned y) const
{
ASSERT_PIXELSIZE(this, 16);
ASSERT_XY(this, x, y);
ASSERT_UNCOMPRESSED();
return (UInt16*)((char*)fCurrLevelPtr + y * fCurrLevelRowBytes + (x << 1));
}
UInt32* GetAddr32(unsigned x, unsigned y) const
{
ASSERT_PIXELSIZE(this, 32);
ASSERT_XY(this, x, y);
ASSERT_UNCOMPRESSED();
return (UInt32*)((char*)fCurrLevelPtr + y * fCurrLevelRowBytes + (x << 2));
}
void* GetAddr64(unsigned x, unsigned y) const
{
ASSERT_PIXELSIZE(this, 64);
ASSERT_XY(this, x, y);
ASSERT_UNCOMPRESSED();
return (void*)((char*)fCurrLevelPtr + y * fCurrLevelRowBytes + (x << 3));
}
// This sets fPixelSize, fSpace, fFlags, for you
// All you need to set is
// fWidth, fHeight, fRowBytes, fImage and fColorTable
enum {
kColor8Config = 0,
kGray44Config = 1,
kGray4Config = 2,
kGray8Config = 8, // So we can use bit depths instead
kRGB16Config = 16,
kRGB32Config = 24,
kARGB32Config = 32,
};
void SetConfig( unsigned config );
//// Really complex creation stuff ////
enum {
kCreateDetailAlpha = 0x1,
kCreateDetailAdd = 0x2,
kCreateDetailMult = 0x4,
kCreateDetailMask = kCreateDetailAlpha | kCreateDetailAdd | kCreateDetailMult,
kCreateCarryAlpha = 0x8,
kCreateCarryWhite = 0x10,
kCreateCarryBlack = 0x20,
kCreateCarryMask = kCreateCarryAlpha | kCreateCarryWhite | kCreateCarryBlack
};
enum hsGPixelType {
kPixelARGB4444,
kPixelARGB1555,
kPixelAI88,
kPixelI8
};
enum hsGCopyOptions {
kCopyLODMask,
};
enum {
kColorDataRLE = 0x1,
kAlphaDataRLE = 0x2
};
void SetBitmapAsLevel(UInt8 iDst, plMipmap *bm, hsScalar sig, UInt32 createFlags,
hsScalar detailDropoffStart, hsScalar detailDropoffStop,
hsScalar detailMax, hsScalar detailMin);
void ICreateLevelNoDetail(UInt8 iDst, const plFilterMask& mask);
void IBlendLevelDetailAlpha(UInt8 iDst, const plFilterMask& mask,
hsScalar detailDropoffStart, hsScalar detailDropoffStop,
hsScalar detailMax, hsScalar detailMin);
void IBlendLevelDetailAdd(UInt8 iDst, const plFilterMask& mask,
hsScalar detailDropoffStart, hsScalar detailDropoffStop,
hsScalar detailMax, hsScalar detailMin);
void IBlendLevelDetailMult(UInt8 iDst, const plFilterMask& mask,
hsScalar detailDropoffStart, hsScalar detailDropoffStop,
hsScalar detailMax, hsScalar detailMin);
void Filter(hsScalar sig);
UInt32 CopyOutPixels(UInt32 destXSize, UInt32 destYSize, UInt32 dstFormat, void *destPixels, UInt32 copyOptions);
void ClipToMaxSize( UInt32 maxDimension );
void RemoveMipping();
void EnsureKonstantBorder( hsBool clampU, hsBool clampV );
enum CompositeFlags
{
kForceOpaque = 0x0001, // Copy src pixels raw, force dest alphas to opaque
kCopySrcAlpha = 0x0002, // Copy the src pixels raw, including alphas, overwrite dest
kBlendSrcAlpha = 0x0004, // Blend src pixels onto dest using src alpha, dest alpha = src alpha
kMaskSrcAlpha = 0x0008, // Same as copySrcAlpha, but dest is untouched when src alpha = 0
kBlendWriteAlpha = 0x0010, // Like default (0), but writes dest alpha values
kDestPremultiplied = 0x0020, // Dest has color premultiplied by alpha
// (src always assumed nonpremultiplied for now)
};
class CompositeOptions
{
// Helper class for specifying options to Composite()
public:
UInt16 fFlags;
UInt8 fSrcLevelsToSkip;
UInt8 fOpacity;
hsScalar fRedTint, fGreenTint, fBlueTint;
UInt16 fSrcClipX, fSrcClipY; // Clipping is applied AFTER levelSkip
UInt16 fSrcClipWidth, fSrcClipHeight; // 0 means max width/height
CompositeOptions() { fFlags = 0; fSrcLevelsToSkip = 0; fRedTint = fGreenTint = fBlueTint = 1.f;
fSrcClipX = fSrcClipY = fSrcClipWidth = fSrcClipHeight = 0; fOpacity = 255;}
CompositeOptions( UInt16 flags, UInt8 srcLevelsToSkip = 0, hsScalar red = 1.f, hsScalar green = 1.f,
hsScalar blue = 1.f, UInt16 srcClipX = 0, UInt16 srcClipY = 0,
UInt16 srcClipWidth = 0, UInt16 srcClipHeight = 0, UInt8 opacity = 255 )
{
fFlags = flags;
fSrcLevelsToSkip = srcLevelsToSkip;
fRedTint = red;
fGreenTint = green;
fBlueTint = blue;
fSrcClipX = srcClipX;
fSrcClipY = srcClipY;
fSrcClipWidth = srcClipWidth;
fSrcClipHeight = srcClipHeight;
fOpacity = opacity;
}
};
// Compositing function. Take a (smaller) mipmap and composite it onto this one at the given location. Nil options means use default
virtual void Composite( plMipmap *source, UInt16 x, UInt16 y, CompositeOptions *options = nil );
// Scaling function
enum ScaleFilter
{
kBoxFilter,
kDefaultFilter = kBoxFilter
};
virtual void ScaleNicely( UInt32 *destPtr, UInt16 destWidth, UInt16 destHeight,
UInt16 destStride, plMipmap::ScaleFilter filter ) const;
virtual hsBool ResizeNicely( UInt16 newWidth, UInt16 newHeight, plMipmap::ScaleFilter filter );
protected:
//// Protected Members ////
void *fImage;
UInt32 fWidth, fHeight, fRowBytes, fTotalSize;
UInt8 fNumLevels;
UInt32 *fLevelSizes;
void *fCurrLevelPtr;
UInt8 fCurrLevel;
UInt32 fCurrLevelWidth, fCurrLevelHeight, fCurrLevelRowBytes;
void IReadRawImage( hsStream *stream );
void IWriteRawImage( hsStream *stream );
plMipmap *ISplitAlpha();
void IRecombineAlpha( plMipmap *alphaChannel );
plMipmap *IReadRLEImage( hsStream *stream );
void IWriteRLEImage( hsStream *stream, plMipmap *mipmap );
void IReadJPEGImage( hsStream *stream );
void IWriteJPEGImage( hsStream *stream );
void IReadPNGImage( hsStream *stream );
void IWritePNGImage( hsStream *stream );
void IBuildLevelSizes();
void IColorLevel( UInt8 level, const UInt8 *colorMask );
hsScalar IGetDetailLevelAlpha( UInt8 level, hsScalar dropStart, hsScalar dropStop, hsScalar min, hsScalar max );
void ICarryZeroAlpha(UInt8 iDst);
void ICarryColor(UInt8 iDst, UInt32 col);
hsBool IGrabBorderColor( hsBool grabVNotU, UInt32 *color );
void ISetCurrLevelUBorder( UInt32 color );
void ISetCurrLevelVBorder( UInt32 color );
virtual UInt32 Read( hsStream *s );
virtual UInt32 Write( hsStream *s );
friend class plCubicEnvironmap;
#ifdef MEMORY_LEAK_TRACER
protected:
class plRecord
{
public:
plRecord *fNext;
plRecord **fBackPtr;
char fKeyName[ 256 ];
void *fImage;
UInt32 fWidth, fHeight, fRowBytes;
UInt8 fNumLevels;
UInt8 fCompressionType;
union
{
DirectXInfo fDirectXInfo;
UncompressedInfo fUncompressedInfo;
};
enum Method
{
kViaCreate,
kViaRead,
kViaClipToMaxSize,
kViaDetailMapConstructor,
kViaCopyFrom,
kViaResize
} fCreationMethod;
void Link( plRecord **backPtr )
{
fBackPtr = backPtr;
fNext = *backPtr;
if( fNext != nil )
fNext->fBackPtr = &fNext;
*backPtr = this;
}
void Unlink()
{
*fBackPtr = fNext;
if( fNext != nil )
fNext->fBackPtr = fBackPtr;
}
};
static plRecord *fRecords;
static UInt32 fNumMipmaps;
static void IAddToMemRecord( plMipmap *mip, plRecord::Method method );
static void IRemoveFromMemRecord( UInt8 *image );
static void IReportLeaks();
#endif
};
#endif // _plMipmap_h

View File

@ -0,0 +1,270 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#include "hsTypes.h"
#include "hsStream.h"
#include "hsExceptions.h"
#include "hsUtils.h"
#include "plPNG.h"
#include "../plGImage/plMipmap.h"
#include <png.h>
#define PNGSIGSIZE 8
// Custom functions to read and write data from or to an hsStream
// used by libPNG's respective functions
void pngReadDelegate(png_structp png_ptr, png_bytep png_data, png_size_t length)
{
hsStream* inStream = (hsStream*)png_get_io_ptr(png_ptr);
inStream->Read(length, (UInt8*)png_data);
}
void pngWriteDelegate(png_structp png_ptr, png_bytep png_data, png_size_t length)
{
hsStream* outStream = (hsStream*)png_get_io_ptr(png_ptr);
outStream->Write(length, (UInt8*)png_data);
}
//// Singleton Instance ///////////////////////////////////////////////////////
plPNG& plPNG::Instance(void)
{
static plPNG theInstance;
return theInstance;
}
//// IRead ////////////////////////////////////////////////////////////////////
// Given an open hsStream, reads the PNG data off of the
// stream and decodes it into a new plMipmap. The mipmap's buffer ends up
// being a packed RGBA buffer.
// Returns a pointer to the new mipmap if successful, NULL otherwise.
plMipmap* plPNG::IRead(hsStream* inStream)
{
plMipmap* newMipmap = NULL;
png_structp png_ptr;
png_infop info_ptr;
png_infop end_info;
try {
// Check PNG Signature
png_byte sig[PNGSIGSIZE];
inStream->Read8Bytes((char*) sig);
if (!png_sig_cmp(sig, 0, PNGSIGSIZE)) {
// Allocate required structs
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr) {
throw(false);
}
info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) {
png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
throw(false);
}
end_info = png_create_info_struct(png_ptr);
if (!end_info) {
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
throw(false);
}
// Assign delegate function for reading from hsStream
png_set_read_fn(png_ptr, (png_voidp)inStream, pngReadDelegate);
// Get PNG Header information
png_set_sig_bytes(png_ptr, PNGSIGSIZE);
png_read_info(png_ptr, info_ptr);
png_uint_32 imgWidth = png_get_image_width(png_ptr, info_ptr);
png_uint_32 imgHeight = png_get_image_height(png_ptr, info_ptr);
png_uint_32 bitdepth = png_get_bit_depth(png_ptr, info_ptr);
png_uint_32 channels = png_get_channels(png_ptr, info_ptr);
png_uint_32 color_type = png_get_color_type(png_ptr, info_ptr);
// Convert images to RGB color space
switch (color_type) {
case PNG_COLOR_TYPE_PALETTE:
png_set_palette_to_rgb(png_ptr);
channels = 3;
break;
case PNG_COLOR_TYPE_GRAY:
if (bitdepth < 8) {
png_set_expand_gray_1_2_4_to_8(png_ptr);
}
bitdepth = 8;
break;
}
// Convert transparency (if needed) to a full alpha channel
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
png_set_tRNS_to_alpha(png_ptr);
channels += 1;
} else if (channels == 3) {
// Add an opaque alpha channel if still none exists
png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
channels = 4;
}
// Invert color byte-order as used by plMipmap for DirectX
png_set_bgr(png_ptr);
/// Construct a new mipmap to hold everything
newMipmap = TRACKED_NEW plMipmap(imgWidth, imgHeight, plMipmap::kARGB32Config, 1, plMipmap::kUncompressed);
char* destp = (char*)newMipmap->GetImage();
png_bytep* row_ptrs = TRACKED_NEW png_bytep[imgHeight];
const unsigned int stride = imgWidth * bitdepth * channels / 8;
// Assign row pointers to the appropriate locations in the newly-created Mipmap
for (size_t i = 0; i < imgHeight; i++) {
row_ptrs[i] = (png_bytep)destp + (i * stride);
}
png_read_image(png_ptr, row_ptrs);
png_read_end(png_ptr, end_info);
// Clean up allocated structs
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
delete [] row_ptrs;
}
} catch (...) {
if (newMipmap != NULL) {
delete newMipmap;
newMipmap = NULL;
}
}
return newMipmap;
}
plMipmap* plPNG::ReadFromFile(const char* fileName)
{
wchar* wFilename = hsStringToWString(fileName);
plMipmap* retVal = ReadFromFile(wFilename);
delete [] wFilename;
return retVal;
}
plMipmap* plPNG::ReadFromFile(const wchar* fileName)
{
hsUNIXStream in;
if (!in.Open(fileName, L"rb")) {
return false;
}
plMipmap* ret = IRead(&in);
in.Close();
return ret;
}
hsBool plPNG::IWrite(plMipmap* source, hsStream* outStream)
{
hsBool result = true;
try {
// Allocate required structs
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr) {
throw(false);
}
png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) {
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
throw(false);
}
// Assign delegate function for writing to hsStream
png_set_write_fn(png_ptr, (png_voidp)outStream, pngWriteDelegate, NULL);
UInt8 psize = source->GetPixelSize();
png_set_IHDR(png_ptr, info_ptr, source->GetWidth(), source->GetHeight(), 8, PNG_COLOR_TYPE_RGB_ALPHA,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
// Invert color byte-order as used by plMipmap for DirectX
png_set_bgr(png_ptr);
// Write out the image metadata
png_write_info(png_ptr, info_ptr);
char* srcp = (char*)source->GetImage();
png_bytep* row_ptrs = TRACKED_NEW png_bytep[source->GetHeight()];
const unsigned int stride = source->GetWidth() * source->GetPixelSize() / 8;
// Assign row pointers to the appropriate locations in the newly-created Mipmap
for (size_t i = 0; i < source->GetHeight(); i++) {
row_ptrs[i] = (png_bytep)srcp + (i * stride);
}
png_write_image(png_ptr, row_ptrs);
png_write_end(png_ptr, info_ptr);
// Clean up allocated structs
png_destroy_write_struct(&png_ptr, &info_ptr);
delete [] row_ptrs;
} catch (...) {
result = false;
}
return result;
}
hsBool plPNG::WriteToFile(const char* fileName, plMipmap* sourceData)
{
wchar* wFilename = hsStringToWString(fileName);
hsBool retVal = WriteToFile(wFilename, sourceData);
delete [] wFilename;
return retVal;
}
hsBool plPNG::WriteToFile(const wchar* fileName, plMipmap* sourceData)
{
hsUNIXStream out;
if (!out.Open(fileName, L"wb")) {
return false;
}
hsBool ret = IWrite(sourceData, &out);
out.Close();
return ret;
}

View File

@ -0,0 +1,71 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef _plPNG_h
#define _plPNG_h
//// Class Definition /////////////////////////////////////////////////////////
class plMipmap;
class hsStream;
class plPNG {
protected:
plMipmap* IRead(hsStream* inStream);
hsBool IWrite(plMipmap* source, hsStream* outStream);
public:
plMipmap* ReadFromStream(hsStream* inStream) { return IRead(inStream); }
plMipmap* ReadFromFile(const char* fileName);
plMipmap* ReadFromFile(const wchar* fileName);
hsBool WriteToStream(hsStream* outStream, plMipmap* sourceData) { return IWrite(sourceData, outStream); }
hsBool WriteToFile(const char* fileName, plMipmap* sourceData);
hsBool WriteToFile(const wchar* fileName, plMipmap* sourceData);
static plPNG& Instance(void);
};
#endif // _plPNG_h

View File

@ -0,0 +1,111 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// plTGAWriter Class Functions //
// Simple utility class for writing a plMipmap out as a TGA file //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 8.15.2001 mcn - Created. //
// //
///////////////////////////////////////////////////////////////////////////////
#include "hsTypes.h"
#include "plTGAWriter.h"
#include "plMipmap.h"
#include "hsStream.h"
//// Class Statics ////////////////////////////////////////////////////////////
plTGAWriter plTGAWriter::fInstance;
//// WriteMipmap //////////////////////////////////////////////////////////////
void plTGAWriter::WriteMipmap( const char *fileName, plMipmap *mipmap )
{
hsUNIXStream stream;
int x, y;
hsRGBAColor32 pixel;
stream.Open( fileName, "wb" );
/// Write header
stream.WriteByte( 0 ); // Size of ID field
stream.WriteByte( 0 ); // Map type
stream.WriteByte( 2 ); // Type 2 image - Unmapped RGB
stream.WriteByte( 0 ); // Color map spec
stream.WriteByte( 0 ); // Color map spec
stream.WriteByte( 0 ); // Color map spec
stream.WriteByte( 0 ); // Color map spec
stream.WriteByte( 0 ); // Color map spec
stream.WriteSwap16( 0 ); // xOrigin
stream.WriteSwap16( 0 ); // yOrigin
stream.WriteSwap16( (UInt16)mipmap->GetWidth() );
stream.WriteSwap16( (UInt16)mipmap->GetHeight() );
stream.WriteByte( 24 );
stream.WriteByte( 0 );
/// Write image data (gotta do inversed, stupid TGAs...)
for( y = mipmap->GetHeight() - 1; y >= 0; y-- )
{
for( x = 0; x < mipmap->GetWidth(); x++ )
{
pixel = *( (hsRGBAColor32 *)mipmap->GetAddr32( x, y ) );
stream.WriteByte( pixel.b );
stream.WriteByte( pixel.g );
stream.WriteByte( pixel.r );
}
}
/// All done!
stream.Close();
}

View File

@ -0,0 +1,79 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// plTGAWriter Class Header //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 8.15.2001 mcn - Created. //
// //
///////////////////////////////////////////////////////////////////////////////
#ifndef _plTGAWriter_h
#define _plTGAWriter_h
#include "hsTypes.h"
class plMipmap;
//// Class Definition /////////////////////////////////////////////////////////
class plTGAWriter
{
private:
static plTGAWriter fInstance;
plTGAWriter() {}
public:
static plTGAWriter &Instance( void ) { return fInstance; }
void WriteMipmap( const char *fileName, plMipmap *mipmap );
};
#endif // _plTGAWriter_h

View File

@ -0,0 +1,299 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// plWinFontCache Class Header //
// I've stopped keeping track, there are far too many reasons already to //
// hate Microsoft. Anyway, this class keeps track of various Win32 fonts we //
// allocate because Win98/ME seems to have problems re-allocating the exact //
// same freaking goddamn font over and over again. I mean, you'd think //
// there'd be a rule somewhere about deterministic behavior when calling //
// the exact same function with the exact same parameters over and over... //
// Oh, wait... //
// //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 11.25.2002 mcn - Created. //
// //
///////////////////////////////////////////////////////////////////////////////
#include "hsTypes.h"
#include "hsWindows.h"
#include "plWinFontCache.h"
#include "../plStatusLog/plStatusLog.h"
#include "../plFile/hsFiles.h"
#include "../plGImage/plDynSurfaceWriter.h"
#if HS_BUILD_FOR_WIN32
#include <wingdi.h>
char *plWinFontCache::kCustFontExtension = ".prf";
plWinFontCache::plWinFontCache()
{
fInShutdown = false;
fCustFontDir = nil;
}
plWinFontCache::~plWinFontCache()
{
fInShutdown = true;
Clear();
delete [] fCustFontDir;
}
plWinFontCache &plWinFontCache::GetInstance( void )
{
static plWinFontCache cache;
return cache;
}
HFONT plWinFontCache::IFindFont( const char *face, int height, int weight, hsBool italic, UInt32 quality )
{
int i;
for( i = 0; i < fFontCache.GetCount(); i++ )
{
// Do other tests first, since they're cheaper
if( fFontCache[ i ].fHeight == height &&
fFontCache[ i ].fWeight == weight &&
fFontCache[ i ].fItalic == italic &&
fFontCache[ i ].fQuality == quality )
{
if( strcmp( fFontCache[ i ].fFace, face ) == 0 )
return fFontCache[ i ].fFont;
}
}
return nil;
}
HFONT plWinFontCache::IMakeFont( const char *face, int height, int weight, hsBool italic, UInt32 quality )
{
plFontRecord myRec;
int i;
// Find a cached name for us
for( i = 0; i < fFontNameCache.GetCount(); i++ )
{
if( strcmp( face, fFontNameCache[ i ] ) == 0 )
break;
}
if( i == fFontNameCache.GetCount() )
fFontNameCache.Append( hsStrcpy( face ) );
myRec.fFace = fFontNameCache[ i ];
myRec.fHeight = height;
myRec.fWeight = weight;
myRec.fItalic = italic;
myRec.fQuality = quality;
myRec.fFont = CreateFont( height, 0, 0, 0, weight, italic ? TRUE : FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, VARIABLE_PITCH, face );
if( myRec.fFont != nil )
{
//#ifdef HS_DEBUGGING
#if 1
LOGFONT fontInfo;
if( GetObject( myRec.fFont, sizeof( fontInfo ), &fontInfo ) )
{
const char *err = nil;
if( fontInfo.lfQuality != quality )
err = "Quality of created font does not match";
if( fontInfo.lfHeight != height )
err = "Height of created font does not match";
if( fontInfo.lfWeight != weight )
err = "Weight of created font does not match";
if( fontInfo.lfItalic != italic )
err = "Italic-ness of created font does not match";
if( stricmp( fontInfo.lfFaceName, face ) != 0 )
err = "Face of created font does not match";
if( err != nil )
{
static bool triedClearing = false;
if( fontInfo.lfQuality != quality )
{
plStatusLog::AddLineS( "pipeline.log", "ERROR: CreateFont() failed to return proper font (%s). Using what was given...", err );
}
else
{
plStatusLog::AddLineS( "pipeline.log", "ERROR: CreateFont() failed to return proper font (%s). %s", err, triedClearing ? "" : "Clearing cache and retrying..." );
if( !triedClearing )
{
triedClearing = true;
// Didn't work, so get rid of it
DeleteObject( myRec.fFont );
// Clear all fonts and try again
Clear();
// Make sure we reload our custom fonts tho
ILoadCustomFonts();
// Try again
HFONT font = IMakeFont( face, height, weight, italic, quality );
triedClearing = false;
return font;
}
}
}
}
#endif
fFontCache.Append( myRec );
}
else
{
plStatusLog::AddLineS( "pipeline.log", "ERROR: CreateFont() call FAILED (face: %s, size: %d %s %s)", face, -height, weight == FW_BOLD ? "bold" : "", italic ? "italic" : "" );
}
return myRec.fFont;
}
HFONT plWinFontCache::GetMeAFont( const char *face, int height, int weight, hsBool italic, UInt32 quality )
{
HFONT font = IFindFont( face, height, weight, italic, quality );
if( font == nil )
font = IMakeFont( face, height, weight, italic, quality );
return font;
}
void plWinFontCache::Clear( void )
{
int i;
if( !fInShutdown )
plStatusLog::AddLineS( "pipeline.log", "** Clearing Win32 font cache **" );
for( i = 0; i < fFontCache.GetCount(); i++ )
DeleteObject( fFontCache[ i ].fFont );
fFontCache.Reset();
for( i = 0; i < fFontNameCache.GetCount(); i++ )
delete [] fFontNameCache[ i ];
fFontNameCache.Reset();
for( i = 0; i < fCustFonts.GetCount(); i++ )
{
#if (_WIN32_WINNT >= 0x0500)
if( plDynSurfaceWriter::CanHandleLotsOfThem() )
RemoveFontResourceEx( fCustFonts[ i ]->fFilename, FR_PRIVATE, 0 );
else
#endif
if( RemoveFontResource( fCustFonts[ i ]->fFilename ) == 0 )
{
int q= 0;
DWORD e = GetLastError();
}
delete fCustFonts[ i ];
}
fCustFonts.Reset();
}
void plWinFontCache::FreeFont( HFONT font )
{
// Currently a no-op, but should do some sort of ref-counting
}
void plWinFontCache::LoadCustomFonts( const char *dir )
{
delete [] fCustFontDir;
fCustFontDir = ( dir != nil ) ? hsStrcpy( dir ) : nil;
ILoadCustomFonts();
}
void plWinFontCache::ILoadCustomFonts( void )
{
if( fCustFontDir == nil )
return;
// Iterate through all the custom fonts in our dir
hsFolderIterator iter( fCustFontDir );
char fileName[ kFolderIterator_MaxPath ];
int numAdded;
while( iter.NextFileSuffix( kCustFontExtension ) )
{
iter.GetPathAndName( fileName );
// Note that this call can be translated as "does my OS suck?"
#if (_WIN32_WINNT >= 0x0500)
if( plDynSurfaceWriter::CanHandleLotsOfThem() )
numAdded = AddFontResourceEx( fileName, FR_PRIVATE, 0 );
else
#endif
numAdded = AddFontResource( fileName );
if( numAdded > 0 )
{
plStatusLog::AddLineS( "pipeline.log", "WinFontCache: Added custom font %s, %d fonts", fileName, numAdded );
fCustFonts.Append( TRACKED_NEW plCustFont( fileName ) );
}
else
{
plStatusLog::AddLineS( "pipeline.log", "WinFontCache: Unable to load custom font %s", fileName );
}
}
}
#endif

View File

@ -0,0 +1,131 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// plWinFontCache Class Header //
// I've stopped keeping track, there are far too many reasons already to //
// hate Microsoft. Anyway, this class keeps track of various Win32 fonts we //
// allocate because Win98/ME seems to have problems re-allocating the exact //
// same freaking goddamn font over and over again. I mean, you'd think //
// there'd be a rule somewhere about deterministic behavior when calling //
// the exact same function with the exact same parameters over and over... //
// Oh, wait... //
// //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 11.25.2002 mcn - Created. //
// //
///////////////////////////////////////////////////////////////////////////////
#ifndef _plWinFontCache_h
#define _plWinFontCache_h
#include "hsColorRGBA.h"
#include "hsWindows.h" // EVIL
#include "hsTemplates.h"
#if HS_BUILD_FOR_WIN32
//// Class Definition /////////////////////////////////////////////////////////
class plWinFontCache
{
protected:
class plFontRecord
{
public:
HFONT fFont;
char *fFace; // Pointer is owned by fFontNameCache
int fHeight;
int fWeight;
hsBool fItalic;
UInt32 fQuality;
};
class plCustFont
{
public:
char *fFilename;
plCustFont( const char *c ) { fFilename = hsStrcpy( c ); }
~plCustFont() { delete [] fFilename; }
};
hsBool fInShutdown;
hsTArray<plFontRecord> fFontCache;
hsTArray<char *> fFontNameCache;
char *fCustFontDir;
hsTArray<plCustFont *> fCustFonts;
plWinFontCache();
HFONT IFindFont( const char *face, int height, int weight, hsBool italic, UInt32 quality );
HFONT IMakeFont( const char *face, int height, int weight, hsBool italic, UInt32 quality );
void ILoadCustomFonts( void );
public:
virtual ~plWinFontCache();
static plWinFontCache &GetInstance( void );
HFONT GetMeAFont( const char *face, int height, int weight, hsBool italic, UInt32 quality );
void FreeFont( HFONT font );
void Clear( void );
void LoadCustomFonts( const char *dir );
// Our custom font extension
static char *kCustFontExtension;
};
#endif // HS_BUILD_FOR_WIN32
#endif // _plWinFontCache_h