Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

View File

@@ -0,0 +1,53 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/endian.h"
#include "glk/scott/types.h"
#include "glk/scott/unp64/unp64.h"
#include "glk/scott/unp64/exo_util.h"
namespace Glk {
namespace Scott {
void scnActionPacker(UnpStr *unp) {
byte *mem;
if (unp->_idFlag)
return;
mem = unp->_mem;
if (unp->_depAdr == 0) {
if (u32eq(mem + 0x811, 0x018538A9) &&
u32eq(mem + 0x81d, 0xCEF7D0E8) &&
u32eq(mem + 0x82d, 0x0F9D0837) &&
u32eq(mem + 0x84b, 0x03D00120)) {
unp->_depAdr = 0x110;
unp->_forced = 0x811;
unp->_strMem = READ_LE_UINT16(&mem[0x848]);
unp->_fEndAf = 0x120;
unp->_retAdr = READ_LE_UINT16(&mem[0x863]);
unp->_idFlag = 1;
return;
}
}
}
} // End of namespace Scott
} // End of namespace Glk

View File

@@ -0,0 +1,94 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/endian.h"
#include "glk/scott/types.h"
#include "glk/scott/unp64/unp64.h"
#include "glk/scott/unp64/exo_util.h"
namespace Glk {
namespace Scott {
void scnByteBoiler(UnpStr *unp) {
byte *mem;
int q, p;
if (unp->_idFlag)
return;
mem = unp->_mem;
if (unp->_depAdr == 0) {
if (u32eq(mem + 0x813, 0xE800F09D) &&
u32eq(mem + 0x818, 0x014E4CF7)) {
p = READ_LE_UINT16(&mem[0x811]);
if (u32eq(mem + p + 1, 0x02D0FAA5)) {
unp->_depAdr = 0x14e;
unp->_forced = 0x80b;
unp->_retAdr = READ_LE_UINT16(&mem[p + 0x5c]);
unp->_endAdr = READ_LE_UINT16(&mem[p + 0x0e]);
unp->_endAdr++;
unp->_fStrAf = 0xfe;
unp->_idFlag = 1;
return;
}
}
}
/* CPX hack */
if (unp->_depAdr == 0) {
if (u32eq(mem + 0x80b, 0xA97800A2) &&
u32eq(mem + 0x815, 0x4C01E6D0)) {
q = READ_LE_UINT16(&mem[0x819]);
if (u32eq(mem + q + 3, 0xE800F09D) &&
u32eq(mem + q + 8, 0x014E4CF7)) {
p = READ_LE_UINT16(&mem[q + 1]);
if (u32eq(mem + p + 1, 0x02D0FAA5)) {
unp->_depAdr = 0x14e;
unp->_forced = 0x80b;
unp->_retAdr = READ_LE_UINT16(&mem[p + 0x5c]);
unp->_endAdr = READ_LE_UINT16(&mem[p + 0x0e]);
unp->_endAdr++;
unp->_fStrAf = 0xfe;
unp->_idFlag = 1;
return;
}
}
}
}
/* SCS hack */
if (unp->_depAdr == 0) {
if (u32eq(mem + 0x813, 0xE800F09D) &&
u32eq(mem + 0x818, 0x01bf4CF7)) {
p = READ_LE_UINT16(&mem[0x811]);
if (u32eq(mem + p + 1, 0x02D0FAA5) &&
u32eq(mem + p + 0xdd, 0x014e4c01)) {
unp->_depAdr = 0x14e;
unp->_forced = 0x80b;
unp->_retAdr = READ_LE_UINT16(&mem[p + 0x5c]);
unp->_endAdr = READ_LE_UINT16(&mem[p + 0x0e]);
unp->_endAdr++;
unp->_fStrAf = 0xfe;
unp->_idFlag = 1;
return;
}
}
}
}
} // End of namespace Scott
} // End of namespace Glk

View File

@@ -0,0 +1,135 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/endian.h"
#include "glk/scott/types.h"
#include "glk/scott/unp64/unp64.h"
#include "glk/scott/unp64/exo_util.h"
namespace Glk {
namespace Scott {
void scnCaution(UnpStr *unp) {
byte *mem;
if (unp->_idFlag)
return;
mem = unp->_mem;
/* quickpacker 1.0 sysless */
if (unp->_depAdr == 0) {
if (u32eq(mem + 0x801, 0xE67800A2) &&
u32eq(mem + 0x805, 0x07EDBD01) &&
u32eq(mem + 0x80d, 0x00284CF8) &&
u32eq(mem + 0x844, 0xAC00334C)) {
unp->_forced = 0x801;
unp->_depAdr = 0x28;
unp->_retAdr = READ_LE_UINT16(&mem[0x86b]);
unp->_endAdr = READ_LE_UINT16(&mem[0x85a]);
unp->_fStrAf = mem[0x863];
unp->_strAdC = EA_ADDFF | 0xffff;
unp->_idFlag = 1;
return;
}
}
/* quickpacker 2.x + sys */
if (unp->_depAdr == 0) {
if (u32eqmasked(mem + 0x80b, 0xf0ffffff, 0x60A200A0) &&
u32eq(mem + 0x80f, 0x0801BD78) &&
u32eq(mem + 0x813, 0xD0CA0095) &&
u32eq(mem + 0x81e, 0xD0C80291) &&
u32eq(mem + 0x817, 0x001A4CF8)) {
unp->_forced = 0x80b;
unp->_depAdr = 0x01a;
if (mem[0x80e] == 0x69) {
unp->_retAdr = READ_LE_UINT16(&mem[0x842]);
unp->_endAdr = READ_LE_UINT16(&mem[0x850]);
unp->_endAdr += 0x100;
unp->_fStrAf = 0x4f;
unp->_strAdC = 0xffff | EA_USE_Y;
unp->_idFlag = 1;
return;
} else if (mem[0x80e] == 0x6c) {
unp->_retAdr = READ_LE_UINT16(&mem[0x844]);
unp->_endAdr = READ_LE_UINT16(&mem[0x84e]);
unp->_endAdr++;
unp->_fStrAf = 0x4d;
unp->_idFlag = 1;
return;
}
}
}
/* strangely enough, sysless v2.0 depacker is at $0002 */
if (unp->_depAdr == 0) {
if (u32eq(mem + 0x83d, 0xAA004A20) &&
u32eq(mem + 0x801, 0xA27800A0) &&
u32eq(mem + 0x805, 0x080FBD55) &&
u32eq(mem + 0x809, 0xD0CA0095) &&
u32eq(mem + 0x80d, 0x00024CF8)) {
unp->_forced = 0x801;
unp->_depAdr = 0x2;
unp->_retAdr = READ_LE_UINT16(&mem[0x83b]);
unp->_endAdr = READ_LE_UINT16(&mem[0x845]);
unp->_endAdr++;
unp->_fStrAf = mem[0x849];
// unp->_StrAdC=0xffff;
unp->_idFlag = 1;
return;
}
}
/* same goes for v2.5 sysless, seems almost another packer */
if (unp->_depAdr == 0) {
if (u32eq(mem + 0x83b, 0xAA005520) &&
u32eq(mem + 0x801, 0x60A200A0) &&
u32eq(mem + 0x805, 0x0801BD78) &&
u32eq(mem + 0x809, 0xD0CA0095) &&
u32eq(mem + 0x80d, 0x00104CF8)) {
unp->_forced = 0x801;
unp->_depAdr = 0x10;
unp->_retAdr = READ_LE_UINT16(&mem[0x839]);
unp->_endAdr = READ_LE_UINT16(&mem[0x847]);
unp->_endAdr += 0x100;
unp->_fStrAf = 0x46;
unp->_strAdC = 0xffff | EA_USE_Y;
unp->_idFlag = 1;
return;
}
}
/* hardpacker */
if (unp->_depAdr == 0) {
if (u32eq(mem + 0x80d, 0x8534A978) &&
u32eq(mem + 0x811, 0xB9B3A001) &&
u32eq(mem + 0x815, 0x4C99081F) &&
u32eq(mem + 0x819, 0xF7D08803) &&
u32eq(mem + 0x81d, 0xB9034D4C)) {
unp->_forced = 0x80d;
unp->_depAdr = 0x34d;
unp->_retAdr = READ_LE_UINT16(&mem[0x87f]);
unp->_endAdr = READ_LE_UINT16(&mem[0x88d]);
unp->_fStrAf = 0x3ba;
unp->_strAdC = EA_ADDFF | 0xffff;
unp->_idFlag = 1;
return;
}
}
}
} // End of namespace Scott
} // End of namespace Glk

View File

