home *** CD-ROM | disk | FTP | other *** search
-
- /* main.c - the central module for playriff.
- This module includes the global variables, the main() routine, and
- various routines to manage the memory etc. for our screen. */
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <graphics/gfx.h>
- #include <intuition/intuition.h>
- #include <libraries/dos.h>
- #include <libraries/dosextens.h>
- #include <functions.h>
- #include <ctype.h>
- #include "jiff.h"
- #include "vcomp.h"
- #include "playriff.h"
-
- /* Height and width of a character */
- #define CH_WIDTH 8
- #define CH_HEIGHT 10
-
- extern long get60hz(); /* a 60Hz clock */
-
- /* Yer standard libraries to do anything graphical with a user interface */
- struct Library *IntuitionBase, *GfxBase;
-
- struct BitMap demo_BitMap; /* Our custom bitmap */
- struct BitMap back_BitMap; /* where to decompress etc */
- struct Screen *demo_screen; /* our own custom screen */
- struct Window *demo_window; /* borderless backdrop window on demo_screen*/
- struct NewScreen ns; /* to help open demo_screen */
- struct NewWindow nw; /* to help open demo_window */
- struct Window *launch_window; /* Where AmigaDOS puts our errors initially */
- struct Process *demo_process; /* our process */
-
- long plane_size;
- WORD colors;
- int skipit; /* is beam skipping enabled */
-
- /* The number of frames loaded, and array of pointers to beginning of
- each frame */
- short riff_count;
- struct vcomp_iff *riff_list[MAX_RIFFS];
- WORD frame_ix; /* the current frame on the screen */
-
- /* the riff head contains our ViewModes and resolution info */
- struct riff_head demo_rh; /* head of last riff loaded */
- struct riff_head first_rh; /* head of first riff if loading more than one
- into memory at once */
-
- /* Little multiplication table ... BytesPerRow*0, BytesPerRow*1 ...
- BytesPerRow*Rows */
- WORD *ytable;
- long ytsize; /* size of above table in bytes */
-
- /* some globals to handle file i/o */
- struct FileHandle *infile; /* handle for the riff file we're loading */
- char *name; /* name of file we're loading or saving */
- char first_name[256]; /* name of first riff file in this batch loaded */
- WORD fatal_load; /* flag set if load failed badly */
-
-
- /* Yer basic handle on the 80 character ROM font */
- UBYTE topaz_name[] = "topaz.font";
- struct TextAttr topaz80 =
- {
- topaz_name,
- TOPAZ_EIGHTY,
- FS_NORMAL,
- FPF_ROMFONT,
- };
-
-
- /* SafeAllocMem() - like AllocMem, but makes sure Intuition still has
- enough memory to do it's thing with menus and windows. */
- void *
- SafeAllocMem(size, type)
- long size, type;
- {
- char *pt;
- char *safept;
-
- if (size <= 0)
- return(NULL);
- pt = AllocMem(size, type);
- if (pt == NULL)
- return(NULL);
- if ((safept = AllocMem(8000L, type) ) == NULL)
- {
- FreeMem(pt, size);
- return(NULL);
- }
- FreeMem(safept, 8000L);
- return(pt);
- }
-
- /* Print error message of up to two lines */
- error(message1, message2)
- char *message1, *message2;
- {
- long width, height;
- long nwidth;
-
- puts(message1);
- if (message2 != NULL)
- puts(message2);
- return;
- }
-
- outta_memory()
- {
- error("Out of memory!", NULL);
- }
-
- cant_open()
- {
- char sbuf[80];
-
- sprintf(sbuf, "can't open %s", name);
- error(sbuf, NULL);
- }
-
- truncated()
- {
- char *sbuf[80];
-
- sprintf(sbuf, "%s truncated!", name);
- error(sbuf, NULL);
- }
-
-
- /* match_res() - checks that the current riff is the same resolution as
- the first riff in the chain. Squawks if its not. */
- match_res()
- {
- char buf[60];
-
- if (first_rh.width != demo_rh.width ||
- first_rh.height != demo_rh.height ||
- first_rh.depth != demo_rh.depth)
- {
- sprintf(buf, "%dx%dx%d and %dx%dx%d",
- first_rh.width, first_rh.height, first_rh.depth,
- demo_rh.width, demo_rh.height, demo_rh.depth);
- error("Resolution mismatch:", buf);
- return(0);
- }
- return(1);
- }
-
- /* make_ytable() - makes up the multiplication table for the decompression
- routines */
- make_ytable(width, height)
- WORD width;
- register WORD height;
- {
- register WORD linebytes;
- register WORD *pt, acc;
-
- free_ytable(); /* free previous y table */
- linebytes = (((width+15)>>4)<<1);
- ytsize = height * sizeof(WORD);
- if ((ytable = SafeAllocMem(ytsize, 0L)) == NULL)
- return(0);
- pt = ytable;
- acc = 0;
- while (--height >= 0)
- {
- *pt++ = acc;
- acc += linebytes;
- }
- return(1);
- }
-
- /* free_ytable() - free up memory used by ytable */
- free_ytable()
- {
- if (ytable != NULL)
- FreeMem(ytable, ytsize);
- ytable = NULL;
- }
-
- /* close_demo_screen() - closes down our screen and window, and puts
- the process error handling window pointer back to where it was when
- we were launched */
- close_demo_screen()
- {
- if (demo_window != NULL)
- {
- CloseWindow(demo_window);
- demo_window = NULL;
- }
- if (demo_screen != NULL)
- {
- CloseScreen(demo_screen);
- demo_screen = NULL;
- }
- free_BitMap(&demo_BitMap);
- free_BitMap(&back_BitMap);
- demo_process->pr_WindowPtr = (APTR)launch_window;
- }
-
- /* free_demo_riff() - free up the memory used by the riff frames in memory */
- free_demo_riff()
- {
- struct vcomp_iff **riffs;
- struct vcomp_iff *riff;
- WORD i;
-
- riffs = riff_list;
- i = riff_count;
- while (--i >= 0)
- {
- riff = *riffs;
- if (riff != NULL)
- FreeMem(riff, riff->iff_size + 8); /* plus 8 is sizeof type +
- sizeof lenght field */
- *riffs++ = NULL;
- }
- riff_count = 0;
- frame_ix = 0;
- }
-
- /* free_BitMap() - frees the bitplanes associated with a BitMap and set
- them to NULL */
- free_BitMap(bm)
- register struct BitMap *bm;
- {
- if (bm->Planes[0] != NULL)
- {
- FreeMem(bm->Planes[0], (long)bm->BytesPerRow * bm->Rows * bm->Depth);
- bm->Planes[0] = NULL;
- }
- }
-
- /* alloc_BitMap() - allocate the bit-planes for a BitMap. Puts 'em in
- CHIP ram of course! */
- alloc_BitMap(bm, w, h, d)
- register struct BitMap *bm;
- short w, h, d;
- {
- register short i;
- register long plane_size;
- register PLANEPTR bits;
-
- plane_size = PlaneSize(w, h);
- bm->Rows = h;
- bm->BytesPerRow = LineBytes(w);
- bm->Depth = d;
- bm->Planes[0] = NULL;
- if ((bits = SafeAllocMem(plane_size * d, (long)MEMF_CHIP)) == NULL)
- return(0);
- for (i=0; i<d; i++)
- {
- bm->Planes[i] = bits;
- bits += plane_size;
- }
- return(1);
- }
-
- /* some variable to keep track of what screen-resolution and mode we're
- in to avoid having to close and re-open screens when possible */
- static WORD ow, oh, od, omode;
-
-
- /* get_draw_space_man() - man went out years ago. Should be
- get_draw_space_dude(). Actually considering it's getting it
- from Intuition perhaps it should be get_draw_space_idiot(). Anyways
- this baby opens a screen and a backdrop window of the indicated dimensions
- and ViewMode. Also initializes the ytable to the screen dimensions, and
- allocates the demo_BitMap. */
- get_draw_space_man(w, h, d, mode)
- WORD w, h, d, mode;
- {
- ow = w;
- oh = h;
- od = d;
- omode = mode;
- if (!make_ytable(w, h))
- {
- outta_memory();
- return(0);
- }
- if (!alloc_BitMap(&demo_BitMap, w, h, d) )
- {
- outta_memory();
- return(0);
- }
- if (!alloc_BitMap(&back_BitMap, w, h, d) )
- {
- outta_memory();
- return(0);
- }
- plane_size = h*demo_BitMap.BytesPerRow;
- if (ns.ViewModes & HAM)
- colors = 16;
- else
- colors = (1<<d);
-
- skipit = (w < 400 && h < 300); /* beam skip if lo-res non-interlace... */
- nw.Width = nw.MinWidth = nw.MaxWidth = ns.Width = w;
- nw.Height = nw.MinHeight = nw.MaxHeight = ns.Height = h;
- ns.Depth = d;
- ns.ViewModes = mode;
- ns.Type = CUSTOMSCREEN | CUSTOMBITMAP;
- ns.CustomBitMap = &demo_BitMap;
- ns.Font = &topaz80;
- if ((demo_screen = OpenScreen(&ns)) == NULL)
- return(0);
- ShowTitle(demo_screen, 0L);
- nw.LeftEdge = 0;
- nw.TopEdge = 0;
- nw.DetailPen = 0;
- nw.BlockPen= 1;
- nw.Title = NULL;
- nw.Flags = BACKDROP| ACTIVATE
- |WINDOWDRAG|BORDERLESS|NOCAREREFRESH;
- nw.IDCMPFlags =
- MOUSEBUTTONS | MENUPICK; /* IDCMP flags */
- nw.Type = CUSTOMSCREEN;
- nw.FirstGadget = NULL;
- nw.CheckMark = NULL;
- nw.Screen = demo_screen;
- nw.BitMap = NULL;
- if ((demo_window = (struct Window *)OpenWindow(&nw)) == NULL)
- {
- CloseScreen(demo_screen);
- demo_screen = NULL;
- }
- demo_process->pr_WindowPtr = (APTR)demo_window;
- return(1);
- }
-
- /* open a screen with the dimensions/modes from the riff-header we just
- loaded */
- screen_for_rh()
- {
- return(get_draw_space_man(demo_rh.width, demo_rh.height, demo_rh.depth,
- demo_rh.ViewModes) );
- }
-
- #define BPOS 47
- #define BWIN 40
-
- skip_beam()
- {
- register WORD pos;
-
- for (;;)
- {
- pos = VBeamPos();
- if (pos > BPOS && pos < BPOS+BWIN)
- break;
- }
- }
-
-
- /* play_demo_riff()
- loop around blasting riffs to the screen until someone hits a mouse
- button */
- play_demo_riff(loops)
- int loops;
- {
- int i;
- register long dest_time;
- register long wait_time;
-
- wait_time = demo_rh.jiffies_frame;
- for (i=0; i<loops; i++)
- {
- for ( ; frame_ix<riff_count; frame_ix++)
- {
- dest_time = get60hz() + wait_time;
- unpack_it(riff_list[frame_ix]);
- if (poll_demo_window())
- {
- return;
- }
- while (get60hz() < dest_time)
- {
- if (poll_demo_window())
- return;
- wait_milli();
- }
- }
- frame_ix = 0;
- }
- }
-
-
- /* poll_demo_window() - see if anythings happening intui-wise. Return
- 1 if we've got a user event, 0 if nothing going on. */
- poll_demo_window()
- {
- struct IntuiMessage *message; /* Gets input event */
-
- message = (struct IntuiMessage *)GetMsg(demo_window->UserPort);
- if (message != NULL)
- {
- ReplyMsg( message ); /* Tell intuition we're through with event */
- return(1);
- }
- return(0);
- }
-
- USHORT *nopointer;
-
- pointeroff()
- {
- if (demo_window != NULL)
- SetPointer(demo_window,nopointer,2,16,0,0);/* turn it back to off*/
- }/* end of pointeroff*/
-
- pointeron()
- {
- if (demo_window != NULL)
- ClearPointer(demo_window);
- }
-
-
- /* unpack_it() - unpack a single frame of a riff onto the screen */
- unpack_it(head_buf)
- register struct vcomp_iff *head_buf;
- {
- WORD w, h, d;
- register char *in;
- register char *out;
- WORD i;
- WORD ctype;
- register WORD size;
- register WORD linebytes;
-
-
- in = (char *)(head_buf+1);
-
- d = back_BitMap.Depth;
- linebytes = back_BitMap.BytesPerRow;
-
- for (i=0; i<d; i++)
- {
- ctype = head_buf->comps[i].comp;
- size = head_buf->comps[i].size;
- out = (char *)back_BitMap.Planes[i];
- switch (ctype)
- {
- case VCOMP_NONE:
- copy_structure(in, out, size);
- break;
- case VCOMP_VRUN:
- decode_vplane(in, out, linebytes);
- break;
- case VCOMP_SKIP:
- decode_vkplane(in, out, linebytes);
- break;
- }
- in += size;
- }
- if (skipit)
- skip_beam();
- qput_cmap(head_buf->cmap);
- copy_lines_blit(back_BitMap.Planes[0], demo_BitMap.Planes[0],
- plane_size, back_BitMap.BytesPerRow,
- back_BitMap.Rows, back_BitMap.Depth);
- }
-
-
- main(count, names)
- int count;
- char *names[];
- {
- demo_process = (struct Process *)FindTask(0L); /* find our process */
- /* see if under CLI. Under 1.1 AmigaDOS the arc count would be like
- 100000 or so from WB launched app's, 1.2 it's zero already */
- if (demo_process->pr_CLI == NULL)
- return(0); /* CLI only! */
-
- if ((GfxBase = OpenLibrary("graphics.library", 0L)) == NULL)
- {
- return;
- }
- if ((IntuitionBase = OpenLibrary("intuition.library", 0L)) == NULL)
- {
- return;
- }
- if (!init_time()) /* try to get our little real-time 60Hz clock */
- {
- puts("can't init timer");
- return;
- }
- launch_window = (struct Window *)demo_process->pr_WindowPtr;
- if (nopointer = AllocMem(32L, MEMF_CHIP | MEMF_CLEAR) )
- cli_playriff(count, names);
- if (nopointer)
- FreeMem(nopointer, 32L);
- free_demo_riff();
- free_ytable();
- close_demo_screen();
- uninit_time();
- CloseLibrary(IntuitionBase);
- CloseLibrary(GfxBase);
- }
-
-