home *** CD-ROM | disk | FTP | other *** search
/ The Amiga Game Guide / AmigaGameGuide_CD.iso / Amiga / PD-Games / DogFight! / Sources.lha / DogFight!_1.0.cpp next >
C/C++ Source or Header  |  1994-05-21  |  43KB  |  1,035 lines

  1. /*×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
  2. ##
  3. ## Filename: DogFight!
  4. ## Compiler: Maxon C++
  5. ##
  6. ##
  7. ## $HISTORY:
  8. ## Date          Rev     Comment
  9. ## 21 May 1994 | 01.22 | Converted to SAS/C
  10. ## 09 May 1994 | 01.21 | Changed header (oooh!), and am attempting to fix
  11. ##                         the crash bug by liberal use of the CacheClearU()
  12. ##                         function.  So far, no success.
  13. ## 09 May 1994 | 00.00 | 18:08:02
  14. ##
  15. ## Old Revision list:
  16. ## v0.5  28-Feb-94   Changing input to direct keyboard read.
  17. ## v0.6  28-FEB-94   Added screenmode requester, alert for illegal
  18. ##                   number of players, info, WB startable.
  19. ##       01-Mar-94   Added menus; removed the need to have WB2.1
  20. ##                   by offering an ASL screenmode requester
  21. ##                   replacement (not ideal, but it works).
  22. ##                   Cosmetix: The Jets are now all erased and then
  23. ##                   all drawn, which prevents seeing the erase
  24. ##                   blocks when Jets fly through each other.
  25. ## v0.9b 10-Mar-94   Changed MUI a bit; added scores while pausing,
  26. ##                   changed color scheme; changed general speed
  27. ##                   of game. Changed game controls.
  28. ## v1.0  18-Mar-94   Reduced the frequency of crashes, though not
  29. ##                   eliminated.  Added computer controlled Jets.
  30. ## v1.1  21-Mar-94   Took out scores page; put the ASL screenmode
  31. ##                   requester in the menu bar.
  32. ## v1.2  30-Mar-94   Added sound.  Wata bitch.
  33. ##       17-Apr-94   Several small modifications.  Think I finally
  34. ##                   solved the Big Bug.  See the dox.
  35. ##
  36. ## ©1994 Apocalypse Productions
  37. ##       Sean Russell
  38. ##
  39. ×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××*/
  40. #define REVISION "1.22"
  41. #define REVDATE  "21/05/94"
  42. #define REVTIME  "14:20:00"
  43. #define VERNUM   1
  44. #define REVNUM   22
  45. #define PROGRAM  "DogFight!"
  46. #define VERSION  PROGRAM " " REVISION " (" REVDATE ")"
  47. const char *VERSTAG = "$VER: " PROGRAM " " REVISION " (" REVDATE ")";
  48.  
  49. char *about_text = "\033c\033b" PROGRAM "\n\033n"
  50.                    "\033i" REVISION " " REVDATE "\033n\n"
  51.                    "\nBy\nSean E. Russell\n\n"
  52.                    "DogFight! is a MUI application\n"
  53.                    "MUI is © Stefan Stunz";
  54.  
  55. /********************************************************************
  56. ×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
  57.                ToDo/Bug list
  58.     (b) The colors are screwy if you're not using a PAL screen.
  59.     (b) It STILL crashes.
  60.     10 - Clean the code up.
  61.     11 - Playtesting
  62.     12 - Parachuters.
  63.  
  64. ×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
  65. *********************************************************************/
  66.  
  67. // keyboard.device OpenDevice opts
  68.  
  69. #define S_UNUM    0
  70. #define S_FLAGS   0
  71.  
  72. /// "Includes"
  73. // general includes
  74.  
  75. #include <string.h>
  76. #include <stddef.h>
  77. #include <stdlib.h>
  78. #include <math.h>
  79. #include <intuition/intuition.h>
  80. #include <libraries/mathffp.h>
  81.  
  82. #include <clib/graphics_protos.h>
  83. #include <clib/intuition_protos.h>
  84. #include <clib/mathffp_protos.h>
  85. #include <clib/mathtrans_protos.h>
  86. #include <clib/alib_protos.h>
  87.  
  88. #include <workbench/startup.h>
  89. #include <workbench/workbench.h>
  90. #include <exec/types.h>
  91. #include <exec/exec.h>
  92. #include <exec/execbase.h>
  93. #include <graphics/displayinfo.h>
  94. #include <graphics/videocontrol.h>
  95. #include <intuition/gadgetclass.h>
  96. #include <libraries/gadtools.h>
  97. #include <libraries/asl.h>
  98. #include <libraries/mui.h>
  99. #include <stdio.h>
  100. #include <devices/keyboard.h>
  101.  
  102. #include <clib/exec_protos.h>
  103. #include <clib/gadtools_protos.h>
  104. #include <clib/asl_protos.h>
  105. #include <clib/muimaster_protos.h>
  106.  
  107. #include <proto/intuition.h>
  108. #include <proto/mathffp.h>
  109. #include <proto/gadtools.h>
  110. #include <proto/mathtrans.h>
  111. #include <proto/graphics.h>
  112. #include <proto/exec.h>
  113. #include <proto/asl.h>
  114. #include <proto/muimaster.h>
  115.  
  116. #include "dogfight!_class9.h"
  117. #include "dogfight!_1.0.h"
  118. #include "sound.h"
  119. ///
  120.  
  121. /// "Global variables"
  122. // shared library pointers
  123.  
  124. struct Library *GadToolsBase     = NULL;
  125. struct Library *MathTransBase    = NULL;
  126. struct Library *AslBase          = NULL;
  127. struct Library *MUIMasterBase    = NULL;
  128.  
  129. // global variables available to this file
  130.  
  131. struct Screen *tankscreen1 = NULL;              // the game screen
  132. struct RastPort rport[2];                       // rasterport array for doublebuffering
  133. struct MsgPort *replyport = NULL;               // for keyboard control
  134. struct IOStdReq *iostdreq = NULL;               // for keyboard.device
  135. struct MsgPort *msgport = NULL;                 // for doublebuffering
  136.  
  137. struct ScreenBuffer *scbuf[] =                  // for doublebuffering
  138. {
  139.     NULL, 
  140.     NULL, 
  141. };
  142.  
  143. struct TagItem vctags[] =
  144. {
  145.     VTAG_BORDERSPRITE_SET, TRUE, 
  146.     TAG_DONE, 0, 
  147. };
  148.  
  149. struct ColorSpec colors[] = {                   // gamescreen colors
  150.         {0, 0,  0,  0},
  151.         {1, 15, 15, 15},
  152.         {2, 0,  0,  15},
  153.         {3, 15, 0,  0},
  154.         {4, 0,  15, 0},
  155.         {5, 15, 14, 0},
  156.         {6, 9,  9,  9},
  157.         {7, 0,  15, 0},
  158.         {-1, -1, -1, -1}, 
  159.         NULL,
  160. };
  161.  
  162. struct NewMenu menu[] = {        // gadtools menu
  163.         {NM_TITLE,      "Project",              0,              0, 0, APTR(0)},
  164.         {NM_ITEM,       "About",                "?",    0, 0, APTR(ID_about)},
  165.         {NM_ITEM,       NM_BARLABEL,    0,              0, 0, APTR(0)},
  166.         {NM_ITEM,       "Screen...",    "C",    0, 0, APTR(ID_screen)},
  167.         {NM_ITEM,       "Save",                 "S",    0, 0, APTR(ID_save)},
  168.         {NM_ITEM,       NM_BARLABEL,    0,    0, 0, APTR(0)},
  169.         {NM_ITEM,       "Quit",                 "Q",    0, 0, APTR(MUIV_Application_ReturnID_Quit)},
  170.         {NM_END,                NULL,                           0,              0, 0, APTR(0)}};
  171.  
  172. UWORD   *mbptr;
  173. struct Window *mbwnd;
  174. ///
  175.  
  176. /// "computer(FIGHTER &player)"
  177. /******************************************
  178. ×××××××××××××××××××××××××××××××××××××××××××
  179.         Computer controlled Jet
  180.         (at this point, only dumb)
  181.         
  182.         returns: 1  for left
  183.                                 2  for right
  184.                                 3  for fire
  185.                                 0  for no action
  186. ×××××××××××××××××××××××××××××××××××××××××××
  187. ******************************************/
  188.  
  189. void computer(FIGHTER &p) {
  190.         long k;
  191.  
  192.         k = lrand48() % 100;
  193.  
  194.         if (k < 5) p.left();
  195.         if (k > 94) p.right();
  196.         if (k > 80) p.fire();
  197. }
  198. ///
  199.  
  200. /// "evaluate(int buffer_element, int left, int right, int fire, int last_key_array, FIGHTER &player)"
  201. /******************************************
  202. ×××××××××××××××××××××××××××××××××××××××××××
  203.         evaluate a keypress.
  204.         
  205.         returns TRUE everytime a key is pressed.
  206. ×××××××××××××××××××××××××××××××××××××××××××
  207. ******************************************/
  208.  
  209. __inline void evaluate(int bf, int lt, int rt, int fr, int *lst, FIGHTER &p) {
  210.         if (buff[bf] & lt) {
  211.                 if (!lst[0]) {
  212.                         lst[0] = TRUE;
  213.                         p.left();
  214.                 }
  215.         }
  216.         else lst[0] =  FALSE;
  217.  
  218.         if (buff[bf] & rt) {
  219.                 if (!lst[1]) {
  220.                         lst[1] = TRUE;
  221.                         p.right();
  222.                 }
  223.         }
  224.         else lst[1] = FALSE;
  225.         
  226.         if (buff[bf] & fr)
  227.                 p.fire();
  228.         
  229. }
  230. ///
  231.  
  232. /// "int openscreen(bool request)"
  233. /******************************************
  234. ×××××××××××××××××××××××××××××××××××××××××××
  235.         Opens the game screen and allocates
  236.         all screen-dependant variables.
  237.         
  238.         If passed TRUE, requests a screen
  239.         size with either an ASL requester
  240.         or a MUI requester.
  241. ×××××××××××××××××××××××××××××××××××××××××××
  242. ******************************************/
  243.  
  244. int openscreen(BOOL req) {
  245.  
  246.         /******************************************
  247.                 If any screen stuff is open, close it.
  248.         ******************************************/
  249.         
  250.         if (mbwnd)                      CloseWindow(mbwnd);
  251.         
  252.         if (scbuf[1])           FreeScreenBuffer(tankscreen1, scbuf[1]);
  253.         if (scbuf[0])           FreeScreenBuffer(tankscreen1, scbuf[0]);
  254.         if (tankscreen1)        CloseScreen(tankscreen1);
  255.  
  256.         ULONG dispid;
  257.  
  258.         if (req) {
  259.                 /******************************************
  260.                         If they have WB2.1 or greater we can
  261.                         use the ASL screenmode requester, which
  262.                         provides graphiccard support.
  263.                         Otherwise, we offer the user a choice
  264.                         from 4 standard screens.
  265.                 ******************************************/
  266.         
  267.                 if (AslBase) {
  268.                         struct ScreenModeRequester *request;
  269.         
  270.                         if (!(request = (struct ScreenModeRequester *)AllocAslRequestTags(
  271.                                         ASL_ScreenModeRequest,
  272.                                         ASLSM_InitialAutoScroll, FALSE,
  273.                                         ASLSM_InitialDisplayID, DBLPALHIRESFF_KEY,
  274.                                         ASLSM_InitialDisplayDepth, 3,
  275.                                         ASLSM_DoOverscanType, FALSE,
  276.                                         ASLSM_DoHeight, TRUE,
  277.                                         ASLSM_DoWidth, TRUE,
  278.                                         ASLSM_MinWidth, 320,
  279.                                         ASLSM_MinHeight, 200,
  280.                                         ASLSM_PropertyFlags, DIPF_IS_DBUFFER,
  281.                                         ASLSM_PropertyMask, DIPF_IS_DBUFFER,
  282.                                         TAG_DONE)))
  283.                                 return ER_ALLOCASL;
  284.         
  285.                         if (!(AslRequest((APTR)request, NULL)))
  286.                                 return ER_OPENASL;
  287.                 
  288.                         dispid = request->sm_DisplayID;
  289.                         scrn_width_MAX = request->sm_DisplayWidth;
  290.                         scrn_height_MAX = request->sm_DisplayHeight;
  291.         
  292.                         FreeAslRequest((APTR)request);
  293.                 }
  294.                 else {
  295.                         signed long choice;
  296.                         int xres[] = {640, 320, 640};
  297.                         int yres[] = {512, 200, 480};
  298.                         int dispids[] = {DBLPALHIRESFF_KEY, LORES_KEY, DBLNTSCHIRES_KEY};
  299.                 
  300.                         choice = MUI_Request(app, NULL, 0, "ScreenMode",
  301.                                 "_Lores NTSC|*_DBLPALHires|DBLNTSCHires",
  302.                                 "Since I can't find asl.library v39+ you only\n"
  303.                                 "have a choice from 4 screen modes.  Lores is\n"
  304.                                 "320x200, DBLPALHires is 640x512, DBLNTSCHires\n"
  305.                                 "is 640x480");
  306.  
  307.                         dispid = dispids[choice];
  308.                         scrn_width_MAX = xres[choice];
  309.                         scrn_height_MAX = yres[choice];
  310.                 }
  311.         }
  312.         else {
  313.                 dispid = DBLPALHIRESFF_KEY;
  314.                 scrn_width_MAX = 640;
  315.                 scrn_height_MAX = 512;
  316.         }
  317.  
  318.         scrn_left = 30;
  319.         scrn_right = scrn_width_MAX - 30;
  320.         scrn_top = 30;
  321.         scrn_bottom = scrn_height_MAX - 30;
  322.  
  323.         /*****************************
  324.                 We open the game screen
  325.                 behind the workbench
  326.         ******************************/
  327.  
  328.         if (!(tankscreen1 = OpenScreenTags(NULL,
  329.                         SA_DisplayID, dispid,
  330.                         SA_Overscan, OSCAN_TEXT,
  331.                         SA_Depth, 3,
  332.                         SA_Width, scrn_width_MAX,
  333.                         SA_Height, scrn_height_MAX,
  334.                         SA_Behind, TRUE,
  335.                         SA_Quiet, TRUE, 
  336.                         SA_VideoControl, vctags,
  337.                         TAG_DONE)))
  338.                 return ER_OS1;
  339.         
  340.         int i;
  341.         
  342.         for (i=0;i<8;i++)
  343.                 SetRGB4(&(tankscreen1->ViewPort), i,
  344.                         colors[i].Red,
  345.                         colors[i].Green,
  346.                         colors[i].Blue);
  347.                          
  348.         SetRast(&(tankscreen1->RastPort), 0);
  349.         
  350.         if (!(mbwnd = OpenWindowTags( 0L,
  351.                                                         WA_CustomScreen, tankscreen1,
  352.                                                         WA_NoCareRefresh, TRUE, 
  353.                                                         WA_Backdrop, TRUE,
  354.                                                         WA_Borderless, TRUE,
  355.                                                         TAG_END )))
  356.                 return ER_OPENMBWND;
  357.                 
  358.         SetPointer( mbwnd, mbptr, 0, 0, 0, 0 );
  359.  
  360.         /******************************
  361.                 Now we allocate screen
  362.                 buffers for the double
  363.                 buffering
  364.         *******************************/
  365.         
  366.         if (!(scbuf[0] = AllocScreenBuffer(tankscreen1, NULL, SB_SCREEN_BITMAP)))
  367.                 return ER_ASBS;
  368.  
  369.         if (!(scbuf[1] = AllocScreenBuffer(tankscreen1, NULL, SB_COPY_BITMAP)))
  370.                 return ER_ASBC;
  371.  
  372.         rport[0].BitMap = scbuf[0]->sb_BitMap;
  373.         rport[1].BitMap = scbuf[1]->sb_BitMap;
  374.         
  375.         return 0;
  376. }       
  377. ///
  378.  
  379. /// "int openall()"
  380. /******************************************
  381. ×××××××××××××××××××××××××××××××××××××××××××
  382.         open all libraries, screens, apps, and
  383.         input devices.
  384.         
  385.         returns 0 if successfull, otherwise the
  386.         error value (see DogFight!4.h)
  387. ×××××××××××××××××××××××××××××××××××××××××××
  388. ******************************************/
  389.  
  390. int openall()   {
  391.  
  392.         /*****************************************
  393.                 Open libraries.
  394.         ******************************************/
  395.         
  396.         if (!(GadToolsBase = OpenLibrary((unsigned char *)"gadtools.library", (unsigned long)39)))
  397.                 return ER_GTL;
  398.                 
  399.         if (!(MathBase = OpenLibrary((unsigned char *)"mathffp.library", (unsigned long)39)))
  400.                 return ER_MATHFFP;
  401.         
  402.         if (!(MathTransBase = OpenLibrary((unsigned char *)"mathtrans.library", (unsigned long)37)))
  403.                 return ER_MATHTRANS;
  404.         
  405.         if (!(MUIMasterBase = OpenLibrary((unsigned char *)MUIMASTER_NAME, (unsigned long)MUIMASTER_VMIN)))
  406.                 return ER_MUIMAST;
  407.         
  408.         if (!(AslBase = OpenLibrary((unsigned char *)"asl.library", (unsigned long)39)))
  409.                 return ER_ASLBASE;
  410.         
  411.         /****************************************
  412.                 Generate MUI application
  413.         *****************************************/
  414.  
  415.         app = ApplicationObject,
  416.                 MUIA_Application_Title, "DogFight!",
  417.                 MUIA_Application_Version, VERSION,
  418.                 MUIA_Application_Copyright, "Apocalypse Productions © MCMXCIV",
  419.                 MUIA_Application_Author, "Sean E. Russell",
  420.                 MUIA_Application_Description, "Up to 4 player dogfight game",
  421.                 MUIA_Application_Base, "DOGF",
  422.                 MUIA_Application_Menu, menu,
  423.                 
  424.                 SubWindow, WI_setup = WindowObject,
  425.                         MUIA_Window_Title, "Prefs",
  426.                         MUIA_Window_ID, MAKE_ID('P', 'R', 'F', 'S'),
  427.                         
  428.                         WindowContents, VGroup,
  429.                                 Child, RG_main = RegisterGroup(pages),
  430.                                         MUIA_Register_Frame, TRUE,
  431.                Child, VGroup,
  432.                   Child, CY_player[PLAYER1] = CycleObject,
  433.                      MUIA_Cycle_Entries, control,
  434.                      MUIA_ExportID, 8,
  435.                   End,
  436.                   Child, HGroup,
  437.                      Child, RA_player[PLAYER1] = RadioObject,
  438.                         MUIA_Radio_Entries, radbutts,
  439.                         MUIA_ExportID, 1,
  440.                      End,
  441.                      Child, TextObject,
  442.                         TextFrame,
  443.                         MUIA_Background, MUII_ListBack,
  444.                         MUIA_Text_Contents, controls[0],
  445.                      End,
  446.                   End,
  447.                End,
  448.                                         Child, VGroup,
  449.                                                 Child, CY_player[PLAYER2] = CycleObject,
  450.                                                         MUIA_Cycle_Entries, control,
  451.                                                         MUIA_ExportID, 7,
  452.                                                 End,
  453.                                                 Child, HGroup,
  454.                                                         Child, RA_player[PLAYER2] = RadioObject,
  455.                                                                 MUIA_Radio_Entries, radbutts,
  456.                                                                 MUIA_ExportID, 2,
  457.                                                         End,
  458.                                                         Child, TextObject,
  459.                                                                 TextFrame,
  460.                                                                 MUIA_Background, MUII_ListBack,
  461.                                                                 MUIA_Text_Contents, controls[1],
  462.                                                         End,
  463.                                                 End,
  464.                                         End,
  465.                Child, VGroup,
  466.                   Child, CY_player[PLAYER3] = CycleObject,
  467.                      MUIA_Cycle_Entries, control,
  468.                      MUIA_ExportID, 9,
  469.                   End,
  470.                   Child, HGroup,
  471.                      Child, RA_player[PLAYER3] = RadioObject,
  472.                         MUIA_Radio_Entries, radbutts,
  473.                         MUIA_ExportID, 3,
  474.                      End,
  475.                      Child, TextObject,
  476.                         TextFrame,
  477.                         MUIA_Background, MUII_ListBack,
  478.                         MUIA_Text_Contents, controls[2],
  479.                      End,
  480.                   End,
  481.                End,
  482.                Child, VGroup,
  483.                   Child, CY_player[PLAYER4] = CycleObject,
  484.                      MUIA_Cycle_Entries, control,
  485.                      MUIA_ExportID, 10,
  486.                   End,
  487.                   Child, HGroup,
  488.                      Child, RA_player[PLAYER4] = RadioObject,
  489.                         MUIA_Radio_Entries, radbutts,
  490.                         MUIA_ExportID, 4,
  491.                      End,
  492.                      Child, TextObject,
  493.                         TextFrame,
  494.                         MUIA_Background, MUII_ListBack,
  495.                         MUIA_Text_Contents, controls[3],
  496.                      End,
  497.                   End,
  498.                End,
  499.                                 End,
  500.                                 Child, VGroup,
  501.                                         Child, HGroup,
  502.                                                 GroupFrameT("Global Options"),
  503.                                                 MUIA_Group_SameHeight, TRUE,
  504.                                                 Child, HVSpace,
  505.                                                 Child, Label("Fast Game"),
  506.                                                 Child, CH_speed = ImageObject,
  507.                                                         ImageButtonFrame,
  508.                                                         MUIA_InputMode, MUIV_InputMode_Toggle,
  509.                                                         MUIA_Image_Spec, MUII_CheckMark,
  510.                                                         MUIA_Image_FreeVert, TRUE,
  511.                                                         MUIA_Selected, TRUE,
  512.                                                         MUIA_Background, MUII_ButtonBack,
  513.                                                         MUIA_ShowSelState, FALSE,
  514.                                                         MUIA_ExportID, 5,
  515.                                                 End,
  516.                                                 Child, HVSpace,
  517.                                                 Child, HVSpace,
  518.                                                 Child, Label1("Safe Start"),
  519.                                                 Child, CH_vuln = ImageObject,
  520.                                                         ImageButtonFrame,
  521.                                                         MUIA_InputMode, MUIV_InputMode_Toggle,
  522.                                                         MUIA_Image_Spec, MUII_CheckMark,
  523.                                                         MUIA_Image_FreeVert, TRUE,
  524.                                                         MUIA_Selected, TRUE,
  525.                                                         MUIA_Background, MUII_ButtonBack,
  526.                                                         MUIA_ShowSelState, FALSE,
  527.                                                         MUIA_ExportID, 6,
  528.                                                 End,
  529.                                                 Child, HVSpace,
  530.                                         End,
  531.                                         Child, HGroup,
  532.                                                 Child, BU_go =  KeyButton("Go!",  'g'),
  533.                                                 Child, BU_save =        KeyButton("Save", 's'),
  534.                                                 Child, BU_quit =        TextObject,
  535.                                                         ButtonFrame,
  536.                                                         MUIA_Text_Contents, "Quit",
  537.                                                         MUIA_Text_PreParse, "\033c",
  538.                                                         MUIA_Text_SetMax, FALSE,
  539.                                                         MUIA_Text_HiChar, 'q',
  540.                                                         MUIA_ControlChar, 'q',
  541.                                                         MUIA_InputMode, MUIV_InputMode_RelVerify,
  542.                                                         MUIA_Background, MUII_ButtonBack,
  543.                                                 End,
  544.                                         End,
  545.                                 End,
  546.                         End,
  547.                 End,
  548.         End;
  549.  
  550.         if (!app) return ER_APP;
  551.  
  552.         /******************************************
  553.                 Here's a messageport for the DBLBUFF
  554.         ******************************************/
  555.         
  556.         if (!(msgport = CreateMsgPort()))
  557.                 return ER_DBMP;
  558.  
  559.         /******************************
  560.                 And create some rasterports
  561.                 so we can draw on the 
  562.                 bitmaps
  563.         *******************************/
  564.         
  565.         InitRastPort(&rport[0]);
  566.         InitRastPort(&rport[1]);
  567.  
  568.         /******************************************
  569.                 Call the OpenScreen routine
  570.         ******************************************/
  571.         
  572.         if (!( mbptr=(UWORD *)AllocVec(sizeof(WORD)*4,MEMF_CHIP)))
  573.                 return ER_ALOCMBPTR;
  574.  
  575.         /************************************
  576.                 Open and initialize the keyboard
  577.                 device.
  578.         *************************************/
  579.  
  580.         if (!(replyport = CreateMsgPort()))
  581.                 return ER_CMSGPORT;
  582.         if (!(iostdreq = (struct IOStdReq *)CreateIORequest(
  583.                                                         replyport, sizeof(struct IOStdReq)
  584.                                                         ) ))
  585.                 return ER_CSTDIO;
  586.         if (OpenDevice((unsigned char *)"keyboard.device", (unsigned long)S_UNUM,
  587.                        (struct IORequest *)iostdreq, (unsigned long)S_FLAGS))
  588.                 return ER_OKBD;
  589.         
  590.         iostdreq->io_Command = KBD_READMATRIX;
  591.         iostdreq->io_Flags = IOF_QUICK;
  592.         iostdreq->io_Length = 16;
  593.         iostdreq->io_Data = buff;
  594.  
  595.         return ER_none;
  596. }
  597. ///
  598.  
  599. /// "error(int error_number)"
  600. /******************************************
  601. ×××××××××××××××××××××××××××××××××××××××××××
  602.         Closes all open devices, screens,
  603.         objects, etc; frees all memory.
  604.         If e, outputs the appropriate
  605.         error message.
  606. ×××××××××××××××××××××××××××××××××××××××××××
  607. ******************************************/
  608.  
  609. void error(int e)       {
  610.         
  611.         if (iostdreq)   {
  612.                 if (iostdreq->io_Device)
  613.                         CloseDevice((struct IORequest *)iostdreq);
  614.                 DeleteIORequest(iostdreq);
  615.         }
  616.         
  617.         if (replyport)                                  DeleteMsgPort(replyport);
  618.         if (mbwnd)                                              CloseWindow(mbwnd);
  619.         if (mbptr)                                              FreeVec(mbptr);
  620.  
  621.         if (scbuf[1])                                   FreeScreenBuffer(tankscreen1, scbuf[1]);
  622.         if (scbuf[0])                                   FreeScreenBuffer(tankscreen1, scbuf[0]);
  623.         if (tankscreen1)                                CloseScreen(tankscreen1);
  624.         if (msgport)                                    DeleteMsgPort(msgport);
  625.  
  626.         if (AslBase)                                    CloseLibrary(AslBase);
  627.         if (app)                                                MUI_DisposeObject(app);
  628.         if (MUIMasterBase)                      CloseLibrary(MUIMasterBase);
  629.         if (MathTransBase)                      CloseLibrary(MathTransBase);
  630.         if (MathBase)                                   CloseLibrary((struct Library *)MathBase);
  631.         if (GadToolsBase)                       CloseLibrary(GadToolsBase);
  632.         
  633.         closesound();
  634.                 
  635.         if (e)  {
  636.                 printf("ERROR: %s\n", ERRORS[e]);
  637.                 exit(20);
  638.         }
  639.         
  640.         exit(0);
  641. }
  642. ///
  643.  
  644. /// "pause(struct RastPort *rp, Fighter *fighter_array)"
  645. /******************************************
  646. ×××××××××××××××××××××××××××××××××××××××××××
  647.         Pauses the game
  648. ×××××××××××××××××××××××××××××××××××××××××××
  649. ******************************************/
  650.  
  651. void pause(struct RastPort *rp, FIGHTER *pl) {
  652.         BOOL paused = TRUE;
  653.         char scrs[50];
  654.         int i;
  655.         struct IntuiText scrstxt = {2, 0, JAM1, 0, 0, &topaz8, (unsigned char *)scrs, NULL};
  656.         
  657.         scrstxt.FrontPen = 6;
  658.         sprintf(scrs, "Scores --");
  659.         PrintIText(rp, &scrstxt,
  660.                 int((scrn_width_MAX - 120)/2),
  661.                 int((scrn_height_MAX - 32)/2));
  662.         for (i=0;i<4;i++) {
  663.                 if (pl[i].in_play) {
  664.                         sprintf(scrs, "Player %d: %d", i+1, pl[i].killscore);
  665.                         scrstxt.FrontPen = 6;
  666.                         PrintIText(rp, &scrstxt,
  667.                                 int((scrn_width_MAX - 160)/2) - 1,
  668.                                 int((scrn_height_MAX - 32)/2) + ((i+1)*10) + 1 );
  669.                         
  670.                         scrstxt.FrontPen = (unsigned char)(i+1);
  671.                         PrintIText(rp, &scrstxt,
  672.                                 int((scrn_width_MAX - 160)/2),
  673.                                 int((scrn_height_MAX - 32)/2) + ((i+1)*10) );
  674.                 }
  675.         }
  676.         
  677.         while (paused) {
  678.                 DoIO((struct IORequest *)iostdreq);
  679.                 if (buff[3] & 1)
  680.                         paused = FALSE;
  681.                 WaitTOF();
  682.         }
  683.         
  684.         SetAPen(rp, 0);
  685.         RectFill(rp, 
  686.                 int((scrn_width_MAX - 160)/2),
  687.                 int((scrn_height_MAX - 32)/2),
  688.                 int((scrn_width_MAX + 160)/2),
  689.                 int((scrn_height_MAX + (i*15) + 32)/2)
  690.                 );
  691. }
  692. ///
  693.  
  694. /******************************************
  695. ×××××××××××××××××××××××××××××××××××××××××××
  696.                 M A I N
  697. ×××××××××××××××××××××××××××××××××××××××××××
  698. ******************************************/
  699.  
  700. void main(int argc, char **argv)        {
  701.         int err=0;
  702.  
  703.         /****************************************
  704.           Open libraries, allocate screens, etc.
  705.         *****************************************/
  706.  
  707.         if (err = openall())
  708.                 error(err);
  709.         
  710.         if (err = setupsound()) {
  711.                 printf("ERROR %i: %s\n", err, SNDERRORS[err]);
  712.                 error(0);
  713.         }
  714.  
  715.         /**************************************
  716.                 Attach buttons; setup general
  717.                 MUI notification
  718.         ***************************************/
  719.  
  720.         DoMethod((Object *)WI_setup, MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
  721.                 app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
  722.         DoMethod((Object *)BU_go, MUIM_Notify, MUIA_Pressed, FALSE,
  723.                 app, 2, MUIM_Application_ReturnID, ID_gobutton);
  724.         DoMethod((Object *)BU_quit, MUIM_Notify, MUIA_Pressed, FALSE,
  725.                 app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
  726.         DoMethod((Object *)BU_save, MUIM_Notify, MUIA_Pressed, FALSE,
  727.                 app, 2, MUIM_Application_ReturnID, ID_save);
  728.         
  729.         // Set up tab chain
  730.         DoMethod((Object *)WI_setup, MUIM_Window_SetCycleChain,
  731.                 CH_speed, CH_vuln, BU_go, BU_save, BU_quit, NULL);
  732.  
  733.         // Load application setup
  734.         DoMethod((Object *)app, MUIM_Application_Load, MUIV_Application_Load_ENV);
  735.                         
  736.         /****************************************
  737.                 Open SetUp window, and wait until
  738.                 they press a button.
  739.         *****************************************/
  740.  
  741.         BOOL go_flag = FALSE;
  742.         BOOL running = TRUE;
  743.         BOOL exit = FALSE;
  744.         ULONG signal;
  745.         int i, numplay = 0;
  746.         ULONG perf[4];
  747.         ULONG cont[4];
  748.  
  749.         set((Object *)WI_setup, MUIA_Window_Open, TRUE);
  750.  
  751.         while (running) {
  752.  
  753.                 while((!go_flag) && (!exit)) {
  754.                         switch (DoMethod((Object *)app, MUIM_Application_Input, &signal)) {
  755.                                 case MUIV_Application_ReturnID_Quit:
  756.                                         exit = TRUE;
  757.                                         running = FALSE;
  758.                                         go_flag = FALSE;
  759.                                         break;
  760.                                 case ID_gobutton:
  761.                                         go_flag = TRUE;
  762.                                         break;
  763.                                 case ID_save:
  764.                                         DoMethod((Object *)app,
  765.                                                 MUIM_Application_Save, MUIV_Application_Save_ENVARC);
  766.                                         DoMethod((Object *)app,
  767.                                                 MUIM_Application_Save, MUIV_Application_Save_ENV);
  768.                                         break;
  769.                                 case ID_about:
  770.                                         MUI_Request(app, WI_setup, 0, "About", "_Ok", about_text);
  771.                                         break;
  772.                                 case ID_screen:
  773.                                         if (err = openscreen(TRUE))
  774.                                                 error(err);
  775.                                         break;
  776.                                 default:
  777.                                         break;
  778.                         }
  779.                         if (signal) Wait(signal);
  780.                 }
  781.                 
  782.                 numplay = 0;
  783.                 for (i=0;i<4;i++) {
  784.                         get((Object *)CY_player[i], MUIA_Cycle_Active, &(perf[i]));
  785.                         get((Object *)RA_player[i], MUIA_Radio_Active, &(cont[i]));
  786.                         if (perf[i])
  787.                                 numplay++;
  788.                 }
  789.                 if (numplay < 2) {
  790.                         go_flag = FALSE;
  791.                         MUI_Request(app, WI_setup, 0, "Ugh", "_Ok", 
  792.                         "\033cYou must activate at least\n2 players to have a dogfight!");
  793.                 }
  794.                 else running = FALSE;
  795.         }
  796.         
  797.         if (!tankscreen1)
  798.                 if (err = openscreen(FALSE))
  799.                         error(err);
  800.  
  801.         ULONG temp;
  802.         
  803.         get((Object *)CH_vuln, MUIA_Selected, &temp);
  804.         vulnerability = (signed short)(!BOOL(temp));
  805.         get((Object *)CH_speed, MUIA_Selected, &temp);
  806.         game_speed = int(temp);
  807.         
  808.         set((Object *)WI_setup, MUIA_Window_Open, FALSE);
  809.         set((Object *)app, MUIA_Application_Sleep, TRUE);
  810.  
  811.         /**************************************
  812.                 Initialize fighters from SetUp
  813.                 window.
  814.         ***************************************/
  815.         
  816.         FIGHTER player[4];
  817.         int j=0;
  818.         
  819.         for (i=0; i < 4; i++) {
  820.                 player[i].shot.stop();
  821.                 if (perf[i])
  822.                         player[i].init(i, int(cont[i])+1);
  823.                 else player[i].init(i, 0);
  824.                 player[i].killscore = 0;
  825.         }
  826.  
  827.         /**************************************
  828.                 This is the main program loop.
  829.         ***************************************/
  830.  
  831.         int buffernum=0;
  832.         int p3last[2], p2last[2], p1last[2], p0last[2];
  833.         struct Message *msg = NULL;
  834.         ULONG sig = 0;
  835.         scbuf[buffernum]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort = msgport;
  836.  
  837.         while (!exit) {
  838.  
  839.                 /**************************************
  840.                         This is the actual dogfight loop.
  841.                 ***************************************/
  842.  
  843.                 ScreenToFront(tankscreen1);
  844.                 ActivateWindow(mbwnd);
  845.                 running = TRUE;
  846.  
  847.                 while (running) {
  848.                         
  849.                         if (sig & (1<<msgport->mp_SigBit)) {
  850.                                 while (msg = GetMsg(msgport)) {
  851.                                         msg = NULL;
  852.                                 }
  853.                         }
  854.  
  855.                         /**************************
  856.                                 Check user input
  857.                         ***************************/
  858.  
  859.                         DoIO((struct IORequest *)iostdreq);
  860.  
  861.                         if (perf[3] == 1)
  862.                                 evaluate(3, 32, 128, 64, p3last, player[3]);
  863.                         else
  864.                                 computer(player[3]);
  865.  
  866.                         if (perf[2] == 1)
  867.                                 evaluate(5, 2, 8, 4, p2last, player[2]);
  868.                         else 
  869.                                 computer(player[2]);
  870.  
  871.                         if (perf[1] == 1)
  872.                                 evaluate(6, 32, 128, 64, p1last, player[1]);
  873.                         else 
  874.                                 computer(player[1]);
  875.  
  876.                         if (perf[0] == 1)
  877.                                 evaluate(6, 1, 4, 2, p0last, player[0]);
  878.                         else
  879.                                 computer(player[0]);
  880.  
  881.                         if (buff[8] & 32)               running = FALSE;
  882.                         if (buff[3] & 2)                pause(&rport[!buffernum], player);
  883.                         
  884.                         /******************
  885.                                 End user input
  886.                         *******************/
  887.  
  888.                         /******************************************
  889.                                 We erase all of the Jets at once...
  890.                         ******************************************/
  891.                         
  892.                         for (i=0;i<4;i++) {
  893.                                 if (player[i].in_play) {
  894.                                         if (!player[i].alive) 
  895.                                                 player[i].resurect(i, int(cont[i])+1);
  896.                                         player[i].erase(&rport[buffernum]);
  897.                                 }
  898.                         }
  899.                         
  900.                         /******************************************
  901.                                 ...and draw them on a "fresh" screen.
  902.                                 This takes a little longer, but jets
  903.                                 overlap nicely instead of blanking each
  904.                                 other.
  905.                         ******************************************/
  906.                          
  907.                         for (i=0;i<4;i++) {
  908.                                 if (player[i].in_play) {
  909.                                         player[i].move(&(rport[buffernum]));
  910.                                         for (j=0;j<4;j++) {
  911.                                                 if ((i!=j)&player[j].in_play)
  912.                                                         if (player[i].collide(&(player[j].shot)))
  913.                                                                 player[j].killscore++;
  914.                                         }
  915.                                 }
  916.                         }
  917.  
  918.                         CacheClearU();
  919.  
  920.                         scbuf[buffernum]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort = msgport;
  921.  
  922.                         while (!(ChangeScreenBuffer(tankscreen1, scbuf[buffernum]))) {
  923.                                 WaitTOF();
  924.                         }
  925.                         
  926.                         sig = Wait(1 << msgport->mp_SigBit);
  927.  
  928.                         buffernum = !buffernum;
  929.                         
  930.                 }
  931.                 /********************
  932.                         End dogfight loop
  933.                 *********************/
  934.  
  935.                 ScreenToBack(tankscreen1);
  936.                 
  937.                 /*******************************
  938.                         Allow players to change opts
  939.                 ********************************/
  940.  
  941.                 running = TRUE;
  942.                 go_flag = FALSE;
  943.  
  944.                 set((Object *)app, MUIA_Application_Sleep, FALSE);              
  945.                 set((Object *)WI_setup, MUIA_Window_Open, TRUE);
  946.  
  947.                 while (running) {
  948.  
  949.                         while((!go_flag) && (!exit)) {
  950.                                 switch (DoMethod((Object *)app, MUIM_Application_Input, &signal)) {
  951.                                         case MUIV_Application_ReturnID_Quit:
  952.                                                 exit = TRUE;
  953.                                                 go_flag = FALSE;
  954.                                                 running = FALSE;
  955.                                                 break;
  956.                                         case ID_gobutton:
  957.                                                 go_flag = TRUE;
  958.                                                 break;
  959.                                         case ID_save:
  960.                                                 DoMethod((Object *)app,
  961.                                                         MUIM_Application_Save, MUIV_Application_Save_ENVARC);
  962.                                                 DoMethod((Object *)app,
  963.                                                         MUIM_Application_Save, MUIV_Application_Save_ENV);
  964.                                                 break;
  965.                                         case ID_about:
  966.                                                 MUI_Request(app, WI_setup, 0, "About", "_Ok", about_text);
  967.                                                 break;
  968.                                         case ID_screen:
  969.                                                 if (err = openscreen(TRUE))
  970.                                                         error(err);
  971.                                                 break;
  972.                                         default:
  973.                                                 break;
  974.                                 }
  975.                                 if (signal) Wait(signal);
  976.                         }
  977.  
  978.                         if (!exit) {
  979.                                 numplay = 0;                    
  980.                                 for (i=0;i<4;i++) {
  981.                                         get((Object *)RA_player[i], MUIA_Radio_Active, &cont[i]);
  982.                                         get((Object *)CY_player[i], MUIA_Cycle_Active, &perf[i]);
  983.                                         if (perf[i])
  984.                                                 numplay++;
  985.                                 }
  986.                                 if (numplay < 2) {
  987.                                         go_flag = FALSE;
  988.                                         MUI_Request(app, WI_setup, 0, "Ugh", "_Ok", 
  989.                                         "\033cYou must activate at least\n2 players to have a dogfight!");
  990.                                 }
  991.                                 else running = FALSE;
  992.                         }
  993.                 }
  994.  
  995.                 if (!exit) {
  996.                         get((Object *)CH_vuln, MUIA_Selected, &temp);
  997.                         vulnerability = (signed short)(!BOOL(temp));
  998.                         get((Object *)CH_speed, MUIA_Selected, &temp);
  999.                         game_speed = int(temp);
  1000.  
  1001.                         set((Object *)WI_setup, MUIA_Window_Open, FALSE);
  1002.                         set((Object *)app, MUIA_Application_Sleep, TRUE);
  1003.  
  1004.                         /************************
  1005.                                 Clear the screens
  1006.                         *************************/
  1007.  
  1008.                         SetRast(&rport[0], 0);
  1009.                         SetRast(&rport[1], 0);
  1010.                 
  1011.                         /************************
  1012.                                 Re-init fighters for
  1013.                                 a new game.
  1014.                         *************************/
  1015.                 
  1016.                         for (i=0; i < 4; i++) {
  1017.                                 if (perf[i])
  1018.                                         player[i].init(i, (int)cont[i] + 1);
  1019.                                 else player[i].init(i, 0);
  1020.                                 player[i].killscore = 0;
  1021.                         }
  1022.                 }
  1023.         }
  1024.         /************************
  1025.                 End main program loop
  1026.         *************************/
  1027.  
  1028.         set((Object *)app, MUIA_Application_Sleep, FALSE);
  1029.         set((Object *)WI_setup, MUIA_Window_Open, FALSE);
  1030.         error(0);
  1031. }
  1032. /************************
  1033.         End main()
  1034. *************************/
  1035.