@@ -0,0 +1,208 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/endian.h"
#include "glk/scott/types.h"
#include "glk/scott/unp64/unp64.h"
#include "glk/scott/unp64/exo_util.h"
namespace Glk {
namespace Scott {
void scnCCS(UnpStr *unp) {
byte *mem;
int p;
if (unp->_idFlag)
return;
mem = unp->_mem;
if (unp->_depAdr == 0) {
if (u32eq(mem + 0x817, 0xB901E678) &&
u32eq(mem + 0x81b, 0xFD990831) &&
u32eq(mem + 0x8ff, 0xFEE60290) &&
u32eq(mem + 0x90f, 0x02903985)) {
if (unp->_info->_run == -1)
unp->_forced = 0x817;
unp->_depAdr = 0x0ff;
unp->_fEndAf = 0x2d;
unp->_endAdC = 0xffff;
unp->_retAdr = READ_LE_UINT16(&mem[0x8ed]);
if (unp->_retAdr == 0xa659) {
mem[0x8ec] = 0x2c;
unp->_retAdr = READ_LE_UINT16(&mem[0x8f0]);
}
unp->_idFlag = 1;
return;
}
}
/* derived from supercomp/eqseq */
if (unp->_depAdr == 0) {
if (u32eq(mem + 0x80b, 0x8C7800A0) &&
u32eq(mem + 0x812, 0x0099082F) &&
u32eq(mem + 0x846, 0x0DADF2D0) &&
u32eq(mem + 0x8c0, 0xF001124C)) {
if (unp->_info->_run == -1)
unp->_forced = 0x80b;
unp->_depAdr = 0x100;
unp->_endAdr = 0xae;
unp->_retAdr = READ_LE_UINT16(&mem[0x8f1]);
if (unp->_retAdr == 0xa659) {
mem[0x8f0] = 0x2c;
unp->_retAdr = READ_LE_UINT16(&mem[0x8f4]);
}
unp->_idFlag = 1;
return;
}
}
if (unp->_depAdr == 0) {
if (u32eq(mem + 0x814, 0xB901E678) &&
u32eq(mem + 0x818, 0xFD990829) &&
u32eq(mem + 0x8a1, 0xFDA6FDB1) &&
u32eq(mem + 0x8a5, 0xFEC602D0)) {
if (unp->_info->_run == -1)
unp->_forced = 0x814;
unp->_depAdr = 0x0ff;
unp->_fEndBf = 0x39;
unp->_idFlag = 1;
return;
}
}
if (unp->_depAdr == 0) {
if (u32eq(mem + 0x818, 0x2CB901E6) &&
u32eq(mem + 0x81c, 0x00FB9908) &&
u32eq(mem + 0x850, 0xFBB1C84A) &&
u32eq(mem + 0x854, 0xB1C81185)) {
if (unp->_info->_run == -1)
unp->_forced = 0x812;
unp->_depAdr = 0x0ff;
unp->_endAdr = 0xae;
unp->_idFlag = 1;
return;
}
}
if (unp->_depAdr == 0) {
if (u32eq(mem + 0x818, 0x2CB901E6) &&
u32eq(mem + 0x81c, 0x00FB9908) &&
u32eq(mem + 0x851, 0xFBB1C812) &&
u32eq(mem + 0x855, 0xB1C81185)) {
if (unp->_info->_run == -1)
unp->_forced = 0x812;
unp->_depAdr = 0x0ff;
unp->_endAdr = 0xae;
unp->_idFlag = 1;
return;
}
}
if (unp->_depAdr == 0) {
if (u32eq(mem + 0x82c, 0x018538A9) &&
u32eq(mem + 0x831, 0xFD990842) &&
u32eq(mem + 0x83e, 0x00FF4CF1) &&
u32eq(mem + 0x8a5, 0x50C651C6)) {
if (unp->_info->_run == -1)
unp->_forced = 0x822;
unp->_depAdr = 0x0ff;
unp->_fEndBf = 0x39;
unp->_retAdr = READ_LE_UINT16(&mem[0x8ea]);
unp->_idFlag = 1;
return;
}
}
if (unp->_depAdr == 0) {
if (u16eq(mem + 0x81a, 0x00A0) &&
(u32eq(mem + 0x820, 0xFB990837) ||
u32eq(mem + 0x824, 0xFB990837)) &&
u32eq(mem + 0x83b, 0xFD91FBB1) &&
u32eq(mem + 0x8bc, 0xEE00FC99)) {
if (unp->_info->_run == -1)
unp->_forced = 0x81a;
unp->_depAdr = 0x0ff;
unp->_fEndAf = 0x39;
unp->_endAdC = 0xffff;
unp->_retAdr = READ_LE_UINT16(&mem[0x8b3]);
unp->_idFlag = 1;
return;
}
}
if (unp->_depAdr == 0) {
if (u32eq(mem + 0x812, 0xE67800A0) &&
u32eq(mem + 0x816, 0x0823B901) &&
u32eq(mem + 0x81a, 0xC800FD99) &&
u32eq(mem + 0x81e, 0xFF4CF7D0) &&
u32eq(mem + 0x885, 0xFDA6FDB1)) {
if (unp->_info->_run == -1)
unp->_forced = 0x812;
unp->_depAdr = 0x0ff;
// $2d is unreliable, Executer uses line number at $0803/4,
// which is read at $0039/3a by basic, as end address,
// then can set arbitrarily $2d/$ae pointers after unpack.
// unp->_fEndAf=0x2d;
unp->_endAdr = READ_LE_UINT16(&mem[0x803]);
unp->_endAdr++;
if (u32eq(mem + 0x87f, 0x4CA65920))
mem[0x87f] = 0x2c;
unp->_retAdr = READ_LE_UINT16(&mem[0x883]);
unp->_idFlag = 1;
return;
}
}
if (unp->_depAdr == 0) {
if (u32eq(mem + 0x812, 0xE67800A0) &&
u32eq(mem + 0x816, 0x084CB901) &&
u32eq(mem + 0x81a, 0xA900FB99) &&
u32eq(mem + 0x848, 0x00FF4CE2)) {
if (unp->_info->_run == -1)
unp->_forced = 0x812;
unp->_depAdr = 0x0ff;
unp->_fEndAf = 0x2d;
unp->_endAdC = 0xffff;
unp->_idFlag = 1;
return;
}
}
/* Triad Hack */
if (unp->_depAdr == 0) {
if (u32eq(mem + 0x838, 0xB9080099) &&
u32eq(mem + 0x83f, 0xD0880816) &&
u32eq(mem + 0x8ff, 0xFEE60290) &&
u32eq(mem + 0x90f, 0x02903985)) {
if (unp->_info->_run == -1) {
for (p = 0x80b; p < 0x820; p++) {
if ((mem[p] & 0xa0) == 0xa0) {
unp->_forced = p;
break;
}
}
}
unp->_depAdr = 0x0ff;
unp->_fEndAf = 0x2d;
unp->_endAdC = 0xffff;
unp->_retAdr = READ_LE_UINT16(&mem[0x8ed]);
if (unp->_retAdr == 0xa659) {
mem[0x8ec] = 0x2c;
unp->_retAdr = READ_LE_UINT16(&mem[0x8f0]);
}
unp->_idFlag = 1;
return;
}
}
}
} // End of namespace Scott
} // End of namespace Glk

View File

