aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/sci/engine/kernel.cpp5
-rw-r--r--engines/sci/engine/kernel32.cpp36
-rw-r--r--engines/sci/engine/kfile.cpp80
-rw-r--r--engines/sci/engine/kgraphics.cpp28
-rw-r--r--engines/sci/engine/kmenu.cpp2
-rw-r--r--engines/sci/engine/kmisc.cpp35
-rw-r--r--engines/sci/engine/kmovement.cpp75
-rw-r--r--engines/sci/engine/kscripts.cpp4
-rw-r--r--engines/sci/engine/ksound.cpp9
-rw-r--r--engines/sci/engine/kstring.cpp25
10 files changed, 165 insertions, 134 deletions
diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp
index 71bedd5ad9..c9b547e6f8 100644
--- a/engines/sci/engine/kernel.cpp
+++ b/engines/sci/engine/kernel.cpp
@@ -436,9 +436,8 @@ uint Kernel::getKernelNamesSize() const {
}
const Common::String &Kernel::getKernelName(uint number) const {
- // FIXME: The following check is a temporary workaround for
- // an issue leading to crashes when using the debugger's backtrace
- // command.
+ // FIXME: The following check is a temporary workaround for an issue
+ // leading to crashes when using the debugger's backtrace command.
if (number >= _kernelNames.size())
return _invalid;
return _kernelNames[number];
diff --git a/engines/sci/engine/kernel32.cpp b/engines/sci/engine/kernel32.cpp
index fb90cfb147..b317719252 100644
--- a/engines/sci/engine/kernel32.cpp
+++ b/engines/sci/engine/kernel32.cpp
@@ -378,12 +378,14 @@ void Kernel::setKernelNamesSci2() {
}
void Kernel::setKernelNamesSci21(GameFeatures *features) {
- // Some SCI games use a modified SCI2 kernel table instead of the SCI2.1/SCI3 kernel table.
- // The GK2 demo does this as well as at least one version of KQ7. We detect which version
- // to use based on where kDoSound is called from Sound::play().
+ // Some SCI games use a modified SCI2 kernel table instead of the
+ // SCI2.1/SCI3 kernel table. The GK2 demo does this as well as at
+ // least one version of KQ7. We detect which version to use based on
+ // where kDoSound is called from Sound::play().
- // This is interesting because they all have the same interpreter version (2.100.002), yet
- // they would not be compatible with other games of the same interpreter.
+ // This is interesting because they all have the same interpreter
+ // version (2.100.002), yet they would not be compatible with other
+ // games of the same interpreter.
if (features->detectSci21KernelType() == SCI_VERSION_2) {
_kernelNames = Common::StringArray(sci2_default_knames, kKernelEntriesGk2Demo);
@@ -399,7 +401,8 @@ void Kernel::setKernelNamesSci21(GameFeatures *features) {
// SCI2 Kernel Functions
reg_t kIsHiRes(EngineState *s, int argc, reg_t *argv) {
- // Returns 0 if the screen width or height is less than 640 or 400, respectively.
+ // Returns 0 if the screen width or height is less than 640 or 400,
+ // respectively.
if (g_system->getWidth() < 640 || g_system->getHeight() < 400)
return make_reg(0, 0);
@@ -606,8 +609,9 @@ reg_t kString(EngineState *s, int argc, reg_t *argv) {
if (string1->getSize() < index1 + count)
string1->setSize(index1 + count);
- // Note: We're accessing from c_str() here because the string's size ignores
- // the trailing 0 and therefore triggers an assert when doing string2[i + index2].
+ // Note: We're accessing from c_str() here because the
+ // string's size ignores the trailing 0 and therefore
+ // triggers an assert when doing string2[i + index2].
for (uint16 i = 0; i < count; i++)
string1->setValue(i + index1, string2[i + index2]);
}
@@ -793,8 +797,9 @@ reg_t kOnMe(EngineState *s, int argc, reg_t *argv) {
uint16 itemX = readSelectorValue(s->_segMan, targetObject, SELECTOR(x));
uint16 itemY = readSelectorValue(s->_segMan, targetObject, SELECTOR(y));
- // If top and left are negative, we need to adjust coordinates by the item's x and y
- // (e.g. happens in GK1, day 1, with detective Mosely's hotspot in his office)
+ // If top and left are negative, we need to adjust coordinates by
+ // the item's x and y (e.g. happens in GK1, day 1, with detective
+ // Mosely's hotspot in his office)
if (nsRect.left < 0)
nsRect.translate(itemX, 0);
@@ -802,8 +807,8 @@ reg_t kOnMe(EngineState *s, int argc, reg_t *argv) {
if (nsRect.top < 0)
nsRect.translate(0, itemY);
- // HACK: nsLeft and nsTop can be invalid, so try and fix them here using x and y
- // (e.g. with the inventory screen in GK1)
+ // HACK: nsLeft and nsTop can be invalid, so try and fix them here
+ // using x and y (e.g. with the inventory screen in GK1)
if (nsRect.left == itemY && nsRect.top == itemX) {
// Swap the values, as they're inversed (eh???)
nsRect.left = itemX;
@@ -821,8 +826,8 @@ reg_t kOnMe(EngineState *s, int argc, reg_t *argv) {
}
reg_t kIsOnMe(EngineState *s, int argc, reg_t *argv) {
- // Tests if the cursor is on the passed object, after adjusting the coordinates
- // of the object according to the object's plane
+ // Tests if the cursor is on the passed object, after adjusting the
+ // coordinates of the object according to the object's plane
uint16 x = argv[0].toUint16();
uint16 y = argv[1].toUint16();
@@ -848,7 +853,8 @@ reg_t kIsOnMe(EngineState *s, int argc, reg_t *argv) {
planeTop = (planeTop * g_sci->_gfxScreen->getHeight()) / planeResY;
planeLeft = (planeLeft * g_sci->_gfxScreen->getWidth()) / planeResX;
- // Adjust the bounding rectangle of the object by the object's actual X, Y coordinates
+ // Adjust the bounding rectangle of the object by the object's
+ // actual X, Y coordinates
itemY = ((itemY * g_sci->_gfxScreen->getHeight()) / planeResY);
itemX = ((itemX * g_sci->_gfxScreen->getWidth()) / planeResX);
itemY += planeTop;
diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp
index 1c0ff31ec1..f371e8a799 100644
--- a/engines/sci/engine/kfile.cpp
+++ b/engines/sci/engine/kfile.cpp
@@ -115,15 +115,17 @@ void file_open(EngineState *s, const char *filename, int mode) {
if (mode == _K_FILE_MODE_OPEN_OR_FAIL) {
// Try to open file, abort if not possible
inFile = saveFileMan->openForLoading(wrappedName);
- // If no matching savestate exists: fall back to reading from a regular file
+ // If no matching savestate exists: fall back to reading from a regular
+ // file
if (!inFile)
inFile = SearchMan.createReadStreamForMember(englishName);
- // Special case for LSL3: It tries to create a new dummy file, LARRY3.DRV
- // Apparently, if the file doesn't exist here, it should be created. The game
- // scripts then go ahead and fill its contents with data. It seems to be a similar
- // case as the dummy MEMORY.DRV file in LSL5, but LSL5 creates the file if it can't
- // find it with a separate call to file_open()
+ // Special case for LSL3: It tries to create a new dummy file,
+ // LARRY3.DRV. Apparently, if the file doesn't exist here, it should be
+ // created. The game scripts then go ahead and fill its contents with
+ // data. It seems to be a similar case as the dummy MEMORY.DRV file in
+ // LSL5, but LSL5 creates the file if it can't find it with a separate
+ // call to file_open().
if (!inFile && englishName == "LARRY3.DRV") {
outFile = saveFileMan->openForSaving(wrappedName);
outFile->finalize();
@@ -144,10 +146,11 @@ void file_open(EngineState *s, const char *filename, int mode) {
outFile = saveFileMan->openForSaving(wrappedName);
if (!outFile)
warning("file_open(_K_FILE_MODE_CREATE) failed to create file '%s'", englishName.c_str());
- // QfG1 opens the character export file with _K_FILE_MODE_CREATE first, closes it immediately and opens it again
- // with this here
- // Perhaps other games use this for read access as well
- // I guess changing this whole code into using virtual files and writing them after close would be more appropriate
+ // QfG1 opens the character export file with _K_FILE_MODE_CREATE first,
+ // closes it immediately and opens it again with this here. Perhaps
+ // other games use this for read access as well. I guess changing this
+ // whole code into using virtual files and writing them after close
+ // would be more appropriate.
} else {
error("file_open: unsupported mode %d (filename '%s')", mode, englishName.c_str());
}
@@ -163,7 +166,8 @@ void file_open(EngineState *s, const char *filename, int mode) {
while ((handle < s->_fileHandles.size()) && s->_fileHandles[handle].isOpen())
handle++;
- if (handle == s->_fileHandles.size()) { // Hit size limit => Allocate more space
+ if (handle == s->_fileHandles.size()) {
+ // Hit size limit => Allocate more space
s->_fileHandles.resize(s->_fileHandles.size() + 1);
}
@@ -274,7 +278,8 @@ void listSavegames(Common::Array<SavegameDesc> &saves) {
SavegameDesc desc;
desc.id = strtol(filename.end() - 3, NULL, 10);
desc.date = meta.savegame_date;
- // We need to fix date in here, because we save DDMMYYYY instead of YYYYMMDD, so sorting wouldnt work
+ // We need to fix date in here, because we save DDMMYYYY instead of
+ // YYYYMMDD, so sorting wouldn't work
desc.date = ((desc.date & 0xFFFF) << 16) | ((desc.date & 0xFF0000) >> 8) | ((desc.date & 0xFF000000) >> 24);
desc.time = meta.savegame_time;
desc.version = meta.savegame_version;
@@ -429,9 +434,9 @@ reg_t kCheckFreeSpace(EngineState *s, int argc, reg_t *argv) {
Common::String path = s->_segMan->getString(argv[0]);
debug(3, "kCheckFreeSpace(%s)", path.c_str());
- // We simply always pretend that there is enough space.
- // The alternative would be to write a big test file, which is not nice
- // on systems where doing so is very slow.
+ // We simply always pretend that there is enough space. The alternative
+ // would be to write a big test file, which is not nice on systems where
+ // doing so is very slow.
return make_reg(0, 1);
}
@@ -641,7 +646,8 @@ reg_t DirSeeker::firstFile(const Common::String &mask, reg_t buffer, SegManager
Common::SaveFileManager *saveFileMan = g_engine->getSaveFileManager();
_savefiles = saveFileMan->listSavefiles(wrappedMask);
- // Reset the list iterator and write the first match to the output buffer, if any.
+ // Reset the list iterator and write the first match to the output buffer,
+ // if any.
_iter = _savefiles.begin();
return nextFile(segMan);
}
@@ -671,7 +677,8 @@ reg_t kFileIO(EngineState *s, int argc, reg_t *argv) {
case K_FILEIO_OPEN : {
Common::String name = s->_segMan->getString(argv[1]);
- // SCI32 can call K_FILEIO_OPEN with only two arguments. It seems to just be checking if it exists.
+ // SCI32 can call K_FILEIO_OPEN with only two arguments. It seems to
+ // just be checking if it exists.
int mode = (argc < 3) ? (int)_K_FILE_MODE_OPEN_OR_FAIL : argv[2].toUint16();
// SQ4 floppy prepends /\ to the filenames
@@ -680,10 +687,10 @@ reg_t kFileIO(EngineState *s, int argc, reg_t *argv) {
name.deleteChar(0);
}
- // SQ4 floppy attempts to update the savegame index file sq4sg.dir
- // when deleting saved games. We don't use an index file for saving
- // or loading, so just stop the game from modifying the file here
- // in order to avoid having it saved in the ScummVM save directory
+ // SQ4 floppy attempts to update the savegame index file sq4sg.dir when
+ // deleting saved games. We don't use an index file for saving or
+ // loading, so just stop the game from modifying the file here in order
+ // to avoid having it saved in the ScummVM save directory.
if (name == "sq4sg.dir") {
debugC(2, kDebugLevelFile, "Not opening unused file sq4sg.dir");
return SIGNAL_REG;
@@ -744,11 +751,13 @@ reg_t kFileIO(EngineState *s, int argc, reg_t *argv) {
name.deleteChar(0);
}
- // Special case for SQ4 floppy: This game has hardcoded names for all of its
- // savegames, and they are all named "sq4sg.xxx", where xxx is the slot. We just
- // take the slot number here, and delete the appropriate save game
+ // Special case for SQ4 floppy: This game has hardcoded names for all of
+ // its savegames, and they are all named "sq4sg.xxx", where xxx is the
+ // slot. We just take the slot number here, and delete the appropriate
+ // save game.
if (name.hasPrefix("sq4sg.")) {
- // Special handling for SQ4... get the slot number and construct the save game name
+ // Special handling for SQ4... get the slot number and construct the
+ // save game name.
int slotNum = atoi(name.c_str() + name.size() - 3);
Common::Array<SavegameDesc> saves;
listSavegames(saves);
@@ -848,14 +857,17 @@ reg_t kFileIO(EngineState *s, int argc, reg_t *argv) {
delete inFile;
}
- // Special case for non-English versions of LSL5: The English version of LSL5 calls
- // kFileIO(), case K_FILEIO_OPEN for reading to check if memory.drv exists (which is
- // where the game's password is stored). If it's not found, it calls kFileIO() again,
- // case K_FILEIO_OPEN for writing and creates a new file. Non-English versions call
- // kFileIO(), case K_FILEIO_FILE_EXISTS instead, and fail if memory.drv can't be found.
- // We create a default memory.drv file with no password, so that the game can continue
+ // Special case for non-English versions of LSL5: The English version of
+ // LSL5 calls kFileIO(), case K_FILEIO_OPEN for reading to check if
+ // memory.drv exists (which is where the game's password is stored). If
+ // it's not found, it calls kFileIO() again, case K_FILEIO_OPEN for
+ // writing and creates a new file. Non-English versions call kFileIO(),
+ // case K_FILEIO_FILE_EXISTS instead, and fail if memory.drv can't be
+ // found. We create a default memory.drv file with no password, so that
+ // the game can continue.
if (!exists && name == "memory.drv") {
- // Create a new file, and write the bytes for the empty password string inside
+ // Create a new file, and write the bytes for the empty password
+ // string inside
byte defaultContent[] = { 0xE9, 0xE9, 0xEB, 0xE1, 0x0D, 0x0A, 0x31, 0x30, 0x30, 0x30 };
Common::WriteStream *outFile = saveFileMan->openForSaving(wrappedName);
for (int i = 0; i < 10; i++)
@@ -872,8 +884,8 @@ reg_t kFileIO(EngineState *s, int argc, reg_t *argv) {
Common::String oldName = s->_segMan->getString(argv[1]);
Common::String newName = s->_segMan->getString(argv[2]);
- // SCI1.1 returns 0 on success and a DOS error code on fail. SCI32 returns -1 on fail.
- // We just return -1 for all versions.
+ // SCI1.1 returns 0 on success and a DOS error code on fail. SCI32
+ // returns -1 on fail. We just return -1 for all versions.
if (g_engine->getSaveFileManager()->renameSavefile(oldName, newName))
return NULL_REG;
else
diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp
index 2ee30f1771..4614ee878a 100644
--- a/engines/sci/engine/kgraphics.cpp
+++ b/engines/sci/engine/kgraphics.cpp
@@ -1325,11 +1325,12 @@ reg_t kPlayVMD(EngineState *s, int argc, reg_t *argv) {
// bit 7 unknown
// bit 8 stretch
- // gammaBoost boosts palette colors in the range gammaFirst to gammaLast, but
- // only if bit 4 in flags is set. Percent value such that 0% = no amplification
- // These three parameters are optional if bit 4 is clear.
- // Also note that the x, y parameters play subtle games if used with subfx 21.
- // The subtleness has to do with creation of temporary planes and positioning relative to such planes.
+ // gammaBoost boosts palette colors in the range gammaFirst to
+ // gammaLast, but only if bit 4 in flags is set. Percent value such that
+ // 0% = no amplification These three parameters are optional if bit 4 is
+ // clear. Also note that the x, y parameters play subtle games if used
+ // with subfx 21. The subtleness has to do with creation of temporary
+ // planes and positioning relative to such planes.
int flags = argv[3].offset;
Common::String flagspec;
@@ -1392,20 +1393,21 @@ reg_t kPlayVMD(EngineState *s, int argc, reg_t *argv) {
#endif
reg_t kSetVideoMode(EngineState *s, int argc, reg_t *argv) {
- // This call is used for KQ6's intro. It has one parameter, which is
- // 1 when the intro begins, and 0 when it ends. It is suspected that
- // this is actually a flag to enable video planar memory access, as
- // the video decoder in KQ6 is specifically written for the planar
- // memory model. Planar memory mode access was used for VGA "Mode X"
- // (320x240 resolution, although the intro in KQ6 is 320x200).
+ // This call is used for KQ6's intro. It has one parameter, which is 1 when
+ // the intro begins, and 0 when it ends. It is suspected that this is
+ // actually a flag to enable video planar memory access, as the video
+ // decoder in KQ6 is specifically written for the planar memory model.
+ // Planar memory mode access was used for VGA "Mode X" (320x240 resolution,
+ // although the intro in KQ6 is 320x200).
// Refer to http://en.wikipedia.org/wiki/Mode_X
//warning("STUB: SetVideoMode %d", argv[0].toUint16());
return s->r_acc;
}
-// New calls for SCI11. Using those is only needed when using text-codes so that one is able to change
-// font and/or color multiple times during kDisplay and kDrawControl
+// New calls for SCI11. Using those is only needed when using text-codes so that
+// one is able to change font and/or color multiple times during kDisplay and
+// kDrawControl
reg_t kTextFonts(EngineState *s, int argc, reg_t *argv) {
g_sci->_gfxText16->kernelTextFonts(argc, argv);
return s->r_acc;
diff --git a/engines/sci/engine/kmenu.cpp b/engines/sci/engine/kmenu.cpp
index 13937c2f61..54543d783f 100644
--- a/engines/sci/engine/kmenu.cpp
+++ b/engines/sci/engine/kmenu.cpp
@@ -73,7 +73,7 @@ reg_t kDrawStatus(EngineState *s, int argc, reg_t *argv) {
int16 colorBack = (argc > 2) ? argv[2].toSint16() : g_sci->getResMan()->isVGA() ? 255 : 15;
if (!textReference.isNull()) {
- // Sometimes this is called without giving text, if thats the case dont process it
+ // Sometimes this is called without giving text, if thats the case dont process it.
text = s->_segMan->getString(textReference);
g_sci->_gfxMenu->kernelDrawStatus(g_sci->strSplit(text.c_str(), NULL).c_str(), colorPen, colorBack);
diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp
index 525f9f5bf4..64da511ca8 100644
--- a/engines/sci/engine/kmisc.cpp
+++ b/engines/sci/engine/kmisc.cpp
@@ -55,20 +55,22 @@ reg_t kGameIsRestarting(EngineState *s, int argc, reg_t *argv) {
uint32 neededSleep = 30;
- // WORKAROUND:
- // LSL3 calculates a machinespeed variable during game startup (right after the filthy questions)
- // This one would go through w/o throttling resulting in having to do 1000 pushups or something
- // Another way of handling this would be delaying incrementing of "machineSpeed" selector
+ // WORKAROUND: LSL3 calculates a machinespeed variable during game startup
+ // (right after the filthy questions). This one would go through w/o
+ // throttling resulting in having to do 1000 pushups or something. Another
+ // way of handling this would be delaying incrementing of "machineSpeed"
+ // selector.
if (g_sci->getGameId() == "lsl3" && s->currentRoomNumber() == 290)
s->_throttleTrigger = true;
- if (g_sci->getGameId() == "iceman" && s->currentRoomNumber() == 27) {
+ else if (g_sci->getGameId() == "iceman" && s->currentRoomNumber() == 27) {
s->_throttleTrigger = true;
neededSleep = 60;
}
if (s->_throttleTrigger) {
- // Some games seem to get the duration of main loop initially and then switch of animations for the whole game
- // based on that (qfg2, iceman). We are now running full speed initially to avoid that.
+ // Some games seem to get the duration of main loop initially and then
+ // switch of animations for the whole game based on that (qfg2, iceman).
+ // We are now running full speed initially to avoid that.
// It seems like we dont need to do that anymore
//if (s->_throttleCounter < 50) {
// s->_throttleCounter++;
@@ -332,11 +334,12 @@ reg_t kPlatform(EngineState *s, int argc, reg_t *argv) {
bool isWindows = g_sci->getPlatform() == Common::kPlatformWindows;
if (argc == 0 && getSciVersion() < SCI_VERSION_2) {
- // This is called in KQ5CD with no parameters, where it seems to do some graphics
- // driver check. This kernel function didn't have subfunctions then. If 0 is
- // returned, the game functions normally, otherwise all the animations show up
- // like a slideshow (e.g. in the intro). So we return 0. However, the behavior
- // changed for kPlatform with no parameters in SCI32.
+ // This is called in KQ5CD with no parameters, where it seems to do some
+ // graphics driver check. This kernel function didn't have subfunctions
+ // then. If 0 is returned, the game functions normally, otherwise all
+ // the animations show up like a slideshow (e.g. in the intro). So we
+ // return 0. However, the behavior changed for kPlatform with no
+ // parameters in SCI32.
return NULL_REG;
}
@@ -375,10 +378,10 @@ reg_t kPlatform(EngineState *s, int argc, reg_t *argv) {
}
reg_t kEmpty(EngineState *s, int argc, reg_t *argv) {
- // Placeholder for empty kernel functions which are still called from the engine
- // scripts (like the empty kSetSynonyms function in SCI1.1). This differs from
- // dummy functions because it does nothing and never throws a warning when it's
- // called
+ // Placeholder for empty kernel functions which are still called from the
+ // engine scripts (like the empty kSetSynonyms function in SCI1.1). This
+ // differs from dummy functions because it does nothing and never throws a
+ // warning when it is called.
return s->r_acc;
}
diff --git a/engines/sci/engine/kmovement.cpp b/engines/sci/engine/kmovement.cpp
index b247275e8c..ccef3d862a 100644
--- a/engines/sci/engine/kmovement.cpp
+++ b/engines/sci/engine/kmovement.cpp
@@ -33,42 +33,43 @@
namespace Sci {
-/*
-Compute "velocity" vector (xStep,yStep)=(vx,vy) for a jump from (0,0) to (dx,dy), with gravity gy.
-The gravity is assumed to be non-negative.
-
-If this was ordinary continuous physics, we would compute the desired (floating point!)
-velocity vector (vx,vy) as follows, under the assumption that vx and vy are linearly correlated
-by some constant factor c, i.e. vy = c * vx:
- dx = t * vx
- dy = t * vy + gy * t^2 / 2
-=> dy = c * dx + gy * (dx/vx)^2 / 2
-=> |vx| = sqrt( gy * dx^2 / (2 * (dy - c * dx)) )
-Here, the sign of vx must be chosen equal to the sign of dx, obviously.
-
-Clearly, this square root only makes sense in our context if the denominator is positive,
-or equivalently, (dy - c * dx) must be positive. For simplicity and by symmetry
-along the x-axis, we assume dx to be positive for all computations, and only adjust for
-its sign in the end. Switching the sign of c appropriately, we set tmp := (dy + c * dx)
-and compute c so that this term becomes positive.
-
-Remark #1: If the jump is straight up, i.e. dx == 0, then we should not assume the above
-linear correlation vy = c * vx of the velocities (as vx will be 0, but vy shouldn't be,
-unless we drop).
-
-
-Remark #2: We are actually in a discrete setup. The motion is computed iteratively: each iteration,
-we add vx and vy to the position, then add gy to vy. So the real formula is the following
-(where t is ideally close to an int):
-
- dx = t * vx
- dy = t * vy + gy * t*(t-1) / 2
-
-But the solution resulting from that is a lot more complicated, so we use the above approximation instead.
-
-Still, what we compute in the end is of course not a real velocity anymore, but an integer approximation,
-used in an iterative stepping algorithm
-*/
+/**
+ * Compute "velocity" vector (xStep,yStep)=(vx,vy) for a jump from (0,0) to
+ * (dx,dy), with gravity constant gy. The gravity is assumed to be non-negative.
+ *
+ * If this was ordinary continuous physics, we would compute the desired
+ * (floating point!) velocity vector (vx,vy) as follows, under the assumption
+ * that vx and vy are linearly correlated by a constant c, i.e., vy = c * vx:
+ * dx = t * vx
+ * dy = t * vy + gy * t^2 / 2
+ * => dy = c * dx + gy * (dx/vx)^2 / 2
+ * => |vx| = sqrt( gy * dx^2 / (2 * (dy - c * dx)) )
+ * Here, the sign of vx must be chosen equal to the sign of dx, obviously.
+ *
+ * This square root only makes sense in our context if the denominator is
+ * positive, or equivalently, (dy - c * dx) must be positive. For simplicity
+ * and by symmetry along the x-axis, we assume dx to be positive for all
+ * computations, and only adjust for its sign in the end. Switching the sign of
+ * c appropriately, we set tmp := (dy + c * dx) and compute c so that this term
+ * becomes positive.
+ *
+ * Remark #1: If the jump is straight up, i.e. dx == 0, then we should not
+ * assume the above linear correlation vy = c * vx of the velocities (as vx
+ * will be 0, but vy shouldn't be, unless we drop down).
+ *
+ * Remark #2: We are actually in a discrete setup. The motion is computed
+ * iteratively: each iteration, we add vx and vy to the position, then add gy
+ * to vy. So the real formula is the following (where t ideally is close to an int):
+ *
+ * dx = t * vx
+ * dy = t * vy + gy * t*(t-1) / 2
+ *
+ * But the solution resulting from that is a lot more complicated, so we use
+ * the above approximation instead.
+ *
+ * Still, what we compute in the end is of course not a real velocity anymore,
+ * but an integer approximation, used in an iterative stepping algorithm.
+ */
reg_t kSetJump(EngineState *s, int argc, reg_t *argv) {
SegManager *segMan = s->_segMan;
// Input data
@@ -115,7 +116,7 @@ reg_t kSetJump(EngineState *s, int argc, reg_t *argv) {
//tmp = dx * 3 / 2; // ALMOST the resulting value, except for obvious rounding issues
// FIXME: Where is the 3 coming from? Maybe they hard/coded, by "accident", that usually gy=3 ?
- // Then this choice of will make t equal to roughly sqrt(dx)
+ // Then this choice of scalar will make t equal to roughly sqrt(dx)
}
}
// POST: c >= 1
diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp
index 5f552080e3..de8710bd83 100644
--- a/engines/sci/engine/kscripts.cpp
+++ b/engines/sci/engine/kscripts.cpp
@@ -234,8 +234,8 @@ reg_t kDisposeScript(EngineState *s, int argc, reg_t *argv) {
if (argc != 2) {
return s->r_acc;
} else {
- // This exists in the KQ5CD and GK1 interpreter. We know it is used when GK1 starts
- // up, before the Sierra logo.
+ // This exists in the KQ5CD and GK1 interpreter. We know it is used
+ // when GK1 starts up, before the Sierra logo.
warning("kDisposeScript called with 2 parameters, still untested");
return argv[1];
}
diff --git a/engines/sci/engine/ksound.cpp b/engines/sci/engine/ksound.cpp
index daff676a28..0d08cc2e06 100644
--- a/engines/sci/engine/ksound.cpp
+++ b/engines/sci/engine/ksound.cpp
@@ -110,8 +110,10 @@ reg_t kDoAudio(EngineState *s, int argc, reg_t *argv) {
number = argv[1].toUint16();
} else if (argc == 6 || argc == 8) {
module = argv[1].toUint16();
- number = ((argv[2].toUint16() & 0xff) << 24) | ((argv[3].toUint16() & 0xff) << 16) |
- ((argv[4].toUint16() & 0xff) << 8) | (argv[5].toUint16() & 0xff);
+ number = ((argv[2].toUint16() & 0xff) << 24) |
+ ((argv[3].toUint16() & 0xff) << 16) |
+ ((argv[4].toUint16() & 0xff) << 8) |
+ (argv[5].toUint16() & 0xff);
if (argc == 8)
warning("kDoAudio: Play called with SQ6 extra parameters");
} else {
@@ -180,7 +182,8 @@ reg_t kDoAudio(EngineState *s, int argc, reg_t *argv) {
warning("kDoAudio: Unhandled case %d, %d extra arguments passed", argv[0].toUint16(), argc - 1);
break;
case 12:
- // Seems to be audio sync, used in Pharkas, silenced warning cause of the spam it produces
+ // Seems to be audio sync, used in Pharkas. Silenced the warning due to
+ // the high level of spam it produces.
//warning("kDoAudio: Unhandled case %d, %d extra arguments passed", argv[0].toUint16(), argc - 1);
break;
case 13:
diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp
index 2681b612e9..5dd3910e3e 100644
--- a/engines/sci/engine/kstring.cpp
+++ b/engines/sci/engine/kstring.cpp
@@ -141,19 +141,22 @@ reg_t kReadNumber(EngineState *s, int argc, reg_t *argv) {
int16 result = 0;
if (*source == '$') {
- // hexadecimal input
+ // Hexadecimal input
result = (int16)strtol(source + 1, NULL, 16);
} else {
- // decimal input, we can not use strtol/atoi in here, because sierra used atoi BUT it was a non standard compliant
- // atoi, that didnt do clipping. In SQ4 we get the door code in here and that's even larger than uint32!
+ // Decimal input. We can not use strtol/atoi in here, because while
+ // Sierra used atoi, it was a non standard compliant atoi, that didn't
+ // do clipping. In SQ4 we get the door code in here and that's even
+ // larger than uint32!
if (*source == '-') {
result = -1;
source++;
}
while (*source) {
if ((*source < '0') || (*source > '9')) {
- // Sierras atoi stopped processing at anything different than number
- // Sometimes the input has a trailing space, that's fine (example: lsl3)
+ // Sierra's atoi stopped processing at anything which is not
+ // a digit. Sometimes the input has a trailing space, that's
+ // fine (example: lsl3)
if (*source != ' ') {
// TODO: this happens in lsl5 right in the intro -> we get '1' '3' 0xCD 0xCD 0xCD 0xCD 0xCD
// find out why this happens and fix it
@@ -423,15 +426,16 @@ reg_t kGetFarText(EngineState *s, int argc, reg_t *argv) {
seeker = (char *)textres->data;
- // The second parameter (counter) determines the number of the string inside the text
- // resource.
+ // The second parameter (counter) determines the number of the string
+ // inside the text resource.
while (counter--) {
while (*seeker++)
;
}
- // If the third argument is NULL, allocate memory for the destination. This occurs in
- // SCI1 Mac games. The memory will later be freed by the game's scripts.
+ // If the third argument is NULL, allocate memory for the destination. This
+ // occurs in SCI1 Mac games. The memory will later be freed by the game's
+ // scripts.
if (argv[2] == NULL_REG)
s->_segMan->allocDynmem(strlen(seeker) + 1, "Mac FarText", &argv[2]);
@@ -578,7 +582,8 @@ reg_t kStrSplit(EngineState *s, int argc, reg_t *argv) {
// Make sure target buffer is large enough
SegmentRef buf_r = s->_segMan->dereference(argv[0]);
if (!buf_r.isValid() || buf_r.maxSize < (int)str.size() + 1) {
- warning("StrSplit: buffer %04x:%04x invalid or too small to hold the following text of %i bytes: '%s'", PRINT_REG(argv[0]), str.size() + 1, str.c_str());
+ warning("StrSplit: buffer %04x:%04x invalid or too small to hold the following text of %i bytes: '%s'",
+ PRINT_REG(argv[0]), str.size() + 1, str.c_str());
return NULL_REG;
}
s->_segMan->strcpy(argv[0], str.c_str());