home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 5 / DATAFILE_PDCD5.iso / utilities / t / tornado / TNdemo / !TMTDemo / c / !RunImage
Encoding:
Text File  |  1996-12-30  |  12.3 KB  |  540 lines

  1. /* !RunImage.c
  2. Provides a demo of TMT at work
  3. by N. Douglas
  4. Started: 30-11-1996
  5. Last updated: 30-12-1996 version 0.12
  6.  
  7. Requires TMTMod to be linked in with it as this provides the Win32 thunking
  8. layer
  9. */
  10.  
  11. #include "TMTMod.h"
  12. #include "kernel.h"
  13. #include <stdlib.h>
  14. #include <string.h>
  15.  
  16. typedef struct ROINITIALISEBLK
  17. {
  18.   int rovers;            /* RO version */
  19.   int wimpvers;            /* Wimp version */
  20.   int tnvers;            /* Support module version */
  21.   char *taskname;        /* RO Wimp task name */
  22.   function handler;        /* address of 17, 18 & 19 handler */
  23.   int taskh;            /* RO Wimp task handle */
  24.  
  25. } ROINITIALISEBLK;
  26.  
  27. static BOOL quit=FALSE;
  28. static char indir[256];
  29. static char templ[256];
  30. static char menus[256];
  31. static int windh;
  32. static char *sp;
  33. static const char spname[]="Sprite";
  34. static char *savearea;
  35. static char sc[16];
  36. static char pix[16*4];
  37. static char halt=FALSE;
  38.  
  39. #define FRAMES 1/*5000*/
  40. #define XOR_SPECIAL 0x1d872b41
  41. static unsigned int seed=0xabcdef12;
  42.  
  43. int codeshandler(int, int);
  44. void CreateNewWindow(void);
  45. void UpdateWindow(void);
  46. unsigned int rnd(int);
  47. void ModeChange(void);
  48. void RedrawWindow(_kernel_swi_regs);
  49. void ROInitialise(ROINITIALISEBLK *);
  50. void ROClosedown(int);
  51. int ROReportError(int, int *);
  52. int ROReportErrora(int, int, char *);
  53. void StdErrHandlr(_kernel_oserror *);
  54. void ROSetPollMask(int);
  55.  
  56. int main(void)
  57. {
  58.   ROINITIALISEBLK blk;
  59.   char taskname[]="TMT Demo";
  60.   char q[256];
  61.   _kernel_swi_regs r;
  62.   int icbarh;
  63.   int count=rnd(FRAMES);
  64.  
  65.   blk.rovers=200;
  66.   blk.wimpvers=200;
  67.   blk.tnvers=010;
  68.   blk.taskname=taskname;
  69.   blk.handler=(function) codeshandler;
  70.  
  71.   ROInitialise(&blk);
  72.  
  73.   /* Now we're being preempted */
  74.  
  75.   /* Load some templates */
  76.   {
  77.     const char templatenm[]="<TMTDemo$Dir>.Templates";
  78.     const char main[]="main";
  79.  
  80.     r.r[1]=(int) templatenm;
  81.     StdErrHandlr(_kernel_swi(0x400d9/*Wimp_OpenTemplate*/, &r, &r));
  82.  
  83.     r.r[1]=(int) templ;
  84.     r.r[2]=(int) indir;
  85.     r.r[3]=(int) indir+256;
  86.     r.r[4]=-1;
  87.     r.r[5]=(int) main;
  88.     r.r[6]=0;
  89.     StdErrHandlr(_kernel_swi(0x400db/*Wimp_LoadTemplate*/, &r, &r));
  90.  
  91.     StdErrHandlr(_kernel_swi(0x400da/*Wimp_CloseTemplate*/, &r, &r));
  92.   }
  93.  
  94.   /* Put an icon on the icbar */
  95.   {
  96.     const char icname[]="!tmtdemo";
  97.  
  98.     *(int *)(q+0)=-1;
  99.     *(int *)(q+4)=0;
  100.     *(int *)(q+8)=0;
  101.     *(int *)(q+12)=68;
  102.     *(int *)(q+16)=68;
  103.     *(int *)(q+20)=0x1700301a;
  104.     *(int *)(q+24)=*(int *) (icname+0);
  105.     *(int *)(q+28)=*(int *) (icname+4);
  106.     *(int *)(q+32)=*(int *) (icname+8);
  107.     r.r[1]=(int) q;
  108.     StdErrHandlr(_kernel_swi(0x400c2/*Wimp_CreateIcon*/, &r, &r));
  109.     icbarh=r.r[0];
  110.   }
  111.  
  112.   StdErrHandlr(_kernel_swi(0x42/*OS_ReadMonotonicTime*/, &r, &r));
  113.   seed=r.r[0];
  114.  
  115.   CreateNewWindow();
  116.   UpdateWindow();
  117.   ModeChange();
  118.  
  119.   r.r[1]=(int) q;
  120.   *(int *)(q+0)=windh;
  121.   StdErrHandlr(_kernel_swi(0x400cb/*Wimp_GetWindowState*/, &r, &r));
  122.   {
  123.     int dx=(*(int *)(q+12))-(*(int *)(q+4)),dy=(*(int *)(q+16))-(*(int *)(q+8));
  124.     *(int *)(q+4)=rnd(640);
  125.     *(int *)(q+8)=rnd(512);
  126.     *(int *)(q+12)=(*(int *)(q+4))+dx;
  127.     *(int *)(q+16)=(*(int *)(q+8))+dy;
  128.   }
  129.   StdErrHandlr(_kernel_swi(0x400c5/*Wimp_OpenWindow*/, &r, &r));
  130.  
  131.   /* Enter main message loop */
  132.   do
  133.   {
  134.     r.r[1]=(int) q;
  135.     StdErrHandlr(_kernel_swi(Tornado_Poll, &r, &r));
  136.     /* We need to reenable until any queue present gets cleared */
  137.     if(r.r[0]!=0)
  138.       ROSetPollMask(0);
  139.     switch(r.r[0])
  140.     {
  141.       case 0:
  142.       /* If 0 gets returned it means the message queue is now empty so it's
  143.       okay to prevent null polls */
  144.       if(halt)
  145.         ROSetPollMask(1);
  146.       else
  147.       {
  148.         if(count<=0)
  149.         {
  150.         UpdateWindow();
  151.         r.r[1]=(int) q;
  152.         *(int *)(q+0)=windh;
  153.         StdErrHandlr(_kernel_swi(0x400cb/*Wimp_GetWindowState*/, &r, &r));
  154.         *(int *)(q+20)=(*(int *)(q+4))-(*(int *)(q+20));
  155.         *(int *)(q+24)=(*(int *)(q+16))-(*(int *)(q+24));
  156.         *(int *)(q+4)=0;
  157.         *(int *)(q+8)=-512;
  158.         *(int *)(q+12)=640;
  159.         *(int *)(q+16)=0;
  160.         RedrawWindow(r);
  161.         count=FRAMES+1;
  162.         }
  163.         count-=1;
  164.       }
  165.       break;
  166.       case 1:
  167.       RedrawWindow(r);
  168.       break;
  169.       case 2:
  170.       StdErrHandlr(_kernel_swi(0x400c5/*Wimp_OpenWindow*/, &r, &r));
  171.       break;
  172.       case 3:
  173.       StdErrHandlr(_kernel_swi(0x400c6/*Wimp_CloseWindow*/, &r, &r));
  174.       break;
  175.       case 6:
  176.       if((*(int *)(q+12))==-2)/*ie; the icon bar*/
  177.       {
  178.         if((*(int *)(q+8) & 2)==2)
  179.         {
  180.           const char quit[]="Quit";
  181.  
  182.           /*Open a quit menu */
  183.           *(int *)(menus+0)=*(int *)(taskname+0);
  184.           *(int *)(menus+4)=*(int *)(taskname+4);
  185.           *(int *)(menus+8)=*(int *)(taskname+8);
  186.           *(char *)(menus+12)=7;
  187.           *(char *)(menus+13)=2;
  188.           *(char *)(menus+14)=7;
  189.           *(char *)(menus+15)=0;
  190.           *(int *)(menus+16)=8*16;    /* I see this is ignored on RO3 */
  191.           *(int *)(menus+20)=44;
  192.           *(int *)(menus+24)=0;
  193.           *(int *)(menus+28)=0x80;
  194.           *(int *)(menus+32)=-1;
  195.           *(int *)(menus+36)=0x7005031;
  196.           *(int *)(menus+40)=*(int *)(quit+0);
  197.           *(int *)(menus+44)=*(int *)(quit+4);
  198.           *(int *)(menus+48)=*(int *)(quit+8);
  199.           r.r[1]=(int) menus;
  200.           r.r[2]=(*(int *)(q+0))-64;
  201.           r.r[3]=96+48;
  202.           StdErrHandlr(_kernel_swi(0x400d4/*Wimp_CreateMenu*/, &r, &r));
  203.         }
  204.         else if((*(int *)(q+8) & 4)==4)
  205.         {
  206.           /* Open the window */
  207.           *(int *)(q+0)=windh;
  208.           r.r[1]=(int) q;
  209.           StdErrHandlr(_kernel_swi(0x400cb/*Wimp_GetWindowState*/, &r, &r));
  210.           *(int *)(q+28)=-1;
  211.           StdErrHandlr(_kernel_swi(0x400c5/*Wimp_OpenWindow*/, &r, &r));
  212.         }
  213.         else
  214.         {
  215.           StdErrHandlr(_kernel_swi(0x107, &r, &r));
  216.         }
  217.         break;
  218.       }
  219.       else if((*(int *)(q+12))==windh) /* ie; it's the window */
  220.       {
  221.         if((*(int *)(q+8) & 4)==4)
  222.         {
  223.           /* Stop the drawing */
  224.           halt=TRUE;
  225.         }
  226.         else if((*(int *)(q+8) & 1)==1)
  227.         {
  228.           /* Restart the drawing */
  229.           halt=FALSE;
  230.         }
  231.         else
  232.         {
  233.           StdErrHandlr(_kernel_swi(0x107, &r, &r));
  234.         }
  235.         break;
  236.       }
  237.       break;
  238.       case 9:
  239.       if((*(int *)(q+0))==0)
  240.         quit=TRUE;
  241.       break;
  242.       case 17:
  243.       case 18:
  244.       switch(*(int *) (r.r[1]+16))
  245.       {
  246.         case 0x400c1:
  247.         ModeChange();
  248.         break;
  249.         default:
  250.         break;
  251.       }
  252.       break;
  253.       default:
  254.       break;
  255.     }
  256.   }
  257.   while(!quit);
  258.  
  259.   /* Shut her down */
  260.   ROClosedown(blk.taskh);
  261.  
  262.   return 0;
  263. }
  264.  
  265. int codeshandler(int msgno, int msgblk)
  266. {
  267.   switch(*(int *) (msgblk+16))
  268.   {
  269.     case 0:
  270.     quit=TRUE;
  271.     return MSG_HANDLED;
  272.     break;
  273.     case 0x502:/*Message_HelpRequest*/
  274.     if(*(int *)(msgblk+32)==-2)
  275.     {
  276.       char msg[]="This is the icon of a demonstration of the tornado II support module's preemption facilities|MClick SELECT to open the demo's main window|MClick MENU to open the demo's icon bar menu";
  277.       _kernel_swi_regs r;
  278.  
  279.       strcpy((char *) msgblk+20,msg);
  280.       *(int *)(msgblk+0)=256;
  281.       *(int *)(msgblk+16)=0x503;/*Message_HelpGive*/
  282.       *(int *)(msgblk+12)=*(int *)(msgblk+8);
  283.       r.r[0]=17;
  284.       r.r[1]=msgblk;
  285.       r.r[2]=*(int *)(msgblk+4);
  286.       _kernel_swi(0x400e7/*Wimp_SendMessage*/, &r, &r);
  287.       return MSG_HANDLED;
  288.     }
  289.     else if(*(int *)(msgblk+32)==windh)
  290.     {
  291.       char msg[]="The lines in this window are being drawn into it preemptively|MClick SELECT to stop the lines being drawn|MClick ADJUST to restart the lines being drawn";
  292.       _kernel_swi_regs r;
  293.  
  294.       strcpy((char *) msgblk+20,msg);
  295.       *(int *)(msgblk+0)=256;
  296.       *(int *)(msgblk+16)=0x503;/*Message_HelpGive*/
  297.       *(int *)(msgblk+12)=*(int *)(msgblk+8);
  298.       r.r[0]=17;
  299.       r.r[1]=msgblk;
  300.       r.r[2]=*(int *)(msgblk+4);
  301.       _kernel_swi(0x400e7/*Wimp_SendMessage*/, &r, &r);
  302.       return MSG_HANDLED;
  303.     }
  304.     return MSG_PASSON;
  305.     break;
  306.     default:
  307.     return MSG_PASSON;
  308.     break;
  309.   }
  310. }
  311.  
  312. void CreateNewWindow(void)
  313. {
  314.   _kernel_swi_regs r;
  315.   int spaddr;
  316.  
  317.   sp=malloc(320*256+1024);
  318.   if(sp==0)
  319.     ROReportErrora(0x102, 0, "Not enough memory to allocate for sprite");
  320.   /* I'm probably missing something here but somehow the sprite area
  321.      needs zeroing or the sprite create fails!!! */
  322.   {
  323.     int n;
  324.  
  325.     for(n=0;n<320*256+1024;n+=4)
  326.       *(int *)(sp+n)=0;
  327.   }
  328.   *(int *)(sp+0)=320*256+1024;
  329.   *(int *)(sp+8)=16;
  330.   r.r[0]=256+9;
  331.   r.r[1]=(int) sp;
  332.   StdErrHandlr(_kernel_swi(0x2e/*OS_SpriteOp*/, &r, &r));
  333.   r.r[0]=256+15;
  334.   r.r[1]=(int) sp;
  335.   r.r[2]=(int) spname;
  336.   r.r[3]=1;
  337.   r.r[4]=320;
  338.   r.r[5]=256;
  339.   r.r[6]=20;
  340.   StdErrHandlr(_kernel_swi(0x2e, &r, &r));
  341.   r.r[0]=256+24;
  342.   r.r[1]=(int) sp;
  343.   r.r[2]=(int) spname;
  344.   StdErrHandlr(_kernel_swi(0x2e, &r, &r));
  345.   spaddr=r.r[2];
  346.   *(int *)(spaddr+44+0)=0x00000000;
  347.   *(int *)(spaddr+44+8)=0x0000ff00;
  348.   *(int *)(spaddr+44+16)=0x00ff0000;
  349.   *(int *)(spaddr+44+24)=0x00ffff00;
  350.   *(int *)(spaddr+44+32)=0xff000000;
  351.   *(int *)(spaddr+44+40)=0xff00ff00;
  352.   *(int *)(spaddr+44+48)=0xffff0000;
  353.   *(int *)(spaddr+44+56)=0xffffff00;
  354.  
  355.   r.r[0]=256+62;
  356.   r.r[1]=(int) sp;
  357.   r.r[2]=(int) spname;
  358.   StdErrHandlr(_kernel_swi(0x2e, &r, &r));
  359.   savearea=malloc(r.r[3]);
  360.   *(int *)(savearea)=0;
  361.  
  362.   r.r[1]=(int) templ;
  363.   StdErrHandlr(_kernel_swi(0x400c1/*Wimp_CreateWindow*/, &r, &r));
  364.   windh=r.r[0];
  365. }
  366.  
  367. void UpdateWindow(void)
  368. {
  369.   _kernel_swi_regs r,r2;
  370.  
  371.   r2.r[0]=256+60;
  372.   r2.r[1]=(int) sp;
  373.   r2.r[2]=(int) spname;
  374.   r2.r[3]=(int) savearea;
  375.   StdErrHandlr(_kernel_swi(0x2e, &r2, &r2));
  376.  
  377.   StdErrHandlr(_kernel_swi(0x100+18, &r, &r));
  378.   StdErrHandlr(_kernel_swi(0x100+0, &r, &r));
  379.   StdErrHandlr(_kernel_swi(0x100+rnd(8), &r, &r));
  380.   /*r.r[0]=4;
  381.   r.r[1]=0;
  382.   r.r[2]=0;
  383.   StdErrHandlr(_kernel_swi(0x45*//*OS_Plot*//*, &r, &r));*/
  384.   r.r[0]=5;
  385.   r.r[1]=rnd(640);
  386.   r.r[2]=rnd(512);
  387.   StdErrHandlr(_kernel_swi(0x45/*OS_Plot*/, &r, &r));
  388.  
  389.   StdErrHandlr(_kernel_swi(0x2e, &r2, &r2));
  390. }
  391.  
  392. unsigned int rnd(int val)
  393. {
  394.   int n;
  395.  
  396.   for(n=0;n<32;n++)
  397.   {
  398.     seed=seed<<1;
  399.     if(seed & (1<<30))
  400.     {
  401.       seed=seed^XOR_SPECIAL;
  402.     }
  403.   }
  404.   n=seed % val;
  405.   if(n>=0)
  406.     return n;
  407.   else
  408.     return -n;
  409. }
  410.  
  411. void ModeChange(void)
  412. {
  413.   _kernel_swi_regs r;
  414.   int spaddr,n;
  415.   char pal2[16*4];
  416.  
  417.   r.r[0]=256+24;
  418.   r.r[1]=(int) sp;
  419.   r.r[2]=(int) spname;
  420.   StdErrHandlr(_kernel_swi(0x2e, &r, &r));
  421.   spaddr=r.r[2];
  422.  
  423.   for(n=0;n<16*8;n+=8)
  424.     *(int *)(pal2+(n/2))=*(int *)(spaddr+44+n);
  425.  
  426.   r.r[0]=*(int *)(spaddr+40);
  427.   r.r[1]=(int) pal2;
  428.   r.r[2]=-1;
  429.   r.r[3]=-1;
  430.   r.r[4]=(int) pix;
  431.   StdErrHandlr(_kernel_swi(0x40740/*ColourTrans_SelectTable*/, &r, &r));
  432.  
  433.   r.r[0]=256;
  434.   r.r[1]=(int) sp;
  435.   r.r[2]=(int) spname;
  436.   r.r[6]=(int) sc;
  437.   r.r[7]=-1;
  438.   StdErrHandlr(_kernel_swi(0x400ed/*Wimp_ReadPixTrans*/, &r, &r));
  439. }
  440.  
  441. void RedrawWindow(_kernel_swi_regs r2)
  442. {
  443.   _kernel_swi_regs r=r2,t;
  444.   int dx=*(int *)(r.r[1]+20), dy=*(int *)(r.r[1]+24);
  445.  
  446.   StdErrHandlr(_kernel_swi(Tornado_RedrawWindow, &r, &r));
  447.   while(r.r[0]!=0)
  448.   {
  449.     t.r[0]=256+52;
  450.     t.r[1]=(int) sp;
  451.     t.r[2]=(int) spname;
  452.     t.r[3]=dx;
  453.     t.r[4]=dy-512;
  454.     t.r[5]=0;
  455.     t.r[6]=(int) sc;
  456.     t.r[7]=(int) pix;
  457.     StdErrHandlr(_kernel_swi(0x2e, &t, &t));
  458.  
  459.     StdErrHandlr(_kernel_swi(Tornado_GetRectangle, &r, &r));
  460.   }
  461. }
  462.  
  463. void ROInitialise(ROINITIALISEBLK *blk)
  464. {
  465.   char task[]="TASK";
  466.   _kernel_swi_regs r;
  467.  
  468.   r.r[0]=blk->wimpvers;
  469.   r.r[1]=* (int *) task;
  470.   r.r[2]=(int) blk->taskname;
  471.   _kernel_swi(0x400C0/*Wimp_Initialise*/,&r, &r);
  472.  
  473.   blk->wimpvers=r.r[0];
  474.   blk->taskh=r.r[1];
  475.  
  476.   r.r[0]=010;
  477.   r.r[1]=(int) blk->taskname;
  478.   r.r[2]=(int) blk->handler;
  479.   r.r[3]=blk->taskh;
  480.   StdErrHandlr(_kernel_swi(Tornado_Initialise, &r, &r));
  481.  
  482.   blk->tnvers=r.r[0];
  483.   blk->rovers=r.r[1];
  484. }
  485.  
  486. void ROClosedown(int taskh)
  487. {
  488.   _kernel_swi_regs r;
  489.  
  490.   r.r[0]=taskh;
  491.   StdErrHandlr(_kernel_swi(Tornado_Closedown, &r, &r));
  492.  
  493.   StdErrHandlr(_kernel_swi(0x400DD/*Wimp_CloseDown*/, &r, &r));
  494. }
  495.  
  496. int ROReportError(int flags, int *blk)
  497. {
  498.   _kernel_swi_regs r;
  499.   char tmesg[]="TMT Demo";
  500.  
  501.   r.r[0]=(int) blk;
  502.   r.r[1]=flags;
  503.   r.r[2]=(int) tmesg;
  504.   _kernel_swi(0x400df/*Wimp_ReportError*/, &r, &r);
  505.  
  506.   if(flags & 0x100)
  507.     exit(EXIT_FAILURE);
  508.   return r.r[1];
  509. }
  510.  
  511. int ROReportErrora(int flags, int errno, char *errstr)
  512. {
  513.   char q[260];
  514.  
  515.   *(int *)(q+0)=errno;
  516.   strcpy((q+4), errstr);
  517.   return ROReportError(flags, (int *) q);
  518. }
  519.  
  520. void StdErrHandlr(_kernel_oserror *blk)
  521. {
  522.   if(blk)
  523.     ROReportError(0x102, (int *) blk);
  524. }
  525.  
  526. void ROSetPollMask(int pollmask)
  527. {
  528.   _kernel_swi_regs r;
  529.  
  530.   r.r[0]=pollmask;
  531.   StdErrHandlr(_kernel_swi(Tornado_SetPollMask, &r, &r));
  532. }
  533.  
  534.  
  535.  
  536. /* Just for debugging purposes */
  537. void end(void)
  538. {
  539. }
  540.