@@ -0,0 +1,374 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/endian.h"
#include "glk/scott/types.h"
#include "glk/scott/unp64/unp64.h"
#include "glk/scott/unp64/exo_util.h"
namespace Glk {
namespace Scott {
void scnCruel(UnpStr *unp) {
byte *mem;
int q, p, strtmp = 0;
if (unp->_idFlag)
return;
mem = unp->_mem;
if (unp->_depAdr == 0) {
if (mem[0x810] == 0xb9 &&
((*(unsigned int *)(mem + 0x813) & 0xfffffeff) == 0xC800FA99) &&
u16eq(mem + 0x818, 0x4CF7)) {
if (mem[0x814] == 0xFA) {
p = READ_LE_UINT16(&mem[0x811]); // mem[0x811] | mem[0x812] << 8;
if (u32eq(mem + p + 9, 0xC8071C99)) {
unp->_endAdr = READ_LE_UINT16(&mem[p + 2]); // mem[p + 2] | mem[p + 3] << 8;
unp->_depAdr = 0x100;
if (unp->_info->_run == -1)
unp->_forced = 0x80b;
unp->_fStrAf = 0xfc;
q = READ_LE_UINT16(&mem[p + 7]); // mem[p + 7] | mem[p + 8] << 8;
if ((mem[q + 0x8e] == 0xc6) && (mem[q + 0x8f] == 0x01) &&
(mem[q + 0x93] == 0xe6) && (mem[q + 0x94] == 0x01)) {
mem[q + 0x90] = 0x2c;
}
/* retadr is not always at the same addr, but at least can't
be anything < $07e8
*/
// unp->_retAdr=0x7e8;
q = READ_LE_UINT16(&mem[p + 7]); // mem[p + 7] | mem[p + 8] << 8;
if (mem[q + 0x3c] == 0x4c) {
/* v2.2/dynamix, v2.5/cross, v2.5/crest */
strtmp = *(unsigned short int *)(mem + q + 0x3d);
} else if (mem[q + 0x4a] == 0x4c) {
strtmp = *(unsigned short int *)(mem + q + 0x4b);
} else if (mem[q + 0x3f] == 0x4c) {
/* v2.2/oneway+scs, also hacked as cruel 2mhz 1.0 */
strtmp = *(unsigned short int *)(mem + q + 0x40);
} else {
/* todo: determine real retadr, for now a default seems ok */
strtmp = 0;
}
if (strtmp) {
if (strtmp >= unp->_retAdr) {
unp->_retAdr = strtmp;
} else { /* now search it... variable code here */
strtmp += p - *(unsigned short int *)(mem + 0x814);
for (q = strtmp; q < unp->_info->_end; q++) {
if ((mem[q] == 0xa9) || (mem[q] == 0x85)) {
q++;
continue;
}
if (mem[q] == 0x8d) {
q += 2;
continue;
}
if (mem[q] == 0x4c) {
unp->_retAdr = *(unsigned short int *)(mem + q + 1);
;
break;
}
}
}
}
}
} else if (mem[0x814] == 0xFB) {
/* not Cruel2 but MSCRUNCH by Marco/Taboo
v1.0 works only with some old AR cart (unless patched ;)
v1.5 is infact more common
*/
p = READ_LE_UINT16(&mem[0x811]); // mem[0x811] | mem[0x812] << 8;
if (u32eq(mem + p + 7, 0xC8071C99)) {
unp->_endAdr = READ_LE_UINT16(&mem[p + 3]); // mem[p + 3] | mem[p + 4] << 8;
unp->_depAdr = 0x100;
unp->_forced = 0x80b;
unp->_fStrAf = 0xfe;
if ((mem[p + 0x93] == 0x4c) && (mem[p + 0xa1] == 0x4c)) {
unp->_retAdr = READ_LE_UINT16(&mem[p + 0xa2]); // mem[p + 0xa2] | mem[p + 0xa3] << 8;
} else if ((mem[p + 0x8c] == 0x4c) && (mem[p + 0x94] == 0x4c)) {
unp->_retAdr = READ_LE_UINT16(&mem[p + 0x95]); // mem[p + 0x95] | mem[p + 0x96] << 8;
} else if ((mem[p + 0x20] == 0x4c) && (mem[p + 0x28] == 0x4c)) {
unp->_retAdr = READ_LE_UINT16(&mem[p + 0x29]); // mem[p + 0x29] | mem[p + 0x2a] << 8;
}
}
}
}
if (unp->_depAdr) {
unp->_idFlag = 1;
return;
}
}
/* MSCRUNCH 1.5 hack by Anubis */
if (unp->_depAdr == 0) {
if (mem[0x819] == 0x4c) {
p = READ_LE_UINT16(&mem[0x81a]); //mem[0x81a] | mem[0x81b] << 8;
if ((mem[p] == 0xa9) && (mem[p + 0x0f] == 0x30) &&
u32eq(mem + p + 0x13, 0xCA04009D) &&
u32eq(mem + p + 0x38, 0x01084C01)) {
q = READ_LE_UINT16(&mem[p + 0x1f]); // mem[p + 0x1f] | mem[p + 0x20] << 8;
if (u32eq(mem + q + 7, 0xC8071C99)) {
unp->_endAdr = READ_LE_UINT16(&mem[q + 3]); // mem[q + 3] | mem[q + 4] << 8;
unp->_depAdr = 0x100;
if (unp->_info->_run == -1)
unp->_forced = 0x819;
unp->_fStrAf = 0xfe;
unp->_retAdr = READ_LE_UINT16(&mem[q + 0xa2]); // mem[q + 0xa2] | mem[q + 0xa3] << 8;
}
}
}
}
/* fast cruel 4.x */
if (unp->_depAdr == 0) {
if (u32eq(mem + 0x80b, 0xE67800A0) &&
u32eq(mem + 0x813, 0xC8034099) &&
(u32eq(mem + 0x818, 0x03404cF7) ||
u32eq(mem + 0x818, 0x03b34cF7) ||
u32eq(mem + 0x818, 0x03db4cF7))) {
p = READ_LE_UINT16(&mem[0x811]); // mem[0x811] | mem[0x812] << 8;
if (u32eq(mem + p, 0xa75801c6)) {
p += 0x45;
q = READ_LE_UINT16(&mem[p]); // mem[p] | mem[p + 1] << 8;
unp->_endAdr = READ_LE_UINT16(&mem[q + 2]); // mem[q + 2] | mem[q + 3] << 8;
unp->_depAdr = 0x340;
unp->_forced = 0x80b;
unp->_fStrAf = 0xfc;
unp->_idFlag = 1;
return;
}
}
}
/* Cruel 2.0 / (BB) packer header */
if (unp->_depAdr == 0) {
if (u32eq(mem + 0x837, 0x9D0845BD) &&
u32eq(mem + 0x84f, 0xE808039D) &&
u32eq(mem + 0x83b, 0xC9E803B7)) {
unp->_depAdr = READ_LE_UINT16(&mem[0x843]); // mem[0x843] | mem[0x844] << 8;
if (unp->_info->_run == -1)
unp->_forced = 0x80d;
unp->_retAdr = READ_LE_UINT16(&mem[0x868]); // mem[0x868] | mem[0x869] << 8;
unp->_endAdr = unp->_info->_end - 0x90;
unp->_strMem = 0x801;
unp->_idFlag = 1;
return;
}
if (u32eq(mem + 0x845, 0x03E04CF2) &&
u32eq(mem + 0x852, 0x9D0893BD) &&
u32eq(mem + 0x856, 0xD0E80803)) {
unp->_depAdr = READ_LE_UINT16(&mem[0x847]); // mem[0x847] | mem[0x848] << 8;
if (unp->_info->_run == -1)
unp->_forced = 0x80d;
unp->_retAdr = READ_LE_UINT16(&mem[0x869]); // mem[0x869] | mem[0x86a] << 8;
unp->_endAdr = unp->_info->_end - 0x90;
unp->_strMem = 0x801;
unp->_idFlag = 1;
return;
}
if (u32eq(mem + 0x841, 0x03B74CF5) &&
u32eq(mem + 0x84c, 0x9D089BBD) &&
u32eq(mem + 0x850, 0xD0E8080B)) {
unp->_depAdr = READ_LE_UINT16(&mem[0x843]); // mem[0x843] | mem[0x844] << 8;
if (unp->_info->_run == -1) {
unp->_forced = 0x811;
} else {
mem[0x808] = '5'; /* just to be safe, change sys for next layer */
mem[0x809] = '9'; /* this hdr leaves it as sys2065 */
}
unp->_retAdr = READ_LE_UINT16(&mem[0x868]); // mem[0x868] | mem[0x869] << 8; /* fixed $080b */
unp->_endAdr = unp->_info->_end - 0x90;
unp->_strMem = 0x801;
unp->_idFlag = 1;
return;
}
/* this is a totally useless header, cheers TCOM! */
if (u32eq(mem + 0x80b, 0x1BB900A0) &&
u32eq(mem + 0x80f, 0x03B79908) &&
u32eq(mem + 0x823, 0x039D0840)) {
unp->_depAdr = READ_LE_UINT16(&mem[0x819]); // mem[0x819] | mem[0x81a] << 8;
if (unp->_info->_run == -1)
unp->_forced = 0x80b;
unp->_retAdr = READ_LE_UINT16(&mem[0x83e]); // mem[0x83e] | mem[0x83f] << 8;
unp->_endAdr = unp->_info->_end - 0x3d;
unp->_strMem = 0x801;
unp->_idFlag = 1;
return;
}
}
/* Cruel 2.0 / (BB) packer sysless */
if (unp->_depAdr == 0) {
if (u32eqmasked(mem + 0x80b, 0x0000ffff, 0x000000A0) &&
u32eq(mem + 0x817, 0xC800CB99) &&
u32eq(mem + 0x81b, 0x004CF7D0) && mem[0x81f] == 1) {
p = READ_LE_UINT16(&mem[0x815]); // mem[0x815] | mem[0x816] << 8;
p += 0x31;
if ((mem[p + 4] == 0xb9) &&
u32eq(mem + p + 7, 0xC8072099)) {
unp->_forced = 0x80b;
unp->_depAdr = 0x100;
unp->_endAdr = READ_LE_UINT16(&mem[p]); // mem[p] | mem[p + 1] << 8;
unp->_fStrAf = 0xfc;
/* patch: some version contain a zp cleaner sub at $01a2 */
if (u32eq(mem + p + 0xa6, 0x00A9CBA2) &&
u32eq(mem + p + 0xaa, 0xD0E80095)) {
mem[p + 0xa6] = 0x60;
}
/* patch: some version expects $01==#$34 already set from the header */
if (u32eq(mem + 0x811, 0xb9eaeaea)) {
mem[0x811] = 0xe6;
mem[0x812] = 0x01;
}
q = READ_LE_UINT16(&mem[p + 5]); // mem[p + 5] | mem[p + 6] << 8;
unp->_retAdr = 0x7e8;
if (mem[q + 0x6c] == 0x4c)
unp->_retAdr = READ_LE_UINT16(&mem[q + 0x6d]); // mem[q + 0x6d] | mem[q + 0x6e] << 8;
unp->_idFlag = 1;
return;
}
}
}
/* Cruel 2.1 / STA */
if (unp->_depAdr == 0) {
if (mem[0x80b] == 0xa0 && u32eq(mem + 0x817, 0xC800CB99) &&
u32eq(mem + 0x81b, 0x004CF7D0) && mem[0x81f] == 1) {
p = READ_LE_UINT16(&mem[0x815]); // mem[0x815] | mem[0x816] << 8;
p += 0x31;
if (mem[p + 6] == 0xb9 &&
u32eq(mem + p + 9, 0xC8072099)) {
unp->_forced = 0x80b;
unp->_depAdr = 0x100;
unp->_endAdr = READ_LE_UINT16(&mem[p]); // mem[p] | mem[p + 1] << 8;
unp->_fStrAf = 0xfc;
q = READ_LE_UINT16(&mem[p + 7]); // mem[p + 7] | mem[p + 8] << 8;
unp->_retAdr = 0x7e8;
if (mem[q + 0x6c] == 0x4c)
unp->_retAdr = READ_LE_UINT16(&mem[q + 0x6d]); // mem[q + 0x6d] | mem[q + 0x6e] << 8;
unp->_idFlag = 1;
return;
}
}
}
/* unknown cruel, jmp $00e9, found in Illusion/Random warez */
if (unp->_depAdr == 0) {
if (mem[0x810] == 0xb9 && u32eq(mem + 0x813, 0xC800e999) &&
u32eq(mem + 0x818, 0x00e94CF7)) {
p = READ_LE_UINT16(&mem[0x811]); // mem[0x811] | mem[0x812] << 8;
q = p - 0xed;
if (u32eq(mem + p, 0x13F01284) &&
u32eq(mem + q, 0xA9C8C8C8)) {
unp->_depAdr = 0xe9;
unp->_endAdr = READ_LE_UINT16(&mem[p + 0x13]); // mem[p + 0x13] | mem[p + 0x14] << 8;
unp->_retAdr = READ_LE_UINT16(&mem[q + 0x38]); // mem[q + 0x38] | mem[q + 0x39] << 8;
if (unp->_info->_run == -1)
unp->_forced = 0x80b;
unp->_fStrAf = 0xfc;
unp->_idFlag = 1;
return;
}
}
}
if (unp->_depAdr == 0) {
if (mem[0x810] == 0xb9 && u32eq(mem + 0x813, 0xC800ed99) &&
u32eq(mem + 0x818, 0x01004CF7)) {
p = READ_LE_UINT16(&mem[0x811]); // mem[0x811] | mem[0x812] << 8;
q = p - 0xed;
if (u32eq(mem + p, 0x01C60888) &&
u32eq(mem + q, 0xA9C8C8C8)) {
unp->_depAdr = 0x100;
unp->_endAdr = READ_LE_UINT16(&mem[p + 0x0f]); // mem[p + 0x0f] | mem[p + 0x10] << 8;
unp->_retAdr = READ_LE_UINT16(&mem[q + 0x38]); // mem[q + 0x38] | mem[q + 0x39] << 8;
if (unp->_info->_run == -1)
unp->_forced = 0x80b;
unp->_fStrAf = 0xfc;
unp->_idFlag = 1;
return;
}
}
}
/* cruel 1.2 / unknown 2059 */
if (unp->_depAdr == 0) {
if (u32eq(mem + 0x80b, 0xE67800A0) &&
u32eq(mem + 0x80f, 0x0803B901) &&
u32eq(mem + 0x813, 0xC800E399) &&
u32eq(mem + 0x817, 0x004CF7D0) &&
u32eq(mem + 0x90b, 0xC068FEC6)) {
unp->_depAdr = 0x100;
unp->_forced = 0x80b;
unp->_retAdr = READ_LE_UINT16(&mem[0x91c]); // mem[0x91c] | mem[0x91d] << 8;
unp->_endAdr = 0x2d;
unp->_fStrAf = 0xfc;
unp->_idFlag = 1;
return;
}
/* this was found in Agile and S451 cracks, Galleon's "Cruel+Search"
it's actually the real v1.0
*/
if (u32eq(mem + 0x80b, 0xE67800A0) &&
u32eq(mem + 0x80f, 0x0803B901) &&
u32eq(mem + 0x813, 0xC800E399) &&
u32eq(mem + 0x8c5, 0x011D4C04) &&
u32eq(mem + 0x90b, 0xB1486018)) {
unp->_depAdr = 0x100;
unp->_forced = 0x80b;
unp->_retAdr = READ_LE_UINT16(&mem[0x92d]); // mem[0x92d] | mem[0x92e] << 8;
unp->_endAdr = 0x2d;
unp->_fStrAf = 0xfc;
unp->_idFlag = 1;
return;
}
if (u32eq(mem + 0x80b, 0xE67800A0) &&
u32eq(mem + 0x80f, 0x0803B901) &&
u32eq(mem + 0x813, 0xC800E399) &&
u32eq(mem + 0x8b7, 0x011D4C04) &&
u32eq(mem + 0x8fc, 0xB1486018)) {
unp->_depAdr = 0x100;
unp->_forced = 0x80b;
unp->_retAdr = READ_LE_UINT16(&mem[0x91e]); // mem[0x91e] | mem[0x91f] << 8;
unp->_endAdr = 0x2d;
unp->_fStrAf = 0xfc;
unp->_idFlag = 1;
return;
}
}
/* TKC "proggy crueler 2.3" (and 2.5) */
if (unp->_depAdr == 0) {
if (mem[0x810] == 0xb9 && mem[0x819] == 0xa9 &&
u32eq(mem + 0x813, 0xC800fa99) &&
u32eq(mem + 0x822, 0x4CAF86AE)) {
p = READ_LE_UINT16(&mem[0x811]); // mem[0x811] | mem[0x812] << 8;
q = p - 0x100;
if (u32eq(mem + p + 0x0c, 0x20F7D0C8) &&
u32eq(mem + q, 0xA9C8C8C8)) {
unp->_depAdr = 0x100;
unp->_endAdr = READ_LE_UINT16(&mem[p + 0x02]); // mem[p + 0x02] | mem[p + 0x03] << 8;
unp->_retAdr = READ_LE_UINT16(&mem[q + 0x3f]); // mem[q + 0x3f] | mem[q + 0x40] << 8;
if (unp->_info->_run == -1)
unp->_forced = 0x80b;
unp->_fStrAf = 0xfc;
unp->_idFlag = 1;
return;
}
}
}
}
} // End of namespace Scott
} // End of namespace Glk

