home *** CD-ROM | disk | FTP | other *** search
/ RISCWORLD 7 / RISCWORLD_VOL7.iso / Software / Issue4 / IYONIX / MANICMINER / SOURCE.ZIP / manicminer-1.6.3 / systems / riscos / c / frontend next >
Encoding:
Text File  |  2003-04-18  |  18.3 KB  |  858 lines

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <signal.h>
  5. #include "oslib/wimp.h"
  6. #include "oslib/osargs.h"
  7. #include "oslib/osfind.h"
  8. #include "oslib/osgbpb.h"
  9. #include "oslib/osmodule.h"
  10. #include "oslib/taskmanager.h"
  11. #include "manic.h"
  12. #include "gfxdata/gfxdata.h"
  13. #include "gfxlibs/keyboard.h"
  14. #include "ROsupport.h"
  15. #include "ROsound.h"
  16. #include "kernel.h"
  17. #ifdef UNIXLIB
  18. #  include "unistd.h"
  19. #endif
  20.  
  21. #define DEFAULTSPEED    3
  22. #define DEFAULTMUSIC    0
  23. #define DEFAULTRES    (machinetype>1)
  24. #define DEFAULTPAUSE    0
  25. #define DEFAULTSOUND    (SOUNDdefault[machinetype])
  26. #define DEFAULTVOLUME    100
  27.  
  28.  
  29. #define TASKNAME "Manic Miner"
  30. #define TASKNAMELEN 11
  31.  
  32.  
  33. static void
  34. report (const os_error * err)
  35. {
  36.   if (err)
  37.     wimp_report_error (err, wimp_ERROR_BOX_OK_ICON, TASKNAME);
  38. }
  39.  
  40.  
  41. static void
  42. reportmsg (const char *msg)
  43. {
  44.   if (msg) {
  45.     os_error err;
  46.     err.errnum = 0;
  47.     strcpy (err.errmess, msg);
  48.     report (&err);
  49.   }
  50. }
  51.  
  52.  
  53. static void
  54. x (const os_error * err)
  55. {
  56.   if (err) {
  57.     report (err);
  58.     exit (1);
  59.   }
  60. }
  61.  
  62.  
  63. static int open = 0, quit = 0, notme = 0, easteregg = 0;
  64. static int ibar_icon;
  65. static os_t eggtimer;
  66. static wimp_icon_flags eggflags;
  67. static char eggpaint[6];
  68. extern const BYTE *const mm_anim;
  69.  
  70.  
  71. static void
  72. closetemplate (void)
  73. {
  74.   if (open)
  75.     xwimp_close_template ();
  76.   open = 0;
  77. }
  78.  
  79.  
  80. static wimp_w
  81. loadt (const char *template)
  82. {
  83.   int used, data_used, context;
  84.   wimp_window *w_raw;
  85.   char tempname[13] = "";
  86.   char *data;
  87.   wimp_w w_handle;
  88.  
  89.   strncpy (tempname, template, 12);
  90.   x (xwimp_load_template (
  91.               (wimp_window *) (-1), 0, 0, (byte *) (-1),
  92.               tempname, 0, &used, &data_used, &context)
  93.     );
  94.   if (!context) {
  95.     os_error err;
  96.     err.errnum = 0;
  97.     sprintf (err.errmess, "Template %s not found", template);
  98.     xwimp_close_template ();
  99.     x (&err);
  100.   }
  101.   w_raw = malloc (used);
  102.   data = malloc (data_used);
  103.   if (w_raw == 0 || data == 0) {
  104.     reportmsg ("malloc failed");
  105.     xwimp_close_template ();
  106.     exit (1);
  107.   }
  108.   x (xwimp_load_template
  109.      (w_raw, data, data + data_used, (byte *) (-1), tempname, 0, &used,
  110.       &data_used, &context)
  111.     );
  112.   x (xwimp_create_window (w_raw, &w_handle));
  113.   free (w_raw);
  114.   return w_handle;
  115. }
  116.  
  117.  
  118. int wimp_v;
  119.  
  120. static const int msgs[] = {
  121.   message_DATA_SAVE, message_DATA_LOAD,
  122.   message_PREQUIT, message_TASK_INITIALISE, message_MENU_WARNING,
  123.   message_MENUS_DELETED, 0x4AF80, 0x4E383, 0
  124. };
  125.  
  126. static wimp_block poll;
  127. static wimp_t task_h;
  128. static wimp_w infobox, optsbox;
  129.  
  130. static char *name_buf, *vol_buf;
  131.  
  132. static wimp_icon_create icon = {
  133.   (wimp_w) - 1,
  134.   {{0, 0, 40, 72}, 0x1700311A, ""}
  135. };
  136.  
  137. static char sprite[] = "!manic";
  138.  
  139.  
  140. static const wimp_MENU (2) loadmenu =
  141. {
  142.   {"Level files"}, 7, 2, 7, 0, 192, 44, 0,
  143.   {
  144.     {0, 0, 0x07000021, {"Standard"}},
  145.     {128, 0, 0x07000021, {"Blood!"}},
  146.   }
  147. };
  148.  
  149.  
  150. static wimp_MENU (5) menu[2] =
  151. {
  152.   {
  153.     {TASKNAME}, 7, 2, 7, 0, 160, 44, 0,
  154.     {
  155.       {8, 0, 0x07000021, {"Info"}},
  156.       {0, 0, 0x07000021, {"Play"}},
  157.       {8, 0, 0x07000021, {"Choices..."}},
  158.       {0, (wimp_menu *) &loadmenu, 0x07000021, {"Load"}},
  159.       {128, 0, 0x07000021, {"Quit"}},
  160.     }
  161.   },
  162.   {
  163.     {TASKNAME}, 7, 2, 7, 0, 160, 44, 0,
  164.     {
  165.       {8, 0, 0x07000021, {"Info"}},
  166.       {0, 0, 0x07000021, {"Resume"}},
  167.       {8, 0, 0x07000021, {"Choices..."}},
  168.       {0, (wimp_menu *) &loadmenu, 0x07400021, {"Load"}},
  169.       {128, 0, 0x07000021, {"Quit"}},
  170.     }
  171.   }
  172. };
  173.  
  174. /*
  175. static const struct
  176. {
  177.   const char *read;
  178.   const char *write;
  179. }
  180. choicesfile[2] =
  181. {
  182.   {"Choices:ManicMiner", "<Choices$Write>.ManicMiner"},    ** Default **
  183.   {"<Manic$Dir>.Choices", "<Manic$Dir>.Choices"}    ** Fallback **
  184. };
  185.  
  186. static BYTE choicesnum = 0;*/
  187.  
  188. static BYTE SPEED_l, MUSIC_l, HIRES_l, PAUSE_l, SOUND_l;
  189. static int VOLUME_l;
  190.  
  191. static const BYTE SOUNDdefault[] = { 2, 4, 5, 9 };
  192.  
  193. /*
  194. static void
  195. setDefaults (void)
  196. {
  197.   SPEED = DEFAULTSPEED;
  198.   MUSICtype = DEFAULTMUSIC;
  199.   VidMode = DEFAULTRES;
  200.   PAUSEtype = DEFAULTPAUSE;
  201.   SOUND = DEFAULTSOUND;
  202.   VOLUME = DEFAULTVOLUME;
  203. }
  204. */
  205.  
  206. static void
  207. select (int icon, int state)
  208. {
  209.   xwimp_set_icon_state (optsbox, icon, state ? 1 << 21 : 0, 1 << 21);
  210. }
  211.  
  212. /*
  213. static void
  214. shade (int icon, int state)
  215. {
  216.   xwimp_set_icon_state (optsbox, icon, state ? 0 : 1 << 22, 1 << 22);
  217. }
  218. */
  219.  
  220. static void
  221. copy_opts (void)
  222. {
  223.   SPEED_l = SPEED;
  224.   MUSIC_l = MUSICtype;
  225.   HIRES_l = VidMode;
  226.   PAUSE_l = PAUSEtype;
  227.   SOUND_l = SOUND;
  228.   VOLUME_l = VOLUME;
  229. }
  230.  
  231.  
  232. static void
  233. reflect_volume (void)
  234. {
  235.   sprintf (vol_buf, "%i", VOLUME_l);
  236.   select (32, 0);
  237. }
  238.  
  239.  
  240. static void
  241. reflect_levels (void)
  242. {
  243.   strcpy (name_buf, LEVELSNAME);
  244.   select (10, 0);
  245. }
  246.  
  247.  
  248. static void
  249. reflect_game (void)
  250. {
  251.   sprite[0] = (MODE == 2) ? '#' : '!';
  252.   xwimp_set_icon_state ((wimp_w) -2, ibar_icon, 0, 0);
  253. }
  254.  
  255.  
  256. static void
  257. reflect_opts (void)
  258. {
  259.   select (2, SPEED_l == 4);
  260.   select (3, SPEED_l == 3);
  261.   select (4, SPEED_l == 2);
  262.   select (5, SPEED_l == 1);
  263.   select (6, SPEED_l == 0);
  264.   select (13, MUSIC_l);
  265.   select (14, !MUSIC_l);
  266.   select (17, HIRES_l);
  267.   select (18, !HIRES_l);
  268.   select (22, PAUSE_l);
  269.   select (25, (SOUND_l >> 2) == 0);
  270.   select (26, (SOUND_l >> 2) == 1);
  271.   select (27, (SOUND_l >> 2) == 2);
  272.   select (28, SOUND_l & 1);
  273.   select (29, SOUND_l & 2);
  274.   reflect_volume ();
  275. }
  276.  
  277.  
  278. static void
  279. openopts (void)
  280. {
  281.   wimp_window_state w;
  282.   int x, y, z;
  283.  
  284.   copy_opts ();
  285.   reflect_opts ();
  286.   os_read_mode_variable ((os_mode) (-1), 11, &x);
  287.   os_read_mode_variable ((os_mode) (-1), 4, &z);
  288.   x = (x + 1) << z;
  289.   os_read_mode_variable ((os_mode) (-1), 12, &y);
  290.   os_read_mode_variable ((os_mode) (-1), 5, &z);
  291.   y = (y + 1) << z;
  292.   w.w = optsbox;
  293.   wimp_get_window_state (&w);
  294.   w.visible.x1 -= w.visible.x0;
  295.   w.visible.y1 -= w.visible.y0;
  296.   w.visible.x0 = (x - w.visible.x1) / 2;
  297.   w.visible.y0 = (y - w.visible.y1) / 2;
  298.   w.visible.x1 += w.visible.x0;
  299.   w.visible.y1 += w.visible.y0;
  300.   w.next = (wimp_w) (-1);
  301.   w.flags |= 1 << 24;
  302.   openwindow (&w);
  303. }
  304.  
  305.  
  306. static void
  307. close_opts (void)
  308. {
  309.   wimp_create_menu ((wimp_menu *) (-1), 0, 0);
  310.   wimp_close_window (optsbox);
  311. }
  312.  
  313.  
  314. #define X(m) { const char *foo; foo=m; if (foo) { godesktop(); return foo; }}
  315. void (X)(const char* msg);
  316.  
  317.  
  318. static const char *
  319. main_singletask ()
  320. {
  321.   modedata[0] = -1;
  322.   if (!sampleptr[0].ptr)
  323.     X (loadSamples ());
  324.   if (initmusic (SOUND & 2 ? 0 : "<Manic$Dir>.snddata.manic/xm"))
  325.     X ("Failed to load the music");
  326.   if (initsfx (SOUND & 2))
  327.     X ("Failed to initialise the sound effects");
  328.   X (Initialise ());
  329.   X (SelMode (VidMode));
  330.   mm_gfx_palset (PALmain);
  331.   if (MODE == 2) {
  332.     DrawLevel();
  333.     mm_gfx_flush ();
  334.     StartGameMusic();
  335.     if (MUSICon && PAUSEtype) musicPause(0);
  336.   }
  337.   mainloop ();
  338.   if (MODE != 2) {
  339.     MODE = 0;
  340.     TITLEm = 0;
  341.   }
  342.   godesktop ();
  343.   return 0;
  344. }
  345.  
  346.  
  347. static void
  348. rungame (void)
  349. {
  350.   if (MODE == 255) {
  351.     reportmsg ("You must load a valid levels file first.");
  352.     return;
  353.   }
  354.   reportmsg (main_singletask ());
  355.   copy_opts ();
  356.   reflect_opts ();
  357.   reflect_game ();
  358. }
  359.  
  360.  
  361. static void
  362. urlDispatch (const char *url)
  363. {
  364.   wimp_message msg;
  365.   msg.size = 256;
  366.   msg.your_ref = 0;
  367.   msg.action = 0x4AF80;
  368.   strcpy ((char *) msg.data.reserved, url);
  369.   x (xwimp_send_message (wimp_USER_MESSAGE_RECORDED, &msg, 0));
  370. }
  371.  
  372.  
  373. static void
  374. launch (const char *url)
  375. {
  376.   wimp_t i;
  377.   if (!module_present ("AcornURI"))
  378.     xwimp_start_task ("/System:Modules.Network.URI", &i);
  379.   if (module_present ("AcornURI"))
  380.     uriDispatch (url, task_h);
  381.   else
  382.     urlDispatch (url);
  383. }
  384.  
  385.  
  386. static void
  387. stop_easteregg (void)
  388. {
  389.   if (easteregg == 4) {
  390.     xwimp_delete_icon (infobox, 11);
  391.     xwimp_delete_icon (infobox, 12);
  392.     xwimp_set_icon_state (infobox, 0, eggflags, -1);
  393.   }
  394.   easteregg = 0;
  395. }
  396.  
  397.  
  398. static void
  399. do_easteregg (void)
  400. {
  401.   os_t t;
  402.   strcpy (eggpaint, eggpaint[1] == 'a' ? "miner" : "manic");
  403.   wimp_set_icon_state (infobox, 12, 0, 0);
  404.   t = os_read_monotonic_time ();
  405.   do {
  406.     eggtimer += 50;
  407.   } while (eggtimer <= t);
  408. }
  409.  
  410.  
  411. static BYTE
  412. iconState (int icon)
  413. {
  414.   wimp_icon_state i;
  415.   i.w = optsbox;
  416.   i.i = icon;
  417.   xwimp_get_icon_state (&i);
  418.   return i.icon.flags >> 21 & 1;
  419. }
  420.  
  421.  
  422. static void
  423. go_loadgame (const char *file)
  424. {
  425.   switch (loadgame (file)) {
  426.   case 0:            /* loaded OK */
  427.     poll.message.size = 256;
  428.     poll.message.your_ref = poll.message.my_ref;
  429.     poll.message.action = message_DATA_SAVE_ACK;
  430.     poll.message.data.data_xfer.est_size = -1;
  431.     xwimp_send_message (wimp_USER_MESSAGE,
  432.             &poll.message, poll.message.sender);
  433.     reflect_levels ();
  434.     MODE = 0;
  435.     break;
  436.   case 1:            /* wrong ID */
  437.     reportmsg ("This is not a valid MM levels file");
  438.     MODE = 0;
  439.     break;
  440.   case 2:            /* couldn't open the file */
  441.     report ((const os_error *) _kernel_last_oserror ());
  442.     MODE = 0;
  443.     break;
  444.   case 3:            /* partially read file :-( */
  445.   default:
  446.     report ((const os_error *) _kernel_last_oserror ());
  447.     strcpy (LEVELSNAME, "– None –");
  448.     reflect_levels ();
  449.     MODE = 255;
  450.     break;
  451.   }
  452.   reflect_game ();
  453. }
  454.  
  455. static void
  456. click (void)
  457. {
  458.   int i;
  459.  
  460.   if (poll.pointer.w == (wimp_w) (-2)) {
  461.     switch (poll.pointer.buttons) {
  462.     case 4:
  463.       rungame ();
  464.       break;
  465.     case 2:
  466.       x (xwimp_create_menu ((wimp_menu *) (&menu[MODE == 2]),
  467.                 poll.pointer.pos.x - 64, 316));
  468.       break;
  469.     case 1:
  470.       openopts ();
  471.     }
  472.   }
  473.   else if (poll.pointer.w == infobox) {
  474.     if ((poll.pointer.buttons & 2) == 0) {
  475.       switch (poll.pointer.i) {
  476.       case 9:
  477.     launch ("mailto:ds@youmustbejoking.demon.co.uk");
  478.     break;
  479.       case 10:
  480.     launch ("http://www.youmustbejoking.demon.co.uk/");
  481.     break;
  482.       }
  483.     }
  484.     else {
  485.       if (poll.pointer.i == 0 && easteregg < 4 && ++easteregg == 4) {
  486.     wimp_icon_state icn;
  487.     wimp_icon_create new;
  488.     new.w = icn.w = infobox;
  489.     icn.i = 0;
  490.     xwimp_get_icon_state (&icn);
  491.     eggflags = icn.icon.flags;
  492.     memcpy (&new.icon.extent, &icn.icon.extent, sizeof (icn.icon.extent));
  493.     new.icon.flags = 0x17000105;
  494.     new.icon.data.indirected_text.text = "";
  495.     new.icon.data.indirected_text.validation = "R2";
  496.     new.icon.data.indirected_text.size = 1;
  497.     xwimp_create_icon (&new, &ibar_icon);
  498.     new.icon.extent.x0 += 4;
  499.     new.icon.extent.y0 += 4;
  500.     new.icon.extent.x1 -= 4;
  501.     new.icon.extent.y1 -= 4;
  502.     new.icon.flags = 0x7700013A;
  503.     new.icon.data.indirected_sprite.id = (osspriteop_id) eggpaint;
  504.     new.icon.data.indirected_sprite.area =
  505.       (osspriteop_area *) (mm_anim - 4);
  506.     new.icon.data.indirected_sprite.size = 6;
  507.     strcpy (eggpaint, "manic");
  508.     xwimp_create_icon (&new, &i);
  509.     xwimp_set_icon_state (infobox, 0, 0, -1);
  510.     eggtimer = os_read_monotonic_time () + 50;
  511.       }
  512.     }
  513.   }
  514.   else if (poll.pointer.w == optsbox) {
  515.     if ((poll.pointer.buttons & 2) == 0) {
  516.       switch (poll.pointer.i) {
  517.       case 2:            /* speed = boring */
  518.       case 3:            /* speed = original */
  519.       case 4:            /* speed = 1997 */
  520.       case 5:            /* speed = hard */
  521.       case 6:            /* speed = silly */
  522.     SPEED_l = 6 - poll.pointer.i;
  523.     select (poll.pointer.i, 1);
  524.     break;
  525.       case 13:            /* music = original */
  526.       case 14:            /* music = 1997 */
  527.     MUSIC_l = 14 - poll.pointer.i;
  528.     select (poll.pointer.i, 1);
  529.     break;
  530.       case 17:            /* resolution = high */
  531.       case 18:            /* resolution = low */
  532.     HIRES_l = 18 - poll.pointer.i;
  533.     select (poll.pointer.i, 1);
  534.     break;
  535.       case 22:
  536.     PAUSE_l = iconState (22);
  537.     break;
  538.       case 25:            /* sound quality = low */
  539.       case 26:            /* sound quality = medium */
  540.       case 27:            /* sound quality = high */
  541.     SOUND_l = (poll.pointer.i - 25) << 2 | (SOUND_l & 3);
  542.     select (poll.pointer.i, 1);
  543.     break;
  544.       case 28:            /* interpolated? */
  545.     SOUND_l = iconState (28) | (SOUND_l & ~1);
  546.     break;
  547.       case 29:            /* off? */
  548.     SOUND_l = iconState (29) << 1 | (SOUND_l & ~2);
  549.     break;
  550.       case 19:            /* cancel */
  551.     if (poll.pointer.buttons == 4)
  552.       close_opts ();
  553.     else {
  554.       copy_opts ();
  555.       reflect_opts ();
  556.     }
  557.     break;
  558.       case 20:            /* ok */
  559.     SPEED = SPEED_l;
  560.     MUSICtype = MUSIC_l;
  561.     VidMode = HIRES_l;
  562.     PAUSEtype = PAUSE_l;
  563.     SOUND = SOUND_l;
  564.     VOLUME = VOLUME_l;
  565.     if (mm_keyb_pressed (131))
  566.       HISCORE = 0;
  567.     if (poll.pointer.buttons & 4)
  568.       close_opts ();
  569.     break;
  570.       case 21:            /* save */
  571.     SPEED = SPEED_l;
  572.     MUSICtype = MUSIC_l;
  573.     VidMode = HIRES_l;
  574.     PAUSEtype = PAUSE_l;
  575.     SOUND = SOUND_l;
  576.     VOLUME = VOLUME_l;
  577.     if (mm_keyb_pressed (131))
  578.       HISCORE = 0;
  579.     if (poll.pointer.buttons & 4)
  580.       close_opts ();
  581.     SaveInfo (1);
  582.     break;
  583.       case 30:            /* defaults */
  584.     SPEED_l = DEFAULTSPEED;
  585.     MUSIC_l = DEFAULTMUSIC;
  586.     HIRES_l = DEFAULTRES;
  587.     PAUSE_l = DEFAULTPAUSE;
  588.     SOUND_l = DEFAULTSOUND;
  589.     VOLUME_l = DEFAULTVOLUME;
  590.     reflect_opts ();
  591.     break;
  592.       case 33:
  593.       case 34:
  594.     i = mm_keyb_pressed (129) ? 10 : 1;
  595.     if ((poll.pointer.i ^ poll.pointer.buttons) & 1) {
  596.       if (VOLUME_l > 0) {
  597.         VOLUME_l -= i;
  598.         if (VOLUME_l < 0)
  599.           VOLUME_l = 0;
  600.         reflect_volume ();
  601.       }
  602.     }
  603.     else {
  604.       if (VOLUME_l < 100) {
  605.         VOLUME_l += i;
  606.         if (VOLUME_l > 100)
  607.           VOLUME_l = 100;
  608.         reflect_volume ();
  609.       }
  610.     }
  611.       }
  612.     }
  613.   }
  614. }
  615.  
  616.  
  617. static void
  618. menuclick (void)
  619. {
  620.   switch (poll.selection.items[0]) {
  621.   case 1:
  622.     rungame ();
  623.     break;
  624.   case 2:
  625.     openopts ();
  626.     break;
  627.   case 3:
  628.     switch (poll.selection.items[1]) {
  629.     case 0:
  630.       go_loadgame ("<Manic$Dir>.set0/lev");
  631.       break;
  632.     case 1:
  633.       go_loadgame ("<Manic$Dir>.set1/lev");
  634.       break;
  635.     }
  636.     break;
  637.   case 4:
  638.     quit = (MODE == 2) ? areyousure (0) : 1;
  639.   }
  640.   if (xwimp_get_pointer_info (&poll.pointer))
  641.     return;
  642.   if (poll.pointer.buttons == 1)
  643.     wimp_create_menu ((wimp_menu *) (&menu), 0, 0);
  644. }
  645.  
  646.  
  647. static void
  648. message (void)
  649. {
  650.   switch (poll.message.action) {
  651.   case 0:
  652.     xwimp_close_down (task_h);
  653.     quit = 1;
  654.     break;
  655.   case message_DATA_SAVE:
  656.     if (poll.message.data.data_xfer.file_type != 0xFFD)
  657.       break;
  658.     poll.message.size = 256;
  659.     poll.message.your_ref = poll.message.my_ref;
  660.     poll.message.action = message_DATA_SAVE_ACK;
  661.     poll.message.data.data_xfer.est_size = -1;
  662.     strcpy (poll.message.data.data_xfer.file_name, "<Wimp$Scrap>");
  663.     xwimp_send_message (wimp_USER_MESSAGE,
  664.             &poll.message, poll.message.sender);
  665.     break;
  666.   case message_DATA_LOAD:
  667.     if (poll.message.data.data_xfer.file_type != 0xFFD)
  668.       break;
  669.     if (MODE == 2 && !areyousure (1))
  670.       break;
  671.     go_loadgame (poll.message.data.data_xfer.file_name);
  672.     break;
  673.   case message_PREQUIT:
  674.     if (MODE == 2 && !areyousure (0)) {
  675.       poll.message.your_ref = poll.message.my_ref;
  676.       xwimp_send_message (wimp_USER_MESSAGE,
  677.               &poll.message, poll.message.sender);
  678.     }
  679.     break;
  680.   case message_TASK_INITIALISE:
  681.     if (poll.message.sender == task_h)
  682.       notme = 1;
  683.     else if (notme) {
  684.       os_error *err;
  685.       char *name;
  686.       err = xtaskmanager_task_name_from_handle (poll.message.sender, &name);
  687.       if (!memcmp (name, TASKNAME, TASKNAMELEN) && name[TASKNAMELEN] < 32) {
  688.     poll.message.size = 20;
  689.     poll.message.my_ref = 0;
  690.     poll.message.action = message_QUIT;
  691.     xwimp_send_message (wimp_USER_MESSAGE,
  692.                 &poll.message, poll.message.sender);
  693.       }
  694.     }
  695.     break;
  696.   case message_MENU_WARNING:
  697.     {
  698.       wimp_message_menu_warning *m =
  699.     (wimp_message_menu_warning *) poll.message.data.reserved;
  700.       switch (m->selection.items[0]) {
  701.       case 0:
  702.     stop_easteregg ();
  703.     goto opensub;
  704.       case 2:
  705.     copy_opts ();
  706.     reflect_opts ();
  707.       opensub:wimp_create_sub_menu (m->sub_menu, m->pos.x, m->pos.y);
  708.     if (m->sub_menu == (wimp_menu *) optsbox) {
  709.       wimp_window_state w;
  710.       w.w = optsbox;
  711.       if (xwimp_get_window_state (&w))
  712.         break;
  713.       w.flags &= ~(1 << 24);
  714.       openwindow (&w);
  715.     }
  716.       }
  717.     }
  718.     break;
  719.   case message_MENUS_DELETED:
  720.     stop_easteregg ();
  721.     break;
  722.   case 0x4E383:
  723.     if (poll.message.data.reserved[0] & 1) {
  724.       char url[256];
  725.       url[0] = 0;
  726.       uriRequest (url, 256, ((int *) poll.message.data.reserved)[1]);
  727.       if (url[0]) {
  728.     urlDispatch (url);
  729.       }
  730.     }
  731.     break;
  732.   }
  733. }
  734.  
  735.  
  736. static void
  737. bounce (void)
  738. {
  739.   if (poll.message.action == 0x4AF80) {
  740.     wimp_t t = 0;
  741.     const char *i, *url;
  742.     static char tmp[256] = "Alias$URLOpen_";    /* len=14 */
  743.     i = strchr (url = (char *) poll.message.data.reserved, ':');
  744.     if (!i)
  745.       return;
  746.     strncpy (tmp + 14, url, i - url);
  747.     if (!getenv (tmp))
  748.       return;
  749.     strcat (tmp, " ");
  750.     strcat (tmp, url);
  751.     xwimp_start_task (tmp + 6, &t);
  752.   }
  753. }
  754.  
  755.  
  756. typedef void (*SIGNAL) (int);
  757.  
  758. void
  759. desktop (void)
  760. {
  761.   int i;
  762.  
  763. #ifdef UNIXLIB
  764.   __uname_control = __UNAME_NO_PROCESS;
  765. #endif
  766.  
  767.   modedata[0] = -1;
  768.   signal (SIGABRT, (SIGNAL) goshutdown);
  769.   signal (SIGFPE, (SIGNAL) goshutdown);
  770.   signal (SIGILL, (SIGNAL) goshutdown);
  771.   signal (SIGINT, (SIGNAL) goshutdown);
  772.   signal (SIGSEGV, (SIGNAL) goshutdown);
  773.   signal (SIGTERM, (SIGNAL) goshutdown);
  774. #ifdef SIGSTAK
  775.   signal (SIGSTAK, (SIGNAL) goshutdown);
  776. #endif
  777. #ifdef SIGOSERROR
  778.   signal (SIGOSERROR, (SIGNAL) goshutdown);
  779. #endif
  780.  
  781. //  if (!getenv ("Choices$Write"))
  782. //    choicesnum = 1;
  783.   findMachineType ();
  784.   task_h =
  785.     wimp_initialise (310, TASKNAME, (wimp_message_list *) msgs, &wimp_v);
  786.   do {
  787.     x (xwimp_poll (0x00003933, &poll, 0, &i));
  788.     if (i == wimp_USER_MESSAGE || i == wimp_USER_MESSAGE_RECORDED)
  789.       message ();
  790.   }
  791.   while (!quit && !notme);
  792.   if (quit)
  793.     exit (0);
  794.  
  795.   wimp_open_template ("<Manic$Dir>.Templates");
  796.   open = 1;
  797.   atexit (closetemplate);
  798.   menu[0].entries[0].sub_menu =
  799.     menu[1].entries[0].sub_menu = (wimp_menu *) (infobox = loadt ("Info"));
  800.   menu[0].entries[2].sub_menu =
  801.     menu[1].entries[2].sub_menu = (wimp_menu *) (optsbox = loadt ("Options"));
  802.   {
  803.     wimp_icon_state i;
  804.     i.w = infobox;
  805.     i.i = 3;
  806.     x (xwimp_get_icon_state (&i));
  807.     strcpy (i.icon.data.indirected_text.text, VERSION);
  808.     i.w = optsbox;
  809.     i.i = 10;
  810.     x (xwimp_get_icon_state (&i));
  811.     name_buf = i.icon.data.indirected_text.text;
  812.     i.i = 32;
  813.     x (xwimp_get_icon_state (&i));
  814.     vol_buf = i.icon.data.indirected_text.text;
  815.   }
  816.   closetemplate ();
  817.   icon.icon.data.indirected_sprite.id = (osspriteop_id) sprite;
  818.   icon.icon.data.indirected_sprite.area = (osspriteop_area *) 1;
  819.   icon.icon.data.indirected_sprite.size = 7;
  820.   x (xwimp_create_icon (&icon, &ibar_icon));
  821.   atexit (goshutdown);
  822.   LoadInfo ();
  823.   reflect_levels ();
  824.   do {
  825.     if (easteregg == 4)
  826.       x (xwimp_poll_idle (0x00003932, &poll, eggtimer, 0, &i));
  827.     else
  828.       x (xwimp_poll (0x00003933, &poll, 0, &i));
  829.     switch (i) {
  830.     case wimp_NULL_REASON_CODE:
  831.       do_easteregg ();
  832.       break;
  833.     case wimp_OPEN_WINDOW_REQUEST:
  834.       xwimp_open_window (&poll.open);
  835.       break;
  836.     case wimp_CLOSE_WINDOW_REQUEST:
  837.       xwimp_close_window (poll.close.w);
  838.       break;
  839.     case wimp_MOUSE_CLICK:
  840.       click ();
  841.       break;
  842.     case wimp_MENU_SELECTION:
  843.       menuclick ();
  844.       break;
  845.     case wimp_USER_MESSAGE:
  846.     case wimp_USER_MESSAGE_RECORDED:
  847.       message ();
  848.       break;
  849.     case wimp_USER_MESSAGE_ACKNOWLEDGE:
  850.       bounce ();
  851.       break;
  852.     }
  853.   } while (!quit);
  854.   xwimp_close_down (task_h);
  855.   SaveInfo ();
  856.   exit (0);
  857. }
  858.