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:
Eugene Sandulenko 2005-10-17 03:28:21 +00:00
parent 3dd9f208cc
commit ee4cbcb98d
12 changed files with 148 additions and 30 deletions

4
README
View file

@ -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)

View file

@ -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)\\

View file

@ -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);

View file

@ -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
}; };

View file

@ -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;

View file

@ -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

View file

@ -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?"
} }
}; };

View file

@ -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

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -1781,20 +1781,26 @@ void Script::sfGetDeltaFrame(SCRIPTFUNC_PARAMS) {
// Script function #73 (0x49) // Script function #73 (0x49)
void Script::sfShowProtect(SCRIPTFUNC_PARAMS) { void Script::sfShowProtect(SCRIPTFUNC_PARAMS) {
if (_vm->_copyProtection) {
thread->wait(kWaitTypeRequest); 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) {
if (_vm->_copyProtection) {
thread->_returnValue = _vm->_interface->getProtectHash();
} else {
int protectHash; int protectHash;
//cheating //cheating
protectHash = thread->pop(); protectHash = thread->pop();
thread->push(protectHash); thread->push(protectHash);
thread->_returnValue = protectHash; thread->_returnValue = protectHash;
} }
}
// Script function #75 (0x4b) // Script function #75 (0x4b)
void Script::sfRand(SCRIPTFUNC_PARAMS) { void Script::sfRand(SCRIPTFUNC_PARAMS) {