View File

@@ -0,0 +1,185 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/endian.h"
#include "glk/scott/types.h"
#include "glk/scott/unp64/unp64.h"
#include "glk/scott/unp64/exo_util.h"
namespace Glk {
namespace Scott {
void scnECA(UnpStr *unp) {
byte *mem;
int q, p;
if (unp->_idFlag)
return;
mem = unp->_mem;
if (unp->_depAdr == 0) {
// for(p=0x810;p<0x830;p+=0x4)
for (p = 0x80d; p < 0x830; p += 0x1) {
if (u32eq(mem + p + 0x08, (unsigned int)(0x2D9D0032 + p)) &&
u32eq(mem + p + 0x3a, 0x2a2a2a2a) &&
u32eq(mem + p + 0x0c, 0xF710CA00)) {
if (((*(unsigned int *)(mem + p + 0x00) & 0xf4fff000) == 0x8434A000) &&
u32eq(mem + p + 0x04, 0xBD05A201)) {
unp->_forced = p + 1;
} else if (((*(unsigned int *)(mem + p + 0x00) & 0xffffff00) == 0x04A27800) &&
u32eq(mem + p + 0x04, 0xBDE80186)) {
unp->_forced = p + 1;
} else if (((*(unsigned int *)(mem + p - 0x03) & 0xffffff00) == 0x04A27800) &&
u32eq(mem + p + 0x04, 0xBDE80186)) {
unp->_forced = p - 2;
} else if (u32eq(mem + p - 0x03, 0x8D00a978)) {
unp->_forced = p - 2;
}
}
if (!unp->_forced) {
if (u32eq(mem + p + 0x3a, 0x2a2a2a2a) &&
u32eq(mem + p + 0x02, 0x8534A978) &&
mem[p - 3] == 0xa0) {
unp->_forced = p - 3;
if (mem[p + 0x0d6] == 0x20 && mem[p + 0x0d7] == 0xe0 &&
mem[p + 0x0d8] == 0x03 && mem[p + 0x1da] == 0x5b &&
mem[p + 0x1e7] == 0x59) {
/* antiprotection :D */
mem[p + 0x0d6] = 0x4c;
mem[p + 0x0d7] = 0xae;
mem[p + 0x0d8] = 0xa7;
}
}
}
if (!unp->_forced) { /* FDT */
if (u32eq(mem + p + 0x3a, 0x2a2a2a2a) &&
u32eq(mem + p + 0x03, 0x8604A278) &&
u32eq(mem + p + 0x0a, 0x2D950842)) {
unp->_forced = p + 3;
}
}
if (!unp->_forced) {
/* decibel hacks */
if (u32eq(mem + p + 0x3a, 0x2a2a2a2a) &&
u32eq(mem + p + 0x00, 0x9D085EBD) &&
u32eq(mem + p - 0x06, 0x018534A9)) {
unp->_forced = p - 0x6;
}
}
if (unp->_forced) {
for (q = 0xd6; q < 0xde; q++) {
if (mem[p + q] == 0x20) {
if (u16eq(mem + p + q + 1, 0xa659) ||
u16eq(mem + p + q + 1, 0xff81) ||
u16eq(mem + p + q + 1, 0xe3bf) ||
u16eq(mem + p + q + 1, 0xe5a0) ||
u16eq(mem + p + q + 1, 0xe518)) {
mem[p + q] = 0x2c;
q += 2;
continue;
} else {
unp->_retAdr = READ_LE_UINT16(&mem[p + q + 1]); // mem[p + q + 1] | mem[p + q + 2] << 8;
break;
}
}
if (mem[p + q] == 0x4c) {
unp->_retAdr = READ_LE_UINT16(&mem[p + q + 1]); // mem[p + q + 1] | mem[p + q + 2] << 8;
break;
}
}
unp->_depAdr = READ_LE_UINT16(&mem[p + 0x30]); // mem[p + 0x30] | mem[p + 0x31] << 8;
// some use $2d, some $ae
for (q = 0xed; q < 0x108; q++) {
if (u32eq(mem + p + q, 0xA518F7D0)) {
unp->_endAdr = mem[p + q + 4];
// if(unp->_DebugP)
// printf("EndAdr from $%02x\n",unp->_endAdr);
break;
}
}
/*
if anything it's unpacked to $d000-efff, it will be copied
to $e000-ffff as last action in unpacker before starting.
0196 20 DA 01 JSR $01DA ; some have this jsr nopped, reloc doesn't
happen 0199 A9 37 LDA #$37 019b 85 01 STA $01 019d 58 CLI
019e 20 00 0D JSR $0D00 ; retaddr can be either here or following
01a1 4C AE A7 JMP $A7AE
01da B9 00 EF LDA $EF00,Y
01dd 99 00 FF STA $FF00,Y
01e0 C8 INY
01e1 D0 F7 BNE $01DA
01e3 CE DC 01 DEC $01DC
01e6 CE DF 01 DEC $01DF
01e9 AD DF 01 LDA $01DF
01ec C9 DF CMP #$DF ;<< not fixed, found as lower as $44 for
example 01ee D0 EA BNE $01DA 01f0 60 RTS Because of this,
$d000-dfff will be a copy of $e000-efff. So if $2d points to >= $d000,
SOMETIMES it's better save up to $ffff or: mem[$2d]|(mem[$2e]+$10)<<8
Still it's not a rule and I don't know exactly when.
17/06/09: Implemented but still experimental, so better check
extensively. use -v to know when it does the adjustments. 28/10/09:
whoops, was clearing ONLY $d000-dfff =)
*/
unp->_strMem = READ_LE_UINT16(&mem[p + 0x32]); // mem[p + 0x32] | mem[p + 0x33] << 8;
for (q = 0xcd; q < 0xd0; q++) {
if (u32eqmasked(mem + p + q, 0xffff00ff, 0xa9010020)) {
unp->_ecaFlg = READ_LE_UINT16(&mem[p + q + 1]); // mem[p + q + 1] | mem[p + q + 2] << 8;
for (q = 0x110; q < 0x11f; q++) {
if (u32eq(mem + p + q, 0x99EF00B9) &&
mem[p + q + 0x12] == 0xc9) {
unp->_ecaFlg |= (mem[p + q + 0x13] - 0xf) << 24;
break;
}
}
break;
}
}
/* radwar hack has a BRK here, fffe/f used as IRQ/BRK vector */
if (mem[0x8e1] == 0) {
mem[0x8e1] = 0x6c;
mem[0x8e2] = 0xfe;
mem[0x8e3] = 0xff;
}
break;
}
}
if (unp->_depAdr) {
unp->_idFlag = 1;
return;
}
}
/* old packer, many old 1985 warez used this */
if (unp->_depAdr == 0) {
if (u32eq(mem + 0x81b, 0x018534A9) &&
u32eq(mem + 0x822, 0xAFC600A0) &&
u32eq(mem + 0x826, 0xB1082DCE) &&
u32eq(mem + 0x85b, 0x2A2A2A2A)) {
unp->_forced = 0x81b;
unp->_depAdr = 0x100;
unp->_strMem = READ_LE_UINT16(&mem[0x853]); // mem[0x853] | mem[0x854] << 8;
unp->_endAdr = mem[0x895];
unp->_retAdr = READ_LE_UINT16(&mem[0x885]); // mem[0x885] | mem[0x886] << 8;
unp->_idFlag = 1;
return;
}
}
}
} // End of namespace Scott
} // End of namespace Glk

View File

@@ -0,0 +1,177 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/endian.h"
#include "glk/scott/types.h"
#include "glk/scott/unp64/unp64.h"
#include "glk/scott/unp64/exo_util.h"
namespace Glk {
namespace Scott {
void scnExomizer(UnpStr *unp) {
byte *mem;
int q, p;
if (unp->_idFlag)
return;
mem = unp->_mem;
/* exomizer 3.x */
if (unp->_depAdr == 0) {
for (p = unp->_info->_end - 4; p > unp->_info->_start; p--) {
if (u32eq(mem + p, 0x100A8069) &&
u32eq(mem + p + 4, 0xD0FD060F) &&
mem[p - 6] == 0x4c && mem[p - 4] == 0x01) {
p -= 5;
q = 2;
if (mem[p - q] == 0x8a)
q++;
/* low byte of EndAdr, it's a lda $ff00,y */
if ((mem[p - q - 1] == mem[p - q - 3]) &&
(mem[p - q - 2] == mem[p - q])) { /* a0 xx a0 xx -> exomizer 3.0/3.01 */
unp->_exoFnd = 0x30;
} else { /* d0 c1 a0 xx -> exomizer 3.0.2, force +1 in start/end */
unp->_exoFnd = 0x32;
}
unp->_exoFnd |= (mem[p - q] << 8);
break;
}
}
if (unp->_exoFnd) {
unp->_depAdr = 0x100 | mem[p];
for (; p < unp->_info->_end; p++) {
if (u32eq(mem + p, 0x7d010020))
break;
}
for (; p < unp->_info->_end; p++) {
if (mem[p] == 0x4c) {
unp->_retAdr = 0;
if ((unp->_retAdr = READ_LE_UINT16(&mem[p + 1])) >= 0x200) {
break;
} else { /* it's a jmp $01xx, goto next */
p++;
p++;
}
}
}
if (unp->_info->_run == -1) {
p = unp->_info->_start;
q = p + 0x10;
for (; p < q; p++) {
if ((mem[p] == 0xba) && (mem[p + 1] == 0xbd)) {
unp->_forced = p;
break;
}
}
for (q = p - 1; q >= unp->_info->_start; q--) {
if (mem[q] == 0xe6)
unp->_forced = q;
if (mem[q] == 0xa0)
unp->_forced = q;
if (mem[q] == 0x78)
unp->_forced = q;
}
}
}
}
/* exomizer 1.x/2.x */
if (unp->_depAdr == 0) {
for (p = unp->_info->_end - 4; p > unp->_info->_start; p--) {
if (((u32eq(mem + p, 0x4CF7D088) &&
u32eq(mem + p - 0x0d, 0xD034C0C8)) ||
(u32eq(mem + p, 0x4CA7A438) &&
u32eq(mem + p - 0x0c, 0x799FA5AE)) ||
(u32eq(mem + p, 0x4CECD08A) &&
u32eq(mem + p - 0x13, 0xCECA0EB0)) ||
(u32eq(mem + p, 0x4C00A0D3) &&
u32eq(mem + p - 0x04, 0xD034C0C8)) ||
(u32eq(mem + p, 0x4C00A0D2) &&
u32eq(mem + p - 0x04, 0xD034C0C8))) &&
mem[p + 5] == 1) {
p += 4;
unp->_exoFnd = 1;
break;
} else if (((u32eq(mem + p, 0x8C00A0d2) &&
u32eq(mem + p - 0x04, 0xD034C0C8)) ||
(u32eq(mem + p, 0x8C00A0d3) &&
u32eq(mem + p - 0x04, 0xD034C0C8)) ||
(u32eq(mem + p, 0x8C00A0cf) &&
u32eq(mem + p - 0x04, 0xD034C0C8))) &&
mem[p + 6] == 0x4c && mem[p + 8] == 1) {
p += 7;
unp->_exoFnd = 1;
break;
}
}
if (unp->_exoFnd) {
unp->_depAdr = 0x100 | mem[p];
if (unp->_depAdr >= 0x134 && unp->_depAdr <= 0x14a /*0x13e*/) {
for (p = unp->_info->_end - 4; p > unp->_info->_start;
p--) { /* 02 04 04 30 20 10 80 00 */
if (u32eq(mem + p, 0x30040402))
break;
}
} else {
// exception for exo v1.x, otherwise add 8 to the counter and
// scan backward from here
if (unp->_depAdr != 0x143)
p += 0x08;
else
p -= 0xb8;
}
for (; p > unp->_info->_start; p--) {
// incredibly there can be a program starting at $4c00 :P
if ((mem[p] == 0x4c) && (mem[p - 1] != 0x4c) && (mem[p - 2] != 0x4c)) {
unp->_retAdr = 0;
if ((unp->_retAdr = READ_LE_UINT16(&mem[p + 1])) >= 0x200) {
break;
}
}
}
if (unp->_info->_run == -1) {
p = unp->_info->_start;
q = p + 0x10;
for (; p < q; p++) {
if ((mem[p] == 0xba) && (mem[p + 1] == 0xbd)) {
unp->_forced = p;
break;
}
}
for (q = p - 1; q >= unp->_info->_start; q--) {
if (mem[q] == 0xe6)
unp->_forced = q;
if (mem[q] == 0xa0)
unp->_forced = q;
if (mem[q] == 0x78)
unp->_forced = q;
}
}
}
}
if (unp->_depAdr != 0) {
unp->_idFlag = 1;
return;
}
}
} // End of namespace Scott
} // End of namespace Glk

