mirror of
https://github.com/scummvm/scummvm.git
synced 2024-05-28 16:57:39 -04:00
Compare commits
9 commits
87b4dd6a26
...
e5bc220045
Author | SHA1 | Date | |
---|---|---|---|
e5bc220045 | |||
c78780bca0 | |||
e35ad1e428 | |||
f21878353f | |||
126cba16cf | |||
a9e5a2fa01 | |||
31011c5b37 | |||
6f36512f77 | |||
3964255a36 |
|
@ -387,7 +387,9 @@ bool TextMgr::messageBox(const char *textPtr) {
|
|||
uint32 windowTimer = _vm->getVar(VM_VAR_WINDOW_AUTO_CLOSE_TIMER);
|
||||
debugC(3, kDebugLevelText, "blocking window v21=%d", windowTimer);
|
||||
|
||||
windowTimer = windowTimer * 20; // 1 = 0.5 seconds (20 cycles)
|
||||
// 1 = 0.5 seconds. NB: ScummVM runs at 40 fps, not 20, so we have
|
||||
// to multiply by 20, not 10, to get the number of cycles.
|
||||
windowTimer = windowTimer * 20;
|
||||
_messageBoxCancelled = false;
|
||||
|
||||
_vm->inGameTimerResetPassedCycles();
|
||||
|
|
|
@ -174,20 +174,18 @@ ErrorCode CBofDataFile::open() {
|
|||
assert(isValidObject(this));
|
||||
|
||||
// Only continue if there is no current error
|
||||
if (_errCode == ERR_NONE) {
|
||||
if (_stream == nullptr) {
|
||||
if (!(_lFlags & CDF_READONLY)) {
|
||||
if (_lFlags & CDF_SAVEFILE) {
|
||||
if (_lFlags & CDF_CREATE)
|
||||
create();
|
||||
} else if (!fileExists(_szFileName))
|
||||
if (_errCode == ERR_NONE && _stream == nullptr) {
|
||||
if (!(_lFlags & CDF_READONLY)) {
|
||||
if (_lFlags & CDF_SAVEFILE) {
|
||||
if (_lFlags & CDF_CREATE)
|
||||
create();
|
||||
}
|
||||
} else if (!fileExists(_szFileName))
|
||||
create();
|
||||
}
|
||||
|
||||
if (_stream == nullptr) {
|
||||
// Open data file
|
||||
CBofFile::open(_szFileName, _lFlags);
|
||||
}
|
||||
if (_stream == nullptr) {
|
||||
// Open data file
|
||||
CBofFile::open(_szFileName, _lFlags);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -242,32 +240,30 @@ ErrorCode CBofDataFile::readHeader() {
|
|||
|
||||
if (_lHeaderLength != 0) {
|
||||
// Allocate buffer to hold header
|
||||
if ((_pHeader = new HEADER_REC[(int)_lNumRecs]) != nullptr) {
|
||||
// Seek to start of header
|
||||
seek(_lHeaderStart);
|
||||
_pHeader = new HEADER_REC[(int)_lNumRecs];
|
||||
if (_pHeader == nullptr)
|
||||
fatalError(ERR_MEMORY, buildString("Could not allocate footer for file '%s'", _szFileName));
|
||||
|
||||
// Read header
|
||||
ErrorCode errCode = ERR_NONE;
|
||||
for (int i = 0; i < _lNumRecs && errCode == ERR_NONE; ++i) {
|
||||
errCode = read(_pHeader[i]);
|
||||
}
|
||||
// Seek to start of header
|
||||
seek(_lHeaderStart);
|
||||
|
||||
if (errCode == ERR_NONE) {
|
||||
uint32 lCrc = calculateCRC(&_pHeader->_lOffset, 4 * _lNumRecs);
|
||||
// Read header
|
||||
ErrorCode errCode = ERR_NONE;
|
||||
for (int i = 0; i < _lNumRecs && errCode == ERR_NONE; ++i) {
|
||||
errCode = read(_pHeader[i]);
|
||||
}
|
||||
|
||||
if (lCrc != stHeaderInfo._lFootCrc) {
|
||||
logError(buildString("Error: '%s' has invalid footer", _szFileName));
|
||||
_errCode = ERR_CRC;
|
||||
}
|
||||
if (errCode == ERR_NONE) {
|
||||
uint32 lCrc = calculateCRC(&_pHeader->_lOffset, 4 * _lNumRecs);
|
||||
|
||||
} else {
|
||||
logError(buildString("Error: Could not read footer in file '%s'", _szFileName));
|
||||
_errCode = ERR_FREAD;
|
||||
if (lCrc != stHeaderInfo._lFootCrc) {
|
||||
logError(buildString("Error: '%s' has invalid footer", _szFileName));
|
||||
_errCode = ERR_CRC;
|
||||
}
|
||||
|
||||
} else {
|
||||
logError(buildString("Error: Could not allocate footer for file '%s'", _szFileName));
|
||||
_errCode = ERR_MEMORY;
|
||||
logError(buildString("Error: Could not read footer in file '%s'", _szFileName));
|
||||
_errCode = ERR_FREAD;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -505,35 +501,33 @@ ErrorCode CBofDataFile::writeRecord(int32 lRecNum, void *pBuf, int32 lSize, bool
|
|||
|
||||
// Allocate a buffer big enough for one chunk
|
||||
byte *pTmpBuf = (byte *)bofAlloc(lChunkSize);
|
||||
if (pTmpBuf != nullptr) {
|
||||
// While there is data to move
|
||||
while (lBufLength > 0) {
|
||||
// Seek to beginning of the source for this chunk
|
||||
setPosition(pRecInfo->_lOffset + pRecInfo->_lLength + lBufLength - lChunkSize);
|
||||
if (pTmpBuf == nullptr)
|
||||
fatalError(ERR_MEMORY, "Unable to allocate %ld bytes to expand record size in writeRecord()", lBufLength);
|
||||
|
||||
// Read the chunk
|
||||
read(pTmpBuf, lChunkSize);
|
||||
// While there is data to move
|
||||
while (lBufLength > 0) {
|
||||
// Seek to beginning of the source for this chunk
|
||||
setPosition(pRecInfo->_lOffset + pRecInfo->_lLength + lBufLength - lChunkSize);
|
||||
|
||||
// Seek to this chunks new positon (offset by 'lDiff' bytes)
|
||||
setPosition(pRecInfo->_lOffset + pRecInfo->_lLength + lBufLength - lChunkSize + lDiff);
|
||||
// Read the chunk
|
||||
read(pTmpBuf, lChunkSize);
|
||||
|
||||
// Write chunk to new position
|
||||
write(pTmpBuf, lChunkSize);
|
||||
// Seek to this chunks new position (offset by 'lDiff' bytes)
|
||||
setPosition(pRecInfo->_lOffset + pRecInfo->_lLength + lBufLength - lChunkSize + lDiff);
|
||||
|
||||
// That much less to do next time thru
|
||||
lBufLength -= lChunkSize;
|
||||
// Write chunk to new position
|
||||
write(pTmpBuf, lChunkSize);
|
||||
|
||||
// Last chunk is lBufLength
|
||||
lChunkSize = MIN(lBufLength, lChunkSize);
|
||||
}
|
||||
// That much less to do next time thru
|
||||
lBufLength -= lChunkSize;
|
||||
|
||||
// Don't need that temp buffer anymore
|
||||
bofFree(pTmpBuf);
|
||||
|
||||
} else {
|
||||
reportError(ERR_MEMORY, "Unable to allocate %ld bytes to expand record size in writeRecord()", lBufLength);
|
||||
// Last chunk is lBufLength
|
||||
lChunkSize = MIN(lBufLength, lChunkSize);
|
||||
}
|
||||
|
||||
// Don't need that temp buffer anymore
|
||||
bofFree(pTmpBuf);
|
||||
|
||||
// Tell the rest of the records that they moved
|
||||
for (int i = lRecNum + 1; i < getNumberOfRecs(); i++) {
|
||||
_pHeader[i]._lOffset += lDiff;
|
||||
|
@ -563,22 +557,20 @@ ErrorCode CBofDataFile::writeRecord(int32 lRecNum, void *pBuf, int32 lSize, bool
|
|||
|
||||
// Allocate a buffer that could hold the largest record
|
||||
byte *pTmpBuf = (byte *)bofAlloc((int)getMaxRecSize());
|
||||
if (pTmpBuf != nullptr) {
|
||||
for (int i = (int)lRecNum + 1; i < (int)_lNumRecs - 1; i++) {
|
||||
_errCode = readRecord(i, pTmpBuf);
|
||||
if (_errCode != ERR_NONE)
|
||||
break;
|
||||
if (pTmpBuf == nullptr)
|
||||
fatalError(ERR_MEMORY, "unable to allocate a buffer of %ld bytes", getMaxRecSize());
|
||||
|
||||
_errCode = writeRecord(i + 1, pTmpBuf);
|
||||
if (_errCode != ERR_NONE)
|
||||
break;
|
||||
}
|
||||
for (int i = (int)lRecNum + 1; i < (int)_lNumRecs - 1; i++) {
|
||||
_errCode = readRecord(i, pTmpBuf);
|
||||
if (_errCode != ERR_NONE)
|
||||
break;
|
||||
|
||||
bofFree(pTmpBuf);
|
||||
|
||||
} else {
|
||||
_errCode = ERR_MEMORY;
|
||||
_errCode = writeRecord(i + 1, pTmpBuf);
|
||||
if (_errCode != ERR_NONE)
|
||||
break;
|
||||
}
|
||||
|
||||
bofFree(pTmpBuf);
|
||||
}
|
||||
|
||||
// If we are to update the header now
|
||||
|
@ -609,13 +601,11 @@ ErrorCode CBofDataFile::verifyRecord(int32 lRecNum) {
|
|||
|
||||
// Allocate space to hold this record
|
||||
void *pBuf = bofAlloc((int)getRecSize(lRecNum));
|
||||
if (pBuf != nullptr) {
|
||||
_errCode = readRecord(lRecNum, pBuf);
|
||||
bofFree(pBuf);
|
||||
if (pBuf == nullptr)
|
||||
fatalError(ERR_MEMORY, "Unable to allocate a buffer of %ld bytes", getRecSize(lRecNum));
|
||||
|
||||
} else {
|
||||
_errCode = ERR_MEMORY;
|
||||
}
|
||||
_errCode = readRecord(lRecNum, pBuf);
|
||||
bofFree(pBuf);
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
|
@ -656,33 +646,30 @@ ErrorCode CBofDataFile::addRecord(void *pBuf, int32 lLength, bool bUpdateHeader,
|
|||
_lNumRecs++;
|
||||
|
||||
HEADER_REC *pTmpHeader = new HEADER_REC[(int)_lNumRecs];
|
||||
if (pTmpHeader != nullptr) {
|
||||
if (_pHeader != nullptr) {
|
||||
memcpy(pTmpHeader, _pHeader, (size_t)(HEADER_REC::size() * (_lNumRecs - 1)));
|
||||
if (pTmpHeader == nullptr)
|
||||
fatalError(ERR_MEMORY, "Could not allocate a data file header");
|
||||
|
||||
delete[] _pHeader;
|
||||
}
|
||||
|
||||
_pHeader = pTmpHeader;
|
||||
|
||||
int32 lRecNum = _lNumRecs - 1;
|
||||
HEADER_REC *pCurRec = &_pHeader[lRecNum];
|
||||
int32 lPrevLength = HEAD_INFO::size();
|
||||
int32 lPrevOffset = 0;
|
||||
|
||||
if (lRecNum != 0) {
|
||||
lPrevLength = _pHeader[lRecNum - 1]._lLength;
|
||||
lPrevOffset = _pHeader[lRecNum - 1]._lOffset;
|
||||
}
|
||||
|
||||
pCurRec->_lLength = lLength;
|
||||
pCurRec->_lOffset = lPrevOffset + lPrevLength;
|
||||
|
||||
writeRecord(lRecNum, pBuf, lLength, bUpdateHeader, lKey);
|
||||
|
||||
} else {
|
||||
reportError(ERR_MEMORY, "Could not allocate a data file header");
|
||||
if (_pHeader != nullptr) {
|
||||
memcpy(pTmpHeader, _pHeader, (size_t)(HEADER_REC::size() * (_lNumRecs - 1)));
|
||||
delete[] _pHeader;
|
||||
}
|
||||
|
||||
_pHeader = pTmpHeader;
|
||||
|
||||
int32 lRecNum = _lNumRecs - 1;
|
||||
HEADER_REC *pCurRec = &_pHeader[lRecNum];
|
||||
int32 lPrevLength = HEAD_INFO::size();
|
||||
int32 lPrevOffset = 0;
|
||||
|
||||
if (lRecNum != 0) {
|
||||
lPrevLength = _pHeader[lRecNum - 1]._lLength;
|
||||
lPrevOffset = _pHeader[lRecNum - 1]._lOffset;
|
||||
}
|
||||
|
||||
pCurRec->_lLength = lLength;
|
||||
pCurRec->_lOffset = lPrevOffset + lPrevLength;
|
||||
|
||||
writeRecord(lRecNum, pBuf, lLength, bUpdateHeader, lKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,17 +54,14 @@ ErrorCode CBofStringTable::load(const char *pszFileName) {
|
|||
|
||||
// Allocate a buffer to hold entire file
|
||||
_pBuf = (byte *)bofAlloc(_lBufSize + 1);
|
||||
if (_pBuf != nullptr) {
|
||||
memset(_pBuf, 0, _lBufSize + 1);
|
||||
if (_pBuf == nullptr)
|
||||
fatalError(ERR_MEMORY, "Unable to allocate %u bytes for String Table", _lBufSize);
|
||||
|
||||
// Read in entire file
|
||||
read(_pBuf, _lBufSize);
|
||||
memset(_pBuf, 0, _lBufSize + 1);
|
||||
|
||||
buildTable();
|
||||
|
||||
} else {
|
||||
reportError(ERR_MEMORY, "Unable to allocate %ld bytes for String Table", _lBufSize);
|
||||
}
|
||||
// Read in entire file
|
||||
read(_pBuf, _lBufSize);
|
||||
buildTable();
|
||||
|
||||
// Don't need this file open anymore
|
||||
close();
|
||||
|
@ -116,16 +113,14 @@ ErrorCode CBofStringTable::buildTable() {
|
|||
pBuf++;
|
||||
|
||||
CResString *pString = new CResString(nId, (const char *)pBuf);
|
||||
if (pString != nullptr) {
|
||||
// Add this string to the table
|
||||
if (_pStringTable == nullptr) {
|
||||
_pStringTable = pString;
|
||||
} else {
|
||||
_pStringTable->addToTail(pString);
|
||||
}
|
||||
if (pString == nullptr)
|
||||
fatalError(ERR_MEMORY, "Unable to allocate a CResString");
|
||||
|
||||
// Add this string to the table
|
||||
if (_pStringTable == nullptr) {
|
||||
_pStringTable = pString;
|
||||
} else {
|
||||
reportError(ERR_MEMORY, "Unable to allocate a CResString");
|
||||
break;
|
||||
_pStringTable->addToTail(pString);
|
||||
}
|
||||
|
||||
while (*pBuf++ != '\0') {
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include "common/config-manager.h"
|
||||
#include "common/file.h"
|
||||
#include "common/substream.h"
|
||||
#include "common/xpfloat.h"
|
||||
|
||||
#include "director/director.h"
|
||||
#include "director/cast.h"
|
||||
|
@ -1242,10 +1241,7 @@ ScriptContext *LingoCompiler::compileLingoV4(Common::SeekableReadStreamEndian &s
|
|||
// Floats are stored as an "80 bit IEEE Standard 754 floating
|
||||
// point number (Standard Apple Numeric Environment [SANE] data type
|
||||
// Extended).
|
||||
uint16 signAndExponent = READ_BE_UINT16(&constsStore[pointer]);
|
||||
uint64 mantissa = READ_BE_UINT64(&constsStore[pointer+2]);
|
||||
|
||||
constant.u.f = Common::XPFloat(signAndExponent, mantissa).toDouble(Common::XPFloat::kSemanticsSANE);
|
||||
constant.u.f = readAppleFloat80(&constsStore[pointer]);
|
||||
} else if (length == 8) {
|
||||
constant.u.f = READ_BE_FLOAT64(&constsStore[pointer]);
|
||||
} else {
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "common/punycode.h"
|
||||
#include "common/str-array.h"
|
||||
#include "common/tokenizer.h"
|
||||
#include "common/xpfloat.h"
|
||||
#include "common/compression/deflate.h"
|
||||
|
||||
#include "director/types.h"
|
||||
|
@ -1650,4 +1651,15 @@ void DirectorEngine::delayMillis(uint32 delay) {
|
|||
_system->delayMillis(delay);
|
||||
}
|
||||
|
||||
double readAppleFloat80(byte *ptr) {
|
||||
// Floats in an "80 bit IEEE Standard 754 floating
|
||||
// point number (Standard Apple Numeric Environment [SANE] data type
|
||||
// Extended).
|
||||
|
||||
uint16 signAndExponent = READ_BE_UINT16(&ptr[0]);
|
||||
uint64 mantissa = READ_BE_UINT64(&ptr[2]);
|
||||
|
||||
return Common::XPFloat(signAndExponent, mantissa).toDouble(Common::XPFloat::kSemanticsSANE);
|
||||
}
|
||||
|
||||
} // End of namespace Director
|
||||
|
|
|
@ -70,6 +70,8 @@ Common::Path dumpFactoryName(const char *prefix, const char *name, const char *e
|
|||
|
||||
bool isButtonSprite(SpriteType spriteType);
|
||||
|
||||
double readAppleFloat80(byte *ptr);
|
||||
|
||||
class RandomState {
|
||||
public:
|
||||
uint32 _seed;
|
||||
|
|
|
@ -140,7 +140,7 @@ RenderedImage::RenderedImage(const Common::String &filename, bool &result) :
|
|||
delete[] pFileData;
|
||||
|
||||
_doCleanup = true;
|
||||
_alphaType = checkForTransparency();
|
||||
_alphaType = _surface.detectAlpha();
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -260,24 +260,4 @@ void RenderedImage::copyDirectly(int posX, int posY) {
|
|||
g_system->copyRectToScreen(data, _backSurface->pitch, posX, posY, w, h);
|
||||
}
|
||||
|
||||
Graphics::AlphaType RenderedImage::checkForTransparency() const {
|
||||
// Check if the source bitmap has any transparent pixels at all
|
||||
Graphics::AlphaType alphaType = Graphics::ALPHA_OPAQUE;
|
||||
uint32 mask = _surface.format.ARGBToColor(0xff, 0, 0, 0);
|
||||
const uint32 *data = (const uint32 *)_surface.getPixels();
|
||||
|
||||
for (int i = 0; i < _surface.h; i++) {
|
||||
for (int j = 0; j < _surface.w; j++) {
|
||||
if ((*data & mask) != mask) {
|
||||
if ((*data & mask) != 0)
|
||||
return Graphics::ALPHA_FULL;
|
||||
else
|
||||
alphaType = Graphics::ALPHA_BINARY;
|
||||
}
|
||||
data++;
|
||||
}
|
||||
}
|
||||
return alphaType;
|
||||
}
|
||||
|
||||
} // End of namespace Sword25
|
||||
|
|
|
@ -113,8 +113,6 @@ private:
|
|||
bool _doCleanup;
|
||||
|
||||
Graphics::ManagedSurface *_backSurface;
|
||||
|
||||
Graphics::AlphaType checkForTransparency() const;
|
||||
};
|
||||
|
||||
} // End of namespace Sword25
|
||||
|
|
|
@ -73,39 +73,6 @@ BaseSurfaceOSystem::~BaseSurfaceOSystem() {
|
|||
renderer->invalidateTicketsFromSurface(this);
|
||||
}
|
||||
|
||||
Graphics::AlphaType hasTransparencyType(const Graphics::Surface *surf) {
|
||||
if (surf->format.bytesPerPixel != 4) {
|
||||
warning("hasTransparencyType:: non 32 bpp surface passed as argument");
|
||||
return Graphics::ALPHA_OPAQUE;
|
||||
}
|
||||
uint8 r, g, b, a;
|
||||
bool seenAlpha = false;
|
||||
bool seenFullAlpha = false;
|
||||
for (int i = 0; i < surf->h; i++) {
|
||||
if (seenFullAlpha) {
|
||||
break;
|
||||
}
|
||||
for (int j = 0; j < surf->w; j++) {
|
||||
uint32 pix = *(const uint32 *)surf->getBasePtr(j, i);
|
||||
surf->format.colorToARGB(pix, a, r, g, b);
|
||||
if (a != 255) {
|
||||
seenAlpha = true;
|
||||
if (a != 0) {
|
||||
seenFullAlpha = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (seenFullAlpha) {
|
||||
return Graphics::ALPHA_FULL;
|
||||
} else if (seenAlpha) {
|
||||
return Graphics::ALPHA_BINARY;
|
||||
} else {
|
||||
return Graphics::ALPHA_OPAQUE;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool BaseSurfaceOSystem::create(const Common::String &filename, bool defaultCK, byte ckRed, byte ckGreen, byte ckBlue, int lifeTime, bool keepLoaded) {
|
||||
/* BaseRenderOSystem *renderer = static_cast<BaseRenderOSystem *>(_gameRef->_renderer); */
|
||||
|
@ -188,7 +155,7 @@ bool BaseSurfaceOSystem::finishLoad() {
|
|||
_surface->applyColorKey(_ckRed, _ckGreen, _ckBlue, replaceAlpha);
|
||||
}
|
||||
|
||||
_alphaType = hasTransparencyType(_surface);
|
||||
_alphaType = _surface->detectAlpha();
|
||||
_valid = true;
|
||||
|
||||
_gameRef->addMem(_width * _height * 4);
|
||||
|
|
|
@ -51,6 +51,7 @@ typedef void (VectorRenderer::*DrawingFunctionCallback)(const Common::Rect &, co
|
|||
struct DrawStep {
|
||||
DrawingFunctionCallback drawingCall; /**< Pointer to drawing function */
|
||||
Graphics::ManagedSurface *blitSrc;
|
||||
Graphics::AlphaType alphaType;
|
||||
|
||||
struct Color {
|
||||
uint8 r, g, b;
|
||||
|
@ -99,6 +100,7 @@ struct DrawStep {
|
|||
DrawStep() {
|
||||
drawingCall = nullptr;
|
||||
blitSrc = nullptr;
|
||||
alphaType = Graphics::ALPHA_OPAQUE;
|
||||
// fgColor, bgColor, gradColor1, gradColor2, bevelColor initialized by Color default constructor
|
||||
autoWidth = autoHeight = false;
|
||||
x = y = w = h = 0;
|
||||
|
@ -472,7 +474,7 @@ public:
|
|||
void drawCallback_BITMAP(const Common::Rect &area, const DrawStep &step) {
|
||||
uint16 x, y, w, h;
|
||||
stepGetPositions(step, area, x, y, w, h);
|
||||
blitManagedSurface(step.blitSrc, Common::Point(x, y));
|
||||
blitManagedSurface(step.blitSrc, Common::Point(x, y), step.alphaType);
|
||||
}
|
||||
|
||||
void drawCallback_CROSS(const Common::Rect &area, const DrawStep &step) {
|
||||
|
@ -523,7 +525,7 @@ public:
|
|||
*/
|
||||
virtual void blitSurface(const Graphics::ManagedSurface *source, const Common::Rect &r) = 0;
|
||||
|
||||
virtual void blitManagedSurface(const Graphics::ManagedSurface *source, const Common::Point &p) = 0;
|
||||
virtual void blitManagedSurface(const Graphics::ManagedSurface *source, const Common::Point &p, Graphics::AlphaType alphaType) = 0;
|
||||
|
||||
/**
|
||||
* Draws a string into the screen. Wrapper for the Graphics::Font string drawing
|
||||
|
|
|
@ -785,7 +785,7 @@ blitSurface(const Graphics::ManagedSurface *source, const Common::Rect &r) {
|
|||
|
||||
template<typename PixelType>
|
||||
void VectorRendererSpec<PixelType>::
|
||||
blitManagedSurface(const Graphics::ManagedSurface *source, const Common::Point &p) {
|
||||
blitManagedSurface(const Graphics::ManagedSurface *source, const Common::Point &p, Graphics::AlphaType alphaType) {
|
||||
Common::Rect drawRect(p.x, p.y, p.x + source->w, p.y + source->h);
|
||||
drawRect.clip(_clippingArea);
|
||||
drawRect.translate(-p.x, -p.y);
|
||||
|
@ -803,7 +803,11 @@ blitManagedSurface(const Graphics::ManagedSurface *source, const Common::Point &
|
|||
np = p;
|
||||
}
|
||||
|
||||
_activeSurface->blitFrom(*source, drawRect, np);
|
||||
if (alphaType != Graphics::ALPHA_OPAQUE) {
|
||||
_activeSurface->transBlitFrom(*source, drawRect, np);
|
||||
} else {
|
||||
_activeSurface->simpleBlitFrom(*source, drawRect, np);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename PixelType>
|
||||
|
|
|
@ -88,7 +88,7 @@ public:
|
|||
|
||||
void fillSurface() override;
|
||||
void blitSurface(const Graphics::ManagedSurface *source, const Common::Rect &r) override;
|
||||
void blitManagedSurface(const Graphics::ManagedSurface *source, const Common::Point &p) override;
|
||||
void blitManagedSurface(const Graphics::ManagedSurface *source, const Common::Point &p, Graphics::AlphaType alphaType) override;
|
||||
|
||||
void applyScreenShading(GUI::ThemeEngine::ShadingStyle shadingStyle) override;
|
||||
|
||||
|
|
|
@ -228,6 +228,73 @@ void ManagedSurface::copyFrom(const Surface &surf) {
|
|||
}
|
||||
}
|
||||
|
||||
void ManagedSurface::simpleBlitFrom(const Surface &src, const Palette *srcPalette) {
|
||||
simpleBlitFrom(src, Common::Rect(0, 0, src.w, src.h), Common::Point(0, 0), srcPalette);
|
||||
}
|
||||
|
||||
void ManagedSurface::simpleBlitFrom(const Surface &src, const Common::Point &destPos, const Palette *srcPalette) {
|
||||
simpleBlitFrom(src, Common::Rect(0, 0, src.w, src.h), destPos, srcPalette);
|
||||
}
|
||||
|
||||
void ManagedSurface::simpleBlitFrom(const Surface &src, const Common::Rect &srcRect,
|
||||
const Common::Point &destPos, const Palette *srcPalette) {
|
||||
simpleBlitFromInner(src, srcRect, destPos, srcPalette, false, 0);
|
||||
}
|
||||
|
||||
void ManagedSurface::simpleBlitFrom(const ManagedSurface &src) {
|
||||
simpleBlitFrom(src, Common::Rect(0, 0, src.w, src.h), Common::Point(0, 0));
|
||||
}
|
||||
|
||||
void ManagedSurface::simpleBlitFrom(const ManagedSurface &src, const Common::Point &destPos) {
|
||||
simpleBlitFrom(src, Common::Rect(0, 0, src.w, src.h), destPos);
|
||||
}
|
||||
|
||||
void ManagedSurface::simpleBlitFrom(const ManagedSurface &src, const Common::Rect &srcRect,
|
||||
const Common::Point &destPos) {
|
||||
simpleBlitFromInner(src._innerSurface, srcRect, destPos, src._palette,
|
||||
src._transparentColorSet, src._transparentColor);
|
||||
}
|
||||
|
||||
void ManagedSurface::simpleBlitFromInner(const Surface &src, const Common::Rect &srcRect,
|
||||
const Common::Point &destPos, const Palette *srcPalette,
|
||||
bool transparentColorSet, uint transparentColor) {
|
||||
|
||||
Common::Rect srcRectC = srcRect;
|
||||
Common::Rect dstRectC = srcRect;
|
||||
|
||||
dstRectC.moveTo(destPos.x, destPos.y);
|
||||
clip(srcRectC, dstRectC);
|
||||
|
||||
const byte *srcPtr = (const byte *)src.getBasePtr(srcRectC.left, srcRectC.top);
|
||||
byte *dstPtr = (byte *)getBasePtr(dstRectC.left, dstRectC.top);
|
||||
|
||||
if (src.format.isCLUT8()) {
|
||||
assert(srcPalette);
|
||||
assert(format.isCLUT8());
|
||||
|
||||
uint32 map[256];
|
||||
convertPaletteToMap(map, srcPalette->data(), srcPalette->size(), format);
|
||||
|
||||
if (transparentColorSet) {
|
||||
crossKeyBlitMap(dstPtr, srcPtr, pitch, src.pitch, srcRectC.width(), srcRectC.height(),
|
||||
format.bytesPerPixel, map, transparentColor);
|
||||
} else {
|
||||
crossBlitMap(dstPtr, srcPtr, pitch, src.pitch, srcRectC.width(), srcRectC.height(),
|
||||
format.bytesPerPixel, map);
|
||||
}
|
||||
} else {
|
||||
if (transparentColorSet) {
|
||||
crossKeyBlit(dstPtr, srcPtr, pitch, src.pitch, srcRectC.width(), srcRectC.height(),
|
||||
format, src.format, transparentColor);
|
||||
} else {
|
||||
crossBlit(dstPtr, srcPtr, pitch, src.pitch, srcRectC.width(), srcRectC.height(),
|
||||
format, src.format);
|
||||
}
|
||||
}
|
||||
|
||||
addDirtyRect(dstRectC);
|
||||
}
|
||||
|
||||
void ManagedSurface::blitFrom(const Surface &src, const Palette *srcPalette) {
|
||||
blitFrom(src, Common::Rect(0, 0, src.w, src.h), Common::Point(0, 0), srcPalette);
|
||||
}
|
||||
|
|
|
@ -85,6 +85,13 @@ private:
|
|||
*/
|
||||
Palette *_palette;
|
||||
protected:
|
||||
/**
|
||||
* Inner method for blitting.
|
||||
*/
|
||||
void simpleBlitFromInner(const Surface &src, const Common::Rect &srcRect,
|
||||
const Common::Point &destPos, const Palette *srcPalette,
|
||||
bool transparentColorSet, uint transparentColor);
|
||||
|
||||
/**
|
||||
* Inner method for blitting.
|
||||
*/
|
||||
|
@ -306,6 +313,38 @@ public:
|
|||
return Common::Rect(0, 0, this->w, this->h);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy another surface into this one.
|
||||
*/
|
||||
void simpleBlitFrom(const Surface &src, const Palette *srcPalette = nullptr);
|
||||
|
||||
/**
|
||||
* Copy another surface into this one at a given destination position.
|
||||
*/
|
||||
void simpleBlitFrom(const Surface &src, const Common::Point &destPos, const Palette *srcPalette = nullptr);
|
||||
|
||||
/**
|
||||
* Copy another surface into this one at a given destination position.
|
||||
*/
|
||||
void simpleBlitFrom(const Surface &src, const Common::Rect &srcRect,
|
||||
const Common::Point &destPos, const Palette *srcPalette = nullptr);
|
||||
|
||||
/**
|
||||
* Copy another surface into this one.
|
||||
*/
|
||||
void simpleBlitFrom(const ManagedSurface &src);
|
||||
|
||||
/**
|
||||
* Copy another surface into this one at a given destination position.
|
||||
*/
|
||||
void simpleBlitFrom(const ManagedSurface &src, const Common::Point &destPos);
|
||||
|
||||
/**
|
||||
* Copy another surface into this one at a given destination position.
|
||||
*/
|
||||
void simpleBlitFrom(const ManagedSurface &src, const Common::Rect &srcRect,
|
||||
const Common::Point &destPos);
|
||||
|
||||
/**
|
||||
* Copy another surface into this one.
|
||||
*/
|
||||
|
@ -674,6 +713,13 @@ public:
|
|||
addDirtyRect(r);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given surface contains alpha transparency
|
||||
*/
|
||||
AlphaType detectAlpha() const {
|
||||
return _innerSurface.detectAlpha();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a sub-area of the screen, but only add a single initial dirty rect
|
||||
* for the retrieved area.
|
||||
|
|
|
@ -443,6 +443,28 @@ bool Surface::setAlpha(uint8 alpha, bool skipTransparent) {
|
|||
skipTransparent, alpha);
|
||||
}
|
||||
|
||||
AlphaType Surface::detectAlpha() const {
|
||||
if (format.isCLUT8() || format.aBits() == 0)
|
||||
return ALPHA_OPAQUE;
|
||||
|
||||
const uint32 mask = format.ARGBToColor(0xff, 0, 0, 0);
|
||||
AlphaType alphaType = ALPHA_OPAQUE;
|
||||
|
||||
for (int y = 0; y < h; y++) {
|
||||
for (int x = 0; x < w; x++) {
|
||||
uint32 pixel = getPixel(x, y);
|
||||
if ((pixel & mask) != mask) {
|
||||
if ((pixel & mask) == 0)
|
||||
alphaType = ALPHA_BINARY;
|
||||
else
|
||||
return ALPHA_FULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return alphaType;
|
||||
}
|
||||
|
||||
Graphics::Surface *Surface::scale(int16 newWidth, int16 newHeight, bool filtering) const {
|
||||
Graphics::Surface *target = new Graphics::Surface();
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ struct Point;
|
|||
}
|
||||
|
||||
#include "graphics/pixelformat.h"
|
||||
#include "graphics/transform_struct.h"
|
||||
|
||||
namespace Graphics {
|
||||
|
||||
|
@ -512,6 +513,11 @@ public:
|
|||
*/
|
||||
bool setAlpha(uint8 alpha, bool skipTransparent = false);
|
||||
|
||||
/**
|
||||
* Checks if the given surface contains alpha transparency
|
||||
*/
|
||||
AlphaType detectAlpha() const;
|
||||
|
||||
/**
|
||||
* Scale the data to the given size.
|
||||
*
|
||||
|
|
|
@ -1240,7 +1240,7 @@ void ThemeEngine::drawPopUpWidget(const Common::Rect &r, const Common::U32String
|
|||
}
|
||||
}
|
||||
|
||||
void ThemeEngine::drawManagedSurface(const Common::Point &p, const Graphics::ManagedSurface &surface) {
|
||||
void ThemeEngine::drawManagedSurface(const Common::Point &p, const Graphics::ManagedSurface &surface, Graphics::AlphaType alphaType) {
|
||||
if (!ready())
|
||||
return;
|
||||
|
||||
|
@ -1248,7 +1248,7 @@ void ThemeEngine::drawManagedSurface(const Common::Point &p, const Graphics::Man
|
|||
return;
|
||||
|
||||
_vectorRenderer->setClippingRect(_clip);
|
||||
_vectorRenderer->blitManagedSurface(&surface, p);
|
||||
_vectorRenderer->blitManagedSurface(&surface, p, alphaType);
|
||||
|
||||
Common::Rect dirtyRect = Common::Rect(p.x, p.y, p.x + surface.w, p.y + surface.h);
|
||||
dirtyRect.clip(_clip);
|
||||
|
|
|
@ -469,7 +469,7 @@ public:
|
|||
void drawDropDownButton(const Common::Rect &r, uint32 dropdownWidth, const Common::U32String &str,
|
||||
WidgetStateInfo buttonState, bool inButton, bool inDropdown, bool rtl = false);
|
||||
|
||||
void drawManagedSurface(const Common::Point &p, const Graphics::ManagedSurface &surface);
|
||||
void drawManagedSurface(const Common::Point &p, const Graphics::ManagedSurface &surface, Graphics::AlphaType alphaType);
|
||||
|
||||
void drawSlider(const Common::Rect &r, int width, WidgetStateInfo state = kStateEnabled, bool rtl = false);
|
||||
|
||||
|
|
|
@ -537,6 +537,8 @@ bool ThemeParser::parseDrawStep(ParserNode *stepNode, Graphics::DrawStep *drawst
|
|||
|
||||
if (!drawstep->blitSrc)
|
||||
return parserError("The given filename hasn't been loaded into the GUI.");
|
||||
|
||||
drawstep->alphaType = drawstep->blitSrc->detectAlpha();
|
||||
}
|
||||
|
||||
if (functionName == "roundedsq" || functionName == "circle" || functionName == "tab") {
|
||||
|
|
|
@ -646,6 +646,8 @@ void PicButtonWidget::setGfx(const Graphics::ManagedSurface *gfx, int statenum,
|
|||
if (!isVisible() || !_boss->isVisible())
|
||||
return;
|
||||
|
||||
_alphaType[statenum] = gfx->detectAlpha();
|
||||
|
||||
float sf = g_gui.getScaleFactor();
|
||||
if (scale && sf != 1.0) {
|
||||
Graphics::Surface *tmp2 = gfx->rawSurface().scale(gfx->w * sf, gfx->h * sf, false);
|
||||
|
@ -686,6 +688,7 @@ void PicButtonWidget::setGfx(int w, int h, int r, int g, int b, int statenum) {
|
|||
|
||||
_gfx[statenum].create(w, h, requiredFormat);
|
||||
_gfx[statenum].fillRect(Common::Rect(0, 0, w, h), _gfx[statenum].format.RGBToColor(r, g, b));
|
||||
_alphaType[statenum] = Graphics::ALPHA_OPAQUE;
|
||||
}
|
||||
|
||||
void PicButtonWidget::drawWidget() {
|
||||
|
@ -693,24 +696,31 @@ void PicButtonWidget::drawWidget() {
|
|||
g_gui.theme()->drawButton(Common::Rect(_x, _y, _x + _w, _y + _h), Common::U32String(), _state, getFlags());
|
||||
|
||||
Graphics::ManagedSurface *gfx;
|
||||
Graphics::AlphaType alphaType;
|
||||
|
||||
if (_state == ThemeEngine::kStateHighlight)
|
||||
if (_state == ThemeEngine::kStateHighlight) {
|
||||
gfx = &_gfx[kPicButtonHighlight];
|
||||
else if (_state == ThemeEngine::kStateDisabled)
|
||||
alphaType = _alphaType[kPicButtonHighlight];
|
||||
} else if (_state == ThemeEngine::kStateDisabled) {
|
||||
gfx = &_gfx[kPicButtonStateDisabled];
|
||||
else if (_state == ThemeEngine::kStatePressed)
|
||||
alphaType = _alphaType[kPicButtonStateDisabled];
|
||||
} else if (_state == ThemeEngine::kStatePressed) {
|
||||
gfx = &_gfx[kPicButtonStatePressed];
|
||||
else
|
||||
alphaType = _alphaType[kPicButtonStatePressed];
|
||||
} else {
|
||||
gfx = &_gfx[kPicButtonStateEnabled];
|
||||
|
||||
if (!gfx->getPixels())
|
||||
alphaType = _alphaType[kPicButtonStateEnabled];
|
||||
}
|
||||
if (!gfx->getPixels()) {
|
||||
gfx = &_gfx[kPicButtonStateEnabled];
|
||||
alphaType= _alphaType[kPicButtonStateEnabled];
|
||||
}
|
||||
|
||||
if (gfx->getPixels()) {
|
||||
const int x = _x + (_w - gfx->w) / 2;
|
||||
const int y = _y + (_h - gfx->h) / 2;
|
||||
|
||||
g_gui.theme()->drawManagedSurface(Common::Point(x, y), *gfx);
|
||||
g_gui.theme()->drawManagedSurface(Common::Point(x, y), *gfx, alphaType);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -928,7 +938,7 @@ int SliderWidget::posToValue(int pos) {
|
|||
#pragma mark -
|
||||
|
||||
GraphicsWidget::GraphicsWidget(GuiObject *boss, int x, int y, int w, int h, bool scale, const Common::U32String &tooltip)
|
||||
: Widget(boss, x, y, w, h, scale, tooltip), _gfx() {
|
||||
: Widget(boss, x, y, w, h, scale, tooltip), _gfx(), _alphaType(Graphics::ALPHA_OPAQUE) {
|
||||
setFlags(WIDGET_ENABLED | WIDGET_CLEARBG);
|
||||
_type = kGraphicsWidget;
|
||||
}
|
||||
|
@ -938,7 +948,7 @@ GraphicsWidget::GraphicsWidget(GuiObject *boss, int x, int y, int w, int h, cons
|
|||
}
|
||||
|
||||
GraphicsWidget::GraphicsWidget(GuiObject *boss, const Common::String &name, const Common::U32String &tooltip)
|
||||
: Widget(boss, name, tooltip), _gfx() {
|
||||
: Widget(boss, name, tooltip), _gfx(), _alphaType(Graphics::ALPHA_OPAQUE) {
|
||||
setFlags(WIDGET_ENABLED | WIDGET_CLEARBG);
|
||||
_type = kGraphicsWidget;
|
||||
}
|
||||
|
@ -970,6 +980,8 @@ void GraphicsWidget::setGfx(const Graphics::ManagedSurface *gfx, bool scale) {
|
|||
_h = gfx->h;
|
||||
}
|
||||
|
||||
_alphaType = gfx->detectAlpha();
|
||||
|
||||
if ((_w != gfx->w || _h != gfx->h) && _w && _h) {
|
||||
Graphics::Surface *tmp2 = gfx->rawSurface().scale(_w, _h, false);
|
||||
_gfx.copyFrom(*tmp2);
|
||||
|
@ -1001,6 +1013,7 @@ void GraphicsWidget::setGfx(int w, int h, int r, int g, int b) {
|
|||
|
||||
_gfx.create(w, h, requiredFormat);
|
||||
_gfx.fillRect(Common::Rect(0, 0, w, h), _gfx.format.RGBToColor(r, g, b));
|
||||
_alphaType = Graphics::ALPHA_OPAQUE;
|
||||
}
|
||||
|
||||
void GraphicsWidget::setGfxFromTheme(const char *name) {
|
||||
|
@ -1014,7 +1027,7 @@ void GraphicsWidget::drawWidget() {
|
|||
const int x = _x + (_w - _gfx.w) / 2;
|
||||
const int y = _y + (_h - _gfx.h) / 2;
|
||||
|
||||
g_gui.theme()->drawManagedSurface(Common::Point(x, y), _gfx);
|
||||
g_gui.theme()->drawManagedSurface(Common::Point(x, y), _gfx, _alphaType);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -319,6 +319,7 @@ protected:
|
|||
void drawWidget() override;
|
||||
|
||||
Graphics::ManagedSurface _gfx[kPicButtonStateMax + 1];
|
||||
Graphics::AlphaType _alphaType[kPicButtonStateMax + 1];
|
||||
bool _showButton;
|
||||
};
|
||||
|
||||
|
@ -454,6 +455,7 @@ protected:
|
|||
void drawWidget() override;
|
||||
|
||||
Graphics::ManagedSurface _gfx;
|
||||
Graphics::AlphaType _alphaType;
|
||||
};
|
||||
|
||||
class PathWidget : public StaticTextWidget {
|
||||
|
|
|
@ -49,8 +49,10 @@ void GridItemWidget::setActiveEntry(GridItemInfo &entry) {
|
|||
void GridItemWidget::updateThumb() {
|
||||
const Graphics::ManagedSurface *gfx = _grid->filenameToSurface(_activeEntry->thumbPath);
|
||||
_thumbGfx.free();
|
||||
if (gfx)
|
||||
if (gfx) {
|
||||
_thumbGfx.copyFrom(*gfx);
|
||||
_thumbAlpha = _thumbGfx.detectAlpha();
|
||||
}
|
||||
}
|
||||
|
||||
void GridItemWidget::update() {
|
||||
|
@ -119,30 +121,32 @@ void GridItemWidget::drawWidget() {
|
|||
r.translate(0, kLineHeight);
|
||||
}
|
||||
} else {
|
||||
g_gui.theme()->drawManagedSurface(Common::Point(_x + _grid->_thumbnailMargin, _y + _grid->_thumbnailMargin), _thumbGfx);
|
||||
g_gui.theme()->drawManagedSurface(Common::Point(_x + _grid->_thumbnailMargin, _y + _grid->_thumbnailMargin), _thumbGfx, _thumbAlpha);
|
||||
}
|
||||
|
||||
Graphics::AlphaType alphaType;
|
||||
|
||||
// Draw Platform Icon
|
||||
const Graphics::ManagedSurface *platGfx = _grid->platformToSurface(_activeEntry->platform);
|
||||
const Graphics::ManagedSurface *platGfx = _grid->platformToSurface(_activeEntry->platform, alphaType);
|
||||
if (platGfx) {
|
||||
Common::Point p(_x + thumbWidth - platGfx->w, _y + thumbHeight - platGfx->h);
|
||||
g_gui.theme()->drawManagedSurface(p, *platGfx);
|
||||
g_gui.theme()->drawManagedSurface(p, *platGfx, alphaType);
|
||||
}
|
||||
|
||||
// Draw Flag
|
||||
const Graphics::ManagedSurface *flagGfx = _grid->languageToSurface(_activeEntry->language);
|
||||
const Graphics::ManagedSurface *flagGfx = _grid->languageToSurface(_activeEntry->language, alphaType);
|
||||
if (flagGfx) {
|
||||
// SVG and PNG can resize differently so it's better to use thumbWidth as reference to
|
||||
// ensure all flags are aligned
|
||||
Common::Point p(_x + thumbWidth - (thumbWidth / 5), _y + 5);
|
||||
g_gui.theme()->drawManagedSurface(p, *flagGfx);
|
||||
g_gui.theme()->drawManagedSurface(p, *flagGfx, alphaType);
|
||||
}
|
||||
|
||||
// Draw Demo Overlay
|
||||
const Graphics::ManagedSurface *demoGfx = _grid->demoToSurface(_activeEntry->extra);
|
||||
const Graphics::ManagedSurface *demoGfx = _grid->demoToSurface(_activeEntry->extra, alphaType);
|
||||
if (demoGfx) {
|
||||
Common::Point p(_x, _y);
|
||||
g_gui.theme()->drawManagedSurface(p, *demoGfx);
|
||||
g_gui.theme()->drawManagedSurface(p, *demoGfx, alphaType);
|
||||
}
|
||||
|
||||
bool validEntry = _activeEntry->validEntry;
|
||||
|
@ -152,7 +156,7 @@ void GridItemWidget::drawWidget() {
|
|||
const Graphics::ManagedSurface *darkenGfx = _grid->disabledThumbnail();
|
||||
if (darkenGfx) {
|
||||
Common::Point p(_x, _y);
|
||||
g_gui.theme()->drawManagedSurface(p, *darkenGfx);
|
||||
g_gui.theme()->drawManagedSurface(p, *darkenGfx, Graphics::ALPHA_FULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -452,6 +456,9 @@ GridWidget::~GridWidget() {
|
|||
_headerEntryList.clear();
|
||||
_sortedEntryList.clear();
|
||||
_visibleEntryList.clear();
|
||||
_platformIconsAlpha.clear();
|
||||
_languageIconsAlpha.clear();
|
||||
_extraIconsAlpha.clear();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
@ -468,21 +475,24 @@ const Graphics::ManagedSurface *GridWidget::filenameToSurface(const Common::Stri
|
|||
return _loadedSurfaces[name];
|
||||
}
|
||||
|
||||
const Graphics::ManagedSurface *GridWidget::languageToSurface(Common::Language languageCode) {
|
||||
const Graphics::ManagedSurface *GridWidget::languageToSurface(Common::Language languageCode, Graphics::AlphaType &alphaType) {
|
||||
if (languageCode == Common::UNK_LANG)
|
||||
return nullptr;
|
||||
alphaType = _languageIconsAlpha[languageCode];
|
||||
return _languageIcons[languageCode];
|
||||
}
|
||||
|
||||
const Graphics::ManagedSurface *GridWidget::platformToSurface(Common::Platform platformCode) {
|
||||
const Graphics::ManagedSurface *GridWidget::platformToSurface(Common::Platform platformCode, Graphics::AlphaType &alphaType) {
|
||||
if (platformCode == Common::kPlatformUnknown)
|
||||
return nullptr;
|
||||
alphaType = _platformIconsAlpha[platformCode];
|
||||
return _platformIcons[platformCode];
|
||||
}
|
||||
|
||||
const Graphics::ManagedSurface *GridWidget::demoToSurface(const Common::String extraString) {
|
||||
const Graphics::ManagedSurface *GridWidget::demoToSurface(const Common::String extraString, Graphics::AlphaType &alphaType) {
|
||||
if (! extraString.contains("Demo") )
|
||||
return nullptr;
|
||||
alphaType = _extraIconsAlpha[0];
|
||||
return _extraIcons[0];
|
||||
}
|
||||
|
||||
|
@ -731,6 +741,7 @@ void GridWidget::loadFlagIcons() {
|
|||
Graphics::ManagedSurface *gfx = loadSurfaceFromFile(path, _flagIconWidth, _flagIconHeight);
|
||||
if (gfx) {
|
||||
_languageIcons[l->id] = gfx;
|
||||
_languageIconsAlpha[l->id] = gfx->detectAlpha();
|
||||
continue;
|
||||
} // if no .svg flag is available, search for a .png
|
||||
path = Common::String::format("icons/flags/%s.png", l->code);
|
||||
|
@ -738,6 +749,7 @@ void GridWidget::loadFlagIcons() {
|
|||
if (gfx) {
|
||||
const Graphics::ManagedSurface *scGfx = scaleGfx(gfx, _flagIconWidth, _flagIconHeight, true);
|
||||
_languageIcons[l->id] = scGfx;
|
||||
_languageIconsAlpha[l->id] = gfx->detectAlpha();
|
||||
if (gfx != scGfx) {
|
||||
gfx->free();
|
||||
delete gfx;
|
||||
|
@ -756,6 +768,7 @@ void GridWidget::loadPlatformIcons() {
|
|||
if (gfx) {
|
||||
const Graphics::ManagedSurface *scGfx = scaleGfx(gfx, _platformIconWidth, _platformIconHeight, true);
|
||||
_platformIcons[l->id] = scGfx;
|
||||
_platformIconsAlpha[l->id] = scGfx->detectAlpha();
|
||||
if (gfx != scGfx) {
|
||||
gfx->free();
|
||||
delete gfx;
|
||||
|
@ -770,12 +783,14 @@ void GridWidget::loadExtraIcons() { // for now only the demo icon is available
|
|||
Graphics::ManagedSurface *gfx = loadSurfaceFromFile("icons/extra/demo.svg", _extraIconWidth, _extraIconHeight);
|
||||
if (gfx) {
|
||||
_extraIcons[0] = gfx;
|
||||
_extraIconsAlpha[0] = gfx->detectAlpha();
|
||||
return;
|
||||
} // if no .svg file is available, search for a .png
|
||||
gfx = loadSurfaceFromFile("icons/extra/demo.png");
|
||||
if (gfx) {
|
||||
const Graphics::ManagedSurface *scGfx = scaleGfx(gfx, _extraIconWidth, _extraIconHeight, true);
|
||||
_extraIcons[0] = scGfx;
|
||||
_extraIconsAlpha[0] = scGfx->detectAlpha();
|
||||
if (gfx != scGfx) {
|
||||
gfx->free();
|
||||
delete gfx;
|
||||
|
@ -1051,6 +1066,9 @@ void GridWidget::reflowLayout() {
|
|||
unloadSurfaces(_platformIcons);
|
||||
unloadSurfaces(_languageIcons);
|
||||
unloadSurfaces(_loadedSurfaces);
|
||||
_platformIconsAlpha.clear();
|
||||
_languageIconsAlpha.clear();
|
||||
_extraIconsAlpha.clear();
|
||||
if (_disabledIconOverlay)
|
||||
_disabledIconOverlay->free();
|
||||
reloadThumbnails();
|
||||
|
|
|
@ -102,6 +102,9 @@ protected:
|
|||
Common::HashMap<int, const Graphics::ManagedSurface *> _platformIcons;
|
||||
Common::HashMap<int, const Graphics::ManagedSurface *> _languageIcons;
|
||||
Common::HashMap<int, const Graphics::ManagedSurface *> _extraIcons;
|
||||
Common::HashMap<int, Graphics::AlphaType> _platformIconsAlpha;
|
||||
Common::HashMap<int, Graphics::AlphaType> _languageIconsAlpha;
|
||||
Common::HashMap<int, Graphics::AlphaType> _extraIconsAlpha;
|
||||
Graphics::ManagedSurface *_disabledIconOverlay;
|
||||
// Images are mapped by filename -> surface.
|
||||
Common::HashMap<Common::String, const Graphics::ManagedSurface *> _loadedSurfaces;
|
||||
|
@ -173,9 +176,9 @@ public:
|
|||
void unloadSurfaces(Common::HashMap<T, const Graphics::ManagedSurface *> &surfaces);
|
||||
|
||||
const Graphics::ManagedSurface *filenameToSurface(const Common::String &name);
|
||||
const Graphics::ManagedSurface *languageToSurface(Common::Language languageCode);
|
||||
const Graphics::ManagedSurface *platformToSurface(Common::Platform platformCode);
|
||||
const Graphics::ManagedSurface *demoToSurface(const Common::String extraString);
|
||||
const Graphics::ManagedSurface *languageToSurface(Common::Language languageCode, Graphics::AlphaType &alphaType);
|
||||
const Graphics::ManagedSurface *platformToSurface(Common::Platform platformCode, Graphics::AlphaType &alphaType);
|
||||
const Graphics::ManagedSurface *demoToSurface(const Common::String extraString, Graphics::AlphaType &alphaType);
|
||||
const Graphics::ManagedSurface *disabledThumbnail();
|
||||
|
||||
/// Update _visibleEntries from _allEntries and returns true if reload is required.
|
||||
|
@ -232,6 +235,7 @@ public:
|
|||
class GridItemWidget : public ContainerWidget, public CommandSender {
|
||||
protected:
|
||||
Graphics::ManagedSurface _thumbGfx;
|
||||
Graphics::AlphaType _thumbAlpha;
|
||||
|
||||
GridItemInfo *_activeEntry;
|
||||
GridWidget *_grid;
|
||||
|
|
|
@ -237,7 +237,7 @@ void RichTextWidget::drawWidget() {
|
|||
|
||||
_txtWnd->draw(_surface, 0, _scrolledY, _textWidth, _textHeight, 0, 0);
|
||||
|
||||
g_gui.theme()->drawManagedSurface(Common::Point(_x + _innerMargin, _y + _innerMargin), *_surface);
|
||||
g_gui.theme()->drawManagedSurface(Common::Point(_x + _innerMargin, _y + _innerMargin), *_surface, Graphics::ALPHA_FULL);
|
||||
}
|
||||
|
||||
void RichTextWidget::draw() {
|
||||
|
|
36
po/zh.po
36
po/zh.po
|
@ -11,7 +11,7 @@ msgstr ""
|
|||
"Project-Id-Version: ScummVM 2.3.0git\n"
|
||||
"Report-Msgid-Bugs-To: scummvm-devel@lists.scummvm.org\n"
|
||||
"POT-Creation-Date: 2024-05-04 22:58+0000\n"
|
||||
"PO-Revision-Date: 2024-03-21 21:40+0000\n"
|
||||
"PO-Revision-Date: 2024-05-14 12:42+0000\n"
|
||||
"Last-Translator: 复予 <clonewith@qq.com>\n"
|
||||
"Language-Team: Chinese <https://translations.scummvm.org/projects/scummvm/"
|
||||
"scummvm/zh/>\n"
|
||||
|
@ -251,31 +251,31 @@ msgstr "载入"
|
|||
|
||||
#: gui/cloudconnectionwizard.cpp:362
|
||||
msgid "Load code from file"
|
||||
msgstr ""
|
||||
msgstr "从文件载入代码"
|
||||
|
||||
#: gui/cloudconnectionwizard.cpp:379
|
||||
msgid "Manual Mode: Something went wrong"
|
||||
msgstr ""
|
||||
msgstr "手动模式:出错了"
|
||||
|
||||
#: gui/cloudconnectionwizard.cpp:383
|
||||
msgid "Cloud storage was not connected."
|
||||
msgstr ""
|
||||
msgstr "未连接云存储。"
|
||||
|
||||
#: gui/cloudconnectionwizard.cpp:384
|
||||
msgid "Make sure the JSON code was copied correctly and retry."
|
||||
msgstr ""
|
||||
msgstr "请确保 JSON 代码复制正确并重试。"
|
||||
|
||||
#: gui/cloudconnectionwizard.cpp:385
|
||||
msgid "If that doesn't work, try again from the beginning."
|
||||
msgstr ""
|
||||
msgstr "如果没有用,请从头再试。"
|
||||
|
||||
#: gui/cloudconnectionwizard.cpp:386
|
||||
msgid "Error message: "
|
||||
msgstr ""
|
||||
msgstr "错误消息: "
|
||||
|
||||
#: gui/cloudconnectionwizard.cpp:400
|
||||
msgid "Manual Mode: Success"
|
||||
msgstr ""
|
||||
msgstr "手动模式:成功"
|
||||
|
||||
#: gui/cloudconnectionwizard.cpp:428 gui/dlcsdialog.cpp:59
|
||||
#: gui/downloaddlcsdialog.cpp:60 engines/crab/input/input.cpp:175
|
||||
|
@ -285,11 +285,11 @@ msgstr "返回"
|
|||
#: gui/cloudconnectionwizard.cpp:436 gui/imagealbum-dialog.cpp:104
|
||||
#: gui/saveload-dialog.cpp:829 engines/crab/input/input.cpp:181
|
||||
msgid "Next"
|
||||
msgstr ""
|
||||
msgstr "下一步"
|
||||
|
||||
#: gui/cloudconnectionwizard.cpp:499
|
||||
msgid "Another Storage is working right now. Do you want to interrupt it?"
|
||||
msgstr ""
|
||||
msgstr "另一存储正工作中。您要中断它吗?"
|
||||
|
||||
#: gui/cloudconnectionwizard.cpp:499 gui/downloaddialog.cpp:118
|
||||
#: gui/downloaddialog.cpp:152 gui/filebrowser-dialog.cpp:135
|
||||
|
@ -320,12 +320,12 @@ msgstr "否"
|
|||
|
||||
#: gui/cloudconnectionwizard.cpp:508
|
||||
msgid "Wait until current Storage finishes and try again."
|
||||
msgstr ""
|
||||
msgstr "请等待当前存储工作完成后再试。"
|
||||
|
||||
#. I18N: JSON is name of the format, this message is displayed if user entered something incorrect to the text field
|
||||
#: gui/cloudconnectionwizard.cpp:536
|
||||
msgid "JSON code contents are malformed."
|
||||
msgstr ""
|
||||
msgstr "JSON 代码内容有误。"
|
||||
|
||||
#: gui/cloudconnectionwizard.cpp:557 gui/downloaddialog.cpp:146
|
||||
#: gui/editgamedialog.cpp:363 gui/editrecorddialog.cpp:67
|
||||
|
@ -355,7 +355,7 @@ msgstr "确认"
|
|||
|
||||
#: gui/cloudconnectionwizard.cpp:558
|
||||
msgid "Incorrect JSON."
|
||||
msgstr ""
|
||||
msgstr "JSON 不正确。"
|
||||
|
||||
#. I18N: error message displayed on 'Manual Mode: Failure' step of 'Cloud Connection Wizard', describing that storage connection process was interrupted
|
||||
#: gui/cloudconnectionwizard.cpp:565
|
||||
|
@ -373,20 +373,20 @@ msgstr ""
|
|||
#. I18N: JSON is a file format name
|
||||
#: gui/cloudconnectionwizard.cpp:631
|
||||
msgid "Select JSON file copied from scummvm.org site"
|
||||
msgstr ""
|
||||
msgstr "选择从 scummvm.org 网站复制的 JSON 文件"
|
||||
|
||||
#. I18N: JSON is a file format name
|
||||
#: gui/cloudconnectionwizard.cpp:637
|
||||
msgid "Failed to load JSON file"
|
||||
msgstr ""
|
||||
msgstr "无法载入 JSON 文件"
|
||||
|
||||
#: gui/dlcsdialog.cpp:41
|
||||
msgid "Download Freeware Games and Demos"
|
||||
msgstr ""
|
||||
msgstr "下载免费游戏与演示游戏"
|
||||
|
||||
#: gui/dlcsdialog.cpp:52
|
||||
msgid "Fetching DLCs..."
|
||||
msgstr ""
|
||||
msgstr "正在获取 DLC..."
|
||||
|
||||
#: gui/dlcsdialog.cpp:60
|
||||
msgid "All Downloads"
|
||||
|
@ -536,7 +536,7 @@ msgstr "開始執行"
|
|||
|
||||
#: gui/dump-all-dialogs.cpp:103 gui/options.cpp:3275
|
||||
msgid "icon packs"
|
||||
msgstr ""
|
||||
msgstr "图标包"
|
||||
|
||||
#: gui/dump-all-dialogs.cpp:107 gui/options.cpp:3286
|
||||
msgid "shader packs"
|
||||
|
|
10862
po/zh_Hant.po
Normal file
10862
po/zh_Hant.po
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue