From: <js...@us...> - 2005-05-06 04:44:37
|
Update of /cvsroot/exult/exult/docs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22195 Added Files: Planets.txt Log Message: Marzo Torres' paper describing the Orrery --- NEW FILE: Planets.txt --- This paper was created by Marzo Sette Torres Junior, 2005-05-04. SUMMARY ------- Intrinsic function 0x6E1 sets the position of the planets in the orrery. Proposed name is UI_set_orrery_state. It accepts two parameters: one is the location of planet Britannia (up to 24 units of distance) and the other is the orrery state, ranging from 0 to 9. Thus, the function declaration is along the lines of "UI_set_orrery_state(pos, orrery_state)". UI_set_orrery_state has the following properties (obtained from the original game): 1) All duplicates of a planet that are at less than 15 units away are deleted (There Can Be Only One! planet); conversely, all planets 15 or more units away from planet Britannia are duplicated near it. 2) The moons and the sun are left alone wherever they are. 3) If planet Britannia is more than 24 units away from the place specified, an error occurs. In all other cases, all planets are placed in their correct relative positions relative to planet Britannia. I have compiled the offsets relative to planet Britannia of all normal values of the 2nd parameter (orrery_state); it is supplied in UCC form below. THE FULL EXPLANATION -------------------- In the original game, the position of the planets in the orrery (in Moonglow) was dependent on how close you were to completing the game; it actually was dependent on which flags on a given set were set to true, in a way that the planets would all be lined up at the very end. In Exult, this doesn't happen because the required intrinsic function is not implemented. The function that updates the orrery is function 0x63 (which I'll call UI_set_orrery_state), and is called by a single function in the entire BG usecode: function 0x6E1. It is obvious from the usecode that UI_set_orrery_state has two parameters: a 3D vector and an integer parameter. Function 0x6E1 (which I'll call Orrery_Egg) is called from two places: one is an egg, the other is the orrery viewer function 0x302 (which I'll call Orrery_Viewer). From the extracted usecode, one can see that Orrery_Viewer calls Orrery_Egg in calle form with item = 0 and event = 3 (= egg). In UCC terms, it is "event = 3; 0x0000->Orrery_Egg();" (there must be a "extern Orrery_Egg 0x6E1;" before the call). In Orrery_Egg, there is a check to see if item = 0; if it is, then it creates a position vector with the components [0x0B4C, 0x058C, 0x0000]. If item is not 0 (in which case it is the egg), Orrery_Egg calls UI_get_object_position(item). In both cases, the resulting vector is the same: the orrery egg is located at [0x0B4C, 0x058C, 0x0000], which is at the base of the "Britannia" planet in the orrery. This position vector is passed to UI_set_orrery_state. Since UI_set_orrery_state requires a position vector, it is only logical to assume that it sets the positions of the planets as offsets from this position. This is actually the case here: the UI_set_orrery_state function is expecting to find the planet Britannia (shape 765) at or near the specified position, and sets the position of all planets relative to planet Britannia. This was determined with hack mover (!) and the orrery viewer. What I was able to determine the properties stated above; for completness, here they are again: 1) All duplicates of a planet that are at less than 15 units away are deleted; conversely, all planets 15 or more units away from planet Britannia are duplicated near it. 2) The moons and the sun are left alone wherever they are. 3) If planet Britannia is more than 24 units away from the place specified, an error occurs. In all other cases, all planets are placed in their correct relative positions relative to planet Britannia. The other parameter of UI_set_orrery_state a number calculated from a set of flags of the game, and it ranges from 0 to 9 (the intrinsic *does* accept values higher than 9, but weird things happen... for example, passing a 10 = 0xA results in a configuration were all planets are in the wrong orbits). I will call this number orrery_state. Using rip/wud/wuc, I editted the usecode to see what were the effects of changing this parameter. For the curious, I changed the "pushf flag:XXXX" commands by "pushi 0001H" commands, one at a time and starting from the top. Since these two opcodes have the same byte length, I didn't have to change anything else. In all cases, I took screenshots (I can send to anyone interested; not that I suppose anyone will be, but the offer is here anyway :-)). For each of the screenshots, I went to Exult and tried to reproduce (with the aid of Exult Studio) the positions of the planets. The result is the table at the end of the file. The "frame" column indicates the planet, since they are all the same shape. The table supplies the absolute position of the planets, not their relative positions; but I am supplying here the offsets in UCC vector form: if (orrery_state == 0){ abs_pos_X = [ 2, 3, 1, 6, 7, 8, -4, 9]; abs_pos_Y = [-3, -3, -6, -2, -1, 1, 8, -2];} else if (orrery_state == 1) abs_pos_X = [ 3, 4, -5, 3, 7, 4, -8, 8]; abs_pos_Y = [-1, -1, -3, 6, 2, 7, 4, 5];} else if (orrery_state == 2) abs_pos_X = [3, 3, -3, -5, 2, -2, -9, 2]; abs_pos_Y = [1, 2, 4, 4, 7, 8, 1, 9];} else if (orrery_state == 3) abs_pos_X = [1, 1, 4, -5, -4, -7, -9, -4]; abs_pos_Y = [3, 4, 3, -3, 6, 4, -1, 9];} else if (orrery_state == 4) abs_pos_X = [-2, -2, 5, 5, -7, -8, -8, -8]; abs_pos_Y = [ 3, 4, -2, -4, 2, 1, -4, 6];} else if (orrery_state == 5) abs_pos_X = [-4, -5, -5, 6, -7, -7, -7, -10]; abs_pos_Y = [ 1, 1, -3, 3, -2, -4, -6, 1];} else if (orrery_state == 6) abs_pos_X = [-4, -5, -3, -3, -6, -5, -7, -10]; abs_pos_Y = [ 9, -1, 4, 6, -4, -6, -6, -2];} else if (orrery_state == 7) abs_pos_X = [-4, -4, 4, -6, -5, -3, -4, -8]; abs_pos_Y = [ 8, -3, 3, 1, -5, -7, -8, -6];} else if (orrery_state == 8) abs_pos_X = [-3, -3, -3, 6, -1, 0, -1, -5]; abs_pos_Y = [ 7, -4, -5, -2, -7, -8, -9, -9];} else if (orrery_state == 9) abs_pos_X = [0, 0, 1, 1, 1, 1, 1, -1]; abs_pos_Y = [6, -5, -6, -6, -7, -8, -9, -10];} I suppose it can be easily converted to C++ for UI_set_orrery_state. With the above arrays, a loop would suffice to set the position of all planets; for example, if orrery_state = 3, the [ X, Y ] offset for the planet with frame 4 (the fifth planet) would be [ abs_pos_X[5], abs_pos_Y[5] ] = [ -4, 6 ] (the index is [5] and not [4] because UCC arrays are 1-based). Here is the position table I obtained by the methods outlined above; planet Britannia was at its default position in all cases: |===============================================================================================| | orrery_state: 0 | orrery_state: 1 | orrery_state: 2 | orrery_state: 3 | |===============================================================================================| |FRAME X Y | X Y | X Y | X Y | |------------------------------------------------------------------------------------------------ | 0 2894 1417 | 2895 1419 | 2895 1421 | 2893 1423 | | 1 2895 1417 | 2896 1419 | 2895 1422 | 2893 1424 | | 2 2893 1414 | 2887 1417 | 2889 1424 | 2896 1423 | | 3 2898 1418 | 2895 1426 | 2887 1424 | 2887 1417 | | 4 2899 1419 | 2899 1422 | 2894 1427 | 2888 1426 | | 5 2900 1421 | 2896 1427 | 2890 1428 | 2885 1424 | | 6 2888 1428 | 2884 1424 | 2883 1421 | 2883 1419 | | 7 2901 1418 | 2900 1425 | 2894 1429 | 2888 1429 | |===============================================================================================| |===============================================================================================| | orrery_state: 4 | orrery_state: 5 | orrery_state: 6 | orrery_state: 7 | |=======================|=======================================================================| |FRAME X Y | X Y | X Y | X Y | |-----------------------|------------------------------------------------------------------------ | 0 2890 1423 | 2888 1421 | 2888 1419 | 2888 1418 | | 1 2890 1424 | 2887 1421 | 2887 1419 | 2888 1417 | | 2 2897 1418 | 2887 1417 | 2889 1424 | 2896 1423 | | 3 2897 1416 | 2898 1423 | 2889 1426 | 2886 1421 | | 4 2885 1422 | 2885 1418 | 2886 1416 | 2887 1415 | | 5 2884 1421 | 2885 1416 | 2887 1414 | 2889 1413 | | 6 2884 1416 | 2885 1414 | 2885 1414 | 2888 1412 | | 7 2884 1426 | 2882 1421 | 2882 1418 | 2884 1414 | |===============================================================================================| |===============================================| | orrery_state: 8 | orrery_state: 9 | |===============================================| |FRAME X Y | X Y | |-----------------------------------------------| | 0 2889 1417 | 2892 1416 | | 1 2889 1416 | 2892 1415 | | 2 2889 1415 | 2893 1414 | | 3 2898 1418 | 2893 1414 | | 4 2891 1413 | 2893 1413 | | 5 2892 1412 | 2893 1412 | | 6 2891 1411 | 2893 1411 | | 7 2887 1411 | 2891 1410 | |===============================================| |