View File

@@ -0,0 +1,247 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/endian.h"
#include "glk/scott/types.h"
#include "glk/scott/unp64/unp64.h"
#include "glk/scott/unp64/exo_util.h"
namespace Glk {
namespace Scott {
void scnExpert(UnpStr *unp) {
byte *mem;
int q, p;
if (unp->_idFlag)
return;
mem = unp->_mem;
if (unp->_depAdr == 0) {
for (q = 0x81b; q < 0x81d; q++) {
if (u32eq(mem + q + 0x00, 0x852FA978) &&
u32eq(mem + q + 0x04, 0x8534A900) &&
u32eq(mem + q + 0x14, 0x03860286)) {
for (p = 0x900; p < 0xfff0; p++) {
if (u32eq(mem + p + 1, 0x00084C9A) &&
u32eq(mem + p - 4, 0xA2058604)) {
if (unp->_info->_run == -1) {
unp->_forced = q;
unp->_info->_run = q;
}
q = 0x100 + mem[p] + 1;
if (q != 0x100) {
unp->_depAdr = q;
}
}
}
break;
}
}
if (unp->_depAdr) {
unp->_rtiFrc = 1;
if (u32eq(mem + 0x835, 0x6E8D48A9)) {
p = 0;
if (u32eq(mem + 0x92c, 0x4902B100)) {
if (!unp->_idOnly) {
p = 0x876;
mem[p] = 0x00; /* 1st anti hack */
p = mem[0x930];
}
} else if (u32eq(mem + 0x92f, 0x4902B100)) {
if (!unp->_idOnly) {
p = 0x873;
mem[p] = 0xa9; /* 1st anti hack */
mem[p + 1] = 0x02;
p = mem[0x933];
}
}
if (p && !unp->_idOnly) {
p |= (p << 24) | (p << 16) | (p << 8);
for (q = 0x980; q < 0xfff0; q++) {
if (((mem[q] ^ (p & 0xff)) == 0xac) &&
((mem[q + 3] ^ (p & 0xff)) == 0xc0) &&
u32eqxored(mem + q + 7, (unsigned int)p, 0xC001F2AC)) {
mem[q + 0x06] = (p & 0xff); /* 2nd anti hack */
mem[q + 0x0d] = (p & 0xff);
break;
}
}
}
}
}
}
if (unp->_depAdr == 0) {
if (u32eq(mem + 0x81b, 0x2FA9D878) &&
u32eq(mem + 0x82d, 0x0873BDB0)) {
for (p = 0x900; p < 0xfff0; p++) {
if (u32eq(mem + p, 0xA2F3D0CA) &&
mem[p + 0x05] == 0x4c) {
q = READ_LE_UINT16(&mem[p + 0x06]); // mem[p + 0x06] | mem[p + 0x07] << 8;
if (q != 0x100) {
unp->_depAdr = q;
break;
}
}
}
if (unp->_depAdr) {
unp->_rtiFrc = 1;
unp->_forced = 0x81b;
}
}
}
/* 2.9 Expert User Club version, found in
BloodMoney/HTL & SWIV/Inceria
*/
if (unp->_depAdr == 0) {
if (u32eq(mem + 0x81b, 0x8C00A078) &&
u32eq(mem + 0x831, 0x05860485) &&
u32eq(mem + 0x998, 0x00084C9A)) {
p = mem[0x919];
q = p << 24 | p << 16 | p << 8 | p;
for (p = 0x900; p < 0xfff0; p++) {
if (((*(unsigned int *)(mem + p) ^ (unsigned int)q) == 0xA2F3D0CA) &&
((mem[p + 0x05] ^ (q & 0xff)) == 0x4c)) {
q = (mem[p + 0x06] ^ (q & 0xff)) | (mem[p + 0x07] ^ (q & 0xff)) << 8;
if (q != 0x100) {
unp->_depAdr = q;
break;
}
}
}
if (unp->_depAdr) {
unp->_rtiFrc = 1;
unp->_forced = 0x81b;
}
}
}
/* sys2070 A.S.S. */
if (unp->_depAdr == 0) {
if (u32eq(mem + 0x817, 0x00852FA9) &&
u32eq(mem + 0x823, 0x05860485) &&
u32eq(mem + 0x9a0, 0x00084C9A)) {
p = mem[0x923];
q = p << 24 | p << 16 | p << 8 | p;
for (p = 0x900; p < 0xfff0; p++) {
if (((*(unsigned int *)(mem + p) ^ (unsigned int)q) == 0xA2F3D0CA) &&
((mem[p + 0x05] ^ (q & 0xff)) == 0x4c)) {
q = (mem[p + 0x06] ^ (q & 0xff)) | (mem[p + 0x07] ^ (q & 0xff)) << 8;
if (q != 0x100) {
unp->_depAdr = q;
break;
}
}
}
if (unp->_depAdr) {
unp->_rtiFrc = 1;
unp->_forced = 0x81b;
}
}
}
if (unp->_depAdr == 0) {
if (u32eq(mem + 0x81b, 0x7FA978D8) ||
u32eq(mem + 0x81b, 0x7FA9D878) ||
u32eq(mem + 0x816, 0x7FA978D8)) {
for (p = 0x900; p < 0xfff0; p++) {
if (u32eq(mem + p, 0xA2F3D0CA) &&
mem[p + 0x05] == 0x4c) {
q = READ_LE_UINT16(&mem[p + 0x06]); // mem[p + 0x06] | mem[p + 0x07] << 8;
if (q != 0x100) {
unp->_depAdr = q;
break;
}
}
}
if (unp->_depAdr) {
unp->_rtiFrc = 1;
if (u32eq(mem + 0x816, 0x7FA978D8)) {
q = 0x816;
if (!unp->_idOnly) {
for (p = 0x900; p < 0xfff0; p++) {
if (u32eq(mem + p, 0xE0A9F0A2) &&
u32eq(mem + p + 4, 0xE807135D) &&
mem[p + 0x8] == 0xd0) {
mem[p + 0x1] = 0x00;
mem[p + 0x3] = 0x98;
memset(mem + p + 4, 0xea, 6);
break;
}
}
}
} else {
q = 0x81b;
if (!unp->_idOnly) {
for (p = 0x900; p < 0xfff0; p++) {
if (u32eq(mem + p, 0xCA08015D) &&
u32eq(mem + p + 4, 0xF8D003E0) &&
mem[p + 0xa] == 0xd0) {
p += 0xa;
mem[p] = 0x24;
break;
}
}
}
}
if (unp->_info->_run == -1) {
unp->_forced = q;
unp->_info->_run = q;
}
}
}
}
if (unp->_depAdr == 0) {
q = 0x81b;
if (u32eq(mem + q + 0x00, 0x852FA978) &&
u32eq(mem + q + 0x04, 0x8534A900) &&
u32eq(mem + q + 0x14, 0x03860286) &&
u32eq(mem + q + 0x4f, 0xA200594C) &&
u32eq(mem + q + 0xad, 0x2000124C)) {
unp->_forced = q;
unp->_info->_run = q;
unp->_depAdr = 0x12;
unp->_rtiFrc = 1;
}
}
/* expert 2.11 (sys2074) & unknown sys2061 */
if (unp->_depAdr == 0) {
for (q = 0x80d; q < 0x820; q++) {
if (u32eq(mem + q + 0x00, 0x852FA978) &&
u32eq(mem + q + 0x04, 0x8534A900) &&
u32eq(mem + q + 0x13, 0x03840284) &&
u32eq(mem + q + 0x4f, 0x084C003A) &&
u32eq(mem + q + 0xad, 0x00AA2048)) {
unp->_forced = q;
unp->_info->_run = q;
unp->_depAdr = 0x100 + mem[q + 0x17a] + 1;
break;
}
}
if (unp->_depAdr != 0) {
unp->_rtiFrc = 1;
}
}
if (unp->_depAdr != 0) {
unp->_idFlag = 1;
return;
}
}
} // End of namespace Scott
} // End of namespace Glk

View File

