Fix bug #1326833 "ITE: Missing copy protection". Though it is disabled
by default by kind permission from Wyrmkeep Entertainment Co. svn-id: r19125
This commit is contained in:
parent
3dd9f208cc
commit
ee4cbcb98d
12 changed files with 148 additions and 30 deletions
4
README
4
README
|
@ -193,10 +193,14 @@ bypasses them. There is no way for us to tell the difference between legitimate
|
||||||
and pirated data files, so for the games where we know the original interpreter
|
and pirated data files, so for the games where we know the original interpreter
|
||||||
may have been cracked ScummVM will always have to bypass the copy protection.
|
may have been cracked ScummVM will always have to bypass the copy protection.
|
||||||
|
|
||||||
|
Wyrmkeep Entertainment kindly let us skip protection in floppy version of
|
||||||
|
Inherit the Earth since it was disabled in all CD releases of the game.
|
||||||
|
|
||||||
At the time of writing, that includes the following games:
|
At the time of writing, that includes the following games:
|
||||||
|
|
||||||
Indiana Jones & the Last Crusade (EGA)
|
Indiana Jones & the Last Crusade (EGA)
|
||||||
Indiana Jones & the Last Crusade (FM-TOWNS version)
|
Indiana Jones & the Last Crusade (FM-TOWNS version)
|
||||||
|
Inherit the Earth (floppy version)
|
||||||
Loom (16 color floppy version)
|
Loom (16 color floppy version)
|
||||||
Maniac Mansion
|
Maniac Mansion
|
||||||
Monkey Island 1 (EGA)
|
Monkey Island 1 (EGA)
|
||||||
|
|
|
@ -7,11 +7,15 @@ bypasses them. There is no way for us to tell the difference between legitimate
|
||||||
and pirated data files, so for the games where we know the original interpreter
|
and pirated data files, so for the games where we know the original interpreter
|
||||||
may have been cracked ScummVM will always have to bypass the copy protection.
|
may have been cracked ScummVM will always have to bypass the copy protection.
|
||||||
|
|
||||||
|
Wyrmkeep Entertainment kindly let us skip protection in floppy version of
|
||||||
|
Inherit the Earth since it was disabled in all CD releases of the game.
|
||||||
|
|
||||||
At the time of writing, that includes the following games:
|
At the time of writing, that includes the following games:
|
||||||
|
|
||||||
\begin{tabular}{l}
|
\begin{tabular}{l}
|
||||||
Indiana Jones \& the Last Crusade (EGA)\\
|
Indiana Jones \& the Last Crusade (EGA)\\
|
||||||
Indiana Jones \& the Last Crusade (FM-TOWNS version)\\
|
Indiana Jones \& the Last Crusade (FM-TOWNS version)\\
|
||||||
|
Inherit the Earth (floppy version)\\
|
||||||
Loom (16 color floppy version)\\
|
Loom (16 color floppy version)\\
|
||||||
Maniac Mansion\\
|
Maniac Mansion\\
|
||||||
Monkey Island 1 (EGA)\\
|
Monkey Island 1 (EGA)\\
|
||||||
|
|
|
@ -438,7 +438,7 @@ void Font::textDraw(FontId fontId, Surface *ds, const char *text, const Common::
|
||||||
|
|
||||||
if (fitWidth < textWidth) {
|
if (fitWidth < textWidth) {
|
||||||
warning("text too long to be displayed in one line");
|
warning("text too long to be displayed in one line");
|
||||||
return;
|
textWidth = fitWidth;
|
||||||
}
|
}
|
||||||
// Entire string fits, draw it
|
// Entire string fits, draw it
|
||||||
textPoint.x = textPoint.x - (textWidth / 2);
|
textPoint.x = textPoint.x - (textWidth / 2);
|
||||||
|
|
|
@ -120,6 +120,11 @@ static PanelButton ITE_SavePanelButtons[] = {
|
||||||
{kPanelButtonSaveText, -1,5, 0,0, kTextEnterSaveGameName,'-',0, 0,0,0},
|
{kPanelButtonSaveText, -1,5, 0,0, kTextEnterSaveGameName,'-',0, 0,0,0},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static PanelButton ITE_ProtectPanelButtons[] = {
|
||||||
|
{kPanelButtonProtectEdit, 26,17, 119,17, 0,'-',0, 0,0,0},
|
||||||
|
{kPanelButtonProtectText, -1,5, 0,0, kTextEnterProtectAnswer,'-',0, 0,0,0},
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
static PanelButton ITE_ProtectionPanelButtons[] = {
|
static PanelButton ITE_ProtectionPanelButtons[] = {
|
||||||
{kPanelButtonArrow, 0,0, 0,0, 0,'-',0, 0,0,0}, //TODO
|
{kPanelButtonArrow, 0,0, 0,0, 0,'-',0, 0,0,0}, //TODO
|
||||||
|
@ -184,7 +189,13 @@ static GameDisplayInfo ITE_DisplayInfo = {
|
||||||
74, 44, // save panel offsets
|
74, 44, // save panel offsets
|
||||||
172, 58, // save panel width & height
|
172, 58, // save panel width & height
|
||||||
ARRAYSIZE(ITE_SavePanelButtons),
|
ARRAYSIZE(ITE_SavePanelButtons),
|
||||||
ITE_SavePanelButtons
|
ITE_SavePanelButtons,
|
||||||
|
|
||||||
|
0, // protect edit index
|
||||||
|
74, 44, // protect panel offsets
|
||||||
|
172, 58, // protect panel width & height
|
||||||
|
ARRAYSIZE(ITE_ProtectPanelButtons),
|
||||||
|
ITE_ProtectPanelButtons
|
||||||
};
|
};
|
||||||
|
|
||||||
static GameResourceDescription ITE_Resources = {
|
static GameResourceDescription ITE_Resources = {
|
||||||
|
@ -635,6 +646,13 @@ static GameDisplayInfo IHNM_DisplayInfo = { //TODO: fill it all
|
||||||
0, 0, // save panel offsets
|
0, 0, // save panel offsets
|
||||||
0, 0, // save panel width & height
|
0, 0, // save panel width & height
|
||||||
ARRAYSIZE(IHNM_SavePanelButtons),
|
ARRAYSIZE(IHNM_SavePanelButtons),
|
||||||
|
IHNM_SavePanelButtons,
|
||||||
|
|
||||||
|
// No protection panel in IHNM
|
||||||
|
-1, // protect edit index
|
||||||
|
0, 0, // protect panel offsets
|
||||||
|
0, 0, // protect panel width & height
|
||||||
|
ARRAYSIZE(IHNM_SavePanelButtons),
|
||||||
IHNM_SavePanelButtons
|
IHNM_SavePanelButtons
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -172,6 +172,15 @@ Interface::Interface(SagaEngine *vm) : _vm(vm) {
|
||||||
_saveEdit = _savePanel.getButton(_vm->getDisplayInfo().saveEditIndex);
|
_saveEdit = _savePanel.getButton(_vm->getDisplayInfo().saveEditIndex);
|
||||||
_savePanel.currentButton = NULL;
|
_savePanel.currentButton = NULL;
|
||||||
|
|
||||||
|
_protectPanel.x = _vm->getDisplayInfo().protectPanelXOffset;
|
||||||
|
_protectPanel.y = _vm->getDisplayInfo().protectPanelYOffset;
|
||||||
|
_protectPanel.imageWidth = _vm->getDisplayInfo().protectPanelWidth;
|
||||||
|
_protectPanel.imageHeight = _vm->getDisplayInfo().protectPanelHeight;
|
||||||
|
_protectPanel.buttons = _vm->getDisplayInfo().protectPanelButtons;
|
||||||
|
_protectPanel.buttonsCount = _vm->getDisplayInfo().protectPanelButtonsCount;
|
||||||
|
_protectEdit = _protectPanel.getButton(_vm->getDisplayInfo().protectEditIndex);
|
||||||
|
_protectPanel.currentButton = NULL;
|
||||||
|
|
||||||
_active = true;
|
_active = true;
|
||||||
_panelMode = _lockedMode = kPanelNull;
|
_panelMode = _lockedMode = kPanelNull;
|
||||||
_savedMode = -1;
|
_savedMode = -1;
|
||||||
|
@ -315,6 +324,15 @@ void Interface::setMode(int mode) {
|
||||||
case kPanelBoss:
|
case kPanelBoss:
|
||||||
_vm->_render->setFlag(RF_DEMO_SUBST);
|
_vm->_render->setFlag(RF_DEMO_SUBST);
|
||||||
break;
|
break;
|
||||||
|
case kPanelProtect:
|
||||||
|
_protectPanel.currentButton = NULL;
|
||||||
|
_textInputMaxWidth = _protectEdit->width - 10;
|
||||||
|
_textInput = true;
|
||||||
|
_textInputString[0] = 0;
|
||||||
|
_textInputStringLength = 0;
|
||||||
|
_textInputPos = _textInputStringLength + 1;
|
||||||
|
_textInputRepeatPhase = 0;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
draw();
|
draw();
|
||||||
|
@ -493,6 +511,21 @@ bool Interface::processAscii(uint16 ascii, bool synthetic) {
|
||||||
_vm->_render->clearFlag(RF_DEMO_SUBST);
|
_vm->_render->clearFlag(RF_DEMO_SUBST);
|
||||||
keyBossExit();
|
keyBossExit();
|
||||||
break;
|
break;
|
||||||
|
case kPanelProtect:
|
||||||
|
if (_textInput && processTextInput(ascii)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ascii == 27 || ascii == 13) { // Esc or Enter
|
||||||
|
_vm->_script->wakeUpThreads(kWaitTypeRequest);
|
||||||
|
_vm->_interface->setMode(kPanelMain);
|
||||||
|
|
||||||
|
_protectHash = 0;
|
||||||
|
|
||||||
|
for (char *p = _textInputString; *p; p++)
|
||||||
|
_protectHash = (_protectHash << 1) + toupper(*p);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1055,6 +1088,26 @@ void Interface::drawSave() {
|
||||||
drawTextInput(backBuffer, &_savePanel, _saveEdit);
|
drawTextInput(backBuffer, &_savePanel, _saveEdit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Interface::drawProtect() {
|
||||||
|
Surface *backBuffer;
|
||||||
|
Rect rect;
|
||||||
|
int i;
|
||||||
|
PanelButton *panelButton;
|
||||||
|
|
||||||
|
backBuffer = _vm->_gfx->getBackBuffer();
|
||||||
|
|
||||||
|
_protectPanel.getRect(rect);
|
||||||
|
drawButtonBox(backBuffer, rect, kButton, false);
|
||||||
|
|
||||||
|
for (i = 0; i < _protectPanel.buttonsCount; i++) {
|
||||||
|
panelButton = &_protectPanel.buttons[i];
|
||||||
|
if (panelButton->type == kPanelButtonProtectText) {
|
||||||
|
drawPanelText(backBuffer, &_protectPanel, panelButton);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
drawTextInput(backBuffer, &_protectPanel, _protectEdit);
|
||||||
|
}
|
||||||
|
|
||||||
void Interface::handleSaveUpdate(const Point& mousePoint) {
|
void Interface::handleSaveUpdate(const Point& mousePoint) {
|
||||||
bool releasedButton;
|
bool releasedButton;
|
||||||
|
|
||||||
|
@ -1460,6 +1513,11 @@ void Interface::update(const Point& mousePoint, int updateFlag) {
|
||||||
handleChapterSelectionClick(mousePoint);
|
handleChapterSelectionClick(mousePoint);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case kPanelProtect:
|
||||||
|
// No mouse interaction
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_lastMousePoint = mousePoint;
|
_lastMousePoint = mousePoint;
|
||||||
|
|
|
@ -237,6 +237,7 @@ public:
|
||||||
void drawQuit();
|
void drawQuit();
|
||||||
void drawLoad();
|
void drawLoad();
|
||||||
void drawSave();
|
void drawSave();
|
||||||
|
void drawProtect();
|
||||||
void update(const Point& mousePoint, int updateFlag);
|
void update(const Point& mousePoint, int updateFlag);
|
||||||
void drawStatusBar();
|
void drawStatusBar();
|
||||||
void setVerbState(int verb, int state);
|
void setVerbState(int verb, int state);
|
||||||
|
@ -297,6 +298,8 @@ public:
|
||||||
|
|
||||||
void mapPanelDrawCrossHair();
|
void mapPanelDrawCrossHair();
|
||||||
|
|
||||||
|
int32 getProtectHash() { return _protectHash; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void handleMainUpdate(const Point& mousePoint); // main panel update
|
void handleMainUpdate(const Point& mousePoint); // main panel update
|
||||||
void handleMainClick(const Point& mousePoint); // main panel click
|
void handleMainClick(const Point& mousePoint); // main panel click
|
||||||
|
@ -418,6 +421,8 @@ private:
|
||||||
InterfacePanel _loadPanel;
|
InterfacePanel _loadPanel;
|
||||||
InterfacePanel _savePanel;
|
InterfacePanel _savePanel;
|
||||||
PanelButton * _saveEdit;
|
PanelButton * _saveEdit;
|
||||||
|
InterfacePanel _protectPanel;
|
||||||
|
PanelButton * _protectEdit;
|
||||||
|
|
||||||
bool _disableAbortSpeeches;
|
bool _disableAbortSpeeches;
|
||||||
|
|
||||||
|
@ -472,6 +477,8 @@ private:
|
||||||
|
|
||||||
PalEntry _mapSavedPal[PAL_ENTRIES];
|
PalEntry _mapSavedPal[PAL_ENTRIES];
|
||||||
bool _mapPanelCrossHairState;
|
bool _mapPanelCrossHairState;
|
||||||
|
|
||||||
|
int32 _protectHash;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End of namespace Saga
|
} // End of namespace Saga
|
||||||
|
|
|
@ -334,7 +334,7 @@ FxTable ITE_SfxTable[ITE_SFXCOUNT] = {
|
||||||
{ FX_CROWD_17, 64 }
|
{ FX_CROWD_17, 64 }
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *ITEinterfaceTextStrings[][51] = {
|
const char *ITEinterfaceTextStrings[][52] = {
|
||||||
{
|
{
|
||||||
"Walk to", "Look At", "Pick Up", "Talk to", "Open",
|
"Walk to", "Look At", "Pick Up", "Talk to", "Open",
|
||||||
"Close", "Use", "Give", "Options", "Test",
|
"Close", "Use", "Give", "Options", "Test",
|
||||||
|
@ -351,7 +351,8 @@ const char *ITEinterfaceTextStrings[][51] = {
|
||||||
"There's no place to open it.",
|
"There's no place to open it.",
|
||||||
"There's no opening to close.",
|
"There's no opening to close.",
|
||||||
"I don't know how to do that.",
|
"I don't know how to do that.",
|
||||||
"Show Dialog"
|
"Show Dialog",
|
||||||
|
"What is Rif's reply?"
|
||||||
},
|
},
|
||||||
// German
|
// German
|
||||||
{
|
{
|
||||||
|
@ -370,7 +371,8 @@ const char *ITEinterfaceTextStrings[][51] = {
|
||||||
"Das kann man nicht \224ffnen.",
|
"Das kann man nicht \224ffnen.",
|
||||||
"Hier ist keine \231ffnung zum Schlie$en.",
|
"Hier ist keine \231ffnung zum Schlie$en.",
|
||||||
"Ich wei$ nicht, wie ich das machen soll.",
|
"Ich wei$ nicht, wie ich das machen soll.",
|
||||||
"Text zeigen"
|
"Text zeigen",
|
||||||
|
"Wie lautet die Antwort?"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ struct FxTable {
|
||||||
extern ObjectTableData ITE_ObjectTable[ITE_OBJECTCOUNT];
|
extern ObjectTableData ITE_ObjectTable[ITE_OBJECTCOUNT];
|
||||||
extern FxTable ITE_SfxTable[ITE_SFXCOUNT];
|
extern FxTable ITE_SfxTable[ITE_SFXCOUNT];
|
||||||
|
|
||||||
extern const char *ITEinterfaceTextStrings[][51];
|
extern const char *ITEinterfaceTextStrings[][52];
|
||||||
|
|
||||||
} // End of namespace Saga
|
} // End of namespace Saga
|
||||||
|
|
||||||
|
|
|
@ -128,6 +128,10 @@ void Render::drawScene() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_vm->_interface->getMode() == kPanelProtect) {
|
||||||
|
_vm->_interface->drawProtect();
|
||||||
|
}
|
||||||
|
|
||||||
// Draw queued text strings
|
// Draw queued text strings
|
||||||
_vm->_scene->drawTextList(backBufferSurface);
|
_vm->_scene->drawTextList(backBufferSurface);
|
||||||
|
|
||||||
|
|
|
@ -181,6 +181,7 @@ int SagaEngine::init(GameDetector &detector) {
|
||||||
_musicVolume = ConfMan.getInt("music_volume") / 25;
|
_musicVolume = ConfMan.getInt("music_volume") / 25;
|
||||||
_subtitlesEnabled = ConfMan.getBool("subtitles");
|
_subtitlesEnabled = ConfMan.getBool("subtitles");
|
||||||
_readingSpeed = ConfMan.getInt("talkspeed");
|
_readingSpeed = ConfMan.getInt("talkspeed");
|
||||||
|
_copyProtection = ConfMan.getBool("copy_protection");
|
||||||
|
|
||||||
if (_readingSpeed > 3)
|
if (_readingSpeed > 3)
|
||||||
_readingSpeed = 0;
|
_readingSpeed = 0;
|
||||||
|
|
46
saga/saga.h
46
saga/saga.h
|
@ -144,25 +144,28 @@ enum HitZoneFlags {
|
||||||
|
|
||||||
|
|
||||||
enum PanelButtonType {
|
enum PanelButtonType {
|
||||||
kPanelButtonVerb = 1,
|
kPanelButtonVerb = 1 << 0,
|
||||||
kPanelButtonArrow = 2,
|
kPanelButtonArrow = 1 << 1,
|
||||||
kPanelButtonConverseText = 4,
|
kPanelButtonConverseText = 1 << 2,
|
||||||
kPanelButtonInventory = 8,
|
kPanelButtonInventory = 1 << 3,
|
||||||
|
|
||||||
kPanelButtonOption = 0x10,
|
kPanelButtonOption = 1 << 4,
|
||||||
kPanelButtonOptionSlider = 0x20,
|
kPanelButtonOptionSlider = 1 << 5,
|
||||||
kPanelButtonOptionSaveFiles = 0x40,
|
kPanelButtonOptionSaveFiles = 1 << 6,
|
||||||
kPanelButtonOptionText = 0x80,
|
kPanelButtonOptionText = 1 << 7,
|
||||||
|
|
||||||
kPanelButtonQuit = 0x100,
|
kPanelButtonQuit = 1 << 8,
|
||||||
kPanelButtonQuitText = 0x200,
|
kPanelButtonQuitText = 1 << 9,
|
||||||
|
|
||||||
kPanelButtonLoad = 0x400,
|
kPanelButtonLoad = 1 << 10,
|
||||||
kPanelButtonLoadText = 0x800,
|
kPanelButtonLoadText = 1 << 11,
|
||||||
|
|
||||||
kPanelButtonSave = 0x1000,
|
kPanelButtonSave = 1 << 12,
|
||||||
kPanelButtonSaveText = 0x2000,
|
kPanelButtonSaveText = 1 << 13,
|
||||||
kPanelButtonSaveEdit = 0x4000,
|
kPanelButtonSaveEdit = 1 << 14,
|
||||||
|
|
||||||
|
kPanelButtonProtectText = 1 << 15,
|
||||||
|
kPanelButtonProtectEdit = 1 << 16,
|
||||||
|
|
||||||
kPanelAllButtons = 0xFFFFF
|
kPanelAllButtons = 0xFFFFF
|
||||||
};
|
};
|
||||||
|
@ -218,7 +221,8 @@ enum TextStringIds {
|
||||||
kTextNoPlaceToOpen,
|
kTextNoPlaceToOpen,
|
||||||
kTextNoOpening,
|
kTextNoOpening,
|
||||||
kTextDontKnow,
|
kTextDontKnow,
|
||||||
kTextShowDialog
|
kTextShowDialog,
|
||||||
|
kTextEnterProtectAnswer
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ImageHeader {
|
struct ImageHeader {
|
||||||
|
@ -467,6 +471,14 @@ struct GameDisplayInfo {
|
||||||
int savePanelHeight;
|
int savePanelHeight;
|
||||||
int savePanelButtonsCount;
|
int savePanelButtonsCount;
|
||||||
PanelButton *savePanelButtons;
|
PanelButton *savePanelButtons;
|
||||||
|
|
||||||
|
int protectEditIndex;
|
||||||
|
int protectPanelXOffset;
|
||||||
|
int protectPanelYOffset;
|
||||||
|
int protectPanelWidth;
|
||||||
|
int protectPanelHeight;
|
||||||
|
int protectPanelButtonsCount;
|
||||||
|
PanelButton *protectPanelButtons;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -587,6 +599,8 @@ public:
|
||||||
bool _subtitlesEnabled;
|
bool _subtitlesEnabled;
|
||||||
int _readingSpeed;
|
int _readingSpeed;
|
||||||
|
|
||||||
|
bool _copyProtection;
|
||||||
|
|
||||||
SndRes *_sndRes;
|
SndRes *_sndRes;
|
||||||
Sound *_sound;
|
Sound *_sound;
|
||||||
Music *_music;
|
Music *_music;
|
||||||
|
|
|
@ -1781,19 +1781,25 @@ void Script::sfGetDeltaFrame(SCRIPTFUNC_PARAMS) {
|
||||||
|
|
||||||
// Script function #73 (0x49)
|
// Script function #73 (0x49)
|
||||||
void Script::sfShowProtect(SCRIPTFUNC_PARAMS) {
|
void Script::sfShowProtect(SCRIPTFUNC_PARAMS) {
|
||||||
thread->wait(kWaitTypeRequest);
|
if (_vm->_copyProtection) {
|
||||||
|
thread->wait(kWaitTypeRequest);
|
||||||
|
|
||||||
//TODO:protection dialog
|
_vm->_interface->setMode(kPanelProtect);
|
||||||
thread->_flags &= ~kTFlagWaiting;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Script function #74 (0x4A)
|
// Script function #74 (0x4A)
|
||||||
void Script::sfProtectResult(SCRIPTFUNC_PARAMS) {
|
void Script::sfProtectResult(SCRIPTFUNC_PARAMS) {
|
||||||
int protectHash;
|
if (_vm->_copyProtection) {
|
||||||
//cheating
|
thread->_returnValue = _vm->_interface->getProtectHash();
|
||||||
protectHash = thread->pop();
|
} else {
|
||||||
thread->push(protectHash);
|
int protectHash;
|
||||||
thread->_returnValue = protectHash;
|
|
||||||
|
//cheating
|
||||||
|
protectHash = thread->pop();
|
||||||
|
thread->push(protectHash);
|
||||||
|
thread->_returnValue = protectHash;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Script function #75 (0x4b)
|
// Script function #75 (0x4b)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue