[Scummvm-devel] Personal Nightmare portability

Max Horn max at quendi.de
Wed Jul 15 01:13:28 CEST 2009


Hi again,

Looking at the PN code, it "simply" uses setjmp/longjmp to fake C++  
exceptions, more or less. I think it'll be possible to rewrite the  
code cleanly. The result wouldn't be beautiful, though.

Basically, the idea would be to replace the longjmp's by a global flag/ 
variable (well, in this case, a member var of AGOSEngine_PN) which is  
set when a longjmp is supposed to happen. Then, in a couple  
strategical places, this variable needs to be checked, causing various  
methods (primarily doaction and anything that calls it indirectly) to  
return prematurely when this flag is set. The central place to modify  
then will be doline(), where the setjmp() logic would be replaced by a  
suitable check for that global flag.

To illustrate this with some examples:

void AGOSEngine_PN::opn_opcode24() {
   popstack(kJmpClassNum);
   longjmp(*(_stackbase->savearea), 2);
   setScriptReturn(false);
}

would become this (note: _longJmpVal is not a good name, but serves  
for this example):

void AGOSEngine_PN::opn_opcode24() {
   popstack(kJmpClassNum);
   _longJmpVal = 2;
   setScriptReturn(false);
}

The only method that calls it is executeOpcode(), but that already  
returns immediately, so no need to change it. Next in line is  
doaction().  Since it basically returns right after calling  
executeOpcode(), we may be able to get away without modifying it,  
actually.

So which places call doaction()? Well, opn_opcode40 till 43 do -- for  
these, the doaction calls should be separateds; if _longJmpVal != 0  
after a doaction call, return immediately.

The only other place calling doaction is doline(). The easiest way to  
tweak it would be to check if _longJmpVal != right after the  
doaction() call; if it is, goto the line where we currently do a  
setjmp; replace x by _longJmpVal.

Granted, this is probably not enough; but I am fairly confident right  
now that a solution along these lines, with some refinements, will  
work. Of course I may have missed some big obstruction, the code is  
quite ... weird... :)


Cheers,
Max




More information about the Scummvm-devel mailing list