@@ -0,0 +1,125 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/endian.h"
#include "glk/scott/types.h"
#include "glk/scott/unp64/unp64.h"
#include "glk/scott/unp64/exo_util.h"
namespace Glk {
namespace Scott {
void scnMasterCompressor(UnpStr *unp) {
byte *mem;
int p;
if (unp->_idFlag)
return;
mem = unp->_mem;
if (unp->_depAdr == 0) {
for (p = 0x80d; p < 0x880; p++) {
if (u32eqmasked(mem + p + 0x005, 0x00ffffff, 0x00BDD2A2) &&
u32eq(mem + p + 0x00a, 0xE000F99D) &&
u32eq(mem + p + 0x017, 0xCAEDD0CA) &&
u32eq(mem + p + 0x031, 0x84C82E86) &&
u32eqmasked(mem + p + 0x035, 0x0000ffff, 0x00004C2D) &&
u32eq(mem + p + 0x134, 0xDBD0FFE6)) {
if (/*mem[p]==0x78&&*/ mem[p + 1] == 0xa9 &&
u32eq(mem + p + 0x003, 0xD2A20185)) {
unp->_depAdr = READ_LE_UINT16(&mem[p + 0x37]);
unp->_forced = p + 1;
if (mem[p + 0x12b] == 0x020) // jsr $0400, unuseful fx
mem[p + 0x12b] = 0x2c;
} else if (u32eq(mem + p, 0xD024E0E8)) {
/* HTL version */
unp->_depAdr = READ_LE_UINT16(&mem[p + 0x37]);
unp->_forced = 0x840;
}
if (unp->_depAdr) {
unp->_retAdr = READ_LE_UINT16(&mem[p + 0x13e]);
unp->_endAdr = 0x2d;
unp->_fStrBf = unp->_endAdr;
unp->_idFlag = 1;
return;
}
}
}
}
if (unp->_depAdr == 0) {
for (p = 0x80d; p < 0x880; p++) {
if (u32eqmasked(mem + p + 0x005, 0x00ffffff, 0x00BDD2A2) &&
u32eq(mem + p + 0x00a, 0xE000F99D) &&
u32eq(mem + p + 0x017, 0xCAEDD0CA) &&
u32eq(mem + p + 0x031, 0x84C82E86) &&
u32eqmasked(mem + p + 0x035, 0x0000ffff, 0x00004C2D) &&
u32eq(mem + p + 0x12d, 0xe2D0FFE6)) {
if (mem[p + 1] == 0xa9 &&
u32eq(mem + p + 0x003, 0xD2A20185)) {
unp->_depAdr = READ_LE_UINT16(&mem[p + 0x37]);
unp->_forced = p + 1;
}
if (unp->_depAdr) {
if (mem[p + 0x136] == 0x4c)
unp->_retAdr = READ_LE_UINT16(&mem[p + 0x137]);
else if (mem[p + 0x13d] == 0x4c)
unp->_retAdr = READ_LE_UINT16(&mem[p + 0x13e]);
unp->_endAdr = 0x2d;
unp->_fStrBf = unp->_endAdr;
unp->_idFlag = 1;
return;
}
}
}
}
if (unp->_depAdr == 0) {
p = 0x812;
if (u32eq(mem + p + 0x000, 0xE67800A0) &&
u32eq(mem + p + 0x004, 0x0841B901) &&
u32eq(mem + p + 0x008, 0xB900FA99) &&
u32eq(mem + p + 0x00c, 0x34990910)) {
unp->_depAdr = 0x100;
unp->_forced = p;
unp->_retAdr = READ_LE_UINT16(&mem[0x943]); // mem[0x943] | mem[0x944] << 8;
unp->_endAdr = 0x2d;
unp->_fStrBf = unp->_endAdr;
unp->_idFlag = 1;
return;
}
}
/* Fred/Channel4 hack */
if (unp->_depAdr == 0) {
if (u32eq(mem + 0x811, 0xA9A98078) &&
u32eq(mem + 0x815, 0x85EE8034) &&
u32eq(mem + 0x819, 0x802DA201) &&
u32eq(mem + 0x882, 0x01004C2D)) {
unp->_depAdr = 0x100;
unp->_forced = 0x811;
unp->_retAdr = READ_LE_UINT16(&mem[0x98b]); // mem[0x98b] | mem[0x98c] << 8;
if (unp->_retAdr < 0x800)
unp->_rtAFrc = 1;
unp->_endAdr = 0x2d;
unp->_idFlag = 1;
return;
}
}
}
} // End of namespace Scott
} // End of namespace Glk

View File

@@ -0,0 +1,82 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/endian.h"
#include "glk/scott/types.h"
#include "glk/scott/unp64/unp64.h"
#include "glk/scott/unp64/exo_util.h"
namespace Glk {
namespace Scott {
void scnMegabyte(UnpStr *unp) {
byte *mem;
int p;
if (unp->_idFlag)
return;
mem = unp->_mem;
if (unp->_depAdr == 0) {
p = 0;
if (mem[0x816] == 0x4c)
p = READ_LE_UINT16(&mem[0x817]); // mem[0x817] | mem[0x818] << 8;
else if (unp->_info->_run == 0x810 && mem[0x814] == 0x4c &&
u32eqmasked(mem + 0x810, 0xffff00ff, 0x018500A9))
p = READ_LE_UINT16(&mem[0x815]); // mem[0x815] | mem[0x816] << 8;
if (p) {
if (mem[p + 0] == 0x78 && mem[p + 1] == 0xa2 &&
mem[p + 3] == 0xa0 &&
u32eq(mem + p + 0x05, 0x15841486) &&
u32eq(mem + p + 0x1d, 0x03804CF7)) {
unp->_depAdr = 0x380;
unp->_endAdr = READ_LE_UINT16(&mem[p + 0x55]); // mem[p + 0x55] | mem[p + 0x56] << 8;
unp->_endAdr++;
unp->_strMem = 0x801;
unp->_retAdr = 0x801; /* usually it just runs */
unp->_idFlag = 1;
return;
}
}
}
if (unp->_depAdr == 0) {
p = 0;
if (mem[0x81a] == 0x4c &&
u32eqmasked(mem + 0x816, 0xffff00ff, 0x018500A9))
p = READ_LE_UINT16(&mem[0x81b]); // mem[0x81b] | mem[0x81c] << 8;
if (p) {
if (mem[p + 0] == 0x78 && mem[p + 1] == 0xa2 &&
mem[p + 3] == 0xa0 &&
u32eq(mem + p + 0x05, 0x15841486) &&
u32eq(mem + p + 0x1d, 0x03844CF7)) {
unp->_depAdr = 0x384;
unp->_forced = 0x816;
unp->_endAdr = READ_LE_UINT16(&mem[p + 0x59]); // mem[p + 0x59] | mem[p + 0x5a] << 8;
unp->_endAdr++;
unp->_strMem = 0x801;
unp->_retAdr = 0x801; /* usually it just runs */
unp->_idFlag = 1;
return;
}
}
}
}
} // End of namespace Scott
} // End of namespace Glk

View File

@@ -0,0 +1,194 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/endian.h"
#include "glk/scott/types.h"
#include "glk/scott/unp64/unp64.h"
#include "glk/scott/unp64/exo_util.h"
namespace Glk {
namespace Scott {
void scnPuCrunch(UnpStr *unp) {
byte *mem;
int q, p;
if (unp->_idFlag)
return;
mem = unp->_mem;
if (unp->_depAdr == 0) {
if (mem[0x80d] == 0x78 &&
u32eq(mem + 0x813, 0x34A20185) &&
u32eq(mem + 0x817, 0x9D0842BD) &&
u32eq(mem + 0x81b, 0xD0CA01FF) &&
u32eq(mem + 0x83d, 0x4CEDD088)) {
for (p = 0x912; p < 0x938; p++) {
if (u32eq(mem + p, 0x2D85FAA5) &&
u32eq(mem + p + 4, 0x2E85FBA5)) {
unp->_endAdr = 0xfa;
unp->_strMem = READ_LE_UINT16(&mem[0x879]); // mem[0x879] | mem[0x87a] << 8;
unp->_depAdr = READ_LE_UINT16(&mem[0x841]); // mem[0x841] | mem[0x842] << 8;
unp->_retAdr = READ_LE_UINT16(&mem[p + 0xa]); // mem[p + 0xa] | mem[p + 0xb] << 8;
unp->_forced = 0x80d;
break;
}
}
} else if (mem[0x80d] == 0x78 &&
u32eq(mem + 0x81a, 0x10CA4B95) &&
u32eq(mem + 0x81e, 0xBD3BA2F8) &&
u32eq(mem + 0x847, 0x4CEDD088)) {
for (p = 0x912; p < 0x938; p++) {
if (u32eq(mem + p, 0x2D85FAA5) &&
u32eq(mem + p + 4, 0x2E85FBA5)) {
unp->_endAdr = 0xfa;
unp->_strMem = READ_LE_UINT16(&mem[p + 0x88a]); // mem[0x88a] | mem[0x88b] << 8;
unp->_depAdr = READ_LE_UINT16(&mem[p + 0x84b]); // mem[0x84b] | mem[0x84c] << 8;
unp->_retAdr = READ_LE_UINT16(&mem[p + 0xa]); // mem[p + 0xa] | mem[p + 0xb] << 8;
unp->_forced = 0x80d;
break;
}
}
} else if (mem[0x80d] == 0x78 &&
u32eq(mem + 0x811, 0x85AAA901) &&
u32eq(mem + 0x81d, 0xF69D083C) &&
u32eq(mem + 0x861, 0xC501C320) &&
u32eq(mem + 0x839, 0x01164CED)) {
unp->_endAdr = 0xfa;
unp->_strMem = READ_LE_UINT16(&mem[0x840]); // mem[0x840] | mem[0x841] << 8;
unp->_depAdr = 0x116;
unp->_retAdr = READ_LE_UINT16(&mem[0x8df]); // mem[0x8df] | mem[0x8e0] << 8;
unp->_forced = 0x80d;
} else if (mem[0x80d] == 0x78 &&
u32eq(mem + 0x811, 0x85AAA901) &&
u32eq(mem + 0x81d, 0xF69D083C) &&
u32eq(mem + 0x861, 0xC501C820) &&
u32eq(mem + 0x839, 0x01164CED)) {
unp->_endAdr = 0xfa;
unp->_strMem = READ_LE_UINT16(&mem[0x840]); // mem[0x840] | mem[0x841] << 8;
unp->_depAdr = 0x116;
if (mem[0x8de] == 0xa9) {
unp->_retAdr = READ_LE_UINT16(&mem[0x8e1]); // mem[0x8e1] | mem[0x8e2] << 8;
if ((unp->_retAdr == 0xa871) && (mem[0x8e0] == 0x20) &&
(mem[0x8e3] == 0x4c)) {
mem[0x8e0] = 0x2c;
unp->_retAdr = READ_LE_UINT16(&mem[0x8e4]); // mem[0x8e4] | mem[0x8e5] << 8;
}
} else {
unp->_retAdr = READ_LE_UINT16(&mem[0x8df]); // mem[0x8df] | mem[0x8e0] << 8;
}
unp->_forced = 0x80d;
} else {
/* unknown old/hacked pucrunch ? */
for (p = 0x80d; p < 0x820; p++) {
if (mem[p] == 0x78) {
q = p;
for (; p < 0x824; p++) {
if (u32eqmasked(mem + p, 0xf0ffffff, 0xF0BD53A2) &&
u32eq(mem + p + 4, 0x01FF9D08) &&
u32eq(mem + p + 8, 0xA2F7D0CA)) {
unp->_forced = q;
q = mem[p + 3] & 0xf; /* can be $f0 or $f2, q&0x0f as offset */
p = READ_LE_UINT16(&mem[p + 0xe]); // mem[p + 0xe] | mem[p + 0xf] << 8;
if (mem[p - 2] == 0x4c && mem[p + 0xa0 + q] == 0x85) {
unp->_depAdr = READ_LE_UINT16(&mem[p - 1]); // mem[p - 1] | mem[p] << 8;
unp->_strMem = READ_LE_UINT16(&mem[p + 4]); // mem[p + 4] | mem[p + 5] << 8;
unp->_endAdr = 0xfa;
p += 0xa2;
q = p + 8;
for (; p < q; p++) {
if (u32eq(mem + p, 0x2D85FAA5) &&
mem[p + 9] == 0x4c) {
unp->_retAdr = READ_LE_UINT16(&mem[p + 0xa]); // mem[p + 0xa] | mem[p + 0xb] << 8;
break;
}
}
}
}
}
}
}
}
/* various old/hacked pucrunch */
/* common pattern, variable pos from 0x79 to 0xd1
90 ?? C8 20 ?? 0? 85 ?? C9 ?0 90 0B A2 0? 20 ?? 0? 85 ?? 20 ?? 0? A8 20 ??
0? AA BD ?? 0? E0 20 90 0? 8A (A2 03) not always 20 ?? 02 A6
?? E8 20 F9
*/
if (unp->_depAdr == 0) {
unp->_idFlag = 0;
for (q = 0x70; q < 0xff; q++) {
if (u32eqmasked(mem + 0x801 + q, 0xFFFF00FF, 0x20C80090) &&
u32eqmasked(mem + 0x801 + q + 8, 0xFFFF0FFF,
0x0B9000C9) &&
u32eqmasked(mem + 0x801 + q + 12, 0x00FFF0FF,
0x002000A2) &&
u32eqmasked(mem + 0x801 + q + 30, 0xF0FFFFFf,
0x009020E0)) {
unp->_idFlag = 385;
break;
}
}
if (unp->_idFlag) {
for (p = 0x801 + q + 34; p < 0x9ff; p++) {
if (u32eq(mem + p, 0x00F920E8)) {
for (; p < 0x9ff; p++) {
if (mem[p] == 0x4c) {
unp->_retAdr = READ_LE_UINT16(&mem[p + 1]);
if (unp->_retAdr > 0x257)
break;
}
}
break;
}
}
for (p = 0; p < 0x40; p++) {
if (unp->_info->_run == -1)
if (unp->_forced == 0) {
if (mem[0x801 + p] == 0x78) {
unp->_forced = 0x801 + p;
unp->_info->_run = unp->_forced;
}
}
if (u32eq(mem + 0x801 + p, 0xCA00F69D) &&
mem[0x801 + p + 0x1b] == 0x4c) {
q = 0x801 + p + 0x1c;
unp->_depAdr = READ_LE_UINT16(&mem[q]);
q = 0x801 + p - 2;
p = READ_LE_UINT16(&mem[q]);
if ((mem[p + 3] == 0x8d) && (mem[p + 6] == 0xe6)) {
unp->_strMem = READ_LE_UINT16(&mem[p + 4]);
}
break;
}
}
unp->_endAdr = 0xfa; // some hacks DON'T xfer fa/b to 2d/e
unp->_idFlag = 1;
}
}
if (unp->_depAdr) {
unp->_idFlag = 1;
return;
}
}
}
} // End of namespace Scott
} // End of namespace Glk

