mirror of
https://github.com/libretro/scummvm.git
synced 2025-03-05 01:38:36 +00:00
AGI: Hercules rendering for game screen
This commit is contained in:
parent
470cdabc58
commit
7a169c90f6
@ -283,18 +283,7 @@ void AgiBase::initRenderMode() {
|
||||
|
||||
switch (platform) {
|
||||
case Common::kPlatformDOS:
|
||||
switch (configRenderMode) {
|
||||
case Common::kRenderCGA:
|
||||
_renderMode = Common::kRenderCGA;
|
||||
break;
|
||||
// Hercules is not supported atm
|
||||
//case Common::kRenderHercA:
|
||||
//case Common::kRenderHercG:
|
||||
// _renderMode = Common::kRenderHercG;
|
||||
// break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// Keep EGA
|
||||
break;
|
||||
case Common::kPlatformAmiga:
|
||||
_renderMode = Common::kRenderAmiga;
|
||||
@ -323,6 +312,12 @@ void AgiBase::initRenderMode() {
|
||||
case Common::kRenderVGA:
|
||||
_renderMode = Common::kRenderVGA;
|
||||
break;
|
||||
case Common::kRenderHercG:
|
||||
_renderMode = Common::kRenderHercG;
|
||||
break;
|
||||
case Common::kRenderHercA:
|
||||
_renderMode = Common::kRenderHercA;
|
||||
break;
|
||||
case Common::kRenderAmiga:
|
||||
_renderMode = Common::kRenderAmiga;
|
||||
break;
|
||||
|
@ -624,6 +624,16 @@ void GfxFont::init() {
|
||||
if (ConfMan.getBool("herculesfont")) {
|
||||
// User wants, that we use Hercules hires font, try to load it
|
||||
loadFontHercules();
|
||||
} else {
|
||||
switch (_vm->_renderMode) {
|
||||
case Common::kRenderHercA:
|
||||
case Common::kRenderHercG:
|
||||
// Render mode is Hercules, we try to load Hercules hires font
|
||||
loadFontHercules();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_fontData) {
|
||||
@ -650,6 +660,8 @@ void GfxFont::init() {
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Common::kRenderHercA:
|
||||
case Common::kRenderHercG:
|
||||
case Common::kRenderCGA:
|
||||
case Common::kRenderEGA:
|
||||
case Common::kRenderVGA:
|
||||
@ -699,6 +711,11 @@ void GfxFont::overwriteSaveRestoreDialogCharacter() {
|
||||
|
||||
// Overwrite extended character set (0x80-0xFF) with Russian characters
|
||||
void GfxFont::overwriteExtendedWithRussianSet() {
|
||||
if (_fontIsHires) {
|
||||
// TODO: Implement overwriting hires font characters too
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_fontDataAllocated) {
|
||||
// nothing allocated, we need to allocate space ourselves to be able to modify an internal font
|
||||
_fontDataAllocated = (uint8 *)calloc(256, 8);
|
||||
|
@ -69,6 +69,8 @@ GfxMgr::GfxMgr(AgiBase *vm, GfxFont *font) : _vm(vm), _font(font) {
|
||||
* @see deinit_video()
|
||||
*/
|
||||
int GfxMgr::initVideo() {
|
||||
bool forceHires = false;
|
||||
|
||||
// Set up palettes
|
||||
initPalette(_paletteTextMode, PALETTE_EGA);
|
||||
|
||||
@ -82,6 +84,14 @@ int GfxMgr::initVideo() {
|
||||
case Common::kRenderVGA:
|
||||
initPalette(_paletteGfxMode, PALETTE_VGA, 256, 8);
|
||||
break;
|
||||
case Common::kRenderHercG:
|
||||
initPalette(_paletteGfxMode, PALETTE_HERCULES_GREEN, 2, 8);
|
||||
forceHires = true;
|
||||
break;
|
||||
case Common::kRenderHercA:
|
||||
initPalette(_paletteGfxMode, PALETTE_HERCULES_AMBER, 2, 8);
|
||||
forceHires = true;
|
||||
break;
|
||||
case Common::kRenderAmiga:
|
||||
if (!ConfMan.getBool("altamigapalette")) {
|
||||
// Set the correct Amiga palette depending on AGI interpreter version
|
||||
@ -137,7 +147,7 @@ int GfxMgr::initVideo() {
|
||||
|
||||
//bool forcedUpscale = true;
|
||||
|
||||
if (_font->isFontHires()) {
|
||||
if (_font->isFontHires() || forceHires) {
|
||||
// Upscaling enable
|
||||
_upscaledHires = DISPLAY_UPSCALED_640x400;
|
||||
_displayScreenWidth = 640;
|
||||
@ -154,6 +164,8 @@ int GfxMgr::initVideo() {
|
||||
case Common::kRenderEGA:
|
||||
case Common::kRenderCGA:
|
||||
case Common::kRenderVGA:
|
||||
case Common::kRenderHercG:
|
||||
case Common::kRenderHercA:
|
||||
initMouseCursor(&_mouseCursor, MOUSECURSOR_SCI, 11, 16, 0, 0);
|
||||
initMouseCursor(&_mouseCursorBusy, MOUSECURSOR_SCI_BUSY, 15, 16, 7, 8);
|
||||
break;
|
||||
@ -500,6 +512,10 @@ void GfxMgr::render_Block(int16 x, int16 y, int16 width, int16 height, bool copy
|
||||
return;
|
||||
|
||||
switch (_vm->_renderMode) {
|
||||
case Common::kRenderHercG:
|
||||
case Common::kRenderHercA:
|
||||
render_BlockHercules(x, y, width, height, copyToScreen);
|
||||
break;
|
||||
case Common::kRenderCGA:
|
||||
render_BlockCGA(x, y, width, height, copyToScreen);
|
||||
break;
|
||||
@ -654,6 +670,106 @@ void GfxMgr::render_BlockCGA(int16 x, int16 y, int16 width, int16 height, bool c
|
||||
}
|
||||
}
|
||||
|
||||
static const uint8 herculesColorMapping[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x88, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
|
||||
0x80, 0x10, 0x02, 0x20, 0x01, 0x08, 0x40, 0x04,
|
||||
0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00,
|
||||
0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88,
|
||||
0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00,
|
||||
0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88,
|
||||
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
||||
0x22, 0x00, 0x88, 0x00, 0x22, 0x00, 0x88, 0x00,
|
||||
0xD7, 0xFF, 0x7D, 0xFF, 0xD7, 0xFF, 0x7D, 0xFF,
|
||||
0xDD, 0x55, 0x77, 0xAA, 0xDD, 0x55, 0x77, 0xAA,
|
||||
0x7F, 0xEF, 0xFD, 0xDF, 0xFE, 0xF7, 0xBF, 0xFB,
|
||||
0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
|
||||
0x77, 0xBB, 0xDD, 0xEE, 0x77, 0xBB, 0xDD, 0xEE,
|
||||
0x77, 0xFF, 0xFF, 0xFF, 0xDD, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
|
||||
};
|
||||
|
||||
// Sierra actually seems to have rendered the whole screen all the time
|
||||
void GfxMgr::render_BlockHercules(int16 x, int16 y, int16 width, int16 height, bool copyToScreen) {
|
||||
uint32 offsetVisual = SCRIPT_WIDTH * y + x;
|
||||
uint32 offsetDisplay = getDisplayOffsetToGameScreenPos(x, y);
|
||||
int16 remainingWidth = width;
|
||||
int16 remainingHeight = height;
|
||||
byte curColor = 0;
|
||||
int16 displayWidth = width * (2 + _displayWidthMulAdjust);
|
||||
|
||||
assert(_upscaledHires == DISPLAY_UPSCALED_640x400);
|
||||
|
||||
uint16 lookupOffset1 = (y * 2 & 0x07);
|
||||
uint16 lookupOffset2 = 0;
|
||||
bool getUpperNibble = false;
|
||||
byte herculesColors1 = 0;
|
||||
byte herculesColors2 = 0;
|
||||
|
||||
while (remainingHeight) {
|
||||
remainingWidth = width;
|
||||
|
||||
lookupOffset1 = (lookupOffset1 + 0) & 0x07;
|
||||
lookupOffset2 = (lookupOffset1 + 1) & 0x07;
|
||||
|
||||
getUpperNibble = (x & 1) ? false : true;
|
||||
while (remainingWidth) {
|
||||
curColor = _activeScreen[offsetVisual++] & 0x0F;
|
||||
|
||||
if (getUpperNibble) {
|
||||
herculesColors1 = herculesColorMapping[curColor * 8 + lookupOffset1] & 0x0F;
|
||||
herculesColors2 = herculesColorMapping[curColor * 8 + lookupOffset2] & 0x0F;
|
||||
} else {
|
||||
herculesColors1 = herculesColorMapping[curColor * 8 + lookupOffset1] >> 4;
|
||||
herculesColors2 = herculesColorMapping[curColor * 8 + lookupOffset2] >> 4;
|
||||
}
|
||||
getUpperNibble ^= true;
|
||||
|
||||
_displayScreen[offsetDisplay + 0] = (herculesColors1 & 0x08) ? 1 : 0;
|
||||
_displayScreen[offsetDisplay + 1] = (herculesColors1 & 0x04) ? 1 : 0;
|
||||
_displayScreen[offsetDisplay + 2] = (herculesColors1 & 0x02) ? 1 : 0;
|
||||
_displayScreen[offsetDisplay + 3] = (herculesColors1 & 0x01) ? 1 : 0;
|
||||
|
||||
_displayScreen[offsetDisplay + _displayScreenWidth + 0] = (herculesColors2 & 0x08) ? 1 : 0;
|
||||
_displayScreen[offsetDisplay + _displayScreenWidth + 1] = (herculesColors2 & 0x04) ? 1 : 0;
|
||||
_displayScreen[offsetDisplay + _displayScreenWidth + 2] = (herculesColors2 & 0x02) ? 1 : 0;
|
||||
_displayScreen[offsetDisplay + _displayScreenWidth + 3] = (herculesColors2 & 0x01) ? 1 : 0;
|
||||
|
||||
offsetDisplay += 4;
|
||||
remainingWidth--;
|
||||
}
|
||||
|
||||
lookupOffset1 += 2;
|
||||
|
||||
offsetVisual += SCRIPT_WIDTH - width;
|
||||
offsetDisplay += _displayScreenWidth - displayWidth;
|
||||
offsetDisplay += _displayScreenWidth;;
|
||||
|
||||
remainingHeight--;
|
||||
}
|
||||
}
|
||||
|
||||
// Table used for at least Manhunter 2, it renders 2 lines -> 3 lines instead of 4
|
||||
// Manhunter 1 is shipped with a broken Hercules font
|
||||
// King's Quest 4 aborts right at the start, when Hercules rendering is active
|
||||
#if 0
|
||||
static const uint8 herculesCoordinateOffset[] = {
|
||||
0x00, 0x01, 0x03, 0x04, 0x06, 0x07, 0x01, 0x02,
|
||||
0x04, 0x05, 0x07, 0x00, 0x02, 0x03, 0x05, 0x06
|
||||
};
|
||||
|
||||
static const uint8 herculesColorMapping[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x08, 0x00,
|
||||
0x80, 0x10, 0x02, 0x20, 0x01, 0x08, 0x40, 0x04, 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00,
|
||||
0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00,
|
||||
0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
||||
0x22, 0x00, 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0xD7, 0xFF, 0x7D, 0xFF, 0xD7, 0xFF, 0x7D, 0xFF,
|
||||
0xDD, 0x55, 0x77, 0xAA, 0xDD, 0x55, 0x77, 0xAA, 0x7F, 0xEF, 0xFD, 0xDF, 0xFE, 0xF7, 0xBF, 0xFB,
|
||||
0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0x77, 0xBB, 0xDD, 0xEE, 0x77, 0xBB, 0xDD, 0xEE,
|
||||
0x7F, 0xEF, 0xFB, 0xBF, 0xEF, 0xFE, 0xBF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
|
||||
};
|
||||
#endif
|
||||
|
||||
void GfxMgr::transition_Amiga() {
|
||||
uint16 screenPos = 1;
|
||||
uint32 screenStepPos = 1;
|
||||
@ -876,6 +992,10 @@ void GfxMgr::drawBox(int16 x, int16 y, int16 width, int16 height, byte backgroun
|
||||
drawDisplayRect(x, +1, y + height, -2, width, -2, 0, 1, 0);
|
||||
drawDisplayRect(x, +1, y, +1, 0, 1, height, -2, 0);
|
||||
break;
|
||||
case Common::kRenderHercA:
|
||||
case Common::kRenderHercG:
|
||||
lineColor = 0; // change linecolor to black
|
||||
// supposed to fall through
|
||||
case Common::kRenderCGA:
|
||||
case Common::kRenderEGA:
|
||||
case Common::kRenderVGA:
|
||||
@ -895,6 +1015,11 @@ void GfxMgr::drawDisplayRect(int16 x, int16 y, int16 width, int16 height, byte c
|
||||
case Common::kRenderCGA:
|
||||
drawDisplayRectCGA(x, y, width, height, color);
|
||||
break;
|
||||
case Common::kRenderHercG:
|
||||
case Common::kRenderHercA:
|
||||
if (color)
|
||||
color = 1; // change any color except black to green/amber
|
||||
// supposed to fall through
|
||||
case Common::kRenderEGA:
|
||||
default:
|
||||
drawDisplayRectEGA(x, y, width, height, color);
|
||||
|
@ -180,6 +180,7 @@ public:
|
||||
private:
|
||||
void render_BlockEGA(int16 x, int16 y, int16 width, int16 height, bool copyToScreen);
|
||||
void render_BlockCGA(int16 x, int16 y, int16 width, int16 height, bool copyToScreen);
|
||||
void render_BlockHercules(int16 x, int16 y, int16 width, int16 height, bool copyToScreen);
|
||||
|
||||
public:
|
||||
void transition_Amiga();
|
||||
|
@ -59,6 +59,22 @@ static const uint8 PALETTE_CGA[4 * 3] = {
|
||||
0xff, 0xff, 0xff
|
||||
};
|
||||
|
||||
/**
|
||||
* 2 color Hercules (green) palette. Using 8-bit RGB values.
|
||||
*/
|
||||
static const uint8 PALETTE_HERCULES_GREEN[2 * 3] = {
|
||||
0x00, 0x00, 0x00, // black
|
||||
0x00, 0xdc, 0x28 // green
|
||||
};
|
||||
|
||||
/**
|
||||
* 2 color Hercules (amber) palette. Using 8-bit RGB values.
|
||||
*/
|
||||
static const uint8 PALETTE_HERCULES_AMBER[2 * 3] = {
|
||||
0x00, 0x00, 0x00, // black
|
||||
0xdc, 0xb4, 0x00 // amber
|
||||
};
|
||||
|
||||
/**
|
||||
* Atari ST AGI palette.
|
||||
* Used by all of the tested Atari ST AGI games
|
||||
|
@ -179,6 +179,16 @@ void TextMgr::charAttrib_Set(byte foreground, byte background) {
|
||||
_textAttrib.combinedBackground = 0;
|
||||
}
|
||||
break;
|
||||
case Common::kRenderHercA:
|
||||
case Common::kRenderHercG:
|
||||
if (background) {
|
||||
_textAttrib.combinedForeground = 0;
|
||||
_textAttrib.combinedBackground = 1;
|
||||
} else {
|
||||
_textAttrib.combinedForeground = 1;
|
||||
_textAttrib.combinedBackground = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// EGA-handling:
|
||||
if (background) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user