home *** CD-ROM | disk | FTP | other *** search
/ ST-Computer Leser 2002 January / STC_CD_01_2002.iso / GAMES / BOINKO21 / SRC / SRC / BOINKOUT.C < prev    next >
C/C++ Source or Header  |  2002-01-03  |  55KB  |  2,396 lines

  1. /********************************************
  2. *        Boinkout program and acc            *
  3. *                                            *
  4. *        Based Upon code by                    *
  5. *        Samuel Streeper 90/02/26            *
  6. *                                            *
  7. *    Original Version                        *
  8. *    Copyright 1990 by Antic Publishing Inc.    *
  9. *                                            *
  10. * "what to do with all that wasted            *
  11. *    CPU time Part III"                        *
  12. ********************************************/
  13.  
  14. /* edited with tabsize = 4 */
  15.  
  16. /*  Updating Notes:
  17.     Well Antic went belly up shortly after running this article and
  18.     code.  There were numerous stories at the time of them not actually
  19.     paying authors for code/articles that they had written.
  20.     I DO NOT KNOW IF THIS WAS THE CASE WITH BOINKOUT!
  21.     However, Mr. Streeper ported it to the next station,
  22.     that he worked on shortly after this.  In fact it became
  23.     a hit there (being one of the few initial games for that 
  24.     platform).  Since then it has seen a few incarnations most
  25.     recently in JAVA.   I thought it was kind of irritating that
  26.     this great game, no longer ran on many modern atari systems
  27.     due to some programming conflicts that have arisen since its
  28.     initial release.  While I was in here I made a few more changes,
  29.     such as the XIMG backdrop support.  There are probably more
  30.     errors running around in here.  Don't try to use the linea support
  31.     unless you put it all back in.  I ripped most of it out.  I know
  32.     that there are some people that can still use linea.  However In
  33.     almost all cases I beleive they can use the initial game as well.
  34.     
  35.         - Dan Ackerman    August 1999
  36.         baldrick@netset.com
  37.         
  38.  
  39.     I spoke with Mr. Streeper via email one day.  He was very happy to
  40.     see BoinkOut2.  Whew!  One worry gone :)
  41. */
  42.  
  43. /*    Compiler notes:        */
  44. /*    ---------------        */
  45. /*    This code compiles with Laser C and Mark Williams C                    */
  46. /*    version 2.0. It shouldn't be tough to get it to compile with other    */
  47. /*    things...                                                             */
  48. /*    There are just a few things to look out for when porting this        */
  49. /*    between compilers:                                                    */
  50.  
  51. /*    The blitter routines require a structure known as a memory form        */
  52. /*    descriptor block. Laser C and Alcyon C call this structure a        */
  53. /*    MFDB, while MWC calls this a FDB.                                    */
  54.  
  55. /*    This code will work as both a desk accessory or a program if you    */
  56. /*    link it with the proper startup module. The default Laser startup    */
  57. /*    module works ok. I recommend linking to the laser or                */
  58. /*    MWC startup code supplied with Start magazine October 89. This code    */
  59. /*    gives the smallest executable file, and will work as a program or    */
  60. /*    DA just by changing the file's extention from .prg to .acc            */
  61.  
  62. #include <stdio.h>
  63. #include <string.h>
  64. #include <stdlib.h>
  65. #include <time.h>
  66.  
  67. #include "boink.h"
  68.  
  69. #ifndef EXIT_FAILURE
  70. #define EXIT_FAILURE 1
  71. #endif
  72.  
  73.  
  74. /** _app should be FALSE if boinkout is started as an accessory  **/
  75. /** This is an compiler dependant variable, so adapt it to yours **/
  76. #if OS_TOS
  77. #define GLOBAL    0x0020
  78. #define ALLOCMODE 3|GLOBAL
  79. #define GS_REQUEST  0x1350
  80. #define GS_REPLY    0x1351
  81. #define GS_COMMAND  0x1352
  82. #define GS_ACK      0x1353
  83. #define GS_QUIT     0x1354
  84.  
  85. #define GSM_COMMAND 0x0001
  86.  
  87. #define GSACK_OK      0
  88. #define GSACK_UNKNOWN 1
  89. #define GSACK_ERROR   2
  90. typedef struct
  91. {
  92.     long len;
  93.     int  version;
  94.     int  msgs;
  95.     long ext;
  96. } GS_INFO;
  97. int gsapp=-1;
  98. char *xaccname =NULL;
  99. GS_INFO    *gsi = NULL;
  100. #ifdef __TURBOC__
  101. extern int _app;
  102. #endif
  103. #endif
  104. #if OS_DOS
  105. int _app=1;
  106. #endif
  107.  
  108. /* prototypes */
  109. void rsrc_init(void);
  110. void do_redraw(void);
  111. void new_game(void);
  112. void add_region(int x,int y,int w,int h);
  113. void clear(int x,int y,int w,int h);
  114. void restart_level(void);
  115. void boink_dial(void);
  116. void load_levels(void);
  117. void load_pic(void);
  118. void multi(void);
  119. int open_game_window(void);
  120. void open_vwork(void);
  121. void open_jump(void);
  122. int do_jumpdial(void);
  123.  
  124. /* External variables */
  125. extern int monoballs[], monobricks[], mono_perm_bricks[], monopaddle[];
  126. extern int mono_digits[], mono_fuji[], monofuji_mask[], mono_eye[];
  127. extern int mono_leveltext[], mono_twobrick[], invis, magic_bottom;
  128. extern int medballs[], medbricks[], med_perm_bricks[], medpaddle[];
  129. extern int med_digits[], med_fuji[], medfuji_mask[], med_eye[];
  130. extern int med_leveltext[], med_twobrick[], gravity;
  131.  
  132. extern long snd_system;
  133. extern int sound_switch;
  134.  
  135.  
  136. /* Variables */
  137. int n_redraws;
  138. GRECT region[MAX_ANI];        /* a list of redraw regions */
  139. GRECT tregion [MAX_ANI];        /* temporary clipping region */
  140. BALL_STRUCT bs[MAX_BALLS];
  141.  
  142. int num_balls;
  143. int done = FALSE; /* Tests whether users wants to quit program under application mode */
  144.  
  145. /*char null[] = "";*/
  146.  
  147. #define WI_KIND    (MOVER|CLOSER|NAME)
  148.  
  149. OBJECT *about_dial,*menu_ptr,*timing_dial,*highscore_dial,*scorelist_dial,
  150.         *loading_dial,*icons_dial,*jump_dial, *objcolor_dial;
  151. char *alert_noscore, *alert_cantcreate, *alert_cantfind, *alert_invalid;
  152.  
  153. int    aes_id;
  154.  
  155. int    gl_hchar, gl_wchar, gl_wbox, gl_hbox;    /* sizes of system characters */
  156.  
  157. int    win_kind = WI_KIND;
  158. int    menu_id, paddle_x, paddle_y, pad_y_min, pad_y_max, pad_y_top;
  159.  
  160. int    phys_handle;    /* physical workstation handle */
  161. int    vdi_handle;            /* virtual workstation handle */
  162.  
  163. struct win_info win[MAX_WINDOWS]; /* 1 win_info struct for each window */
  164.  
  165. SCORE_ENTRY scores[10] =
  166.     "Mr. Humphries", 10, 5000L,
  167.     "Mr. Grace Jr.", 9, 4000L,
  168.     "Mr. Lucas", 8, 3500L,
  169.     "Cpt. Peacock", 7, 3000L,
  170.     "Mr. Rumbold", 6, 2500L,
  171.     "Mr. Granger", 5, 2000L,
  172.     "Mrs. Slocumb", 4, 1500L,
  173.     "Mr. Harmon", 3, 1000L,
  174.     "Ms. Brahms", 2, 750L,
  175.     "Mr. Tebbs", 1, 500L
  176. } ; /* This is our highscore list */
  177.  
  178. GRECT desk;
  179. GRECT old;
  180. GRECT work;    /* desktop and work areas */
  181. GRECT max;
  182.  
  183. int    msg[8];                    /* event message buffer */
  184. int    ret;
  185.  
  186. int win_width = 448;
  187. int win_height = 344;
  188.  
  189. extern char intbrickmask[36][63];
  190. char brickmask[99][63];
  191. int level;
  192. int file_levels = 36; /* Number of levels in current file */
  193.  
  194. extern int mode;
  195. int ani_count, num_bricks, cheat;
  196. int    ball_ht = 20; /* Was 21; for some reason */
  197. int win_ht = HEIGHT;
  198. int max_xspeed = 8;
  199. int min_yspeed = -8;
  200. int planes;            /* number of bit planes */
  201.  
  202. int btop = 44;        /* actual top of block of bricks */
  203. int btopm = 39;        /* measured top of bricks */
  204. int bth = 26;        /* total brick height, including space */
  205. int bh = 16;        /* brick height */
  206. int block_bot = 221;    /* block_top = btopm + 7 * bth */
  207. int bleft = 6;
  208. int btw = 48;
  209. int pady_offset = 25;
  210. int max_pad_dy = 16;
  211. int pad_ht = 19;     /* paddle height */
  212. int fuji_ht = 13;
  213. int fmask_ht = 15;
  214. int text_ht = 12;
  215.  
  216. char brickcount[63];
  217. int objcolors[6] = {1,1,1,1,1,1};
  218. int curr_colorobj = -1;
  219.  
  220. char title_bar[] = " BoinkOut2 ";
  221.  
  222. long score, old_score, bonus_life, old_bonus;
  223. int lives, old_lives;
  224.  
  225. int    timer = 0;
  226. int ttimer, event_kind = MU_KEYBD | MU_MESAG | MU_BUTTON;
  227.  
  228. int remap_pal = 1;  /* If this is off the screen colors will be modified by window */
  229.  
  230. int screen_colors;
  231. int junkcolors[2] = {0,1};
  232.  
  233. int ballarray[8];            /* ball blit array */
  234. int paddlearray[8];            /* paddle blit array */
  235. int brickarray[8];
  236.  
  237. long mfdb_buffersize;
  238.  
  239. MFDB ballsource = {0L,144,20,144/16,0,1,0,0,0};
  240. MFDB ballmask = {0L,144,20,144/16,0,1,0,0,0};
  241. MFDB paddlesource = {0L,64,19,64/16,0,1,0,0,0};
  242. MFDB paddlemask = {0L,64,19,64/16,0,1,0,0,0};
  243. MFDB bricksource = {0L,192,16,192/16,0,1,0,0,0};
  244. MFDB nbrickmask = {0L,192,16,192/16,0,1,0,0,0};
  245. MFDB twobricksource = {0L,192,16,192/16,0,1,0,0,0};
  246. MFDB magicbricksource = {0L,192,16,192/16,0,1,0,0,0};
  247. MFDB twobrickmask = {0L,192,16,192/16,0,1,0,0,0};
  248. MFDB permbricksource = {0L,192,16,192/16,0,1,0,0,0};
  249. MFDB permbrickmask = {0L,192,16,192/16,0,1,0,0,0};
  250. MFDB windsource = {0L,448,344,448/16,0,1,0,0,0};
  251. MFDB pic_buf = {0L,448,344,448/16,0,1,0,0,0};
  252. MFDB tit_buf = {0L,474,77,474/16,0,1,0,0,0};
  253. MFDB digitsource = {0L,5*16,12,5,0,1,0,0,0};
  254. MFDB fujisource = {0L,7*16,13,7,0,1,0,0,0};
  255. MFDB fmasksource = {0L,7*16,15,7,0,1,0,0,0};
  256. MFDB eyesource = {0L,144,20,144/16,0,1,0,0,0};
  257. MFDB eyemask = {0L,144,20,144/16,0,1,0,0,0};
  258. MFDB levelsource = {0L,3*16,12,3,0,1,0,0,0};
  259. MFDB screen_fdb;
  260.  
  261. char path[PATH_MAX], name[FILENAME_MAX], lpath[PATH_MAX], spath[PATH_MAX], image_name[FILENAME_MAX];
  262. char config_file[FILENAME_MAX];
  263. char score_file[FILENAME_MAX];
  264.  
  265. RGB1000 screen_colortab[256]; /* used to save colors */
  266. RGB1000 imgcolortab[256]; /* used to save colors */
  267. RGB1000 aboutcolortab[256]; /* used to save colors */
  268.  
  269.  
  270. char *boinkout_version = "This version FREEWARE  Ver: 2.1";
  271.  
  272. #if OS_TOS
  273.     int    AES_type; /* We might want this to be global */
  274. #endif
  275.  
  276. /****************************************************************/
  277. /* open virtual workstation                                        */
  278. /****************************************************************/
  279. void
  280. open_vwork(void)
  281. {
  282.     register int i;
  283.     int work_in[11], work_out[57], vwork_out[57];
  284.  
  285.     for(i=0;i<10;work_in[i++]=1);
  286.     work_in[10]=2;
  287.     vdi_handle=phys_handle;
  288.     v_opnvwk(work_in,&vdi_handle,work_out);
  289.  
  290.     vq_extnd(vdi_handle, 1, vwork_out);
  291.     screen_colors = work_out[13];
  292.     planes = vwork_out[4];
  293.  
  294.     screen_fdb.fd_addr = 0L; /* This is the official way for the screen FDB */
  295. }
  296.  
  297.  
  298.  
  299.  
  300. int hidden;        /* = FALSE */
  301. /****************************************************************/
  302. /* find and redraw all clipping rectangles            */
  303. /****************************************************************/
  304. void
  305. do_redraw(void)
  306. {
  307.     register GRECT *p;
  308.     GRECT t;
  309.     register int i;
  310.     int array[8];
  311.     int x_pos,y_pos, mxmin, mxmax, mymin, mymax;
  312.     int mbut,kstate;
  313.     
  314.     graf_mkstate(&x_pos,&y_pos,&mbut,&kstate);
  315.  
  316.     if (mbut == 0)
  317.         ttimer = timer;
  318.     else
  319.         ttimer = 200;
  320.         
  321.     mxmin = x_pos - 20;
  322.     mxmax = x_pos + 20;
  323.     mymin = y_pos - 20;
  324.     mymax = y_pos + 20;
  325.  
  326.     wind_update(TRUE);
  327.  
  328.     /* check all redraw regions for mouse interference */
  329.     for (i=0; i<n_redraws; i++)
  330.     {
  331.         p = ®ion[i];
  332.         if ((p->g_x < mxmax) && ((p->g_x + p->g_w) > mxmin) &&
  333.             (p->g_y < mymax) && ((p->g_y + p->g_h) > mymin))
  334.         {    
  335.             HIDE_MOUSE;
  336.             hidden = TRUE;
  337.             break;
  338.         }
  339.     }
  340.  
  341.     /* clip all regions to screen size */
  342.     for (i=0; i<n_redraws; i++)
  343.     {
  344.         p = ®ion[i];
  345.  
  346.         if (p->g_x < 0) 
  347.             p->g_x = 0;
  348.  
  349.         if ((p->g_x+p->g_w) > desk.g_w) p->g_w = desk.g_w - p->g_x;
  350.         if ((p->g_y+p->g_h) > max.g_y) p->g_h =max.g_y-p->g_y;
  351.     }
  352.  
  353.     wind_get(win[GAME_WIN].handle,WF_FIRSTXYWH,ELTR(t));
  354.  
  355.     while (t.g_w && t.g_h)
  356.     {
  357.         for (i=0; i<n_redraws; i++)
  358.         {
  359.             p = &tregion[i];
  360.             *p = t;                /* copy this window rect */
  361.  
  362.             if (rc_intersect(®ion[i],p))
  363.             /* tregion[i] clipped to my redraw region */
  364.             {
  365.                 array[0] = p->g_x - work.g_x;
  366.                 array[1] = p->g_y - work.g_y;
  367.                 array[2] = p->g_x - work.g_x + p->g_w - 1;
  368.                 array[3] = p->g_y - work.g_y + p->g_h - 1;
  369.                 array[4] = p->g_x;
  370.                 array[5] = p->g_y;
  371.                 array[6] = p->g_x + p->g_w - 1;
  372.                 array[7] = p->g_y + p->g_h - 1;
  373.  
  374.                 vro_cpyfm(vdi_handle,S_ONLY,array,&windsource,&screen_fdb);
  375.             }
  376.         }
  377.         wind_get(win[GAME_WIN].handle,WF_NEXTXYWH,ELTR(t));
  378.     }
  379.  
  380.     if (hidden)
  381.     {    
  382.         hidden = FALSE;
  383.         SHOW_MOUSE;
  384.     }
  385.  
  386.     wind_update(FALSE);
  387.     n_redraws = 0;
  388. }
  389.  
  390. /********************************/
  391. /*        MAIN()                     */
  392. /********************************/
  393. int
  394. main()
  395. {
  396.     char tempname[FILENAME_MAX];
  397.     char titname[FILENAME_MAX];
  398.  
  399.     srand(time(NULL)); /* Initialize the random number generator ( for rand() )*/
  400.  
  401.     aes_id = appl_init(); /* aes_id wasn't being set?  - DAN */
  402.  
  403. #if OS_TOS
  404.     AES_type = identify_AES();
  405.  
  406.     if (_app != 0)
  407.     {
  408.         if( AES_type != AES_single ) 
  409.         {
  410.             shel_write(9,1,1,"","");
  411.                 
  412.             if ( (AES_type == AES_MTOS)||(AES_type == AES_nAES))
  413.                 menu_register(aes_id, "  BoinkOut2  ");
  414.         }
  415.     }
  416.     else
  417.         menu_id = menu_register(aes_id, "  BoinkOut2  ");
  418. #else
  419.     if (!_app) menu_id=menu_register(aes_id,"  BoinkOut2  ");
  420. #endif
  421.  
  422.  
  423.       if( AES_type == AES_single ) 
  424.        {
  425.            if (_app != 0)
  426.             va_helpbuf = (char *) Malloc(250);
  427.         else
  428.             va_helpbuf = (char *) malloc(250);
  429.     }
  430.     else
  431.         va_helpbuf = (char *) Mxalloc(250,ALLOCMODE);
  432.  
  433.     va_helpbuf[0] = 0;
  434.  
  435.     send_avprot();
  436.     
  437.     phys_handle=graf_handle(&gl_wchar,&gl_hchar,&gl_wbox,&gl_hbox);
  438.  
  439.     wind_get(0, WF_WORKXYWH, ELTR(desk));
  440.  
  441.     old.g_x = desk.g_x + (desk.g_w - WIDTH) / 2;
  442.     old.g_y = desk.g_y + (desk.g_h - win_ht) / 3;
  443.     old.g_w = WIDTH;
  444.     old.g_h = win_ht;
  445.  
  446.     max.g_x = desk.g_x + desk.g_w;
  447.     max.g_y = desk.g_y + desk.g_h;
  448.  
  449. /*    Set up the path for the background picture*/
  450. #if OS_TOS
  451.     path[0] = Dgetdrv() + 'A';
  452.     path[1] = ':';
  453.     Dgetpath(path+2, 0);
  454. #endif
  455. #if OS_DOS
  456.     path[0] = dos_gdrv() + 'A';
  457.     path[1] = ':';
  458.     path[2] = '\\';
  459.     dos_gdir(0, path+3);
  460. #endif
  461. #if OS_UNIX
  462.     getcwd(path, PATH_MAX); /* Will most probably not work */
  463. #endif
  464.     if(path[strlen(path)-1]=='\\')  path[strlen(path)-1]=0;
  465.  
  466.     strcpy(tempname,path);
  467.     strcpy(titname,path);
  468.     strcpy(config_file,path);
  469.     strcpy(score_file,path);
  470.     strcpy(lpath,path);
  471.     strcpy(spath,path);
  472.  
  473. #if OS_TOS
  474.     if( AES_type != AES_single ) 
  475.     {
  476. #endif
  477.         strcat(lpath,"\\data\\levels\\*.lvl");
  478.         strcat(path,"\\data\\img\\*.img");
  479.         strcat(spath,"\\data\\snd\\*.avr");
  480.         strcpy(name,"BOINKOUT.LVL"/*null*/);
  481. #if OS_TOS
  482.     }
  483.     else
  484.     {
  485.         strcat(lpath,"\\data\\levels\\*.LVL");
  486.         strcat(path,"\\data\\img\\*.IMG");
  487.         strcat(spath,"\\data\\snd\\*.AVR");
  488.         strcpy(name,"BOINKOUT.LVL"/*null*/);    
  489.     }
  490. #endif
  491.  
  492.     win[GAME_WIN].handle = NO_WINDOW;
  493.     win[ABOUT_WIN].handle = NO_WINDOW;
  494.     win[JUMP_WIN].handle = NO_WINDOW;
  495.     win[SCORE_WIN].handle = NO_WINDOW;
  496.  
  497.     if (_app)
  498.     {
  499.         open_vwork();
  500.     }
  501.  
  502.     strcat(config_file,"\\data\\boinkout.cfg");
  503.     read_cfg_file(config_file);
  504.  
  505.     if(desk.g_h>300)            /* new monitor */
  506.     {
  507.         windsource.fd_nplanes = planes;
  508.         pic_buf.fd_nplanes = planes;
  509.         tit_buf.fd_nplanes = planes;
  510.          pic_buf.fd_w = windsource.fd_w = win_width;   /* width        */
  511.         windsource.fd_wdwidth = pic_buf.fd_wdwidth = (pic_buf.fd_w + 15) >> 4;
  512.         tit_buf.fd_wdwidth = (tit_buf.fd_w + 15) >> 4;
  513.         windsource.fd_h = pic_buf.fd_h = win_height;     /* height       */
  514.         windsource.fd_stand = pic_buf.fd_stand = 0;                     /* raster format = device */
  515.  
  516.         ballsource.fd_addr = monoballs; 
  517.         ballmask.fd_addr = monoballs; 
  518.         paddlesource.fd_addr = monopaddle;
  519.         paddlemask.fd_addr = monopaddle;
  520.         bricksource.fd_addr = monobricks;
  521.         nbrickmask.fd_addr = monobricks;
  522.         twobricksource.fd_addr = mono_twobrick;
  523.         magicbricksource.fd_addr = mono_twobrick;
  524.         twobrickmask.fd_addr = mono_twobrick;
  525.         permbricksource.fd_addr = mono_perm_bricks;
  526.         permbrickmask.fd_addr = mono_perm_bricks;
  527.         digitsource.fd_addr = mono_digits;
  528.         fujisource.fd_addr = mono_fuji;
  529.         fmasksource.fd_addr = monofuji_mask;
  530.         eyesource.fd_addr = mono_eye;
  531.         eyemask.fd_addr = mono_eye;
  532.         levelsource.fd_addr = mono_leveltext;
  533.  
  534.         fix_image(&ballsource,objcolors[1]);
  535.         fix_image(&paddlesource,objcolors[0]);
  536.         fix_image(&bricksource,objcolors[2]);
  537.         fix_image(&twobricksource,objcolors[5]);
  538.         fix_image(&magicbricksource,objcolors[4]);
  539.         fix_image(&permbricksource,objcolors[3]);
  540.         fix_image(&digitsource,1);
  541.         fix_image(&fujisource,objcolors[1]);
  542.         fix_image(&eyesource,objcolors[1]);
  543.         fix_image(&levelsource,1);
  544.  
  545.         pad_y_min = 247;
  546.         pad_y_max = 323;
  547.     }
  548.     else
  549.     {
  550.         win_height=win_height/2;
  551.         windsource.fd_nplanes = planes;
  552.         pic_buf.fd_nplanes = planes;
  553.         tit_buf.fd_nplanes = planes;
  554.          pic_buf.fd_w = windsource.fd_w = win_width;   /* width        */
  555.         windsource.fd_wdwidth = pic_buf.fd_wdwidth = (pic_buf.fd_w + 15) >> 4;
  556.         tit_buf.fd_wdwidth = (tit_buf.fd_w + 15) >> 4;
  557.         windsource.fd_h = pic_buf.fd_h = win_height;     /* height       */
  558.         windsource.fd_stand = pic_buf.fd_stand = 0;                     /* raster format = device */
  559.  
  560.         ball_ht = 10;
  561.         win_ht = HEIGHT/2;
  562.         min_yspeed = -4;
  563.         btop = 22;
  564.         btopm = 20;
  565.         bth = 13;
  566.         bh = 8;
  567.         block_bot = 111;
  568.         pady_offset = 12;
  569.         max_pad_dy = 8;
  570.         pad_ht = 10;
  571.         fuji_ht = 6;
  572.         fmask_ht = 8;
  573.         text_ht = 6;
  574.  
  575.         pad_y_min = 122;
  576.         pad_y_max = 159;
  577.  
  578.         ballsource.fd_addr = medballs;
  579.         paddlesource.fd_addr = medpaddle;
  580.         paddlemask.fd_addr = medpaddle;
  581.         bricksource.fd_addr = medbricks;
  582.         nbrickmask.fd_addr = medbricks;
  583.         twobricksource.fd_addr = med_twobrick;
  584.         magicbricksource.fd_addr = med_twobrick;
  585.         twobrickmask.fd_addr = med_twobrick;
  586.         permbricksource.fd_addr = med_perm_bricks;
  587.         permbrickmask.fd_addr = med_perm_bricks;
  588.         digitsource.fd_addr = med_digits;
  589.         fujisource.fd_addr = med_fuji;
  590.         fmasksource.fd_addr = medfuji_mask;
  591.         eyesource.fd_addr = med_eye;
  592.         eyemask.fd_addr = med_eye;
  593.         levelsource.fd_addr = med_leveltext;
  594.  
  595.     }
  596.  
  597.     mfdb_buffersize = 2L*(long)pic_buf.fd_wdwidth*(long)pic_buf.fd_nplanes*(long)pic_buf.fd_h;
  598.  
  599.     if(( windsource.fd_addr = (short *) malloc(mfdb_buffersize ))== NULL)
  600.         printf("No memory for window buffer\r\n");
  601.     if(( pic_buf.fd_addr = (short *) malloc(mfdb_buffersize )) == NULL)
  602.         printf("No memory for off screen buffer\r\n");
  603.  
  604.     /* Now load the title picture */
  605.  
  606.     mfdb_buffersize = 2L*(long)tit_buf.fd_wdwidth*(long)tit_buf.fd_nplanes*(long)tit_buf.fd_h;
  607.  
  608.     /* Not being able to load the title image should NOT be fatal 
  609.         however it is at the moment */
  610.  
  611.     if(( tit_buf.fd_addr = (short *) malloc(mfdb_buffersize )) == NULL)
  612.         printf("No memory for title buffer\r\n");
  613.  
  614.     /* Load RSC */
  615.     if (!rsrc_load("boinkout.rsc"))
  616.     {
  617.         form_alert(1, "[1][Error Loading Resource!][Quit]");
  618.         exit(EXIT_FAILURE);
  619.     }
  620.         
  621.     rsrc_init();
  622.     
  623.     set_tedinfo(about_dial, R_VERSION, boinkout_version);
  624.     
  625.     if (_app)
  626.     {
  627.         graf_mouse( ARROW, 0L);
  628.  
  629.         menu_bar(menu_ptr, 1);    /* display the menu */
  630.     }
  631.  
  632.     save_colors();
  633.  
  634.     if (_app)
  635.     {
  636.         do_loading();
  637.  
  638.         do_wind_redraw(win[LOADING_WIN].handle,&win[LOADING_WIN].curr);
  639.     }
  640.  
  641.     strcat(titname,"\\data\\img\\title.img");
  642.     img_load(&tit_buf, titname);
  643.  
  644.     save_about_colors();
  645.  
  646.     if (_app)
  647.     {
  648.         set_tedinfo(loading_dial, RIMG_COUNT, "(2/2)");
  649.         
  650.         do_wind_redraw(win[LOADING_WIN].handle,&win[LOADING_WIN].curr);
  651.     }
  652.  
  653.     strcat(tempname,"\\data\\img\\back.img");
  654.     img_load(&pic_buf, tempname);
  655.  
  656.     save_image_colors();
  657.  
  658.     if (_app)
  659.     {
  660.         wind_close(win[LOADING_WIN].handle);
  661.         wind_delete(win[LOADING_WIN].handle);
  662.  
  663.         win[LOADING_WIN].handle = NO_WINDOW;
  664.     }
  665.  
  666.     reset_colors();
  667.  
  668.     strcat(score_file,"\\data\\boinkout.hgh");
  669.     read_highscore();
  670.  
  671.     memcpy(brickmask,intbrickmask,sizeof(intbrickmask));
  672.  
  673.     sound_init();
  674.  
  675.     multi();            /* accessory will not return, program will */
  676.  
  677.     sound_exit();
  678.  
  679.     menu_bar(menu_ptr, 0);    /* erase the menu bar */
  680.  
  681.     if (remap_pal == 0)
  682.         reset_colors();
  683.  
  684.     v_clsvwk(vdi_handle);    /* close the vdi handle */
  685.  
  686.     if (planes > 2)
  687.     {
  688.         free(ballsource.fd_addr); 
  689.         free(paddlesource.fd_addr);
  690.         free(bricksource.fd_addr);
  691.         free(twobricksource.fd_addr);
  692.         free(magicbricksource.fd_addr);
  693.         free(permbricksource.fd_addr);
  694.         free(digitsource.fd_addr);
  695.         free(fujisource.fd_addr);
  696.         free(eyesource.fd_addr);
  697.         free(levelsource.fd_addr);
  698.     }
  699.  
  700.     free(pic_buf.fd_addr);
  701.     free(tit_buf.fd_addr);
  702.     free(windsource.fd_addr);
  703.  
  704.     send_avexit();
  705.     
  706.     Mfree(va_helpbuf);
  707.  
  708.     rsrc_free();
  709.     appl_exit();
  710.     
  711.     exit(1);
  712. }
  713.  
  714. void
  715. m_timing_event(void)
  716. {
  717.     int xchoice;
  718.     GRECT dial;
  719.     char tempstr[4];
  720.  
  721.     if (remap_pal == 0)
  722.         reset_colors();
  723.  
  724.     sprintf(tempstr,"%d",timer);
  725.  
  726.     set_tedinfo(timing_dial, TIMING_VALUE, tempstr);
  727.  
  728.     form_center(timing_dial,ELTR(dial));
  729.     form_dial(FMD_START,0,0,10,10,ELTS(dial));
  730.     objc_draw(timing_dial,0,3,ELTS(dial));
  731.  
  732.     xchoice = (form_do(timing_dial, 0) & 0x7fff);
  733.  
  734.     form_dial(FMD_FINISH,0,0,10,10,ELTS(dial));
  735.  
  736.     timing_dial[xchoice].ob_state &= ~SELECTED;
  737.  
  738.     if (xchoice == B_SETTIME)
  739.     {
  740.         get_tedinfo(timing_dial,TIMING_VALUE,tempstr);
  741.         timer = atoi(tempstr);
  742.     }
  743.  
  744.     if (remap_pal == 0)
  745.         load_image_colors();
  746. }
  747.  
  748. void
  749. get_high_name(int x)
  750. {
  751.     int xchoice;
  752.     GRECT dial;
  753.     static char tempstr[14]="";
  754.  
  755.     if (remap_pal == 0)
  756.         reset_colors();
  757.  
  758.     set_tedinfo(highscore_dial, D_ENTERNAME, tempstr);
  759.  
  760.     form_center(highscore_dial,ELTR(dial));
  761.     form_dial(FMD_START,0,0,10,10,ELTS(dial));
  762.     objc_draw(highscore_dial,0,3,ELTS(dial));
  763.     xchoice = (form_do(highscore_dial, 0) & 0x7fff);
  764.     form_dial(FMD_FINISH,0,0,10,10,ELTS(dial));
  765.  
  766.     highscore_dial[xchoice].ob_state &= ~SELECTED;
  767.  
  768.     get_tedinfo(highscore_dial,D_ENTERNAME,tempstr);
  769.  
  770.     strcpy(scores[x].name,tempstr);
  771.     scores[x].level = level + 1;
  772.     scores[x].score = score;    /* MAR -- .score is now long  */
  773.  
  774.     write_score();
  775.     read_highscore();
  776.  
  777.     if (remap_pal == 0)
  778.         load_image_colors();
  779. }
  780.  
  781. void
  782. m_load_event(void)
  783. {
  784.     if (remap_pal == 0)
  785.         reset_colors();
  786.  
  787.     load_pic();
  788. }
  789.  
  790. void
  791. m_quit_event(void)
  792. {
  793.     if (win[GAME_WIN].handle != NO_WINDOW)
  794.     {    
  795.         wind_close(win[GAME_WIN].handle);
  796.         wind_delete(win[GAME_WIN].handle);
  797.     }
  798.  
  799.     done = TRUE;
  800. }
  801.  
  802. void
  803. m_new_event(void)
  804. {
  805.     if (win[GAME_WIN].handle != NO_WINDOW)
  806.     {    
  807.         if (win[GAME_WIN].status == 3) /* iconified */
  808.             un_iconify(GAME_WIN,(GRECT *)&win[GAME_WIN].curr);
  809.  
  810.         wind_set(win[GAME_WIN].handle,WF_TOP,0,0,0,0);
  811.  
  812.         if (lives <= 0)
  813.         {
  814.             new_game();
  815.             restart_level();
  816.             event_kind = MU_MESAG | MU_TIMER | MU_BUTTON | MU_KEYBD;
  817.         }
  818.     }
  819.     else open_game_window();
  820. }
  821.  
  822. /*
  823.  *  This routine handles all keyboard input
  824.  */
  825. void
  826. handle_key_evnts(int key,int mousex,int mousey)
  827. {
  828.     int cont, next, state, scan;
  829.     int w_info, top_window;
  830.     GRECT p;
  831.  
  832.     top_window = get_topwindow(0);
  833.  
  834.     wind_get(top_window,WF_WORKXYWH,ELTR(p));
  835.  
  836.     w_info = get_wininfo_from_handle(top_window);
  837.  
  838.     if ((w_info != -1) && (win[w_info].status == 1))
  839.     {            
  840.         if(w_info == JUMP_WIN)
  841.         {
  842.             cont = form_keybd(win[JUMP_WIN].window_obj, win[JUMP_WIN].cur_item, 0, key, &next, &scan);
  843.  
  844.             if (scan)
  845.             {
  846.                 /* if not special the edit the form */
  847.                     
  848.                 objc_edit(win[JUMP_WIN].window_obj, win[JUMP_WIN].cur_item, scan, (int *)win[JUMP_WIN].edit_pos, ED_CHAR,(int *)&win[JUMP_WIN].edit_pos);
  849.                 return;
  850.             }
  851.  
  852.             if ((cont != 1) || (next!=0 && next != win[w_info].cur_item))
  853.             {    
  854.                 objc_edit(win[JUMP_WIN].window_obj, win[JUMP_WIN].cur_item, 0, win[JUMP_WIN].edit_pos, ED_END,&win[JUMP_WIN].edit_pos);
  855.  
  856.                 if (next == JUMP_GO)
  857.                     jump_drive(next);
  858.                 else
  859.                 {
  860.                     win[JUMP_WIN].cur_item = next;
  861.  
  862.                     objc_edit(win[JUMP_WIN].window_obj,win[JUMP_WIN].cur_item,0, win[JUMP_WIN].edit_pos,ED_INIT,&win[JUMP_WIN].edit_pos);
  863.                 }
  864.                 return;
  865.             }                
  866.         }            
  867.     }                
  868. /*printf("%d\r\n",key);
  869. */            
  870.     switch (key)
  871.     {
  872.         case 283:  /* Esc key */
  873.             if(w_info == GAME_WIN)
  874.             {
  875.                 if(win[w_info].status == 1)
  876.                 {
  877.                     /* Esc - Pause */
  878.                     if (event_kind == (MU_MESAG | MU_TIMER | MU_BUTTON | MU_KEYBD))
  879.                         event_kind = MU_MESAG | MU_KEYBD | MU_BUTTON;
  880.                     else
  881.                         event_kind = MU_MESAG | MU_TIMER | MU_BUTTON | MU_KEYBD;
  882.                 }
  883.             }
  884.             break;
  885.                     
  886.         case 9740:
  887.             /* Control L */
  888.             m_load_event();
  889.             break;
  890.                     
  891.         case 4113:
  892.             /* Control Q */
  893.             m_quit_event();
  894.             break;
  895.                     
  896.         case 6159:
  897.             /* Control O */
  898.             m_new_event();
  899.             break;
  900.                     
  901.         case 9226:
  902.             /* Control J */
  903.             open_jump();    
  904.             break;
  905.  
  906.         case 11779:
  907.             /* Control C - copy */
  908.             if ((w_info != -1) && (win[w_info].status == 1)&&
  909.                 (win[w_info].edit == 1) && (win[w_info].cur_item != -1))
  910.                 copy_paste(w_info);
  911.             break;
  912.         case 12054:
  913.             /* Control V - Paste */
  914.             if ((w_info != -1) && (win[w_info].status == 1))
  915.                 paste_text(w_info);
  916.             break;
  917.                     
  918.         case 12558:
  919.             /* Control N */
  920.             m_new_event();
  921.             break;
  922.  
  923.         case 25088: /* Help Key */
  924.  
  925. #if 0            
  926.             switch(w_info)
  927.             {
  928.                 case INBOX_WIN:
  929.                     do_help("INBOX Window");
  930.                     break;
  931.                 case OUTBOX_WIN:
  932.                     do_help("OUTBOX Window");
  933.                     break;
  934.                 case ABOUT_WIN:
  935.                     do_help("Contents");
  936.                     break;
  937.                 default:
  938.                     do_help("Main");
  939.                     break;
  940.             }
  941. #endif
  942.             do_help("Main");
  943.             break;
  944.             
  945.         default:
  946. sendkey:
  947.             state = (int)Kbshift(-1);
  948.                     
  949.             msg[0] = AV_SENDKEY;
  950.  
  951. #ifdef __GNUC__
  952.              msg[1] = _global[2];  /* my apps id */ 
  953. #else
  954.               msg[1] = _GemParBlk.global[2];  /* my apps id */ 
  955. #endif
  956.             msg[2] = 0;
  957.             msg[3] = state;
  958.             msg[4] = key;
  959.             msg[5] = msg[6] = msg[7] = 0;
  960.             appl_write(get_avserver(), 16, &msg);
  961.             break;     
  962.     }
  963.                         
  964.     return;
  965. }
  966. #if OS_TOS
  967. int doGSCommand(int pipe[8])
  968. {
  969.     int   answ[8], ret=0;
  970.     char *cmd = *(char **)&pipe[3];
  971.     char *gslongname =NULL;
  972.     answ[0]=GS_ACK;
  973.     answ[1]=aes_id;
  974.     answ[2]=0;
  975.     answ[3]=pipe[3];
  976.     answ[4]=pipe[4];
  977.     answ[5]=0;
  978.     answ[6]=0;
  979.     answ[7]=GSACK_ERROR;
  980.     if (xaccname==NULL) {
  981.         xaccname = (char *)Mxalloc(96L,ALLOCMODE);
  982.     }
  983.     gslongname = xaccname+64;
  984.     strcpy(gslongname,"BoinkOut");
  985.     if (cmd)
  986.     {
  987.         answ[7]=GSACK_UNKNOWN;
  988.  
  989.         if ( (!stricmp(cmd,"Quit")) || (!stricmp(cmd,"Shutdown")) )
  990.         {
  991.             ret=1;
  992.             answ[7]=GSACK_OK;
  993.         }
  994.         else if (!stricmp(cmd,"Open")) {
  995.             m_load_event();            
  996.             answ[7]=GSACK_OK;
  997.         } else if (!stricmp(cmd,"AppGetLongName")) {
  998.             if (gslongname)
  999.             {
  1000.                 answ[5]=(int)(((long)gslongname >> 16) & 0x0000ffffL);
  1001.                 answ[6]=(int)((long)gslongname & 0x0000ffffL);
  1002.                 answ[7]=GSACK_OK;
  1003.             }
  1004.             else
  1005.             {
  1006.                 answ[7]=GSACK_ERROR;
  1007.             }
  1008.         }
  1009.     }
  1010.  
  1011.     appl_write(pipe[1],16,answ);
  1012.     if ( (!stricmp(cmd,"Quit")) || (!stricmp(cmd,"Shutdown")) ) {
  1013.         m_quit_event();
  1014.     }
  1015.  
  1016.     return(ret);
  1017. }
  1018.  
  1019. #endif
  1020. /****************************************************************/
  1021. /* dispatches all accessory tasks                */
  1022. /****************************************************************/
  1023. void
  1024. multi(void)
  1025. {
  1026.     int event, scan;
  1027.     int junk, k, w_info, top_window;
  1028.     int button = 0, clicks = 0;
  1029.     int mousex, mousey;    
  1030.     int which_obj;
  1031.  
  1032. /*    The accessory will loop forever, the program loops until    */
  1033. /*    the done variable is set to TRUE.                            */
  1034.  
  1035.     while ((!_app) || !done)
  1036.     {
  1037.         event = evnt_multi(event_kind,
  1038. /*            1,0,0,*/
  1039.             2,1,1,
  1040.             0,0,0,0,0,
  1041.             0,0,0,0,0,
  1042.             msg,
  1043.             ttimer,0,
  1044.             &mousex,&mousey,&button,&ret,&scan,&clicks);
  1045.  
  1046.         if (event & MU_MESAG) switch (msg[0])
  1047.         {
  1048.  
  1049.         case MN_SELECTED:
  1050.  
  1051.         /* menu functions, program only */
  1052.  
  1053.             switch(msg[4])
  1054.             {
  1055.  
  1056.             case ABOUT_BOINK:
  1057.                 boink_dial();
  1058.                 break;
  1059.  
  1060.             case M_NEW:
  1061.                 m_new_event();
  1062.                 break;
  1063.  
  1064.             case M_PAUSE:
  1065.                 if (event_kind == (MU_MESAG | MU_TIMER | MU_BUTTON | MU_KEYBD))
  1066.                     event_kind = MU_MESAG | MU_KEYBD | MU_BUTTON;
  1067.                 else
  1068.                     event_kind = MU_MESAG | MU_TIMER | MU_BUTTON | MU_KEYBD;
  1069.                 break;
  1070.  
  1071.             case M_LEVEL:
  1072.                 load_levels();
  1073.                 break;
  1074.                 
  1075.             case M_JUMP:
  1076.                 open_jump();
  1077.                 break;
  1078.                 
  1079.             case M_LOAD:
  1080.                 m_load_event();
  1081.                 break;
  1082.  
  1083.             case M_QUIT:
  1084.                 m_quit_event();
  1085.                 break;
  1086.                 
  1087.             case M_SOUNDSWITCH:
  1088.                 sound_switch=!sound_switch;
  1089.                 break;
  1090. #if 0
  1091.     I removed this option right now
  1092.                     
  1093.             case M_REMAPPALETTE:
  1094.                 remap_pal=!remap_pal;
  1095.                 break;
  1096. #endif 
  1097.             
  1098.             case M_SETCOLORS:
  1099.                 open_objcolors();
  1100.                 break;
  1101.                 
  1102.             case M_TIMING:
  1103.                 m_timing_event();
  1104.                 break;
  1105.                 
  1106.             case M_VIEWSCORES:
  1107.                 high_score();
  1108.                 break;
  1109.                 
  1110.             case M_SAVEPREF:
  1111.                 write_cfg_file(config_file);
  1112.                 break;
  1113.             
  1114.             case M_HELP:
  1115.                 do_help("Main");
  1116.                 break;
  1117.             }
  1118.  
  1119.             menu_tnormal(menu_ptr, msg[3], TRUE ); /* deselect menubar */
  1120.             break;
  1121.  
  1122.         case WM_REDRAW:
  1123.             w_info = get_wininfo_from_handle(msg[3]);
  1124.         
  1125.             if (w_info != -1)
  1126.             {
  1127.                 if ((w_info == GAME_WIN)&&
  1128.                     (win[w_info].status == 1))
  1129.                 {
  1130.                     add_region(msg[4],msg[5],msg[6],msg[7]);
  1131.                     do_redraw();
  1132.                 }
  1133.                 else
  1134.                     do_wind_redraw(win[w_info].handle,(GRECT *)&msg[4]);
  1135.             }
  1136.             break;
  1137.  
  1138.         case WM_NEWTOP:
  1139.         case WM_TOPPED:
  1140.             wind_set(msg[3], WF_TOP, msg[3], 0,0,0);
  1141.             /* Nasty hack for lower resolutions
  1142.                 and to deal with my nasty programming */
  1143.  
  1144.             if (remap_pal == 0)
  1145.             {
  1146.                 if (msg[3] == win[GAME_WIN].handle)
  1147.                     load_image_colors();
  1148.                 else if (msg[3] == win[OBJCOLOR_WIN].handle)
  1149.                     load_image_colors();
  1150.                 else if (msg[3] == win[ABOUT_WIN].handle)        
  1151.                     load_about_colors();
  1152.                 else 
  1153.                     reset_colors();
  1154.             }
  1155.                     
  1156.             break;
  1157.  
  1158.         case AC_CLOSE:
  1159.             if((msg[3] == menu_id) && (win[GAME_WIN].handle != NO_WINDOW))
  1160.             {
  1161.                 wind_update(TRUE);
  1162.  
  1163.                 v_clsvwk(vdi_handle);
  1164.  
  1165.                 win[GAME_WIN].handle = NO_WINDOW;
  1166.                 sound_exit();
  1167.                 event_kind = MU_MESAG | MU_KEYBD | MU_BUTTON;
  1168.                 wind_update(FALSE);
  1169.             }
  1170.             break;
  1171.  
  1172. #if OS_TOS
  1173.         case AP_TERM:
  1174.             if (_app)
  1175.                 done = 1;
  1176.             break;
  1177. #endif
  1178.         case WM_CLOSED:
  1179.             if(msg[3] == win[GAME_WIN].handle)
  1180.             {    wind_close(win[GAME_WIN].handle);
  1181.                 graf_shrinkbox(desk.g_x,desk.g_y,gl_wbox,gl_hbox,ELTS(old));
  1182.                 wind_delete(win[GAME_WIN].handle);
  1183.  
  1184.                 if (!_app) v_clsvwk(vdi_handle);
  1185.  
  1186.                 win[GAME_WIN].handle = NO_WINDOW;
  1187.                 sound_exit();
  1188.                 event_kind = MU_MESAG | MU_KEYBD | MU_BUTTON;
  1189.             }
  1190.             else
  1191.             {
  1192.                 wind_close(msg[3]);
  1193.                 wind_delete(msg[3]);
  1194.  
  1195.                 w_info = get_wininfo_from_handle(msg[3]);
  1196.             
  1197.                 win[w_info].handle = NO_WINDOW;            
  1198.  
  1199.                 if (remap_pal == 0)
  1200.                 {
  1201.                     if (win[GAME_WIN].handle == get_topwindow(msg[3]))                    
  1202.                         load_image_colors();
  1203.                     else if (win[ABOUT_WIN].handle == get_topwindow(msg[3]))
  1204.                         load_about_colors();
  1205.                     else
  1206.                         reset_colors();
  1207.                 }
  1208.             }
  1209.             break;
  1210.  
  1211. #if OS_TOS
  1212.         case GS_REQUEST:
  1213.             {
  1214.                 int answ[8];
  1215.                 
  1216.                 answ[0]=GS_REPLY;
  1217.                 answ[1]=aes_id;
  1218.                 answ[2]=0;
  1219.                 answ[3]=0;
  1220.                 answ[4]=0;
  1221.                 answ[5]=0;
  1222.                 answ[6]=1;
  1223.                 answ[7]=msg[7];
  1224.  
  1225.                 if (!gsi) gsi = (GS_INFO *)Mxalloc(sizeof(GS_INFO),ALLOCMODE);
  1226.                 
  1227.                 if (gsi)
  1228.                 {
  1229.                     GS_INFO *sender = *(GS_INFO **)&msg[3];
  1230.  
  1231.                     gsi->len     = sizeof(GS_INFO);
  1232.                     gsi->version = 0x0100;
  1233.                     gsi->msgs    = GSM_COMMAND;
  1234.                     gsi->ext     = 0L;
  1235.                     
  1236.                     answ[3]=(int)(((long)gsi >> 16) & 0x0000ffffL);
  1237.                     answ[4]=(int)((long)gsi & 0x0000ffffL);
  1238.                     
  1239.                     if (sender)
  1240.                     {
  1241.                         if (sender->version >= 0x0070)
  1242.                         {
  1243.                             answ[6]=0;
  1244.                             gsapp=msg[1];
  1245.                         }
  1246.                     }
  1247.                 }
  1248.                 
  1249.                 appl_write(gsapp,16,answ);
  1250.             }
  1251.             break;
  1252.         case GS_COMMAND:
  1253.             if (doGSCommand(msg)) return; /* (1); - we don't track returns from here so does it really matter */
  1254.             break;
  1255.         case WM_ICONIFY:
  1256.             w_info = get_wininfo_from_handle(msg[3]);
  1257.             
  1258.             if (w_info != -1)            
  1259.                 iconify(w_info,((GRECT *)&msg[4]));
  1260.  
  1261.             if (w_info == GAME_WIN)
  1262.                 event_kind = MU_MESAG | MU_KEYBD | MU_BUTTON;
  1263.  
  1264.             if (remap_pal == 0)
  1265.             {
  1266.                 if (win[GAME_WIN].handle == get_topwindow(msg[3]))            
  1267.                     load_image_colors();
  1268.                 else
  1269.                     reset_colors();
  1270.             }
  1271.             break;
  1272.  
  1273.         case WM_UNICONIFY:
  1274.             w_info = get_wininfo_from_handle(msg[3]);
  1275.  
  1276.             if (w_info != -1)
  1277.             {
  1278.                 un_iconify(w_info,((GRECT *)&msg[4]));
  1279.  
  1280.                 wind_set(msg[3], WF_TOP, msg[3]);
  1281.             
  1282.                 if (remap_pal == 0)
  1283.                 {
  1284.                     if (w_info == GAME_WIN)
  1285.                         load_image_colors();
  1286.                     else if (w_info == ABOUT_WIN)
  1287.                         load_about_colors();
  1288.                     else 
  1289.                         reset_colors();
  1290.                 }
  1291.             }
  1292.                 
  1293.             break;
  1294. #endif /* OS_TOS */
  1295.  
  1296.         case WM_MOVED:
  1297.             if(msg[3] == win[GAME_WIN].handle) 
  1298.             {
  1299.                 old.g_x = msg[4];
  1300.                 old.g_y = msg[5];
  1301.  
  1302.                 wind_set(win[GAME_WIN].handle,WF_CURRXYWH,msg[4],
  1303.                     msg[5],old.g_w,old.g_h);
  1304.                 wind_get(win[GAME_WIN].handle,WF_WORKXYWH,ELTR(work));
  1305.             }
  1306.             else
  1307.             {
  1308.                 wind_set(msg[3], WF_CURRXYWH, PTRS((GRECT *)&msg[4]));
  1309.  
  1310.                 w_info = get_wininfo_from_handle(msg[3]);
  1311.  
  1312.                 switch(win[w_info].status)
  1313.                 {
  1314.                     case 1:
  1315.                         /* Normal */
  1316.                             
  1317.                         if (win[w_info].type == 0)
  1318.                             wind_calc(WC_WORK, W_TYPE, PTRS((GRECT *)&msg[4]),
  1319.                               ELTR(win[w_info].curr));
  1320.                         else
  1321.                             wind_calc(WC_WORK, W_T2, PTRS((GRECT *)&msg[4]),
  1322.                               ELTR(win[w_info].curr));
  1323.  
  1324.                         win[w_info].window_obj[ROOT].ob_x = win[w_info].curr.g_x;
  1325.                         win[w_info].window_obj[ROOT].ob_y = win[w_info].curr.g_y;
  1326.                         win[w_info].window_obj[ROOT].ob_width = win[w_info].curr.g_w;
  1327.                         win[w_info].window_obj[ROOT].ob_height = win[w_info].curr.g_h;
  1328.                         break;
  1329.                             
  1330.                     case 2:
  1331.                         /* Rolled up */                        
  1332.  
  1333.                         wind_calc(WC_WORK, W_TYPE, PTRS((GRECT *)&msg[4]),
  1334.                           &win[w_info].curr.g_x,
  1335.                           &win[w_info].curr.g_y,
  1336.                           &junk,
  1337.                           &junk);
  1338.  
  1339.                     case 3:
  1340.                         /* Iconified */
  1341.  
  1342.                         wind_calc(WC_WORK, W_TYPE, PTRS((GRECT *)&msg[4]),
  1343.                           ELTR(win[w_info].icon));
  1344.  
  1345.                         win[w_info].icon_obj[ROOT].ob_x = win[w_info].icon.g_x;
  1346.                         win[w_info].icon_obj[ROOT].ob_y = win[w_info].icon.g_y;
  1347.                         win[w_info].icon_obj[ROOT].ob_width = win[w_info].icon.g_w;
  1348.                         win[w_info].icon_obj[ROOT].ob_height = win[w_info].icon.g_h;
  1349.                         break;
  1350.                 }
  1351.             }
  1352.  
  1353.             break;
  1354.  
  1355.         case AC_OPEN:
  1356.             if (msg[4] == menu_id)
  1357.             {
  1358.                 graf_mkstate(&junk, &junk, &junk, &k);
  1359.                 if(k & 3)
  1360.                 {
  1361.                     boink_dial();
  1362.                     break;
  1363.                 }
  1364.  
  1365.                 if (win[GAME_WIN].handle == NO_WINDOW)
  1366.                 {    
  1367.                     open_vwork();
  1368.  
  1369.                     if (open_game_window() < 0)
  1370.                     {
  1371.                         v_clsvwk(vdi_handle);
  1372.                         break;
  1373.                     }
  1374.                 }
  1375.                 else
  1376.                 {
  1377.                     if (win[GAME_WIN].status == 3) /* iconified */
  1378.                         un_iconify(GAME_WIN,(GRECT *)&win[GAME_WIN].curr);
  1379.  
  1380.                     wind_set(win[GAME_WIN].handle,WF_TOP,0,0,0,0);
  1381.                     if (lives <= 0)
  1382.                     {
  1383.                         new_game();
  1384.                         restart_level();
  1385.                         event_kind = MU_MESAG | MU_TIMER | MU_BUTTON | MU_KEYBD;
  1386.                     }
  1387.                 }
  1388.             }
  1389.             break;
  1390.  
  1391.         } /* switch (msg[0]) */
  1392.  
  1393.  
  1394.         
  1395.         /* Grab those fabulous hot keys */
  1396.         if (event & MU_KEYBD)
  1397.             handle_key_evnts(scan, mousex, mousey);
  1398.         
  1399.         if (event & MU_TIMER)
  1400.         {    if (win[GAME_WIN].handle != NO_WINDOW)
  1401.             {
  1402.                 new_ball();
  1403.             }
  1404.         }
  1405.  
  1406.         /* Get Mouse Button Events */
  1407.         if (event & MU_BUTTON)
  1408.         {
  1409.             if (button == 1)
  1410.             {
  1411.                 junk = wind_find(mousex,mousey);
  1412.  
  1413.                 top_window = get_topwindow(junk);
  1414.         
  1415.                 if (top_window == junk) /* don't do anything unless top window */
  1416.                 {    
  1417.                     w_info = get_wininfo_from_handle(junk);
  1418.                         
  1419.                     if (win[w_info].status == 1) /* don't do anything if iconified */
  1420.                     {
  1421.                         which_obj = objc_find(win[w_info].window_obj,0,MAX_DEPTH,mousex,mousey);
  1422.     
  1423.                         if (w_info == JUMP_WIN)
  1424.                             jump_drive(which_obj);
  1425.                         else if (w_info == OBJCOLOR_WIN)
  1426.                             objcolors_drive(which_obj);
  1427.                         else if (w_info == ABOUT_WIN)
  1428.                             about_drive(which_obj);
  1429.                     }
  1430.                 }
  1431.             }
  1432.         }
  1433.         
  1434.     } /* while (!_app || !done) */
  1435. }
  1436.  
  1437. /* put up high score list window */
  1438. void
  1439. high_score(void)
  1440. {
  1441.  
  1442.     if (win[SCORE_WIN].handle == NO_WINDOW)
  1443.     {
  1444.         do_scorelist();
  1445.         return;
  1446.     }
  1447.  
  1448.     if (win[SCORE_WIN].status == 3) /* iconified */
  1449.     {
  1450.         un_iconify(SCORE_WIN, (GRECT *)&win[SCORE_WIN].curr);
  1451.         wind_set(win[SCORE_WIN].handle, WF_TOP, win[SCORE_WIN].handle,0,0,0);
  1452.     }
  1453.     else if (win[SCORE_WIN].status == 1) /* normal */
  1454.     {
  1455.         wind_set(win[SCORE_WIN].handle, WF_TOP, win[SCORE_WIN].handle,0,0,0);
  1456.     }
  1457.     else
  1458.         do_scorelist();
  1459.  
  1460.     return;
  1461. }
  1462.  
  1463. /* put up about window */
  1464. void
  1465. boink_dial(void)
  1466. {
  1467.     if (win[ABOUT_WIN].handle == NO_WINDOW)
  1468.     {
  1469.         do_title();
  1470.         return;
  1471.     }
  1472.  
  1473.     if (win[ABOUT_WIN].status == 3) /* iconified */
  1474.     {
  1475.         un_iconify(ABOUT_WIN,(GRECT *)&win[ABOUT_WIN].curr);
  1476.         wind_set(win[ABOUT_WIN].handle, WF_TOP, win[ABOUT_WIN].handle,0,0,0);
  1477.     }
  1478.     else if (win[ABOUT_WIN].status == 1) /* normal */
  1479.     {
  1480.         wind_set(win[ABOUT_WIN].handle, WF_TOP, win[ABOUT_WIN].handle,0,0,0);
  1481.     }
  1482.     else
  1483.         do_title();
  1484.  
  1485.     return;
  1486. }
  1487.  
  1488. /* put up jump window dialog */
  1489. void
  1490. open_jump(void)
  1491. {
  1492.     if (win[JUMP_WIN].handle == NO_WINDOW)
  1493.     {
  1494.         do_jumpdial();
  1495.         return;
  1496.     }
  1497.  
  1498.     if (win[JUMP_WIN].status == 3) /* iconified */
  1499.     {
  1500.         un_iconify(JUMP_WIN,(GRECT *)&win[JUMP_WIN].curr);
  1501.         wind_set(win[JUMP_WIN].handle, WF_TOP, win[JUMP_WIN].handle,0,0,0);
  1502.     }
  1503.     else if (win[JUMP_WIN].status == 1) /* normal */
  1504.     {
  1505.         wind_set(win[JUMP_WIN].handle, WF_TOP, win[JUMP_WIN].handle,0,0,0);
  1506.     }
  1507.     else
  1508.         do_jumpdial();
  1509.  
  1510.     return;
  1511. }
  1512.  
  1513. int
  1514. about_drive(int which_obj)
  1515. {
  1516.     GRECT p;
  1517.     int x_pos,y_pos;
  1518.     int mbut,kstate;
  1519.  
  1520.     
  1521.     wind_get(win[ABOUT_WIN].handle,WF_WORKXYWH,ELTR(p));
  1522.  
  1523.     if(which_obj == R_URL)
  1524.     {
  1525.         objc_change(win[ABOUT_WIN].window_obj,which_obj,0,ELTS(p),0x0001,1);
  1526.  
  1527.         objc_change(win[ABOUT_WIN].window_obj,which_obj,0,ELTS(p),0x0000,1);
  1528.  
  1529.         run_web_browser("*http://www.netset.com/~baldrick/boinkout2.html");
  1530.         
  1531.         while(TRUE)
  1532.         {
  1533.             graf_mkstate(&x_pos,&y_pos,&mbut,&kstate);
  1534.             
  1535.             if (mbut == 0)
  1536.                 break;
  1537.         }
  1538.     }
  1539.         
  1540.     return(1);
  1541. }
  1542.  
  1543. int
  1544. jump_drive(int which_obj)
  1545. {
  1546.     GRECT p;
  1547.     char ft[100] = "";
  1548.     int jump_lvl;
  1549.     
  1550.     set_tedinfo(win[JUMP_WIN].window_obj, JUMP_LEVEL_NAME, name);
  1551.     sprintf(ft,"%d",file_levels);
  1552.     set_tedinfo(win[JUMP_WIN].window_obj, JUMP_LEVEL_NUM, ft);
  1553.  
  1554.     wind_get(win[JUMP_WIN].handle,WF_WORKXYWH,ELTR(p));
  1555.  
  1556.     if(which_obj == JUMP_GO)
  1557.     {
  1558.         objc_change(win[JUMP_WIN].window_obj,which_obj,0,ELTS(p),0x0001,1);
  1559.  
  1560.         objc_change(win[JUMP_WIN].window_obj,which_obj,0,ELTS(p),0x0000,1);
  1561.  
  1562.         jump_lvl = atoi(win[JUMP_WIN].window_obj[JUMP_SELECT].ob_spec.tedinfo->te_ptext);
  1563.  
  1564.         if ((jump_lvl > file_levels)||
  1565.             (jump_lvl < 1)) /* make sure it's in range and the user isn't a joker */
  1566.         {
  1567.             form_alert(1,alert_invalid);
  1568.             return(0);
  1569.         }
  1570.         
  1571.         if (win[GAME_WIN].handle != NO_WINDOW)
  1572.         {
  1573.             lives = old_lives = 3;
  1574.             score = old_score = 0;
  1575.             bonus_life = old_bonus = BONUS;
  1576.             pad_y_top = pad_y_min;
  1577.             level = jump_lvl - 1;
  1578.  
  1579.             /* Close the jump window */
  1580.             wind_close(win[JUMP_WIN].handle);
  1581.             wind_delete(win[JUMP_WIN].handle);
  1582.  
  1583.             /* clear JUMP_WIN handle */
  1584.             win[JUMP_WIN].handle = NO_WINDOW;
  1585.  
  1586.             /* If GAME_WIN is iconified, uniconify it */
  1587.             if (win[GAME_WIN].status == 3) /* iconified */
  1588.                 un_iconify(GAME_WIN,(GRECT *)&win[GAME_WIN].curr);
  1589.  
  1590.             /* Top the Game window */
  1591.             wind_set(win[GAME_WIN].handle, WF_TOP, win[GAME_WIN].handle,0,0,0);
  1592.  
  1593.             /* Set the colors to the Game Window colors */
  1594.             if (remap_pal == 0)
  1595.                 load_image_colors();
  1596.  
  1597.             restart_level();
  1598.             event_kind = MU_MESAG | MU_TIMER | MU_BUTTON | MU_KEYBD;
  1599.         }
  1600.     }
  1601.     else if (which_obj == JUMP_SELECT)
  1602.     {
  1603.         /* Disable old edit field */
  1604.  
  1605.         objc_edit(win[JUMP_WIN].window_obj, win[JUMP_WIN].cur_item, 0, &win[JUMP_WIN].edit_pos, ED_END, &win[JUMP_WIN].edit_pos);
  1606.         objc_draw(win[JUMP_WIN].window_obj, ROOT, MAX_DEPTH, ELTS(p));
  1607.  
  1608.         /* Enable Level selection edit field */
  1609.         objc_edit(win[JUMP_WIN].window_obj,win[JUMP_WIN].cur_item,0, win[JUMP_WIN].edit_pos,ED_INIT, &win[JUMP_WIN].edit_pos);
  1610.         objc_draw(win[JUMP_WIN].window_obj, JUMP_SELECT, MAX_DEPTH, ELTS(p));
  1611.     }
  1612.         
  1613.     return(1);
  1614. }
  1615.  
  1616. int
  1617. redraw_objcolors(void)
  1618. {
  1619.     int x,y,x1;
  1620.     int loop,size,tot_colors;
  1621.     
  1622.         
  1623.     HIDE_MOUSE;
  1624.     wind_update(TRUE);
  1625.  
  1626.     /* First reset the color pallete in the window */
  1627.  
  1628.     objc_offset(objcolor_dial,COLOR1,&x,&y);
  1629.     color_square(vdi_handle, objcolors[0], x, y, 16);
  1630.  
  1631.     objc_offset(objcolor_dial,COLOR2,&x,&y);
  1632.     color_square(vdi_handle, objcolors[1], x, y, 16);
  1633.             
  1634.     objc_offset(objcolor_dial,COLOR3,&x,&y);
  1635.     color_square(vdi_handle, objcolors[2], x, y, 16);
  1636.  
  1637.     objc_offset(objcolor_dial,COLOR4,&x,&y);
  1638.     color_square(vdi_handle, objcolors[3], x, y, 16);
  1639.  
  1640.     objc_offset(objcolor_dial,COLOR5,&x,&y);
  1641.     color_square(vdi_handle, objcolors[4], x, y, 16);
  1642.  
  1643.     objc_offset(objcolor_dial,COLOR6,&x,&y);
  1644.     color_square(vdi_handle, objcolors[5], x, y, 16);
  1645.  
  1646.     /* Now draw the color selection box */
  1647.     if (planes >= 8)
  1648.         tot_colors = 256;
  1649.     else
  1650.         tot_colors = (1 << planes);
  1651.  
  1652.     /* I'm tired and the following is crap but it's 
  1653.      * working crap
  1654.      */
  1655.      
  1656.     switch(tot_colors)
  1657.     {
  1658.         case 1:
  1659.         case 4:
  1660.             size = 64;
  1661.             break;
  1662.         case 16:
  1663.             size = 32;
  1664.             break;
  1665.         case 256:
  1666.             size = 8;
  1667.             break;
  1668.     }
  1669.     
  1670.     objc_offset(objcolor_dial,DCOLORBOX,&x1,&y);
  1671.  
  1672.     x = x1; /* Store real offsets for later */
  1673.     
  1674.     for (loop=0;loop < tot_colors;loop++)
  1675.     {
  1676.         color_square(vdi_handle, loop, x, y, size);
  1677.         
  1678.         x = x + size;
  1679.  
  1680.         if (x >= (x1 + 128))
  1681.         {
  1682.             x = x1;
  1683.             y = y + size;
  1684.         }
  1685.     }
  1686.  
  1687.     wind_update(FALSE);
  1688.     SHOW_MOUSE;
  1689.  
  1690.     return(1);
  1691. }
  1692.  
  1693. /* put up jump window dialog */
  1694. void
  1695. open_objcolors(void)
  1696. {
  1697.     if (win[OBJCOLOR_WIN].handle == NO_WINDOW)
  1698.     {
  1699.         do_objcolorsdial();
  1700.         return;
  1701.     }
  1702.  
  1703.     if (win[OBJCOLOR_WIN].status == 3) /* iconified */
  1704.     {
  1705.         un_iconify(OBJCOLOR_WIN,(GRECT *)&win[OBJCOLOR_WIN].curr);
  1706.         wind_set(win[OBJCOLOR_WIN].handle, WF_TOP, win[OBJCOLOR_WIN].handle,0,0,0);
  1707.     }
  1708.     else if (win[OBJCOLOR_WIN].status == 1) /* normal */
  1709.     {
  1710.         wind_set(win[OBJCOLOR_WIN].handle, WF_TOP, win[OBJCOLOR_WIN].handle,0,0,0);
  1711.     }
  1712.     else
  1713.         do_objcolorsdial();
  1714.  
  1715.     return;
  1716. }
  1717.  
  1718. int
  1719. objcolors_drive(int which_obj)
  1720. {
  1721.     GRECT p;
  1722.     int x,y,x1,y1,x2,y2,junk;
  1723.     int hardware_color, vdi_color ;    
  1724.     int tot_colors, size;
  1725.  
  1726.     redraw_objcolors();
  1727.  
  1728.     wind_get(win[OBJCOLOR_WIN].handle,WF_WORKXYWH,ELTR(p));
  1729.  
  1730.     if(which_obj == DPADCOLOR)
  1731.     {
  1732.         objc_change(objcolor_dial,which_obj,0,ELTS(p),0x0001,1);
  1733.         objc_change(objcolor_dial,curr_colorobj,0,ELTS(p),0x0000,1);
  1734.         curr_colorobj = DPADCOLOR;
  1735.     }
  1736.     else if(which_obj == DBALLCOLOR)
  1737.     {
  1738.         objc_change(objcolor_dial,which_obj,0,ELTS(p),0x0001,1);
  1739.         objc_change(objcolor_dial,curr_colorobj,0,ELTS(p),0x0000,1);
  1740.         curr_colorobj = DBALLCOLOR;
  1741.     }
  1742.     else if(which_obj == DBRICKCOLOR)
  1743.     {
  1744.         objc_change(objcolor_dial,which_obj,0,ELTS(p),0x0001,1);
  1745.         objc_change(objcolor_dial,curr_colorobj,0,ELTS(p),0x0000,1);
  1746.         curr_colorobj = DBRICKCOLOR;
  1747.     }
  1748.     else if(which_obj == DPERMCOLOR)
  1749.     {
  1750.         objc_change(objcolor_dial,which_obj,0,ELTS(p),0x0001,1);
  1751.         objc_change(objcolor_dial,curr_colorobj,0,ELTS(p),0x0000,1);
  1752.         curr_colorobj = DPERMCOLOR;
  1753.     }
  1754.     else if(which_obj == DMAGICCOLOR)
  1755.     {
  1756.         objc_change(objcolor_dial,which_obj,0,ELTS(p),0x0001,1);
  1757.         objc_change(objcolor_dial,curr_colorobj,0,ELTS(p),0x0000,1);
  1758.         curr_colorobj = DMAGICCOLOR;
  1759.     }        
  1760.     else if(which_obj == DSPINCOLOR)
  1761.     {
  1762.         objc_change(objcolor_dial,which_obj,0,ELTS(p),0x0001,1);
  1763.         objc_change(objcolor_dial,curr_colorobj,0,ELTS(p),0x0000,1);
  1764.         curr_colorobj = DSPINCOLOR;
  1765.     }    
  1766.     else if(which_obj == DCOLORBOX)
  1767.     {
  1768.         graf_mkstate(&x,&y,&junk,&junk);
  1769.         
  1770.         v_get_pixel(vdi_handle, x-1, y-1, &hardware_color, &vdi_color);
  1771.  
  1772.         /* If we are in TrueColor modes then we need to track down
  1773.          * which color we want - Yuck!
  1774.          *
  1775.          * If this were really nice for true color we wouldn't 
  1776.          * mess with the pens and would just display a wide color
  1777.          * map that the user could select from.
  1778.          *
  1779.          * However I have too many projects to work on that people
  1780.          * are asking for fixes to spend another week working this out
  1781.          * right now.  So I am going to be cheap and track the pen by the physical
  1782.          * location on the screen from where I drew the color boxes.
  1783.          */
  1784.  
  1785.         if (planes > 8)
  1786.         {
  1787.             /* Get the size of color selection box */
  1788.             if (planes >= 8)
  1789.                 tot_colors = 256;
  1790.             else
  1791.                 tot_colors = (1 << planes);
  1792.  
  1793.             /* Copied from redraw_objcolors above.
  1794.              * working crap
  1795.              */
  1796.      
  1797.             switch(tot_colors)
  1798.             {
  1799.                 case 1:
  1800.                 case 4:
  1801.                     size = 64;
  1802.                 break;
  1803.                 case 16:
  1804.                     size = 32;
  1805.                     break;
  1806.                 case 256:
  1807.                     size = 8;
  1808.                     break;
  1809.             }
  1810.         
  1811.             /* Get x and y of color box object */
  1812.             objc_offset(objcolor_dial,DCOLORBOX,&x1,&y1);
  1813.  
  1814.             x2 = x - x1;
  1815.             y2 = y - y1;
  1816.  
  1817.             x2 = x2/size;
  1818.             y2 = y2/size;
  1819.             
  1820.             vdi_color = x2 + (y2 * (128/size));
  1821.         }
  1822.         
  1823.         switch(curr_colorobj)
  1824.         {
  1825.             case DPADCOLOR:
  1826.                 objcolors[0] = vdi_color;
  1827.                 break;
  1828.             case DBALLCOLOR:
  1829.                 objcolors[1] = vdi_color;
  1830.                 break;
  1831.             case DBRICKCOLOR:
  1832.                 objcolors[2] = vdi_color;
  1833.                 break;
  1834.             case DPERMCOLOR:
  1835.                 objcolors[3] = vdi_color;
  1836.                 break;
  1837.             case DMAGICCOLOR:
  1838.                 objcolors[4] = vdi_color;
  1839.                 break;
  1840.             case DSPINCOLOR:
  1841.                 objcolors[5] = vdi_color;
  1842.                 break;
  1843.         }
  1844.         
  1845.         redraw_objcolors();
  1846.     }
  1847.     else if(which_obj == DSETCOLOR)
  1848.     {
  1849.         objc_change(objcolor_dial,which_obj,0,ELTS(p),0x0001,1);
  1850.         objc_change(objcolor_dial,which_obj,0,ELTS(p),0x0000,1);
  1851.         curr_colorobj = -1;
  1852.  
  1853.         free(ballsource.fd_addr); 
  1854.         free(paddlesource.fd_addr);
  1855.         free(bricksource.fd_addr);
  1856.         free(twobricksource.fd_addr);
  1857.         free(magicbricksource.fd_addr);
  1858.         free(permbricksource.fd_addr);
  1859.         free(fujisource.fd_addr);
  1860.         free(eyesource.fd_addr);
  1861.         
  1862.         ballsource.fd_addr = monoballs; 
  1863.         paddlesource.fd_addr = monopaddle;
  1864.         bricksource.fd_addr = monobricks;
  1865.         twobricksource.fd_addr = mono_twobrick;
  1866.         magicbricksource.fd_addr = mono_twobrick;
  1867.         permbricksource.fd_addr = mono_perm_bricks;
  1868.         fujisource.fd_addr = mono_fuji;
  1869.         eyesource.fd_addr = mono_eye;
  1870.  
  1871.         fix_image(&paddlesource,objcolors[0]);
  1872.         fix_image(&ballsource,objcolors[1]);
  1873.         fix_image(&fujisource,objcolors[1]);
  1874.         fix_image(&eyesource,objcolors[1]);
  1875.         fix_image(&bricksource,objcolors[2]);
  1876.         fix_image(&permbricksource,objcolors[3]);
  1877.         fix_image(&magicbricksource,objcolors[4]);
  1878.         fix_image(&twobricksource,objcolors[5]);
  1879.  
  1880.         wind_set(win[GAME_WIN].handle, WF_TOP, win[GAME_WIN].handle,0,0,0);
  1881.  
  1882.         restart_level();
  1883.         event_kind = MU_MESAG | MU_TIMER | MU_BUTTON | MU_KEYBD;
  1884.     }
  1885.             
  1886.     return(1);
  1887. }
  1888.  
  1889. void 
  1890. rsrc_init(void)
  1891. {
  1892.     rsrc_gaddr(0, MENU,&menu_ptr);     
  1893.     rsrc_gaddr(0, ABOUT,&about_dial);
  1894.     rsrc_gaddr(0, TIMING,&timing_dial);
  1895.     rsrc_gaddr(0, HIGHSCORE,&highscore_dial);
  1896.     rsrc_gaddr(0, SCORELIST,&scorelist_dial);
  1897.     rsrc_gaddr(0, LOADING,&loading_dial);
  1898.     rsrc_gaddr(0, JUMPLEVEL,&jump_dial);
  1899.     rsrc_gaddr(0, ICONS,&icons_dial);
  1900.     rsrc_gaddr(0, OBJCOLORS,&objcolor_dial);
  1901.     rsrc_gaddr(R_STRING,ALERT_NOSCOR,&alert_noscore);
  1902.     rsrc_gaddr(R_STRING,ALERT_CANTCREATE,&alert_cantcreate);
  1903.     rsrc_gaddr(R_STRING,ALERT_CANTFIND,&alert_cantfind);
  1904.     rsrc_gaddr(R_STRING,ALERT_INVALID,&alert_invalid);
  1905. }
  1906.  
  1907.  
  1908.  
  1909. /* Allow the user access to a Gem file selector to pick a new */
  1910. /* level file */
  1911.  
  1912. void
  1913. load_levels(void)
  1914. {
  1915.     register int i;
  1916.     FILE *fd;
  1917.     int button;
  1918.     char complete[80];
  1919.  
  1920.     if (remap_pal == 0)
  1921.         reset_colors();
  1922.  
  1923.     wind_update(TRUE);
  1924.     fsel_input(lpath,name,&button);
  1925.     if (!button) goto end;
  1926.  
  1927.     i = (int)strlen(lpath) - 1;
  1928.     while (i > 0 && (lpath[i] != '\\') && (lpath[i] != ':'))
  1929.         i--;
  1930.     strcpy(complete,lpath);
  1931.     strcpy(&complete[i+1],name);
  1932.  
  1933.     fd = fopen(complete, "r");
  1934.     if (fd == NULL) goto end;
  1935.  
  1936.     fclose(fd);
  1937.     
  1938.     read_level_file(complete);
  1939.  
  1940.     if (remap_pal == 0)
  1941.         load_image_colors();
  1942.  
  1943.     if (win[GAME_WIN].handle != NO_WINDOW)
  1944.     {
  1945.         if (lives <= 0) new_game();
  1946.         restart_level();
  1947.         event_kind = MU_MESAG | MU_TIMER | MU_BUTTON | MU_KEYBD;
  1948.     }
  1949.  
  1950. end:
  1951.     wind_update(FALSE);
  1952. }
  1953.  
  1954. /* Allow the user access to a Gem file selector to pick a new */
  1955. /* background picture */
  1956.  
  1957. void
  1958. load_pic(void)
  1959. {
  1960.     register int i;
  1961.     FILE *fd;
  1962.     int button;
  1963.     char complete[80];
  1964.  
  1965.     wind_update(TRUE);
  1966.     fsel_input(path,image_name,&button);
  1967.     if (!button) goto end;
  1968.  
  1969.     i = (int)strlen(path) - 1;
  1970.     while (i > 0 && (path[i] != '\\') && (path[i] != ':'))
  1971.         i--;
  1972.     strcpy(complete,path);
  1973.     strcpy(&complete[i+1],image_name);
  1974.  
  1975.     fd = fopen(complete, "r");
  1976.     if (fd == NULL) goto end;
  1977.  
  1978.     fclose(fd);
  1979.  
  1980.     if (remap_pal == 0)
  1981.         reset_colors();
  1982.  
  1983.     wind_update(FALSE);
  1984.  
  1985.     if (_app)
  1986.     {
  1987.         do_loading();
  1988.  
  1989.         set_tedinfo(loading_dial, RIMG_COUNT, "(1/1)");
  1990.  
  1991.         do_wind_redraw(win[LOADING_WIN].handle,&win[LOADING_WIN].curr);
  1992.     }
  1993.  
  1994.     img_load(&pic_buf, complete);
  1995.  
  1996.     save_image_colors();
  1997.  
  1998.     reset_colors();
  1999.  
  2000.     if (_app)
  2001.     {
  2002.         wind_close(win[LOADING_WIN].handle);
  2003.         wind_delete(win[LOADING_WIN].handle);
  2004.         win[LOADING_WIN].handle = NO_WINDOW;
  2005.     }    
  2006.  
  2007.     wind_update(TRUE);
  2008.  
  2009.     if (win[GAME_WIN].handle != NO_WINDOW)
  2010.     {
  2011.         if (lives <= 0) new_game();
  2012.         restart_level();
  2013.         event_kind = MU_MESAG | MU_TIMER | MU_BUTTON | MU_KEYBD;
  2014.     }
  2015.  
  2016. end:
  2017.     wind_update(FALSE);
  2018. }
  2019.  
  2020. void
  2021. restart_level(void)
  2022. {
  2023.     register int x, y, image, ndx;
  2024.     int ltemp = level % file_levels;
  2025.  
  2026.     int colors[2];
  2027.     
  2028.     colors[0] = 0;
  2029.     colors[1] = 1;
  2030.     
  2031.     if (win[GAME_WIN].handle == NO_WINDOW) return;
  2032.  
  2033.     magic_bottom = 0;
  2034.      gravity = 0;
  2035.     score = old_score;
  2036.     lives = old_lives;
  2037.     bonus_life = old_bonus;
  2038.     invis = FALSE;
  2039.  
  2040.     clear_areas();
  2041.  
  2042.     num_bricks = 0;
  2043.  
  2044.     brickarray[0] = brickarray[1] = brickarray[4] = brickarray[5] = 0;
  2045.     brickarray[2] = brickarray[6] = pic_buf.fd_w - 1;
  2046.     brickarray[3] = brickarray[7] = pic_buf.fd_h - 1;
  2047.     vro_cpyfm(vdi_handle,S_ONLY,brickarray,&pic_buf,&windsource); /* windsource */
  2048.  
  2049.     show_lives();
  2050.     show_level();
  2051.     show_score();
  2052.  
  2053.     brickarray[1] = 0;
  2054.     brickarray[3] = bh-1;
  2055.  
  2056.     ndx = 0;
  2057.     for (y=0; y<7; y++)
  2058.     {
  2059.         for (x=0; x < 9; x++)
  2060.         {
  2061.             brickarray[0] = 0;
  2062.             brickarray[2] = 43;
  2063.             brickarray[4] = bleft + x * btw;
  2064.             brickarray[5] = btop + y * bth;
  2065.             brickarray[6] = brickarray[4] + 43;
  2066.             brickarray[7] = brickarray[5] + bh - 1;
  2067.  
  2068.             switch(brickmask[ltemp][ndx])
  2069.             {
  2070.                 case 9:        /* permanent */
  2071.                     vrt_cpyfm(vdi_handle, MD_TRANS, brickarray,&permbrickmask,&windsource,colors);    
  2072.                     vro_notcpy(brickarray, &permbricksource, &windsource);
  2073.                     break;
  2074.  
  2075.                 case 1:            /* normal */
  2076.                     num_bricks++;
  2077.                     break;
  2078.  
  2079.                 case 2:            /* magic */
  2080.                     vrt_cpyfm(vdi_handle, MD_TRANS, brickarray,&twobrickmask,&windsource,colors);
  2081.                     vro_notcpy(brickarray, &magicbricksource, &windsource);
  2082.  
  2083.                     num_bricks++;
  2084.                     break;
  2085.  
  2086.                 case 3:
  2087.                 case 4:
  2088.                 case 5:
  2089.                 case 6:
  2090.                     num_bricks++;
  2091.                     break;
  2092.             }
  2093.             ndx++;
  2094.         }
  2095.     }
  2096.  
  2097.     n_redraws = 0;
  2098.     add_region(work.g_x,work.g_y,work.g_w,work.g_h);
  2099.     do_redraw();
  2100.  
  2101.     evnt_timer(150,0);
  2102.  
  2103.     sound_play(S_APPEAR);
  2104.     
  2105.     evnt_timer(350,0);
  2106.  
  2107.     for (image = 3; image >= 0; image--)
  2108.     {
  2109.         ndx = 0;
  2110.         brickarray[0] = image * btw;
  2111.         brickarray[2] = brickarray[0] + btw - 1;
  2112.  
  2113.         for (y=0; y<7; y++)
  2114.         {
  2115.             for (x=0; x < 9; x++)
  2116.             {
  2117.                 brickarray[4] = bleft + x * btw;
  2118.                 brickarray[5] = btop + y * bth;
  2119.                 brickarray[6] = brickarray[4] + btw - 1;
  2120.                 brickarray[7] = brickarray[5] + bh - 1;
  2121.  
  2122.                 switch(brickmask[ltemp][ndx++])
  2123.                 {
  2124.                     case 1:
  2125.                         vrt_cpyfm(vdi_handle, MD_TRANS, brickarray,&nbrickmask,&windsource,junkcolors);
  2126.                         vro_notcpy(brickarray, &bricksource, &windsource);
  2127.                         break;
  2128.                 case 3:
  2129.                 case 4:
  2130.                 case 5:
  2131.                 case 6:
  2132.                     if (image > 0)
  2133.                     {
  2134.                         vrt_cpyfm(vdi_handle, MD_TRANS, brickarray,&twobrickmask,&windsource,junkcolors);
  2135.                         vro_notcpy(brickarray, &twobricksource, &windsource);
  2136.                     }
  2137.                     break;
  2138.                 }
  2139.             }
  2140.         }
  2141.         add_region(work.g_x,work.g_y,work.g_w,work.g_h);
  2142.         do_redraw();
  2143.     }
  2144.     evnt_timer(500,0);
  2145.  
  2146.     ani_count = 0;
  2147.     paddle_x = 0;
  2148.     paddle_y = pad_y_max;
  2149.     paddlearray[4] = 0;
  2150.     paddlearray[5] = pad_y_max;
  2151.     paddlearray[6] = 52;
  2152.     paddlearray[7] = paddlearray[5] + pad_ht - 1;
  2153.  
  2154.     num_balls = 0;
  2155.  
  2156.     if (cheat)
  2157.     {
  2158.         for (x=0; x<3; x++)
  2159.             add_ball(0,pad_y_min - ball_ht,max_xspeed-x,-min_yspeed, TRUE);
  2160.     }
  2161.     else add_ball(0,pad_y_min - ball_ht,2,2, FALSE);
  2162.  
  2163.     mode = BNORMAL;
  2164.  
  2165.     for (x=0; x < 63; x++) brickcount[x] = brickmask[ltemp][x];
  2166. }
  2167.  
  2168. void
  2169. add_region(int x,int y,int w,int h)
  2170. {
  2171.     register GRECT *p;
  2172.  
  2173.     /* this should never happen... */
  2174.     if (n_redraws >= MAX_ANI) return;
  2175.  
  2176.     p = ®ion[n_redraws];
  2177.     p->g_x = x;
  2178.     p->g_y = y;
  2179.     p->g_w = w;
  2180.     p->g_h = h;
  2181.     n_redraws++;
  2182. }
  2183.  
  2184. void
  2185. new_game(void)
  2186. {
  2187.     lives = old_lives = 3;
  2188.     score = old_score = 0;
  2189.     bonus_life = old_bonus = BONUS;
  2190.     pad_y_top = pad_y_min;
  2191.     level = 0;
  2192. }
  2193.  
  2194. void
  2195. clear(int x,int y,int w,int h)
  2196. {
  2197.     int pxy[8];
  2198.     
  2199.     pxy[0] = pxy[1] = 0;
  2200.     pxy[2] = w-1;
  2201.     pxy[3] = h-1;
  2202.     pxy[4] = x;
  2203.     pxy[5] = y;
  2204.     pxy[6] = x + w - 1;
  2205.     pxy[7] = y + h - 1;
  2206.  
  2207.     vro_cpyfm(vdi_handle,(planes>9)?ALL_BLACK:ALL_WHITE,pxy,&pic_buf,&pic_buf);
  2208. }
  2209.  
  2210. /* Saves colors in global array screen_colortab[] */
  2211. void
  2212. save_colors(void)
  2213. {
  2214.     int i;
  2215.     int coltab[3];
  2216.     
  2217.     for (i=0;i<screen_colors;i++)
  2218.     {
  2219.         vq_color(vdi_handle,i,0,coltab);
  2220.  
  2221.         screen_colortab[i].red = coltab[0];
  2222.         screen_colortab[i].green = coltab[1];
  2223.         screen_colortab[i].blue = coltab[2];            
  2224.     }
  2225. }
  2226.  
  2227. void
  2228. reset_colors(void)
  2229. {
  2230.     int i;
  2231.     int coltab[3];
  2232.  
  2233. #if OS_DOS
  2234.     if( planes == 1 )  return;  /* Looks better */
  2235. #endif
  2236.  
  2237.     for (i=0;i<screen_colors;i++)
  2238.     {
  2239.         coltab[0] = screen_colortab[i].red;
  2240.         coltab[1] = screen_colortab[i].green;
  2241.         coltab[2] = screen_colortab[i].blue;
  2242.  
  2243.         vs_color(vdi_handle,i,coltab);
  2244.     }
  2245. }
  2246.  
  2247. /* These 2 would be better stored in the window
  2248.     structure.  However I don't have the time
  2249.     at the moment if I want to meet the deadline
  2250.     I've agreed to. To make this modification.
  2251.     
  2252.     It would be fairly simple to do.
  2253.     
  2254.     All one needs to do is create all the windows you
  2255.     might want to use at the startup of the program.
  2256.     
  2257.     Then if the window contains an image.
  2258.     Set the colortab for that window to be equal to that
  2259.     image.  voila!
  2260.     
  2261.     */
  2262.  
  2263.  
  2264. void
  2265. save_image_colors(void)
  2266. {
  2267.     int i;
  2268.     int coltab[3];
  2269.  
  2270.     for (i=0;i<screen_colors;i++)
  2271.         {
  2272.             vq_color(vdi_handle,i,0,coltab);
  2273.  
  2274.             imgcolortab[i].red = coltab[0];
  2275.             imgcolortab[i].green = coltab[1];
  2276.             imgcolortab[i].blue = coltab[2];            
  2277.         }
  2278. }
  2279.     
  2280. void
  2281. load_image_colors(void)
  2282. {
  2283.     int i;
  2284.     int coltab[3];
  2285.  
  2286. #if OS_DOS
  2287.     if( planes == 1 )  return;  /* Looks better */
  2288. #endif
  2289.     
  2290.     for (i=0;i<screen_colors;i++)
  2291.     {
  2292.         coltab[0] = imgcolortab[i].red;
  2293.         coltab[1] = imgcolortab[i].green;
  2294.         coltab[2] = imgcolortab[i].blue;
  2295.             
  2296.         vs_color(vdi_handle,i,coltab);
  2297.     }
  2298. }
  2299.  
  2300. void
  2301. save_about_colors(void)
  2302. {
  2303.     int i;
  2304.     int coltab[3];
  2305.  
  2306.     for (i=0;i<screen_colors;i++)
  2307.     {
  2308.         vq_color(vdi_handle,i,0,coltab);
  2309.  
  2310.         aboutcolortab[i].red = coltab[0];
  2311.         aboutcolortab[i].green = coltab[1];
  2312.         aboutcolortab[i].blue = coltab[2];            
  2313.     }
  2314. }
  2315.     
  2316. void
  2317. load_about_colors(void)
  2318. {
  2319.     int i;
  2320.     int coltab[3];
  2321.  
  2322. #if OS_DOS
  2323.     if( planes == 1 )  return;  /* Looks better */
  2324. #endif
  2325.  
  2326.     for (i=0;i<screen_colors;i++)
  2327.     {
  2328.         coltab[0] = aboutcolortab[i].red;
  2329.         coltab[1] = aboutcolortab[i].green;
  2330.         coltab[2] = aboutcolortab[i].blue;
  2331.  
  2332.         vs_color(vdi_handle,i,coltab);
  2333.     }
  2334. }
  2335.  
  2336. /* waits for a period of time */
  2337. void
  2338. delay(int period)
  2339. {
  2340.     evnt_timer(period,0);
  2341. }
  2342.  
  2343. /********************************************/
  2344. /*        open game window                    */
  2345. /********************************************/
  2346. int 
  2347. open_game_window(void)
  2348. {
  2349.     int i, k;
  2350.  
  2351.     if ((win[GAME_WIN].handle=wind_create(W_TYPE,desk.g_x,desk.g_y,max.g_w,max.g_h)) < 0)
  2352.         return -1;
  2353.  
  2354.     graf_mkstate(&i, &i, &i, &k);
  2355.     cheat = (k & 3);
  2356.  
  2357. #if OS_DOS
  2358.     wind_set(win[GAME_WIN].handle, WF_NAME, LLOWD(title_bar), LHIWD(title_bar), 0,0);
  2359. #else
  2360.     wind_set(win[GAME_WIN].handle, WF_NAME,title_bar);
  2361. #endif
  2362.     graf_growbox(desk.g_x,desk.g_y,gl_wbox,gl_hbox,ELTS(old));
  2363.  
  2364.     wind_open(win[GAME_WIN].handle,ELTS(old));
  2365.  
  2366.     wind_get(win[GAME_WIN].handle,WF_WORKXYWH,ELTR(work));
  2367.  
  2368.         win[GAME_WIN].window_obj = (OBJECT *)NULL;
  2369.         win[GAME_WIN].title = title_bar;
  2370.         win[GAME_WIN].cur_item = -1;
  2371.         win[GAME_WIN].text_block = NULL;
  2372.         win[GAME_WIN].buf_size = 0;
  2373.         win[GAME_WIN].status = 1;
  2374.         win[GAME_WIN].edit = 0;
  2375.         win[GAME_WIN].type = 0;
  2376.         
  2377.         win[GAME_WIN].icon_obj = icons_dial;
  2378.  
  2379.         wind_get(win[GAME_WIN].handle, WF_CURRXYWH, ELTR(win[GAME_WIN].curr));
  2380.  
  2381.     if (remap_pal == 0)
  2382.         load_image_colors();
  2383.     
  2384.     /*if (lives <= 0) */
  2385.     new_game();
  2386.     restart_level();
  2387.  
  2388.     event_kind = MU_MESAG | MU_TIMER | MU_BUTTON | MU_KEYBD;
  2389.  
  2390.     ttimer = timer;
  2391.  
  2392.     return 0;
  2393. }
  2394.  
  2395.