View File

@@ -0,0 +1,72 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "glk/scott/unp64/unp64.h"
namespace Glk {
namespace Scott {
void scnECA(UnpStr *unp);
void scnExpert(UnpStr *unp);
void scnCruel(UnpStr *unp);
void scnPuCrunch(UnpStr *unp);
void scnByteBoiler(UnpStr *unp);
void scnMasterCompressor(UnpStr *unp);
void scnTCScrunch(UnpStr *unp);
void scnTBCMultiComp(UnpStr *unp);
void scnXTC(UnpStr *unp);
void scnCCS(UnpStr *unp);
void scnMegabyte(UnpStr *unp);
void scnSection8(UnpStr *unp);
void scnCaution(UnpStr *unp);
void scnActionPacker(UnpStr *unp);
void scnExomizer(UnpStr *unp);
Scnptr g_scanFunc[] = {
scnECA,
scnExpert,
scnCruel,
scnPuCrunch,
scnByteBoiler,
scnMasterCompressor,
scnTCScrunch,
scnTBCMultiComp,
scnXTC,
scnCCS,
scnMegabyte,
scnSection8,
scnCaution,
scnActionPacker,
scnExomizer
};
void scanners(UnpStr* unp) {
int x, y;
y = sizeof(g_scanFunc) / sizeof(*g_scanFunc);
for (x = 0; x < y; x++) {
(g_scanFunc[x])(unp);
if (unp->_idFlag)
break;
}
}
} // End of namespace Scott
} // End of namespace Glk

View File

@@ -0,0 +1,103 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/endian.h"
#include "glk/scott/types.h"
#include "glk/scott/unp64/unp64.h"
#include "glk/scott/unp64/exo_util.h"
namespace Glk {
namespace Scott {
void scnSection8(UnpStr *unp) {
byte *mem;
int p;
if (unp->_idFlag)
return;
mem = unp->_mem;
if (unp->_depAdr == 0) {
for (p = 0x810; p <= 0x828; p++) {
if (u32eq(mem + p, (unsigned int)(0x00BD00A2 + (((p & 0xff) + 0x11) << 24))) &&
u32eq(mem + p + 0x04, 0x01009D08) &&
u32eq(mem + p + 0x10, 0x34A97801) &&
u32eq(mem + p + 0x6a, 0xB1017820) &&
u32eq(mem + p + 0x78, 0x017F20AE)) {
unp->_depAdr = 0x100;
break;
}
}
if (unp->_depAdr) {
if (unp->_info->_run == -1)
unp->_forced = p;
unp->_strMem = mem[p + 0x47] | mem[p + 0x4b] << 8;
unp->_retAdr = READ_LE_UINT16(&mem[p + 0x87]); // mem[p + 0x87] | mem[p + 0x88] << 8;
if (unp->_retAdr == 0xf7) {
unp->_retAdr = 0xa7ae;
mem[p + 0x87] = 0xae;
mem[p + 0x88] = 0xa7;
}
unp->_endAdr = 0xae;
unp->_idFlag = 1;
return;
}
}
/* Crackman variant? */
if (unp->_depAdr == 0) {
if (u32eq(mem + 0x827, 0x38BD00A2) &&
u32eq(mem + 0x82b, 0x01009D08) &&
u32eq(mem + 0x837, 0x34A97801) &&
u32eq(mem + 0x891, 0xB1018420) &&
u32eq(mem + 0x89f, 0x018b20AE)) {
unp->_depAdr = 0x100;
if (unp->_info->_run == -1)
unp->_forced = 0x827;
unp->_strMem = mem[0x86e] | mem[0x872] << 8;
if (u16eq(mem + 0x8b7, 0xff5b)) {
mem[0x8b6] = 0x2c;
unp->_retAdr = READ_LE_UINT16(&mem[0x8ba]); // mem[0x8ba] | mem[0x8bb] << 8;
} else {
unp->_retAdr = READ_LE_UINT16(&mem[0x8b7]); // mem[0x8b7] | mem[0x8b8] << 8;
}
unp->_endAdr = 0xae;
unp->_idFlag = 1;
return;
}
}
/* PET||SLAN variant? */
if (unp->_depAdr == 0) {
if (u32eq(mem + 0x812, 0x20BD00A2) &&
u32eq(mem + 0x816, 0x033c9D08) &&
u32eq(mem + 0x863, 0xB103B420) &&
u32eq(mem + 0x86c, 0x03BB20AE)) {
unp->_depAdr = 0x33c;
if (unp->_info->_run == -1)
unp->_forced = 0x812;
unp->_strMem = mem[0x856] | mem[0x85a] << 8;
unp->_retAdr = READ_LE_UINT16(&mem[0x896]); // mem[0x896] | mem[0x897] << 8;
unp->_endAdr = 0xae;
unp->_idFlag = 1;
return;
}
}
}
} // End of namespace Scott
} // End of namespace Glk

View File

@@ -0,0 +1,166 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/endian.h"
#include "glk/scott/types.h"
#include "glk/scott/unp64/unp64.h"
#include "glk/scott/unp64/exo_util.h"
namespace Glk {
namespace Scott {
void scnTBCMultiComp(UnpStr *unp) {
byte *mem;
int p = 0, q = 0, strtmp;
if (unp->_idFlag)
return;
mem = unp->_mem;
if (unp->_depAdr == 0) {
if (u32eqmasked(mem + 0x82c, 0xfffffffd, 0x9ACA0184) &&
u32eq(mem + 0x830, 0xA001004C) &&
u32eq(mem + 0x834, 0x84FD8400) &&
u32eq(mem + 0x8a2, 0x01494C01)) {
/*normal 2080*/
if (mem[0x84a] == 0x81) {
if (u32eq(mem + 0x820, 0x32BDE9A2)) {
unp->_forced = 0x820;
unp->_retAdr = READ_LE_UINT16(&mem[0x8b2]); // mem[0x8b2] | mem[0x8b3] << 8;
if (unp->_retAdr == 0x1e1) {
if (u32eq(mem + 0x916, 0x4CA87120)) {
p = *(unsigned short int *)(mem + 0x91a);
if (p == 0xa7ae) {
unp->_retAdr = p;
mem[0x8b2] = 0xae;
mem[0x8b3] = 0xa7;
} else {
mem[0x916] = 0x2c;
unp->_retAdr = p;
}
} else if ((mem[0x916] == 0x4C) || (mem[0x916] == 0x20)) {
unp->_retAdr = READ_LE_UINT16(&mem[0x917]); // mem[0x917] | mem[0x918] << 8;
} else if (mem[0x919] == 0x4c) {
unp->_retAdr = READ_LE_UINT16(&mem[0x91a]); // mem[0x91a] | mem[0x91b] << 8;
}
}
if ((unp->_retAdr == 0) && (mem[0x8b1] == 0)) {
unp->_retAdr = 0xa7ae;
mem[0x8b1] = 0x4c;
mem[0x8b2] = 0xae;
mem[0x8b3] = 0xa7;
}
p = 0x8eb;
}
}
/*firelord 2076*/
else if (mem[0x84a] == 0x7b) {
if (u32eq(mem + 0x81d, 0x32BDE9A2)) {
unp->_forced = 0x81d;
unp->_retAdr = READ_LE_UINT16(&mem[0x8ac]); // mem[0x8ac] | mem[0x8ad] << 8;
p = 0x8eb;
}
}
if (unp->_forced) {
unp->_depAdr = 0x100;
unp->_strMem = READ_LE_UINT16(&mem[p + 1]); // mem[p + 1] | mem[p + 2] << 8;
q = p;
q += mem[p];
unp->_endAdr = 0;
for (; q > p; q -= 4) {
strtmp = READ_LE_UINT16(&mem[q - 1]); //(mem[q - 1] | mem[q] << 8);
if (strtmp == 0)
strtmp = 0x10000;
if (strtmp > unp->_endAdr)
unp->_endAdr = strtmp;
}
unp->_idFlag = 1;
return;
}
}
}
/* TBC Multicompactor ? very similar but larger code */
if (unp->_depAdr == 0) {
if (u32eq(mem + 0x822, 0x9D083DBD) &&
u32eq(mem + 0x826, 0xD0CA0333) &&
u32eq(mem + 0x832, 0xF7D0CA00) &&
u32eq(mem + 0x836, 0xCA018678) &&
u32eq(mem + 0x946, 0xADC5AFA5)) {
if (unp->_info->_run == -1) {
for (p = 0x81e; p < 0x821; p++) {
if (mem[p] == 0xa2) {
unp->_forced = p;
break;
}
}
}
unp->_depAdr = 0x334;
unp->_retAdr = READ_LE_UINT16(&mem[0x92a]); // mem[0x92a] | mem[0x92b] << 8;
p = 0x94d;
unp->_strMem = READ_LE_UINT16(&mem[p + 1]); // mem[p + 1] | mem[p + 2] << 8;
q = p;
q += mem[p];
unp->_endAdr = 0;
for (; q > p; q -= 4) {
strtmp = READ_LE_UINT16(&mem[q - 1]); //(mem[q - 1] | mem[q] << 8);
if (strtmp == 0)
strtmp = 0x10000;
if (strtmp > unp->_endAdr)
unp->_endAdr = strtmp;
}
unp->_idFlag = 1;
return;
}
}
/*"AUTOMATIC BREAK SYSTEM" found in Manowar Cracks*/
if (unp->_depAdr == 0) {
if (u32eq(mem + 0x835, 0x9D0845BD) &&
u32eq(mem + 0x839, 0xD0CA00ff) &&
u32eq(mem + 0x83e, 0xCA018678) &&
u32eq(mem + 0x8e1, 0xADC5AFA5)) {
if (unp->_info->_run == -1) {
for (p = 0x830; p < 0x834; p++) {
if (mem[p] == 0xa2) {
unp->_forced = p;
break;
}
}
}
unp->_depAdr = 0x100;
unp->_retAdr = READ_LE_UINT16(&mem[0x8c5]); // mem[0x8c5] | mem[0x8c6] << 8;
p = 0x8fe;
unp->_strMem = READ_LE_UINT16(&mem[p + 1]); // mem[p + 1] | mem[p + 2] << 8;
q = p;
q += mem[p];
unp->_endAdr = 0;
for (; q > p; q -= 4) {
strtmp = READ_LE_UINT16(&mem[q - 1]); //(mem[q - 1] | mem[q] << 8);
if (strtmp == 0)
strtmp = 0x10000;
if (strtmp > unp->_endAdr)
unp->_endAdr = strtmp;
}
unp->_idFlag = 1;
return;
}
}
}
} // End of namespace Scott
} // End of namespace Glk

