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
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:
Indiana Jones & the Last Crusade (EGA)
Indiana Jones & the Last Crusade (FM-TOWNS version)
Inherit the Earth (floppy version)
Loom (16 color floppy version)
Maniac Mansion
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
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:
\begin{tabular}{l}
Indiana Jones \& the Last Crusade (EGA)\\
Indiana Jones \& the Last Crusade (FM-TOWNS version)\\
Inherit the Earth (floppy version)\\
Loom (16 color floppy version)\\
Maniac Mansion\\
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) {
warning("text too long to be displayed in one line");
return;
textWidth = fitWidth;
}
// Entire string fits, draw it
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},
};
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[] = {
{kPanelButtonArrow, 0,0, 0,0, 0,'-',0, 0,0,0}, //TODO
@ -184,7 +189,13 @@ static GameDisplayInfo ITE_DisplayInfo = {
74, 44, // save panel offsets
172, 58, // save panel width & height
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 = {
@ -635,6 +646,13 @@ static GameDisplayInfo IHNM_DisplayInfo = { //TODO: fill it all
0, 0, // save panel offsets
0, 0, // save panel width & height
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
};

View file

@ -172,6 +172,15 @@ Interface::Interface(SagaEngine *vm) : _vm(vm) {
_saveEdit = _savePanel.getButton(_vm->getDisplayInfo().saveEditIndex);
_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;
_panelMode = _lockedMode = kPanelNull;
_savedMode = -1;
@ -315,6 +324,15 @@ void Interface::setMode(int mode) {
case kPanelBoss:
_vm->_render->setFlag(RF_DEMO_SUBST);
break;
case kPanelProtect:
_protectPanel.currentButton = NULL;
_textInputMaxWidth = _protectEdit->width - 10;
_textInput = true;
_textInputString[0] = 0;
_textInputStringLength = 0;
_textInputPos = _textInputStringLength + 1;
_textInputRepeatPhase = 0;
break;
}
draw();
@ -493,6 +511,21 @@ bool Interface::processAscii(uint16 ascii, bool synthetic) {
_vm->_render->clearFlag(RF_DEMO_SUBST);
keyBossExit();
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;
}
@ -1055,6 +1088,26 @@ void Interface::drawSave() {
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) {
bool releasedButton;
@ -1460,6 +1513,11 @@ void Interface::update(const Point& mousePoint, int updateFlag) {
handleChapterSelectionClick(mousePoint);
}
break;
case kPanelProtect:
// No mouse interaction
break;
}
_lastMousePoint = mousePoint;

View file

@ -237,6 +237,7 @@ public:
void drawQuit();
void drawLoad();
void drawSave();
void drawProtect();
void update(const Point& mousePoint, int updateFlag);
void drawStatusBar();
void setVerbState(int verb, int state);
@ -297,6 +298,8 @@ public:
void mapPanelDrawCrossHair();
int32 getProtectHash() { return _protectHash; }
private:
void handleMainUpdate(const Point& mousePoint); // main panel update
void handleMainClick(const Point& mousePoint); // main panel click
@ -418,6 +421,8 @@ private:
InterfacePanel _loadPanel;
InterfacePanel _savePanel;
PanelButton * _saveEdit;
InterfacePanel _protectPanel;
PanelButton * _protectEdit;
bool _disableAbortSpeeches;
@ -472,6 +477,8 @@ private:
PalEntry _mapSavedPal[PAL_ENTRIES];
bool _mapPanelCrossHairState;
int32 _protectHash;
};
} // End of namespace Saga

View file

@ -334,7 +334,7 @@ FxTable ITE_SfxTable[ITE_SFXCOUNT] = {
{ FX_CROWD_17, 64 }
};
const char *ITEinterfaceTextStrings[][51] = {
const char *ITEinterfaceTextStrings[][52] = {
{
"Walk to", "Look At", "Pick Up", "Talk to", "Open",
"Close", "Use", "Give", "Options", "Test",
@ -351,7 +351,8 @@ const char *ITEinterfaceTextStrings[][51] = {
"There's no place to open it.",
"There's no opening to close.",
"I don't know how to do that.",
"Show Dialog"
"Show Dialog",
"What is Rif's reply?"
},
// German
{
@ -370,7 +371,8 @@ const char *ITEinterfaceTextStrings[][51] = {
"Das kann man nicht \224ffnen.",
"Hier ist keine \231ffnung zum Schlie$en.",
"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 FxTable ITE_SfxTable[ITE_SFXCOUNT];
extern const char *ITEinterfaceTextStrings[][51];
extern const char *ITEinterfaceTextStrings[][52];
} // 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
_vm->_scene->drawTextList(backBufferSurface);

View file

@ -181,6 +181,7 @@ int SagaEngine::init(GameDetector &detector) {
_musicVolume = ConfMan.getInt("music_volume") / 25;
_subtitlesEnabled = ConfMan.getBool("subtitles");
_readingSpeed = ConfMan.getInt("talkspeed");
_copyProtection = ConfMan.getBool("copy_protection");
if (_readingSpeed > 3)
_readingSpeed = 0;

View file

@ -144,25 +144,28 @@ enum HitZoneFlags {
enum PanelButtonType {
kPanelButtonVerb = 1,
kPanelButtonArrow = 2,
kPanelButtonConverseText = 4,
kPanelButtonInventory = 8,
kPanelButtonVerb = 1 << 0,
kPanelButtonArrow = 1 << 1,
kPanelButtonConverseText = 1 << 2,
kPanelButtonInventory = 1 << 3,
kPanelButtonOption = 0x10,
kPanelButtonOptionSlider = 0x20,
kPanelButtonOptionSaveFiles = 0x40,
kPanelButtonOptionText = 0x80,
kPanelButtonOption = 1 << 4,
kPanelButtonOptionSlider = 1 << 5,
kPanelButtonOptionSaveFiles = 1 << 6,
kPanelButtonOptionText = 1 << 7,
kPanelButtonQuit = 0x100,
kPanelButtonQuitText = 0x200,
kPanelButtonQuit = 1 << 8,
kPanelButtonQuitText = 1 << 9,
kPanelButtonLoad = 0x400,
kPanelButtonLoadText = 0x800,
kPanelButtonLoad = 1 << 10,
kPanelButtonLoadText = 1 << 11,
kPanelButtonSave = 0x1000,
kPanelButtonSaveText = 0x2000,
kPanelButtonSaveEdit = 0x4000,
kPanelButtonSave = 1 << 12,
kPanelButtonSaveText = 1 << 13,
kPanelButtonSaveEdit = 1 << 14,
kPanelButtonProtectText = 1 << 15,
kPanelButtonProtectEdit = 1 << 16,
kPanelAllButtons = 0xFFFFF
};
@ -218,7 +221,8 @@ enum TextStringIds {
kTextNoPlaceToOpen,
kTextNoOpening,
kTextDontKnow,
kTextShowDialog
kTextShowDialog,
kTextEnterProtectAnswer
};
struct ImageHeader {
@ -467,6 +471,14 @@ struct GameDisplayInfo {
int savePanelHeight;
int savePanelButtonsCount;
PanelButton *savePanelButtons;
int protectEditIndex;
int protectPanelXOffset;
int protectPanelYOffset;
int protectPanelWidth;
int protectPanelHeight;
int protectPanelButtonsCount;
PanelButton *protectPanelButtons;
};
@ -587,6 +599,8 @@ public:
bool _subtitlesEnabled;
int _readingSpeed;
bool _copyProtection;
SndRes *_sndRes;
Sound *_sound;
Music *_music;

View file

@ -1781,19 +1781,25 @@ void Script::sfGetDeltaFrame(SCRIPTFUNC_PARAMS) {
// Script function #73 (0x49)
void Script::sfShowProtect(SCRIPTFUNC_PARAMS) {
if (_vm->_copyProtection) {
thread->wait(kWaitTypeRequest);
//TODO:protection dialog
thread->_flags &= ~kTFlagWaiting;
_vm->_interface->setMode(kPanelProtect);
}
}
// Script function #74 (0x4A)
void Script::sfProtectResult(SCRIPTFUNC_PARAMS) {
if (_vm->_copyProtection) {
thread->_returnValue = _vm->_interface->getProtectHash();
} else {
int protectHash;
//cheating
protectHash = thread->pop();
thread->push(protectHash);
thread->_returnValue = protectHash;
}
}
// Script function #75 (0x4b)