void ScummEngine_v70he::o70_writeINI() { int type, value; byte option[256], string[256]; int len; type = pop(); value = pop(); convertMessageToString(_scriptPointer, option, sizeof(option)); len = resStrLen(_scriptPointer); _scriptPointer += len + 1; switch (type) { case 1: // number ConfMan.setInt((char *)option, value); debug(1, "o70_writeINI: Option %s Value %d", option, value); break; case 2: // string convertMessageToString(_scriptPointer, string, sizeof(string)); len = resStrLen(_scriptPointer); _scriptPointer += len + 1; ConfMan.set((char *)option, (char *)string); debug(1, "o70_writeINI: Option %s String %s", option, string); break; default: error("o70_writeINI: default type %d", type); } }
void ScummEngine_v71he::o71_concatString() { int dst, size; int src2 = pop(); int src1 = pop(); size = resStrLen(getStringAddress(src1)); size += resStrLen(getStringAddress(src2)) + 1; dst = setupStringArray(size); appendSubstring(dst, src1, 0, -1); appendSubstring(dst, src2, 0, -1); push(dst); }
Common::String ScummEngine_v60he::convertSavePathOld(const byte *src) { // This is provided solely for loading older saved games. // No new saves should go through this function. int srcSize = resStrLen(src); // Old hacky target name insertion // (This breaks the soccer and football games) if (src[srcSize - 3] == 's' && src[srcSize - 2] == 'g') return _targetName + ".sg" + (char)src[srcSize - 1]; if (src[0] == 'u' && src[1] == 's') { // Save Game Path (Moonbase Commander) // The default save path is 'user/' return (const char *)src + 5; } else if (src[0] == '*' && (src[1] == '\\' || src[1] == ':')) { // Save Game Path (HE72 - HE100) // The default save game path is set to '*\\' by ScummVM for Windows // and '*:' for Macintosh return (const char *)src + 2; } else if (src[0] == 'c' && src[1] == ':') { // The default save path is game path (DOS) or 'c:\\hegames\\' (Windows) for (int i = srcSize; i > 0; i--) if (src[i] == '\\') return (const char *)src + i + 1; } // Can't reach here return ""; }
void ScummEngine_v70he::o70_systemOps() { byte *src, string[256]; int id, len; byte subOp = fetchScriptByte(); switch (subOp) { case 158: restart(); break; case 160: // Confirm shutdown quitGame(); break; case 244: quitGame(); break; case 250: id = pop(); src = getStringAddress(id); len = resStrLen(src) + 1; memcpy(string, src, len); debug(0, "Start executable (%s)", string); break; case 251: convertMessageToString(_scriptPointer, string, sizeof(string)); len = resStrLen(_scriptPointer); _scriptPointer += len + 1; debug(0, "Start executable (%s)", string); break; case 252: convertMessageToString(_scriptPointer, string, sizeof(string)); len = resStrLen(_scriptPointer); _scriptPointer += len + 1; debug(0, "Start game (%s)", string); break; case 253: id = pop(); src = getStringAddress(id); len = resStrLen(src) + 1; memcpy(string, src, len); debug(0, "Start game (%s)", string); break; default: error("o70_systemOps invalid case %d", subOp); } }
int ScummEngine_v60he::convertFilePath(byte *dst, int dstSize) { debug(1, "convertFilePath: original filePath is %s", dst); int len = resStrLen(dst); if (_game.platform == Common::kPlatformMacintosh) { // Remove : prefix in HE71 games if (dst[0] == ':') { len -= 1; memmove(dst, dst + 1, len); dst[len] = 0; } // Switch all : to / for portablity for (int i = 0; i < len; i++) { if (dst[i] == ':') dst[i] = '/'; } } else { // Switch all \ to / for portablity for (int i = 0; i < len; i++) { if (dst[i] == '\\') dst[i] = '/'; } } // Strip path int r = 0; if (dst[len - 3] == 's' && dst[len - 2] == 'g') { // Save Game File // Change filename prefix to target name, for save game files. const char c = dst[len - 1]; snprintf((char *)dst, dstSize, "%s.sg%c", _targetName.c_str(), c); } else if (dst[0] == '.' && dst[1] == '/') { // Game Data Path // The default game data path is set to './' by ScummVM r = 2; } else if (dst[2] == 'b' && dst[5] == 'k') { // Backyard Basketball INI r = 13; } else if (dst[0] == '*' && dst[1] == '/') { // Save Game Path (Windows HE72 - HE100) // The default save game path is set to '*/' by ScummVM r = 2; } else if (dst[0] == '*' && dst[1] == ':') { // Save Game Path (Macintosh HE72 - HE100) // The default save game path is set to ':/' by ScummVM r = 2; } else if (dst[0] == 'c' && dst[1] == ':') { // Save Game Path (HE60 - HE71) // The default save path is game path (DOS) or 'c:/hegames/' (Windows) for (r = len; r != 0; r--) { if (dst[r - 1] == '/') break; } } else if (dst[0] == 'u' && dst[1] == 's') { // Save Game Path (Moonbase Commander) // The default save path is 'user/' r = 5; } debug(1, "convertFilePath: converted filePath is %s", dst + r); return r; }
void ScummEngine_v70he::o70_createDirectory() { int len; byte directoryName[100]; convertMessageToString(_scriptPointer, directoryName, sizeof(directoryName)); len = resStrLen(_scriptPointer); _scriptPointer += len + 1; debug(1,"stub o70_createDirectory(%s)", directoryName); }
void ScummEngine_v71he::o71_copyString() { int dst, size; int src = pop(); size = resStrLen(getStringAddress(src)) + 1; dst = setupStringArray(size); appendSubstring(dst, src, -1, -1); push(dst); }
void ScummEngine_v70he::o70_getStringLen() { int id, len; byte *addr; id = pop(); addr = getStringAddress(id); if (!addr) error("o70_getStringLen: Reference to zeroed array pointer (%d)", id); len = resStrLen(getStringAddress(id)); push(len); }
void ScummEngine_v70he::o70_readINI() { byte option[256]; byte *data; const char *entry; int len, type; convertMessageToString(_scriptPointer, option, sizeof(option)); len = resStrLen(_scriptPointer); _scriptPointer += len + 1; type = pop(); switch (type) { case 1: // number if (!strcmp((char *)option, "NoPrinting")) { push(1); } else if (!strcmp((char *)option, "TextOn")) { push(ConfMan.getBool("subtitles")); } else { push(ConfMan.getInt((char *)option)); } break; case 2: // string entry = (ConfMan.get((char *)option).c_str()); writeVar(0, 0); len = resStrLen((const byte *)entry); data = defineArray(0, kStringArray, 0, len); memcpy(data, entry, len); push(readVar(0)); break; default: error("o70_readINI: default type %d", type); } debug(1, "o70_readINI: Option %s", option); }
void ScummEngine_v71he::appendSubstring(int dst, int src, int srcOffs, int len) { int dstOffs, value; int i = 0; if (len == -1) { len = resStrLen(getStringAddress(src)); srcOffs = 0; } dstOffs = resStrLen(getStringAddress(dst)); len -= srcOffs; len++; while (i < len) { writeVar(0, src); value = readArray(0, 0, srcOffs + i); writeVar(0, dst); writeArray(0, 0, dstOffs + i, value); i++; } writeArray(0, 0, dstOffs + i, 0); }
Common::String ScummEngine_v60he::convertFilePath(const byte *src) { debug(2, "convertFilePath in: '%s'", (const char *)src); int srcSize = resStrLen(src); int start = 0; if (srcSize > 2) { if (src[0] == ':') { // Game Data Path (Macintosh) // The default game data path is set to ':' by ScummVM start = 1; } else if (src[0] == '.' && src[1] == '\\') { // Game Data Path (Windows) // The default game data path is set to '.\\' by ScummVM start = 2; } else if (src[0] == '*' && src[1] == '\\') { // Save Game Path (Windows HE72 - HE100) // The default save game path is set to '*\\' by ScummVM start = 2; } else if (src[0] == '*' && src[1] == ':') { // Save Game Path (Macintosh HE72 - HE100) // The default save game path is set to '*:' by ScummVM start = 2; } else if (src[0] == 'c' && src[1] == ':') { // Save Game Path (HE60 - HE71) // The default save path is game path (DOS) or 'c:\\hegames\\' (Windows) for (start = srcSize; start != 0; start--) if (src[start - 1] == '\\') break; } else if (src[0] == 'u' && src[1] == 's') { // Save Game Path (Moonbase Commander) // The default save path is 'user\\' start = 5; } } Common::String dst; for (int i = start; i < srcSize; i++) { // Convert path separators if (src[i] == '\\' || src[i] == ':') dst += '/'; else dst += src[i]; } // Sanity check if (dst.lastChar() == '/') dst.deleteLastChar(); debug(2, "convertFilePath out: '%s'", dst.c_str()); return dst; }
void ScummEngine_v71he::o71_getCharIndexInString() { int array, end, len, pos, value; value = pop(); end = pop(); pos = pop(); array = pop(); if (end >= 0) { len = resStrLen(getStringAddress(array)); if (len < end) end = len; } else { end = 0; } if (pos < 0) pos = 0; writeVar(0, array); if (end > pos) { while (end >= pos) { if (readArray(0, 0, pos) == value) { push(pos); return; } pos++; } } else { while (end <= pos) { if (readArray(0, 0, pos) == value) { push(pos); return; } pos--; } } push(-1); }
void ScummEngine_v70he::o70_setSystemMessage() { int len; byte name[255]; byte subOp = fetchScriptByte(); convertMessageToString(_scriptPointer, name, sizeof(name)); len = resStrLen(_scriptPointer); _scriptPointer += len + 1; switch (subOp) { case 240: debug(1,"o70_setSystemMessage: (%d) %s", subOp, name); break; case 241: // Set Version debug(1,"o70_setSystemMessage: (%d) %s", subOp, name); break; case 242: debug(1,"o70_setSystemMessage: (%d) %s", subOp, name); break; case 243: // Set Window Caption // TODO: The 'name' string can contain non-ASCII data. This can lead to // problems, because (a) the encoding used for "name" is not clear, // (b) OSystem::setWindowCaption only supports ASCII. As a result, odd // behavior can occur, from strange wrong titles, up to crashes (happens // under Mac OS X). // // Possible fixes/workarounds: // - Simply stop using this. It's a rather unimportant "feature" anyway. // - Try to translate the text to ASCII. // - Refine OSystem to accept window captions that are non-ASCII, e.g. // by enhancing all backends to deal with UTF-8 data. Of course, then // one still would have to convert 'name' to the correct encoding. //_system->setWindowCaption((const char *)name); break; default: error("o70_setSystemMessage: default case %d", subOp); } }
void ScummEngine_v71he::o71_getStringLenForWidth() { int chr, max; int array, len, pos, width = 0; max = pop(); pos = pop(); array = pop(); len = resStrLen(getStringAddress(array)); writeVar(0, array); while (pos <= len) { chr = readArray(0, 0, pos); width += getStringCharWidth(chr); if (width >= max) { push(pos); return; } pos++; } push(len); }
void ScummEngine_v71he::o71_getStringWidth() { int array, pos, len; int chr, width = 0; len = pop(); pos = pop(); array = pop(); if (len == -1) { pos = 0; len = resStrLen(getStringAddress(array)); } writeVar(0, array); while (pos <= len) { chr = readArray(0, 0, pos); if (chr == 0) break; width += getStringCharWidth(chr); pos++; } push(width); }
void ScummEngine_v60he::o60_roomOps() { int a, b, c, d, e; byte subOp = fetchScriptByte(); switch (subOp) { case 172: // SO_ROOM_SCROLL b = pop(); a = pop(); if (a < (_screenWidth / 2)) a = (_screenWidth / 2); if (b < (_screenWidth / 2)) b = (_screenWidth / 2); if (a > _roomWidth - (_screenWidth / 2)) a = _roomWidth - (_screenWidth / 2); if (b > _roomWidth - (_screenWidth / 2)) b = _roomWidth - (_screenWidth / 2); VAR(VAR_CAMERA_MIN_X) = a; VAR(VAR_CAMERA_MAX_X) = b; break; case 174: // SO_ROOM_SCREEN b = pop(); a = pop(); if (_game.heversion >= 71) initScreens(a, _screenHeight); else initScreens(a, b); break; case 175: // SO_ROOM_PALETTE d = pop(); c = pop(); b = pop(); a = pop(); setPalColor(d, a, b, c); break; case 176: // SO_ROOM_SHAKE_ON setShake(1); break; case 177: // SO_ROOM_SHAKE_OFF setShake(0); break; case 179: // SO_ROOM_INTENSITY c = pop(); b = pop(); a = pop(); darkenPalette(a, a, a, b, c); break; case 180: // SO_ROOM_SAVEGAME _saveTemporaryState = true; _saveLoadSlot = pop(); _saveLoadFlag = pop(); break; case 181: // SO_ROOM_FADE a = pop(); if (_game.heversion >= 70) { // Defaults to 1 but doesn't use fade effects } else if (a) { _switchRoomEffect = (byte)(a & 0xFF); _switchRoomEffect2 = (byte)(a >> 8); } else { fadeIn(_newEffect); } break; case 182: // SO_RGB_ROOM_INTENSITY e = pop(); d = pop(); c = pop(); b = pop(); a = pop(); darkenPalette(a, b, c, d, e); break; case 183: // SO_ROOM_SHADOW e = pop(); d = pop(); c = pop(); b = pop(); a = pop(); if (_game.heversion == 60) setShadowPalette(a, b, c, d, e, 0, 256); break; case 186: // SO_ROOM_TRANSFORM d = pop(); c = pop(); b = pop(); a = pop(); palManipulateInit(a, b, c, d); break; case 187: // SO_CYCLE_SPEED b = pop(); a = pop(); assertRange(1, a, 16, "o60_roomOps: 187: color cycle"); _colorCycle[a - 1].delay = (b != 0) ? 0x4000 / (b * 0x4C) : 0; break; case 213: // SO_ROOM_NEW_PALETTE a = pop(); setCurrentPalette(a); break; case 220: a = pop(); b = pop(); copyPalColor(a, b); break; case 221: byte buffer[100]; int len, r; convertMessageToString(_scriptPointer, buffer, sizeof(buffer)); len = resStrLen(_scriptPointer); _scriptPointer += len + 1; r = convertFilePath(buffer, sizeof(buffer)); memcpy(_saveLoadFileName, buffer + r, sizeof(buffer) - r); debug(1, "o60_roomOps: case 221: filename %s", _saveLoadFileName); _saveLoadFlag = pop(); _saveLoadSlot = 255; _saveTemporaryState = true; break; case 234: // HE 7.1 b = pop(); a = pop(); swapObjects(a, b); break; case 236: // HE 7.1 b = pop(); a = pop(); setRoomPalette(a, b); break; default: error("o60_roomOps: default case %d", subOp); }