View File

@@ -0,0 +1,78 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/endian.h"
#include "glk/scott/types.h"
#include "glk/scott/unp64/unp64.h"
#include "glk/scott/unp64/exo_util.h"
namespace Glk {
namespace Scott {
void scnTCScrunch(UnpStr *unp) {
byte *mem;
int q, p;
if (unp->_idFlag)
return;
mem = unp->_mem;
if (unp->_depAdr == 0) {
if (u32eq(mem + 0x819, 0x018536A9) && mem[0x81d] == 0x4c) {
p = READ_LE_UINT16(&mem[0x81e]); // mem[0x81e] | mem[0x81f] << 8;
if (mem[p] == 0xa2 && mem[p + 2] == 0xbd &&
u32eq(mem + p + 0x05, 0xE801109D) &&
(u32eq(mem + p + 0x38, 0x01524CFB) ||
(u32eq(mem + p + 0x38, 0x8DE1A9FB) &&
u32eq(mem + p + 0x3c, 0x524C0328)))) {
unp->_depAdr = 0x334;
unp->_forced = 0x819;
unp->_endAdr = 0x2d;
}
} else if (u32eq(mem + 0x819, 0x018534A9) && mem[0x81d] == 0x4c) {
p = READ_LE_UINT16(&mem[0x81e]); // mem[0x81e] | mem[0x81f] << 8;
if (mem[p] == 0xa2 && mem[p + 2] == 0xbd &&
u32eq(mem + p + 0x05, 0xE801109D) &&
u32eq(mem + p + 0x38, 0x01304CFB)) {
unp->_depAdr = 0x334;
unp->_forced = 0x818;
if (mem[unp->_forced] != 0x78)
unp->_forced++;
unp->_endAdr = 0x2d;
unp->_retAdr = READ_LE_UINT16(&mem[p + 0xd9]); // mem[p + 0xd9] | mem[p + 0xda] << 8;
p += 0xc8;
q = p + 6;
for (; p < q; p += 3) {
if (mem[p] == 0x20 &&
u16gteq(mem + p + 1, 0xa000) &&
u16lteq(mem + p + 1, 0xbfff)) {
mem[p] = 0x2c;
}
}
}
}
if (unp->_depAdr) {
unp->_idFlag = 1;
return;
}
}
}
} // End of namespace Scott
} // End of namespace Glk

View File

@@ -0,0 +1,162 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/endian.h"
#include "glk/scott/types.h"
#include "glk/scott/unp64/unp64.h"
#include "glk/scott/unp64/exo_util.h"
namespace Glk {
namespace Scott {
void scnXTC(UnpStr *unp) {
byte *mem;
int q = 0, p;
if (unp->_idFlag)
return;
mem = unp->_mem;
if (unp->_depAdr == 0) {
if (u16eq(mem + 0x80d, 0xE678) &&
u32eq(mem + 0x811, 0x1BCE0818) &&
u32eq(mem + 0x819, 0xC8000099) &&
u32eq(mem + 0x82c, 0x4CF7D0CA) &&
mem[0x85c] == 0x99) {
unp->_retAdr = READ_LE_UINT16(&mem[0x872]); // mem[0x872] | mem[0x873] << 8;
unp->_depAdr = 0x100;
unp->_forced = 0x80d; /* the ldy #$00 can be missing, skipped */
unp->_fEndAf = 0x121;
unp->_endAdC = 0xffff | EA_USE_Y;
unp->_strMem = READ_LE_UINT16(&mem[0x85d]); // mem[0x85d] | mem[0x85e] << 8;
unp->_idFlag = 1;
return;
}
}
/* XTC packer 1.0 & 2.2/2.4 */
if (unp->_depAdr == 0) {
for (p = 0x801; p < 0x80c; p += 0x0a) {
if (u16eq(mem + p + 0x02, 0xE678) &&
u32eq(mem + p + 0x07, (unsigned int)(0xce08 | ((p + 0x10) << 16))) &&
u32eq(mem + p + 0x0e, 0xC8000099) &&
u32eq(mem + p + 0x23, 0x4CF7D0CA)) {
/* has variable codebytes so addresses varies */
for (q = p + 0x37; q < p + 0x60; q += 4) {
if (mem[q] == 0xc9)
continue;
if (mem[q] == 0x99) {
unp->_depAdr = 0x100;
break;
}
break; /* unexpected byte, get out */
}
break;
}
}
if (unp->_depAdr) {
unp->_retAdr = READ_LE_UINT16(&mem[q + 0x16]); // mem[q + 0x16] | mem[q + 0x17] << 8;
if (u16noteq(mem + p, 0x00a0))
unp->_forced = p + 2; /* the ldy #$00 can be missing, skipped */
else
unp->_forced = p;
unp->_fEndAf = READ_LE_UINT16(&mem[q + 0x7]); // mem[q + 0x7] | mem[q + 0x8] << 8;
unp->_fEndAf--;
unp->_endAdC = 0xffff | EA_USE_Y;
unp->_strMem = READ_LE_UINT16(&mem[q + 1]); // mem[q + 1] | mem[q + 2] << 8;
if (u32eq(mem + q + 0x1f, 0xDDD00285)) {
} else if (u32eq(mem + q + 0x1f, 0xF620DFD0)) {
/* rockstar's 2.2+ & shade/light's 2.4 are all the same */
} else { /* actually found to be Visiomizer 6.2/Zagon */
unp->_depAdr = READ_LE_UINT16(&mem[p + 0x27]); // mem[p + 0x27] | mem[p + 0x28] << 8;
}
unp->_idFlag = 1;
return;
}
}
/* XTC 2.3 / 6codezipper */
if (unp->_depAdr == 0) {
if (u32eq(mem + 0x803, 0xB9018478) &&
u32eq(mem + 0x80b, 0xF7D0C8FF) &&
u32eq(mem + 0x81b, 0x00FC9D08) &&
u32eq(mem + 0x85b, 0xD0D0FFE4)) {
unp->_depAdr = READ_LE_UINT16(&mem[0x823]); // mem[0x823] | mem[0x824] << 8;
unp->_forced = 0x803;
unp->_retAdr = READ_LE_UINT16(&mem[0x865]); // mem[0x865] | mem[0x866] << 8;
unp->_strMem = READ_LE_UINT16(&mem[0x850]); // mem[0x850] | mem[0x851] << 8;
unp->_endAdC = 0xffff | EA_USE_Y;
unp->_fEndAf = 0x128;
unp->_idFlag = 1;
return;
}
}
/* XTC 2.3 / G*P, probably by Rockstar */
if (unp->_depAdr == 0) {
if ((u32eq(mem + 0x803, 0xB901e678) ||
u32eq(mem + 0x803, 0xB9018478)) &&
u32eq(mem + 0x80b, 0xF7D0C8FF) &&
u32eq(mem + 0x81b, 0x00F59D08) &&
u32eq(mem + 0x85b, 0xD0D0F8E4)) {
unp->_depAdr = READ_LE_UINT16(&mem[0x823]); // mem[0x823] | mem[0x824] << 8;
unp->_forced = 0x803;
unp->_retAdr = READ_LE_UINT16(&mem[0x865]); // mem[0x865] | mem[0x866] << 8;
unp->_strMem = READ_LE_UINT16(&mem[0x850]); // mem[0x850] | mem[0x851] << 8;
unp->_endAdC = 0xffff | EA_USE_Y;
unp->_fEndAf = 0x121;
unp->_idFlag = 1;
return;
}
}
/* XTC packer 2.x? found in G*P/NEI/Armageddon warez
just some different byte on copy loop, else is equal to 2.3
*/
if (unp->_depAdr == 0) {
for (p = 0x801; p < 0x80c; p += 0x0a) {
if (u32eqmasked(mem + p + 0x00, 0xffff0000, 0xE6780000) &&
u32eqmasked(mem + p + 0x05, 0xffff00ff, 0xB90800CE) &&
u32eq(mem + p + 0x0b, 0xC8000099) &&
u32eq(mem + p + 0x1e, 0x4CF7D0CA)) {
/* has variable codebytes so addresses varies */
for (q = p + 0x36; q < p + 0x60; q += 4) {
if (mem[q] == 0xc9)
continue;
if (mem[q] == 0x99) {
unp->_depAdr = 0x100;
break;
}
break; /* unexpected byte, get out */
}
break;
}
}
if (unp->_depAdr) {
unp->_retAdr = READ_LE_UINT16(&mem[q + 0x16]); // mem[q + 0x16] | mem[q + 0x17] << 8;
unp->_forced = p + 2;
unp->_fEndAf = READ_LE_UINT16(&mem[q + 0x7]); // mem[q + 0x7] | mem[q + 0x8] << 8;
unp->_fEndAf--;
unp->_endAdC = 0xffff | EA_USE_Y;
unp->_strMem = READ_LE_UINT16(&mem[q + 1]); // mem[q + 1] | mem[q + 2] << 8;
unp->_idFlag = 1;
return;
}
}
}
} // End of namespace Scott
} // End of namespace Glk