home *** CD-ROM | disk | FTP | other *** search
/ PC Gamer 3.10 / 1998-01_Disc_3.10.iso / PATCHES / fc_111a.zip / JIMTECH.TXT < prev    next >
Text File  |  1997-09-04  |  17KB  |  443 lines

  1. ;;------------------------------------------------------------------------------
  2. ;;Filename       jimtech.txt
  3. ;;System         
  4. ;;Author         JIM TAYLOR
  5. ;;Date           Wed 3 Sep 1997
  6. ;;Description    Technical programming information for Flying Corps
  7. ;;------------------------------------------------------------------------------
  8.  
  9.  
  10. This file describes programming information for the extra files
  11. provided with Flying corps gold. The following areas are covered:
  12.  
  13.     Keyboard input
  14.  
  15.     Analogue interface
  16.  
  17.     Config file
  18.  
  19.     Mission editor
  20.  
  21. Please understand that these programming details are extremely brief.
  22. Quite a bit of additional research will be required by a potential
  23. programmer. I don't know if anybody will ever actually look at this!
  24.  
  25. Keyboard input
  26. ==============
  27.  
  28. During the 3d sections, the keyboard is mapped into a bit lookup table.
  29. There is a 1 bit per keyboard scancode lookup which describes wether
  30. the key is currently pressed. In addition, each key and shift combination 
  31. can be associated with 2 bits in a larger table. See keytest.h.
  32.  
  33. When a key is pressed, both bits are set if the key is not already
  34. pressed. When the key is released, only 1 bit is cleared. Within the
  35. program, these bits are polled, and then the second bit is cleared.
  36.  
  37. In keymaps.h, the macro Keyname() defines equate names for each bit
  38. pair.
  39.  
  40. The mapping of scancodes and shiftkeys to these equates is now driven
  41. by the binary file FLY\keyboard\keyb3d.bin. By modifying this file, 
  42. the keyboard mapping of the program can be changed.
  43.  
  44. This file is generated by compiling the table KeyMapping in keymaps.h.
  45.  
  46. Note that while this system supports 8 shift states only 5 work in
  47. Windows95 (unshifted, shift, alt, ctrl, and 101key), the 3 RHS shift keys
  48. are only distinguishable to the DOS program.
  49.  
  50. Analogue interface
  51. ==================
  52.  
  53. Another method of getting input from the program is via the analogue
  54. interface. This is a set of DLLs which can be automatically loaded by
  55. the program at runtime via the savegame file.
  56.  
  57. As well as generating analogue axis inputs which will be recognised by
  58. the game, these routines can also emulate keyboard events and drive
  59. output effects for force feedback joysticks, for instance.
  60.  
  61. We wish to make this interface public so that new devices can be
  62. supported and further tuning of our interface can take place. 
  63.  
  64. Sources for the existing drivers has been included.
  65.  
  66. During calibration, the input routine is called once per screen
  67. refresh, perhaps 5 to 10 times a second. Once the 3d is running it is 
  68. called every 3 centiseconds. We found that the windows driver simply 
  69. stopped the computer if called 33 times a second, so the driver applys 
  70. a stepping down factor.
  71.  
  72. However, our DOS direct access driver runs far faster even under windows.
  73.  
  74. Data structure
  75. --------------
  76.  
  77. The data structures are in the header file analogue.h
  78.  
  79. There are 32 instances of Axis, and 8 instances of Device.
  80.  
  81. The enum AxisUses indexes the axis array.
  82. MAKEFIELD() produces a bitfield called AxisUsesField.
  83.  
  84. The instance of this in each Device indicates which axes the device
  85. will drive. Each device must own at least one axis which is polled by 
  86. the game.
  87.  
  88. Axis[]:
  89.  
  90. Note that this structure is 'future proofed' Flying Corps only uses 
  91. 7 of the axes for input, and FCG uses 11:
  92.     flight: elevator, aileron, rudder, throttle, cooliehat
  93.     front:    UI_X,UI_Y
  94.     views:    head hdg, pitch, roll; zoom
  95.  
  96.  
  97. Axes 28 to 31 are dummies for DLLs which don't actually generate axis 
  98. values. Devices owning one of these axes are always polled, but the 
  99. results are ignored. Instead, these axes are written to by the program 
  100. so that a force feedback device can respond to the effects.
  101.  
  102. The axis record contains a number of fields which are intended to hold
  103. the calibration information for that axis. It is up to the driver to
  104. make the position field contain a value between -32767, 0, and +32767.
  105. A disabled or ignored axis returns 32768. In addition, the Throttle is
  106. ignored for readings of +/-32767.
  107.  
  108. The signed values centre, min, and max are particularly useful, and I
  109. also use scale1 and scale2 as multiplication factors. The capitalised
  110. access functions Min(), Max(), etc. access the same word fields as
  111. absolute values.
  112.  
  113. When used to represent feedback, the access functions FB_Lx() are
  114. intended to represent linear effects, and the functions FB_Rx()
  115. represent rotational effects. When the value is actually changed by 
  116. the game, position will be set non-zero.
  117.  
  118. In addition, the Axis record contains indexes to the "rowan text
  119. system" for printing calibration messages, and the status field
  120. indicates any errors during calibration.
  121.  
  122. The equates for these texts are in text.h. A number of spares have been
  123. prepared starting at JOYSTIC_SPARE_2. Alternate text can be poked into
  124. the existing binary text files. See the english\text directory, and look for
  125. "DeviceNameSpare2DeviceNameSpare2" etcetera.
  126.  
  127. The first 8 entries from JOYSTICK_DEVICE_NAME to JOYSTIC_SPARE_6 are
  128. printed in the driver selection list, and map directly to the order of
  129. the files in the file libcode\dir.dir. All the spares after 6 are
  130. unassigned.
  131.  
  132. Device[]:
  133.  
  134. As well as the "activeaxes" field which lists which axes the device
  135. will update and the "rowan text system" device name, which is actually
  136. used to identify the curent driver on the calibration screen, a small ammount of
  137. workspace is provided in the LastButtons field.
  138.  
  139. The STUBLOADABLE and devfile are used to manage the loading of the
  140. driver, so should not be altered at runtime.
  141.  
  142. Code interface
  143. ==============
  144.  
  145. Initial loading of the driver code involves making a C++ virtual
  146. function table to access the Device member functions.
  147.  
  148. In MS-DOS this is done by the main program. It matches the routines
  149. listed in analpub.cpp and creates a new table. The exact order and size
  150. of this list in analpub is critical.
  151.  
  152. In Windows, the DEVICEHOOK() routine in the DLL provides this facility.
  153.  
  154. These two interfaces can be used simultaniously, and are: ANALJOY.BIN.
  155.  
  156. In both cases, a compilation datestamp is checked to ensure compatibility 
  157. between the main program and the DLL. This will have to be modified in
  158. the DLLs to match the date the main program was last compiled.
  159.  
  160. Unlike the traditional Windows COM, the main program owns the Device
  161. instances, and is able to store useful data in them.
  162.  
  163. In MS-DOS, the DLL has no access to any data or functions except those
  164. provided as parameters. Any further facilities required must be managed
  165. independently through the DPMI interrupt INT31. Any handles or pointers 
  166. can be held in the LastButtons field.
  167. The 5K low memory data area workspace is passed to all the functions 
  168. (except close()) for use as required. The contents are not guaranteed
  169. between calls, but the address is.
  170. In windows, the DLL has full access to all system functions and data areas
  171. as normal.
  172.  
  173. The following member functions are required:
  174.  
  175. Bool    Initialise(UByte*const workspace,Axis    axes[]);
  176.     -allows the DLL to set itself up.
  177.  
  178. Bool    LoadGame(UByte*const workspace,Axis    axes[]);
  179.     -called after the savegame record has been loaded
  180.  
  181. Bool    CloseDown(UByte*const workspace);
  182.     -called before the driver is removed from memory
  183.  
  184. void    PreCalib(UByte*const  workspace,Axis    axes[],axisconfigpages& pages);
  185.     -called on beginning to calibrate the joystick.
  186.         activeaxes has been filled in with required options.
  187.     The routine can initialise any axes it will be calibrating.
  188.     The routine fills in pages. This is a list of 4 axis indexes
  189.     per page displayed during configuration. 
  190.     The normal configuration processes 4 axes at once on 1 page,
  191.     but you can force the display to be repeated up to 5 times.
  192.     If no axes are nabled on the first page then configuration is
  193.     skipped. This can be done if you trust the standard windows joystick
  194.     configuration, or if your device returns fixed values anyway.
  195.  
  196. Bool    CalibCenter(UByte*const  workspace,Axis    axes[],const AxisUsesField& reqaxes);
  197. Bool    CalibExtreme(UByte*const  workspace,Axis    axes[],const AxisUsesField& reqaxes);
  198.     -These two routines are called continuously during the two
  199.     calibration phases.
  200.     For each axis flagged in reqaxis, the corresponding axes[].position 
  201.     should be filled in with estimates of the joystick position
  202.     in the range -32K to +32K.
  203.     Simultaniously, the values read should be used to calibrate the
  204.     joystick, and the status should be set to indicate the
  205.     progress.
  206.     When the phase is over they simply cease to be called, and
  207.     each axis's status field is checked. There is no "phase over" routine.
  208.     They can cause calibration to cease by setting their return code true,
  209.     indicating that a button on the stick was pressed.
  210.  
  211.  
  212. Bool    ReadPosition(UByte*const  workspace,Axis    axes[],const AxisUsesField& reqaxes,keytests* keyboard);
  213.     -This is the main joystick workhorse.
  214.     Position values should be provided for all the reqaxes, but
  215.     others can be filled in as well. Then, when these are requested
  216.     the routine would return quickly.
  217.             
  218.     The keyboard routine gives access to the keyboard class
  219.     instance, and pointers to routines to set and clear keys by
  220.     their rowan key indexes rather than the scancodes.
  221.  
  222.  
  223. Additionally, the following prototypes are provided as templates for
  224. writing your routines. You don't have to use them, but I'd advise it:
  225.  
  226. Bool    ReadHWPos(UByte*const  workspace,Axis    axes[],const AxisUsesField& reqaxes,ULong* newbuttons);
  227.     -gets raw values into the position fields
  228. Bool    ScaleHWPos(UByte*const  workspace,Axis    axes[],const AxisUsesField& reqaxes);
  229.     -converts the raw values into +/-32K
  230. Bool    ReadButtons(UByte*const  workspace,Axis    axes[],const AxisUsesField& reqaxes,ULong* newbuttons,keytests* keyboard);
  231.     -processes the buttons into key presses
  232.  
  233. Compiling
  234. ---------
  235.  
  236. I compile and link these programs using Watcom C++ ver 10.5. You are
  237. welcome to use whatever you like, but you may have problems with the
  238. optimisation of the analpub.cpp module which is used to interface with
  239. MS-DOS.
  240.  
  241. Compile the analpub fully optimised and it turns into a series of jmp
  242. statements. Compile the main code module with stack checking turned
  243. off. Link analpub, then the main module, then any libraries you need.
  244.  
  245. In MS-DOS only code between "ROWANLIB" markers will be loaded in. These
  246. markers are emitted into the code segment. See stub.m for more detail.
  247.  
  248. The binaries generated live in the LIBCODE directory. They are
  249. referenced by the DIR.DIR file in that directory. 
  250. This is the C type "char [][16];"
  251.  
  252. There is a lot more information in the various header files.
  253.  
  254. Config File
  255. ===========
  256.  
  257. The main config file is savegame\settings.cfg and savegame\winset.cfg
  258. for windows.
  259.  
  260. This file contains 3 elements:
  261.  
  262. 1) A zero terminated date string which is compared with the main
  263. executable's date
  264.  
  265. 2) The structure SaveData (savegame.h) which controls a wide number of
  266. effects
  267.  
  268. 3) The structure Analogue (analogue.h) which contains all 8 devices and
  269. all 32 axes.
  270.  
  271. In particular, the devices[] contain a word devfile field which identifies the
  272. DLL file to load. If zero that driver is not loaded, but if set to a
  273. certain value, this indicates the location of the DLL. 
  274. The upper byte identifies the directory by accessing the COMMON.DIR
  275. file. LIBCODE is directory 201. The lower byte indexes the DIR.DIR file
  276. inside the directory.
  277.  
  278. The displayed joystick is Devices[0]
  279. In MS-DOS the mouse input is drive by Devices[1]
  280. In windows the mouse input is handled by winmain.
  281.  
  282. By directly modifying the savegame file before running the program,
  283. additional drivers can be made to load.
  284.  
  285.  
  286. Mission Editor
  287. ==============
  288.  
  289. The mission editor provided with FCG is by no means comprehensive. If
  290. you should decide that you have nothing better to do for a few months,
  291. then you could try to do better.
  292.  
  293. The basic feature of the mission editor is that it generates a textfile
  294. which is then compiled by the utility MAKEBFW.EXE. However, it reads in
  295. the binary file generated by MAKEBF. There is only ever one user
  296. generated source file in the usersrc directory.
  297.  
  298. While the mission editor is unable to allow certain advanced features
  299. to be directly edited, these features should be preserved as a
  300. "complex" expression. These expressions are described in bfnumber.h.
  301. Note that while bfnumber is an internal representation of an expression
  302. the structure does not exactly mirror the binary files generated by
  303. MAKEBFW.
  304.  
  305. MAKEBFW.EXE actually reads bfields\initial.res and then attempts to 
  306. compile bfields\battle.src which contains the source for all the 
  307. battlefields for the original campaigns, but because 
  308. they are unchanged it then generates just one user battlefield.
  309.  
  310. The actual syntax is:
  311.  
  312.     MAKEBFW    bfields\initial.res bfields\battle.src
  313.  
  314. Optionally, "-M" stops uidvals.g from being generated (destroyed), OR "." 
  315. generates the file textfour.err in directory ".".
  316.  
  317. Textfour.err shows the internal tree structure built by MAKEBFW, and is over
  318. 14MB long. Generating it also quadrouples the duration of MAKEBFW.
  319.  
  320. The basic structure stored to disk is made up of command byte/child
  321. count byte pairs. The command bytes are listed in makebf.h.
  322.  
  323. The mission editor is able to communicate with the main game via the
  324. scratchpad. It can send "MED: directory file" or "MED: directory".
  325.  
  326. If the main program doesn't delete this message with a few seconds then
  327. it is launched again.
  328.  
  329. The mission editor also supports a command-line interface to decompile
  330. one battlefield back into usersrc\custom.bfi:
  331.  
  332.     meditor    directory\file.bf 
  333.  
  334. The Family statement in the custom mission is generated by the
  335. following fprint statement:
  336.  
  337.     fprintf(f,
  338.         "%i %i "
  339.         "%hi %hi "
  340.         "%c %c "
  341.         "%hi %hi %hi "
  342.         "%hi %hi %hi "
  343.         "%hi %hi "
  344.         "%hi %hi "
  345.         "%hi %hi %hi "
  346.         ,
  347.         missiondate,timeofday,
  348.         numofsquadronac,numofflightac,
  349.         PlayerNationality+'@',formationtypeindex+'@',
  350.         weathernum,windspeed,winddirection,
  351.         era,region,PlayerAcType,
  352.         PlayerHomeBase,EnemyHomeBase,
  353.         MainObjective,SubObjective,
  354.         WP1,WP2,WP3
  355.         );
  356.  
  357. The second description is the news.
  358.  
  359. The main game considers all directories beginning with "M" to be mission
  360. groups, plus "default"; all that begin with "C" are campaigns.
  361.  
  362. The dictionary system in MAKEBFW is unable to cope with filenames that
  363. start with digits.
  364.  
  365. In a campaign directory, the dir.dir offers access to the campaign
  366. initialisation data as index 251, and the pilots as 252.
  367.  
  368. The entries 1..250 form the sequential missions for the campaign.
  369.  
  370. The campaign structure is in mecamp.h
  371. The pilots are each:
  372.  
  373. struct PilotType
  374. {
  375.     TextRef    name;            /word filled at runtime
  376.     SkillType    skill;        /byte
  377.     pilotstatus    status;        /byte
  378.     CharacterType    character;    /byte
  379.     MoraleType    morale;        /byte
  380.     NextFollAct    nextfollact;    /byte
  381.     SWord    dayssincerest;
  382.     SWord    kills;
  383.     SWord    daystorecover;
  384. struct    ImageMaps
  385. {
  386.      UByte    topwing;
  387.      UByte    tail;
  388.      UByte    btmwing;
  389.      UByte    fuselage;
  390.      UByte    other;
  391.     UByte    emblem;
  392. }    imagemaps;
  393. };
  394.  
  395. followed by a 50 byte name field.
  396.  
  397. The mission editor is unable to modify the main world. This is
  398. specified by the region as a rowan file number. The upper byte
  399. specifies the directory number, and the lower byte is the index in
  400. dir.dir.
  401.  
  402. Additional base worlds could be saved in the campaign directory by
  403. counting backwards from 250. Unfortunately, a directory may only
  404. contain 254 files maximum including dir.dir at position 0.
  405.  
  406. UniqueIDs
  407. ---------
  408.  
  409. The location of objects is driven by uniqueids. In makebf, an object
  410. can be placed with only a umiqueid band. At runtime such objects will
  411. be allocated uniqueids within that band sequentially. The bands are
  412. listed in uniqueid.h
  413.  
  414. However, if the object is referenced either within the MAKEBFW system, or
  415. by the main program, then it will be assigned a permanent uniqueID
  416. within it's band by MAKEBFW. MAKEBFW assigns these downward from the
  417. top of the band, but as far as the runtime game is concerned they are
  418. cast in stone in uidvals.g, which MAKEBFW outputs.
  419.  
  420. The same object can exist in different base era files by applying the
  421. same SetUID instruction in both items.
  422.  
  423. Needless to say, every object should get a unique uniqeid. If two
  424. objects with the same UID are loaded, or a band overflows the game 
  425. will emit an error message and stop.
  426.  
  427. This is particularly a problem in events, where complex waypoints
  428. positions often refer to each other forcing MAKEBFW generate a
  429. permanent uid. This event then cannot be loaded twice in the same
  430. mission.
  431.  
  432. One important feature of MAKEBFW is that it can forward-reference within
  433. the source. However, it sometimes needs help to decide what type a
  434. symbol is. If it guesses wrong then it will generate an error on
  435. reaching the actual definition.
  436.  
  437. MAKEBFW only generates one error message and then stops. Press a key to
  438. exit.
  439.  
  440.  
  441. /Jim
  442.  
  443.