home *** CD-ROM | disk | FTP | other *** search
/ 17 Bit Software 1: Collection A / 17Bit_Collection_A.iso / files / 290.dms / in.adf / quickrif.source / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-01-31  |  10.8 KB  |  503 lines

  1.  
  2. /* main.c - the central module for playriff. 
  3.     This module includes the global variables, the main() routine, and
  4.     various routines to manage the memory etc. for our screen.  */
  5.     
  6. #include <exec/types.h>
  7. #include <exec/memory.h>
  8. #include <graphics/gfx.h>
  9. #include <intuition/intuition.h>
  10. #include <libraries/dos.h>
  11. #include <libraries/dosextens.h>
  12. #include <functions.h>
  13. #include <ctype.h>
  14. #include "jiff.h"
  15. #include "vcomp.h"
  16. #include "playriff.h"
  17.  
  18. /* Height and width of a character */
  19. #define CH_WIDTH 8
  20. #define CH_HEIGHT 10
  21.  
  22. extern long get60hz();    /* a 60Hz clock */
  23.  
  24. /* Yer standard libraries to do anything graphical with a user interface */
  25. struct Library *IntuitionBase, *GfxBase;
  26.  
  27. struct BitMap demo_BitMap;    /* Our custom bitmap */
  28. struct BitMap back_BitMap;    /* where to decompress etc */
  29. struct Screen *demo_screen;    /* our own custom screen */
  30. struct Window *demo_window;    /* borderless backdrop window on demo_screen*/
  31. struct NewScreen ns;    /* to help open demo_screen */
  32. struct NewWindow nw;    /* to help open demo_window */
  33. struct Window *launch_window; /* Where AmigaDOS puts our errors initially */
  34. struct Process *demo_process; /* our process */
  35.  
  36. long plane_size;
  37. WORD colors;
  38. int skipit;  /* is beam skipping enabled */
  39.  
  40. /* The number of frames loaded, and array of pointers to beginning of
  41.    each frame */
  42. short riff_count;    
  43. struct vcomp_iff *riff_list[MAX_RIFFS];
  44. WORD frame_ix;        /* the current frame on the screen */
  45.  
  46. /* the riff head contains our ViewModes and resolution info */
  47. struct riff_head demo_rh;    /* head of last riff loaded */
  48. struct riff_head first_rh;    /* head of first riff if loading more than one
  49.                               into memory at once */
  50.  
  51. /* Little multiplication table ... BytesPerRow*0, BytesPerRow*1 ...
  52.     BytesPerRow*Rows */
  53. WORD *ytable;
  54. long ytsize;    /* size of above table in bytes */
  55.  
  56. /* some globals to handle file i/o */
  57. struct FileHandle *infile; /* handle for the riff file we're loading */
  58. char *name;        /* name of file we're loading or saving */
  59. char first_name[256];    /* name of first riff file in this batch loaded */
  60. WORD fatal_load;    /* flag set if load failed badly */
  61.  
  62.  
  63. /* Yer basic handle on the 80 character ROM font */
  64. UBYTE topaz_name[] =  "topaz.font";
  65. struct TextAttr topaz80 =
  66.     {
  67.     topaz_name,
  68.     TOPAZ_EIGHTY,
  69.     FS_NORMAL,
  70.     FPF_ROMFONT,
  71.     };    
  72.  
  73.  
  74. /* SafeAllocMem() - like AllocMem, but makes sure Intuition still has
  75.    enough memory to do it's thing with menus and windows. */
  76. void *
  77. SafeAllocMem(size, type)
  78. long size, type;
  79. {
  80. char *pt;
  81. char *safept;
  82.  
  83. if (size <= 0)
  84.     return(NULL);
  85. pt = AllocMem(size, type);
  86. if (pt == NULL)
  87.     return(NULL);
  88. if ((safept = AllocMem(8000L, type) ) == NULL)
  89.     {
  90.     FreeMem(pt, size);
  91.     return(NULL);
  92.     }
  93. FreeMem(safept, 8000L);
  94. return(pt);
  95. }
  96.  
  97. /* Print error message of up to two lines */
  98. error(message1, message2)
  99. char *message1, *message2;
  100. {
  101. long width, height;
  102. long nwidth;
  103.  
  104. puts(message1);
  105. if (message2 != NULL)
  106.     puts(message2);
  107. return;
  108. }
  109.  
  110. outta_memory()
  111. {
  112. error("Out of memory!", NULL);
  113. }
  114.  
  115. cant_open()
  116. {
  117. char sbuf[80];
  118.  
  119. sprintf(sbuf, "can't open %s", name);
  120. error(sbuf, NULL);
  121. }
  122.  
  123. truncated()
  124. {
  125. char *sbuf[80];
  126.  
  127. sprintf(sbuf, "%s truncated!", name);
  128. error(sbuf, NULL);
  129. }
  130.  
  131.  
  132. /* match_res() - checks that the current riff is the same resolution as
  133.    the first riff in the chain.  Squawks if its not. */
  134. match_res()
  135. {
  136. char buf[60];
  137.  
  138. if (first_rh.width != demo_rh.width ||
  139.     first_rh.height != demo_rh.height ||
  140.     first_rh.depth != demo_rh.depth)
  141.     {
  142.     sprintf(buf, "%dx%dx%d and %dx%dx%d",
  143.         first_rh.width, first_rh.height, first_rh.depth,
  144.         demo_rh.width, demo_rh.height, demo_rh.depth);
  145.     error("Resolution mismatch:", buf);
  146.     return(0);
  147.     }
  148. return(1);
  149. }
  150.  
  151. /* make_ytable() - makes up the multiplication table for the decompression
  152.    routines */
  153. make_ytable(width, height)
  154. WORD width;
  155. register WORD height;
  156. {
  157. register WORD linebytes;
  158. register WORD *pt, acc;
  159.  
  160. free_ytable();    /* free previous y table */
  161. linebytes = (((width+15)>>4)<<1);
  162. ytsize = height * sizeof(WORD);
  163. if ((ytable = SafeAllocMem(ytsize, 0L)) == NULL)
  164.     return(0);
  165. pt = ytable;
  166. acc = 0;
  167. while (--height >= 0)
  168.     {
  169.     *pt++ = acc;
  170.     acc += linebytes;
  171.     }
  172. return(1);
  173. }
  174.  
  175. /* free_ytable() - free up memory used by ytable */
  176. free_ytable()
  177. {
  178. if (ytable != NULL)
  179.     FreeMem(ytable, ytsize);
  180. ytable = NULL;
  181. }
  182.  
  183. /* close_demo_screen() - closes down our screen and window, and puts
  184.    the process error handling window pointer back to where it was when
  185.    we were launched */
  186. close_demo_screen()
  187. {
  188. if (demo_window != NULL)
  189.     {
  190.     CloseWindow(demo_window);
  191.     demo_window = NULL;
  192.     }
  193. if (demo_screen != NULL)
  194.     {
  195.     CloseScreen(demo_screen);
  196.     demo_screen = NULL;
  197.     }
  198. free_BitMap(&demo_BitMap);
  199. free_BitMap(&back_BitMap);
  200. demo_process->pr_WindowPtr = (APTR)launch_window;
  201. }
  202.  
  203. /* free_demo_riff() - free up the memory used by the riff frames in memory */
  204. free_demo_riff()
  205. {
  206. struct vcomp_iff **riffs;
  207. struct vcomp_iff *riff;
  208. WORD i;
  209.  
  210. riffs = riff_list;
  211. i = riff_count;
  212. while (--i >= 0)
  213.     {
  214.     riff = *riffs;
  215.     if (riff != NULL)
  216.         FreeMem(riff, riff->iff_size + 8); /* plus 8 is sizeof type +
  217.                                                 sizeof lenght field */
  218.     *riffs++ = NULL;
  219.     }
  220. riff_count = 0;
  221. frame_ix = 0;
  222. }
  223.  
  224. /* free_BitMap() - frees the bitplanes associated with a BitMap and set
  225.    them to NULL */
  226. free_BitMap(bm)
  227. register struct BitMap *bm;
  228. {
  229. if (bm->Planes[0] != NULL)
  230.     {
  231.     FreeMem(bm->Planes[0], (long)bm->BytesPerRow * bm->Rows * bm->Depth); 
  232.     bm->Planes[0] = NULL;
  233.     }
  234. }
  235.  
  236. /* alloc_BitMap() - allocate the bit-planes for a BitMap.  Puts 'em in
  237.    CHIP ram of course! */
  238. alloc_BitMap(bm, w, h, d)
  239. register struct BitMap *bm;
  240. short w, h, d;
  241. {
  242. register short i;
  243. register long plane_size;
  244. register PLANEPTR bits;
  245.  
  246. plane_size = PlaneSize(w, h);
  247. bm->Rows = h;
  248. bm->BytesPerRow = LineBytes(w);
  249. bm->Depth = d;
  250. bm->Planes[0] = NULL;
  251. if ((bits = SafeAllocMem(plane_size * d, (long)MEMF_CHIP)) == NULL)
  252.     return(0);
  253. for (i=0; i<d; i++)    
  254.     {
  255.     bm->Planes[i] = bits;
  256.     bits += plane_size;
  257.     }
  258. return(1);
  259. }
  260.  
  261. /* some variable to keep track of what screen-resolution and mode we're
  262.    in to avoid having to close and re-open screens when possible */
  263. static WORD ow, oh, od, omode;
  264.  
  265.  
  266. /* get_draw_space_man() - man went out years ago.  Should be
  267.    get_draw_space_dude().  Actually considering it's getting it
  268.    from Intuition perhaps it should be get_draw_space_idiot().  Anyways
  269.    this baby opens a screen and a backdrop window of the indicated dimensions
  270.    and ViewMode.  Also initializes the ytable to the screen dimensions, and
  271.    allocates the demo_BitMap. */
  272. get_draw_space_man(w, h, d, mode)
  273. WORD w, h, d, mode;
  274. {
  275. ow = w;
  276. oh = h;
  277. od = d;
  278. omode = mode;
  279. if (!make_ytable(w, h))
  280.     {
  281.     outta_memory();
  282.     return(0);
  283.     }
  284. if (!alloc_BitMap(&demo_BitMap, w, h, d) )
  285.     {
  286.     outta_memory();
  287.     return(0);
  288.     }
  289. if (!alloc_BitMap(&back_BitMap, w, h, d) )
  290.     {
  291.     outta_memory();
  292.     return(0);
  293.     }
  294. plane_size = h*demo_BitMap.BytesPerRow;
  295. if (ns.ViewModes & HAM)
  296.     colors = 16;
  297. else
  298.     colors = (1<<d);
  299.  
  300. skipit = (w < 400 && h < 300);    /* beam skip if lo-res non-interlace... */
  301. nw.Width = nw.MinWidth = nw.MaxWidth = ns.Width = w;
  302. nw.Height = nw.MinHeight = nw.MaxHeight = ns.Height = h;
  303. ns.Depth = d;
  304. ns.ViewModes = mode;
  305. ns.Type = CUSTOMSCREEN | CUSTOMBITMAP;
  306. ns.CustomBitMap = &demo_BitMap;
  307. ns.Font = &topaz80;
  308. if ((demo_screen = OpenScreen(&ns)) == NULL)
  309.     return(0);
  310. ShowTitle(demo_screen, 0L);
  311. nw.LeftEdge = 0;
  312. nw.TopEdge = 0;
  313. nw.DetailPen = 0;
  314. nw.BlockPen= 1;
  315. nw.Title = NULL;
  316. nw.Flags = BACKDROP| ACTIVATE
  317.              |WINDOWDRAG|BORDERLESS|NOCAREREFRESH;
  318. nw.IDCMPFlags = 
  319.     MOUSEBUTTONS | MENUPICK; /* IDCMP flags */
  320. nw.Type = CUSTOMSCREEN;
  321. nw.FirstGadget = NULL;
  322. nw.CheckMark = NULL;
  323. nw.Screen = demo_screen;
  324. nw.BitMap = NULL;
  325. if ((demo_window = (struct Window *)OpenWindow(&nw)) == NULL)
  326.     {
  327.     CloseScreen(demo_screen);
  328.     demo_screen = NULL;
  329.     }
  330. demo_process->pr_WindowPtr = (APTR)demo_window;
  331. return(1);
  332. }
  333.  
  334. /* open a screen with the dimensions/modes from the riff-header we just
  335.    loaded */
  336. screen_for_rh()
  337. {
  338. return(get_draw_space_man(demo_rh.width, demo_rh.height, demo_rh.depth,
  339.     demo_rh.ViewModes) );
  340. }
  341.  
  342. #define BPOS 47
  343. #define BWIN 40
  344.  
  345. skip_beam()
  346. {
  347. register WORD pos;
  348.  
  349. for (;;)
  350.     {
  351.     pos = VBeamPos();
  352.     if (pos > BPOS && pos < BPOS+BWIN)
  353.         break;
  354.     }
  355. }
  356.  
  357.  
  358. /* play_demo_riff()
  359.     loop around blasting riffs to the screen until someone hits a mouse
  360.     button */
  361. play_demo_riff(loops)
  362. int loops;
  363. {
  364. int i;
  365. register long dest_time;
  366. register long wait_time;
  367.  
  368. wait_time = demo_rh.jiffies_frame;
  369. for (i=0; i<loops; i++)
  370.     {
  371.     for ( ; frame_ix<riff_count; frame_ix++)
  372.         {
  373.         dest_time = get60hz() + wait_time;
  374.         unpack_it(riff_list[frame_ix]);
  375.         if (poll_demo_window())
  376.             {
  377.             return;
  378.             }
  379.         while (get60hz() < dest_time)
  380.             {
  381.             if (poll_demo_window())
  382.                 return;
  383.             wait_milli();
  384.             }
  385.         }
  386.     frame_ix = 0;
  387.     }
  388. }
  389.  
  390.  
  391. /* poll_demo_window() - see if anythings happening intui-wise.  Return
  392.    1 if we've got a user event, 0 if nothing going on.  */
  393. poll_demo_window()
  394. {
  395. struct IntuiMessage *message;   /* Gets input event   */
  396.  
  397. message = (struct IntuiMessage *)GetMsg(demo_window->UserPort);
  398. if (message != NULL)
  399.     {
  400.     ReplyMsg( message );    /* Tell intuition we're through with event   */
  401.     return(1);
  402.     }
  403. return(0);
  404. }
  405.  
  406. USHORT *nopointer;
  407.  
  408. pointeroff()
  409. {
  410. if (demo_window != NULL)
  411.     SetPointer(demo_window,nopointer,2,16,0,0);/* turn it back to off*/
  412. }/* end of pointeroff*/
  413.  
  414. pointeron()
  415. {
  416. if (demo_window != NULL)
  417.     ClearPointer(demo_window);
  418. }
  419.  
  420.  
  421. /* unpack_it() - unpack a single frame of a riff onto the screen */
  422. unpack_it(head_buf)
  423. register struct vcomp_iff *head_buf;
  424. {
  425. WORD w, h, d;
  426. register char *in;
  427. register char *out;
  428. WORD i;
  429. WORD ctype;
  430. register WORD size;
  431. register WORD linebytes;
  432.  
  433.  
  434. in = (char *)(head_buf+1);
  435.  
  436. d = back_BitMap.Depth;
  437. linebytes = back_BitMap.BytesPerRow;
  438.  
  439. for (i=0; i<d; i++)
  440.     {
  441.     ctype = head_buf->comps[i].comp;
  442.     size = head_buf->comps[i].size;
  443.     out = (char *)back_BitMap.Planes[i];
  444.     switch (ctype)
  445.         {
  446.         case VCOMP_NONE:
  447.             copy_structure(in, out, size);
  448.             break;
  449.         case VCOMP_VRUN:
  450.             decode_vplane(in, out, linebytes);
  451.             break;
  452.         case VCOMP_SKIP:
  453.             decode_vkplane(in, out, linebytes);
  454.             break;
  455.         }
  456.     in += size;
  457.     }
  458. if (skipit)
  459.     skip_beam();
  460. qput_cmap(head_buf->cmap);
  461. copy_lines_blit(back_BitMap.Planes[0], demo_BitMap.Planes[0],
  462.     plane_size, back_BitMap.BytesPerRow, 
  463.     back_BitMap.Rows, back_BitMap.Depth);
  464. }
  465.  
  466.  
  467. main(count, names)
  468. int count;
  469. char *names[];
  470. {
  471. demo_process = (struct Process *)FindTask(0L);    /* find our process */
  472. /* see if under CLI.  Under 1.1 AmigaDOS the arc count would be like
  473.    100000 or so from WB launched app's, 1.2 it's zero already */
  474. if (demo_process->pr_CLI == NULL)
  475.     return(0);    /* CLI only! */
  476.  
  477. if ((GfxBase = OpenLibrary("graphics.library", 0L)) == NULL)
  478.     {
  479.     return;
  480.     }
  481. if ((IntuitionBase = OpenLibrary("intuition.library", 0L)) == NULL)
  482.     {
  483.     return;
  484.     }
  485. if (!init_time())    /* try to get our little real-time 60Hz clock */
  486.     {
  487.     puts("can't init timer");
  488.     return;
  489.     }
  490. launch_window = (struct Window *)demo_process->pr_WindowPtr;
  491. if (nopointer = AllocMem(32L, MEMF_CHIP | MEMF_CLEAR) )
  492.     cli_playriff(count, names);
  493. if (nopointer)
  494.     FreeMem(nopointer, 32L);
  495. free_demo_riff();
  496. free_ytable();
  497. close_demo_screen();
  498. uninit_time();
  499. CloseLibrary(IntuitionBase);
  500. CloseLibrary(GfxBase);
  501. }
  502.  
  503.