[Scummvm-cvs-logs] SF.net SVN: scummvm: [27998] scummvm/trunk/engines/scumm
sev at users.sourceforge.net
sev at users.sourceforge.net
Tue Jul 10 02:39:13 CEST 2007
Revision: 27998
http://scummvm.svn.sourceforge.net/scummvm/?rev=27998&view=rev
Author: sev
Date: 2007-07-09 17:39:12 -0700 (Mon, 09 Jul 2007)
Log Message:
-----------
Preliminary (and buggy) Kanji support.
Modified Paths:
--------------
scummvm/trunk/engines/scumm/charset.cpp
scummvm/trunk/engines/scumm/gfx.cpp
scummvm/trunk/engines/scumm/input.cpp
scummvm/trunk/engines/scumm/scumm.cpp
scummvm/trunk/engines/scumm/scumm.h
Modified: scummvm/trunk/engines/scumm/charset.cpp
===================================================================
--- scummvm/trunk/engines/scumm/charset.cpp 2007-07-09 21:56:35 UTC (rev 27997)
+++ scummvm/trunk/engines/scumm/charset.cpp 2007-07-10 00:39:12 UTC (rev 27998)
@@ -48,6 +48,8 @@
void ScummEngine::loadCJKFont() {
Common::File fp;
_useCJKMode = false;
+ _textSurfaceMultiplier = 1;
+
if (_language == Common::JA_JPN && _game.version <= 5) { // FM-TOWNS v3 / v5 Kanji
int numChar = 256 * 32;
_2byteWidth = 16;
@@ -60,6 +62,7 @@
fp.read(_2byteFontPtr, ((_2byteWidth + 7) / 8) * _2byteHeight * numChar);
fp.close();
}
+ _textSurfaceMultiplier = 2;
} else if (_language == Common::KO_KOR || _language == Common::JA_JPN || _language == Common::ZH_TWN) {
int numChar = 0;
const char *fontFile = NULL;
@@ -85,6 +88,7 @@
if (fontFile && fp.open(fontFile)) {
debug(2, "Loading CJK Font");
_useCJKMode = true;
+ _textSurfaceMultiplier = 1; // No multiplication here
fp.seek(2, SEEK_CUR);
_2byteWidth = fp.readByte();
_2byteHeight = fp.readByte();
@@ -276,7 +280,7 @@
// do spacing for variable width old-style font
int CharsetRendererClassic::getCharWidth(byte chr) {
if (chr >= 0x80 && _vm->_useCJKMode)
- return _vm->_2byteWidth / 2;
+ return _vm->_2byteWidth;
int spacing = 0;
int offs = READ_LE_UINT32(_fontPtr + chr * 4 + 4);
@@ -1160,7 +1164,7 @@
int CharsetRendererV3::getCharWidth(byte chr) {
if (chr & 0x80 && _vm->_useCJKMode)
- return _vm->_2byteWidth / 2;
+ return _vm->_2byteWidth;
int spacing = 0;
spacing = *(_widthTable + chr);
@@ -1257,18 +1261,18 @@
_hasMask = true;
_textScreenID = vs->number;
}
- if (ignoreCharsetMask || !vs->hasTwoBuffers) {
+ if ((ignoreCharsetMask || !vs->hasTwoBuffers) && !(_vm->_useCJKMode && _vm->_textSurfaceMultiplier == 2)) {
dst = vs->getPixels(_left, drawTop);
drawBits1(*vs, dst, charPtr, drawTop, origWidth, origHeight);
} else {
- dst = (byte *)_vm->_textSurface.getBasePtr(_left, _top);
+ dst = (byte *)_vm->_textSurface.getBasePtr(_left * _vm->_textSurfaceMultiplier, _top * _vm->_textSurfaceMultiplier);
drawBits1(_vm->_textSurface, dst, charPtr, drawTop, origWidth, origHeight);
}
if (_str.left > _left)
_str.left = _left;
- _left += origWidth;
+ _left += origWidth / _vm->_textSurfaceMultiplier;
if (_str.right < _left) {
_str.right = _left;
@@ -1276,8 +1280,8 @@
_str.right++;
}
- if (_str.bottom < _top + height)
- _str.bottom = _top + height;
+ if (_str.bottom < _top + height / _vm->_textSurfaceMultiplier)
+ _str.bottom = _top + height / _vm->_textSurfaceMultiplier;
}
void CharsetRendererV3::drawChar(int chr, const Graphics::Surface &s, int x, int y) {
@@ -1391,8 +1395,8 @@
_top += offsY;
_left += offsX;
- if (_left + origWidth > _right + 1 || _left < 0) {
- _left += origWidth;
+ if (_left + origWidth / _vm->_textSurfaceMultiplier > _right + 1 || _left < 0) {
+ _left += origWidth / _vm->_textSurfaceMultiplier;
_top -= offsY;
return;
}
@@ -1424,7 +1428,7 @@
printCharIntern(is2byte, charPtr, origWidth, origHeight, width, height, vs, ignoreCharsetMask);
- _left += origWidth;
+ _left += origWidth / _vm->_textSurfaceMultiplier;
if (_str.right < _left) {
_str.right = _left;
@@ -1432,8 +1436,8 @@
_str.right++;
}
- if (_str.bottom < _top + height)
- _str.bottom = _top + height;
+ if (_str.bottom < _top + height / _vm->_textSurfaceMultiplier)
+ _str.bottom = _top + height / _vm->_textSurfaceMultiplier;
_top -= offsY;
}
@@ -1473,12 +1477,12 @@
} else {
Graphics::Surface dstSurface;
Graphics::Surface backSurface;
- if (ignoreCharsetMask || !vs->hasTwoBuffers) {
+ if ((ignoreCharsetMask || !vs->hasTwoBuffers) && !(_vm->_useCJKMode && _vm->_textSurfaceMultiplier == 2)) {
dstSurface = *vs;
dstPtr = vs->getPixels(_left, drawTop);
} else {
dstSurface = _vm->_textSurface;
- dstPtr = (byte *)_vm->_textSurface.pixels + (_top - _vm->_screenTop) * _vm->_textSurface.pitch + _left;
+ dstPtr = (byte *)_vm->_textSurface.pixels + (_top - _vm->_screenTop) * _vm->_textSurface.pitch * _vm->_textSurfaceMultiplier + _left * _vm->_textSurfaceMultiplier;
}
if (_blitAlso && vs->hasTwoBuffers) {
Modified: scummvm/trunk/engines/scumm/gfx.cpp
===================================================================
--- scummvm/trunk/engines/scumm/gfx.cpp 2007-07-09 21:56:35 UTC (rev 27997)
+++ scummvm/trunk/engines/scumm/gfx.cpp 2007-07-10 00:39:12 UTC (rev 27998)
@@ -561,8 +561,25 @@
return;
const byte *src = vs->getPixels(x, top);
+ int m = _textSurfaceMultiplier;
+ byte *dst;
+ int vsPitch;
int pitch = vs->pitch;
+ if (_useCJKMode && _textSurfaceMultiplier == 2) {
+ dst = _fmtownsBuf;
+
+ scale2x(dst, _screenWidth * m, src, vs->pitch, width, height);
+ src = dst;
+
+ vsPitch = _screenWidth * m - width * m;
+
+ } else {
+ vsPitch = vs->pitch - width;
+ }
+
+ dst = _compositeBuf;
+
if (_game.version < 7) {
// For The Dig, FT and COMI, we just blit everything to the screen at once.
// For older games, things are more complicated. First off, we need to
@@ -572,7 +589,7 @@
// Compute pointer to the text surface
assert(_compositeBuf);
- const byte *text = (byte *)_textSurface.getBasePtr(x, y);
+ const byte *text = (byte *)_textSurface.getBasePtr(x * m, y * m);
// The values x, width, etc. are all multiples of 8 at this point,
// so loop unrolloing might be a good idea...
@@ -594,19 +611,18 @@
// but also more complicated to implement, and incurs a bigger overhead when
// writing to the text surface.
#ifdef __DS__
- DS::asmDrawStripToScreen(height, width, text, src, _compositeBuf, vs->pitch, width, _textSurface.pitch);
+ DS::asmDrawStripToScreen(height, width, text, src, dst, vs->pitch, width, _textSurface.pitch);
#else
- byte *dst = _compositeBuf;
- for (int h = 0; h < height; ++h) {
- for (int w = 0; w < width; ++w) {
+ for (int h = 0; h < height * m; ++h) {
+ for (int w = 0; w < width * m; ++w) {
byte tmp = *text++;
if (tmp == CHARSET_MASK_TRANSPARENCY)
tmp = *src;
*dst++ = tmp;
src++;
}
- src += vs->pitch - width;
- text += _textSurface.pitch - width;
+ src += vsPitch;
+ text += _textSurface.pitch - width * m;
}
#endif
@@ -621,6 +637,12 @@
// center image on the screen
x += (Common::kHercW - _screenWidth * 2) / 2; // (720 - 320*2)/2 = 40
+ } else if (_useCJKMode && m == 2) {
+ pitch *= m;
+ x *= m;
+ y *= m;
+ width *= m;
+ height *= m;
} else {
if (_renderMode == Common::kRenderCGA)
ditherCGA(_compositeBuf, width, x, y, width, height);
@@ -721,7 +743,26 @@
*height = dsty - *y;
}
+void ScummEngine::scale2x(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h) {
+ byte *dstL1 = dst;
+ byte *dstL2 = dst + dstPitch;
+ int dstAdd = dstPitch * 2 - w * 2;
+ int srcAdd = srcPitch - w;
+
+ while (h--) {
+ for (int x = 0; x < w; ++x, dstL1 += 2, dstL2 += 2) {
+ uint16 col = *src++;
+ col |= col << 8;
+ *(uint16*)(dstL1) = col;
+ *(uint16*)(dstL2) = col;
+ }
+ dstL1 += dstAdd; dstL2 += dstAdd;
+ src += srcAdd;
+ }
+}
+
+
#pragma mark -
#pragma mark --- Background buffers & charset mask ---
#pragma mark -
@@ -1117,8 +1158,8 @@
error("can only copy bg to main window");
blit(backbuff, vs->pitch, bgbuff, vs->pitch, width, height);
if (_charset->_hasMask) {
- byte *mask = (byte *)_textSurface.getBasePtr(x, y - _screenTop);
- fill(mask, _textSurface.pitch, CHARSET_MASK_TRANSPARENCY, width, height);
+ byte *mask = (byte *)_textSurface.getBasePtr(x * _textSurfaceMultiplier, (y - _screenTop) * _textSurfaceMultiplier);
+ fill(mask, _textSurface.pitch, CHARSET_MASK_TRANSPARENCY, width * _textSurfaceMultiplier, height * _textSurfaceMultiplier);
}
} else if (_game.heversion >= 71) {
// Flags are used for different methods in HE games
@@ -3362,8 +3403,18 @@
for (i = 0; i < w * h; i++) {
x = offsets[i] % vs->pitch;
y = offsets[i] / vs->pitch;
- _system->copyRectToScreen(vs->getPixels(x, y), vs->pitch, x, y + vs->topline, width, height);
+ if (_useCJKMode && _textSurfaceMultiplier == 2) {
+ int m = _textSurfaceMultiplier;
+ byte *dst = _fmtownsBuf + x * m + y * m * _screenWidth * m;
+ scale2x(dst, _screenWidth * m, vs->getPixels(x, y), vs->pitch, width, height);
+
+ _system->copyRectToScreen(dst, _screenWidth * m, x * m, (y + vs->topline) * m, width * m, height * m);
+ } else {
+ _system->copyRectToScreen(vs->getPixels(x, y), vs->pitch, x, y + vs->topline, width, height);
+ }
+
+
if (++blits >= blits_before_refresh) {
blits = 0;
waitForTimer(30);
@@ -3391,16 +3442,30 @@
step = (step * delay) / kScrolltime;
+ byte *src;
+ int m = _textSurfaceMultiplier;
+ int vsPitch = vs->pitch;
+
switch (dir) {
case 0:
//up
y = 1 + step;
while (y < vs->h) {
moveScreen(0, -step, vs->h);
- _system->copyRectToScreen(vs->getPixels(0, y - step),
- vs->pitch,
- 0, vs->h - step,
- vs->w, step);
+
+ src = vs->getPixels(0, y - step);
+ if (_useCJKMode && m == 2) {
+ int x1 = 0, y1 = vs->h - step;
+ byte *dst = _fmtownsBuf + x1 * m + y1 * m * _screenWidth * m;
+ scale2x(dst, _screenWidth * m, src, vs->pitch, vs->w, step);
+ src = dst;
+ vsPitch = _screenWidth * 2;
+ }
+
+ _system->copyRectToScreen(src,
+ vsPitch,
+ 0 * m, (vs->h - step) * m,
+ vs->w * m, step * m);
_system->updateScreen();
waitForTimer(delay);
@@ -3412,10 +3477,18 @@
y = 1 + step;
while (y < vs->h) {
moveScreen(0, step, vs->h);
- _system->copyRectToScreen(vs->getPixels(0, vs->h - y),
- vs->pitch,
+ src = vs->getPixels(0, vs->h - y);
+ if (_useCJKMode && m == 2) {
+ int x1 = 0, y1 = 0;
+ byte *dst = _fmtownsBuf + x1 * m + y1 * m * _screenWidth * m;
+ scale2x(dst, _screenWidth * m, src, vs->pitch, vs->w, step);
+ src = dst;
+ vsPitch = _screenWidth * 2;
+ }
+ _system->copyRectToScreen(src,
+ vsPitch,
0, 0,
- vs->w, step);
+ vs->w * m, step * m);
_system->updateScreen();
waitForTimer(delay);
@@ -3427,10 +3500,18 @@
x = 1 + step;
while (x < vs->w) {
moveScreen(-step, 0, vs->h);
- _system->copyRectToScreen(vs->getPixels(x - step, 0),
- vs->pitch,
- vs->w - step, 0,
- step, vs->h);
+ src = vs->getPixels(x - step, 0);
+ if (_useCJKMode && m == 2) {
+ int x1 = vs->w - step, y1 = 0;
+ byte *dst = _fmtownsBuf + x1 * m + y1 * m * _screenWidth * m;
+ scale2x(dst, _screenWidth * m, src, vs->pitch, step, vs->h);
+ src = dst;
+ vsPitch = _screenWidth * 2;
+ }
+ _system->copyRectToScreen(src,
+ vsPitch,
+ (vs->w - step) * m, 0,
+ step * m, vs->h * m);
_system->updateScreen();
waitForTimer(delay);
@@ -3442,8 +3523,16 @@
x = 1 + step;
while (x < vs->w) {
moveScreen(step, 0, vs->h);
- _system->copyRectToScreen(vs->getPixels(vs->w - x, 0),
- vs->pitch,
+ src = vs->getPixels(vs->w - x, 0);
+ if (_useCJKMode && m == 2) {
+ int x1 = 0, y1 = 0;
+ byte *dst = _fmtownsBuf + x1 * m + y1 * m * _screenWidth * m;
+ scale2x(dst, _screenWidth * m, src, vs->pitch, step, vs->h);
+ src = dst;
+ vsPitch = _screenWidth * 2;
+ }
+ _system->copyRectToScreen(src,
+ vsPitch,
0, 0,
step, vs->h);
_system->updateScreen();
Modified: scummvm/trunk/engines/scumm/input.cpp
===================================================================
--- scummvm/trunk/engines/scumm/input.cpp 2007-07-09 21:56:35 UTC (rev 27997)
+++ scummvm/trunk/engines/scumm/input.cpp 2007-07-10 00:39:12 UTC (rev 27998)
@@ -162,8 +162,11 @@
if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
_mouse.x -= (Common::kHercW - _screenWidth * 2) / 2;
- _mouse.x /= 2;
+ _mouse.x >>= 1;
_mouse.y = _mouse.y * 4 / 7;
+ } else if (_useCJKMode && _textSurfaceMultiplier == 2) {
+ _mouse.x >>= 1;
+ _mouse.y >>= 1;
}
break;
case Common::EVENT_LBUTTONUP:
Modified: scummvm/trunk/engines/scumm/scumm.cpp
===================================================================
--- scummvm/trunk/engines/scumm/scumm.cpp 2007-07-09 21:56:35 UTC (rev 27997)
+++ scummvm/trunk/engines/scumm/scumm.cpp 2007-07-10 00:39:12 UTC (rev 27998)
@@ -587,6 +587,7 @@
free(_compositeBuf);
free(_herculesBuf);
+ free(_fmtownsBuf);
delete _debugger;
@@ -1078,12 +1079,19 @@
_fileHandle = new ScummFile();
}
+ // Load CJK font, if present
+ // Load it earlier so _useCJKMode variable could be set
+ loadCJKFont();
+
// Initialize backend
_system->beginGFXTransaction();
bool defaultTo1XScaler = false;
if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
_system->initSize(Common::kHercW, Common::kHercH);
defaultTo1XScaler = true;
+ } else if (_useCJKMode) {
+ _system->initSize(_screenWidth * _textSurfaceMultiplier, _screenHeight * _textSurfaceMultiplier);
+ defaultTo1XScaler = true;
} else {
_system->initSize(_screenWidth, _screenHeight);
defaultTo1XScaler = (_screenWidth > 320);
@@ -1135,14 +1143,11 @@
// Load localization data, if present
loadLanguageBundle();
- // Load CJK font, if present
- loadCJKFont();
-
// Create the charset renderer
setupCharsetRenderer();
// Create and clear the text surface
- _textSurface.create(_screenWidth, _screenHeight, 1);
+ _textSurface.create(_screenWidth * _textSurfaceMultiplier, _screenHeight * _textSurfaceMultiplier, 1);
clearTextSurface();
// Create the costume renderer
@@ -1210,6 +1215,13 @@
#if (defined(PALMOS_ARM) || defined(PALMOS_DEBUG) || defined(__GP32__))
Graphics::initfonts();
#endif
+
+ _fmtownsBuf = 0;
+ if (_game.platform == Common::kPlatformFMTowns && _language == Common::JA_JPN) {
+ _fmtownsBuf = (byte *)malloc(_screenWidth * _textSurfaceMultiplier * _screenHeight * _textSurfaceMultiplier);
+ }
+
+ _compositeBuf = (byte *)malloc(_screenWidth * _textSurfaceMultiplier * _screenHeight * _textSurfaceMultiplier);
}
#ifndef DISABLE_SCUMM_7_8
Modified: scummvm/trunk/engines/scumm/scumm.h
===================================================================
--- scummvm/trunk/engines/scumm/scumm.h 2007-07-09 21:56:35 UTC (rev 27997)
+++ scummvm/trunk/engines/scumm/scumm.h 2007-07-10 00:39:12 UTC (rev 27998)
@@ -1026,10 +1026,12 @@
// Screen rendering
byte *_compositeBuf;
byte *_herculesBuf;
+ byte *_fmtownsBuf;
virtual void drawDirtyScreenParts();
void updateDirtyScreen(VirtScreenNumber slot);
void drawStripToScreen(VirtScreen *vs, int x, int w, int t, int b);
void ditherCGA(byte *dst, int dstPitch, int x, int y, int width, int height) const;
+ void scale2x(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h);
public:
VirtScreen *findVirtScreen(int y);
@@ -1151,6 +1153,7 @@
* drawStripToScreen() composits it over the game graphics.
*/
Graphics::Surface _textSurface;
+ int _textSurfaceMultiplier;
protected:
byte _charsetColor;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list