home *** CD-ROM | disk | FTP | other *** search
Wrap
/* !RunImage.c Provides a demo of TMT at work by N. Douglas Started: 30-11-1996 Last updated: 30-12-1996 version 0.12 Requires TMTMod to be linked in with it as this provides the Win32 thunking layer */ #include "TMTMod.h" #include "kernel.h" #include <stdlib.h> #include <string.h> typedef struct ROINITIALISEBLK { int rovers; /* RO version */ int wimpvers; /* Wimp version */ int tnvers; /* Support module version */ char *taskname; /* RO Wimp task name */ function handler; /* address of 17, 18 & 19 handler */ int taskh; /* RO Wimp task handle */ } ROINITIALISEBLK; static BOOL quit=FALSE; static char indir[256]; static char templ[256]; static char menus[256]; static int windh; static char *sp; static const char spname[]="Sprite"; static char *savearea; static char sc[16]; static char pix[16*4]; static char halt=FALSE; #define FRAMES 1/*5000*/ #define XOR_SPECIAL 0x1d872b41 static unsigned int seed=0xabcdef12; int codeshandler(int, int); void CreateNewWindow(void); void UpdateWindow(void); unsigned int rnd(int); void ModeChange(void); void RedrawWindow(_kernel_swi_regs); void ROInitialise(ROINITIALISEBLK *); void ROClosedown(int); int ROReportError(int, int *); int ROReportErrora(int, int, char *); void StdErrHandlr(_kernel_oserror *); void ROSetPollMask(int); int main(void) { ROINITIALISEBLK blk; char taskname[]="TMT Demo"; char q[256]; _kernel_swi_regs r; int icbarh; int count=rnd(FRAMES); blk.rovers=200; blk.wimpvers=200; blk.tnvers=010; blk.taskname=taskname; blk.handler=(function) codeshandler; ROInitialise(&blk); /* Now we're being preempted */ /* Load some templates */ { const char templatenm[]="<TMTDemo$Dir>.Templates"; const char main[]="main"; r.r[1]=(int) templatenm; StdErrHandlr(_kernel_swi(0x400d9/*Wimp_OpenTemplate*/, &r, &r)); r.r[1]=(int) templ; r.r[2]=(int) indir; r.r[3]=(int) indir+256; r.r[4]=-1; r.r[5]=(int) main; r.r[6]=0; StdErrHandlr(_kernel_swi(0x400db/*Wimp_LoadTemplate*/, &r, &r)); StdErrHandlr(_kernel_swi(0x400da/*Wimp_CloseTemplate*/, &r, &r)); } /* Put an icon on the icbar */ { const char icname[]="!tmtdemo"; *(int *)(q+0)=-1; *(int *)(q+4)=0; *(int *)(q+8)=0; *(int *)(q+12)=68; *(int *)(q+16)=68; *(int *)(q+20)=0x1700301a; *(int *)(q+24)=*(int *) (icname+0); *(int *)(q+28)=*(int *) (icname+4); *(int *)(q+32)=*(int *) (icname+8); r.r[1]=(int) q; StdErrHandlr(_kernel_swi(0x400c2/*Wimp_CreateIcon*/, &r, &r)); icbarh=r.r[0]; } StdErrHandlr(_kernel_swi(0x42/*OS_ReadMonotonicTime*/, &r, &r)); seed=r.r[0]; CreateNewWindow(); UpdateWindow(); ModeChange(); r.r[1]=(int) q; *(int *)(q+0)=windh; StdErrHandlr(_kernel_swi(0x400cb/*Wimp_GetWindowState*/, &r, &r)); { int dx=(*(int *)(q+12))-(*(int *)(q+4)),dy=(*(int *)(q+16))-(*(int *)(q+8)); *(int *)(q+4)=rnd(640); *(int *)(q+8)=rnd(512); *(int *)(q+12)=(*(int *)(q+4))+dx; *(int *)(q+16)=(*(int *)(q+8))+dy; } StdErrHandlr(_kernel_swi(0x400c5/*Wimp_OpenWindow*/, &r, &r)); /* Enter main message loop */ do { r.r[1]=(int) q; StdErrHandlr(_kernel_swi(Tornado_Poll, &r, &r)); /* We need to reenable until any queue present gets cleared */ if(r.r[0]!=0) ROSetPollMask(0); switch(r.r[0]) { case 0: /* If 0 gets returned it means the message queue is now empty so it's okay to prevent null polls */ if(halt) ROSetPollMask(1); else { if(count<=0) { UpdateWindow(); r.r[1]=(int) q; *(int *)(q+0)=windh; StdErrHandlr(_kernel_swi(0x400cb/*Wimp_GetWindowState*/, &r, &r)); *(int *)(q+20)=(*(int *)(q+4))-(*(int *)(q+20)); *(int *)(q+24)=(*(int *)(q+16))-(*(int *)(q+24)); *(int *)(q+4)=0; *(int *)(q+8)=-512; *(int *)(q+12)=640; *(int *)(q+16)=0; RedrawWindow(r); count=FRAMES+1; } count-=1; } break; case 1: RedrawWindow(r); break; case 2: StdErrHandlr(_kernel_swi(0x400c5/*Wimp_OpenWindow*/, &r, &r)); break; case 3: StdErrHandlr(_kernel_swi(0x400c6/*Wimp_CloseWindow*/, &r, &r)); break; case 6: if((*(int *)(q+12))==-2)/*ie; the icon bar*/ { if((*(int *)(q+8) & 2)==2) { const char quit[]="Quit"; /*Open a quit menu */ *(int *)(menus+0)=*(int *)(taskname+0); *(int *)(menus+4)=*(int *)(taskname+4); *(int *)(menus+8)=*(int *)(taskname+8); *(char *)(menus+12)=7; *(char *)(menus+13)=2; *(char *)(menus+14)=7; *(char *)(menus+15)=0; *(int *)(menus+16)=8*16; /* I see this is ignored on RO3 */ *(int *)(menus+20)=44; *(int *)(menus+24)=0; *(int *)(menus+28)=0x80; *(int *)(menus+32)=-1; *(int *)(menus+36)=0x7005031; *(int *)(menus+40)=*(int *)(quit+0); *(int *)(menus+44)=*(int *)(quit+4); *(int *)(menus+48)=*(int *)(quit+8); r.r[1]=(int) menus; r.r[2]=(*(int *)(q+0))-64; r.r[3]=96+48; StdErrHandlr(_kernel_swi(0x400d4/*Wimp_CreateMenu*/, &r, &r)); } else if((*(int *)(q+8) & 4)==4) { /* Open the window */ *(int *)(q+0)=windh; r.r[1]=(int) q; StdErrHandlr(_kernel_swi(0x400cb/*Wimp_GetWindowState*/, &r, &r)); *(int *)(q+28)=-1; StdErrHandlr(_kernel_swi(0x400c5/*Wimp_OpenWindow*/, &r, &r)); } else { StdErrHandlr(_kernel_swi(0x107, &r, &r)); } break; } else if((*(int *)(q+12))==windh) /* ie; it's the window */ { if((*(int *)(q+8) & 4)==4) { /* Stop the drawing */ halt=TRUE; } else if((*(int *)(q+8) & 1)==1) { /* Restart the drawing */ halt=FALSE; } else { StdErrHandlr(_kernel_swi(0x107, &r, &r)); } break; } break; case 9: if((*(int *)(q+0))==0) quit=TRUE; break; case 17: case 18: switch(*(int *) (r.r[1]+16)) { case 0x400c1: ModeChange(); break; default: break; } break; default: break; } } while(!quit); /* Shut her down */ ROClosedown(blk.taskh); return 0; } int codeshandler(int msgno, int msgblk) { switch(*(int *) (msgblk+16)) { case 0: quit=TRUE; return MSG_HANDLED; break; case 0x502:/*Message_HelpRequest*/ if(*(int *)(msgblk+32)==-2) { 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"; _kernel_swi_regs r; strcpy((char *) msgblk+20,msg); *(int *)(msgblk+0)=256; *(int *)(msgblk+16)=0x503;/*Message_HelpGive*/ *(int *)(msgblk+12)=*(int *)(msgblk+8); r.r[0]=17; r.r[1]=msgblk; r.r[2]=*(int *)(msgblk+4); _kernel_swi(0x400e7/*Wimp_SendMessage*/, &r, &r); return MSG_HANDLED; } else if(*(int *)(msgblk+32)==windh) { 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"; _kernel_swi_regs r; strcpy((char *) msgblk+20,msg); *(int *)(msgblk+0)=256; *(int *)(msgblk+16)=0x503;/*Message_HelpGive*/ *(int *)(msgblk+12)=*(int *)(msgblk+8); r.r[0]=17; r.r[1]=msgblk; r.r[2]=*(int *)(msgblk+4); _kernel_swi(0x400e7/*Wimp_SendMessage*/, &r, &r); return MSG_HANDLED; } return MSG_PASSON; break; default: return MSG_PASSON; break; } } void CreateNewWindow(void) { _kernel_swi_regs r; int spaddr; sp=malloc(320*256+1024); if(sp==0) ROReportErrora(0x102, 0, "Not enough memory to allocate for sprite"); /* I'm probably missing something here but somehow the sprite area needs zeroing or the sprite create fails!!! */ { int n; for(n=0;n<320*256+1024;n+=4) *(int *)(sp+n)=0; } *(int *)(sp+0)=320*256+1024; *(int *)(sp+8)=16; r.r[0]=256+9; r.r[1]=(int) sp; StdErrHandlr(_kernel_swi(0x2e/*OS_SpriteOp*/, &r, &r)); r.r[0]=256+15; r.r[1]=(int) sp; r.r[2]=(int) spname; r.r[3]=1; r.r[4]=320; r.r[5]=256; r.r[6]=20; StdErrHandlr(_kernel_swi(0x2e, &r, &r)); r.r[0]=256+24; r.r[1]=(int) sp; r.r[2]=(int) spname; StdErrHandlr(_kernel_swi(0x2e, &r, &r)); spaddr=r.r[2]; *(int *)(spaddr+44+0)=0x00000000; *(int *)(spaddr+44+8)=0x0000ff00; *(int *)(spaddr+44+16)=0x00ff0000; *(int *)(spaddr+44+24)=0x00ffff00; *(int *)(spaddr+44+32)=0xff000000; *(int *)(spaddr+44+40)=0xff00ff00; *(int *)(spaddr+44+48)=0xffff0000; *(int *)(spaddr+44+56)=0xffffff00; r.r[0]=256+62; r.r[1]=(int) sp; r.r[2]=(int) spname; StdErrHandlr(_kernel_swi(0x2e, &r, &r)); savearea=malloc(r.r[3]); *(int *)(savearea)=0; r.r[1]=(int) templ; StdErrHandlr(_kernel_swi(0x400c1/*Wimp_CreateWindow*/, &r, &r)); windh=r.r[0]; } void UpdateWindow(void) { _kernel_swi_regs r,r2; r2.r[0]=256+60; r2.r[1]=(int) sp; r2.r[2]=(int) spname; r2.r[3]=(int) savearea; StdErrHandlr(_kernel_swi(0x2e, &r2, &r2)); StdErrHandlr(_kernel_swi(0x100+18, &r, &r)); StdErrHandlr(_kernel_swi(0x100+0, &r, &r)); StdErrHandlr(_kernel_swi(0x100+rnd(8), &r, &r)); /*r.r[0]=4; r.r[1]=0; r.r[2]=0; StdErrHandlr(_kernel_swi(0x45*//*OS_Plot*//*, &r, &r));*/ r.r[0]=5; r.r[1]=rnd(640); r.r[2]=rnd(512); StdErrHandlr(_kernel_swi(0x45/*OS_Plot*/, &r, &r)); StdErrHandlr(_kernel_swi(0x2e, &r2, &r2)); } unsigned int rnd(int val) { int n; for(n=0;n<32;n++) { seed=seed<<1; if(seed & (1<<30)) { seed=seed^XOR_SPECIAL; } } n=seed % val; if(n>=0) return n; else return -n; } void ModeChange(void) { _kernel_swi_regs r; int spaddr,n; char pal2[16*4]; r.r[0]=256+24; r.r[1]=(int) sp; r.r[2]=(int) spname; StdErrHandlr(_kernel_swi(0x2e, &r, &r)); spaddr=r.r[2]; for(n=0;n<16*8;n+=8) *(int *)(pal2+(n/2))=*(int *)(spaddr+44+n); r.r[0]=*(int *)(spaddr+40); r.r[1]=(int) pal2; r.r[2]=-1; r.r[3]=-1; r.r[4]=(int) pix; StdErrHandlr(_kernel_swi(0x40740/*ColourTrans_SelectTable*/, &r, &r)); r.r[0]=256; r.r[1]=(int) sp; r.r[2]=(int) spname; r.r[6]=(int) sc; r.r[7]=-1; StdErrHandlr(_kernel_swi(0x400ed/*Wimp_ReadPixTrans*/, &r, &r)); } void RedrawWindow(_kernel_swi_regs r2) { _kernel_swi_regs r=r2,t; int dx=*(int *)(r.r[1]+20), dy=*(int *)(r.r[1]+24); StdErrHandlr(_kernel_swi(Tornado_RedrawWindow, &r, &r)); while(r.r[0]!=0) { t.r[0]=256+52; t.r[1]=(int) sp; t.r[2]=(int) spname; t.r[3]=dx; t.r[4]=dy-512; t.r[5]=0; t.r[6]=(int) sc; t.r[7]=(int) pix; StdErrHandlr(_kernel_swi(0x2e, &t, &t)); StdErrHandlr(_kernel_swi(Tornado_GetRectangle, &r, &r)); } } void ROInitialise(ROINITIALISEBLK *blk) { char task[]="TASK"; _kernel_swi_regs r; r.r[0]=blk->wimpvers; r.r[1]=* (int *) task; r.r[2]=(int) blk->taskname; _kernel_swi(0x400C0/*Wimp_Initialise*/,&r, &r); blk->wimpvers=r.r[0]; blk->taskh=r.r[1]; r.r[0]=010; r.r[1]=(int) blk->taskname; r.r[2]=(int) blk->handler; r.r[3]=blk->taskh; StdErrHandlr(_kernel_swi(Tornado_Initialise, &r, &r)); blk->tnvers=r.r[0]; blk->rovers=r.r[1]; } void ROClosedown(int taskh) { _kernel_swi_regs r; r.r[0]=taskh; StdErrHandlr(_kernel_swi(Tornado_Closedown, &r, &r)); StdErrHandlr(_kernel_swi(0x400DD/*Wimp_CloseDown*/, &r, &r)); } int ROReportError(int flags, int *blk) { _kernel_swi_regs r; char tmesg[]="TMT Demo"; r.r[0]=(int) blk; r.r[1]=flags; r.r[2]=(int) tmesg; _kernel_swi(0x400df/*Wimp_ReportError*/, &r, &r); if(flags & 0x100) exit(EXIT_FAILURE); return r.r[1]; } int ROReportErrora(int flags, int errno, char *errstr) { char q[260]; *(int *)(q+0)=errno; strcpy((q+4), errstr); return ROReportError(flags, (int *) q); } void StdErrHandlr(_kernel_oserror *blk) { if(blk) ROReportError(0x102, (int *) blk); } void ROSetPollMask(int pollmask) { _kernel_swi_regs r; r.r[0]=pollmask; StdErrHandlr(_kernel_swi(Tornado_SetPollMask, &r, &r)); } /* Just for debugging purposes */ void end(void) { }