home *** CD-ROM | disk | FTP | other *** search
- /* > $.CLIB.C.sprite
- *
- * HASWIN Graphics Library
- * =========================
- *
- * Copyright (C) H.A.Shaw 1990.
- * Howard A. Shaw.
- * The Unit for Space Sciences,
- * Room 165,
- * Physics Building,
- * University of Kent at Canterbury.
- * Canterbury.
- * Kent. CT2 7NJ
- * You may use and distribute this code freely, however please leave
- * it alone. If you find bugs (and there will be many) please contact
- * me and the master source can be modified. If you keep me informed
- * of who you give copies of this to then I can get release upgrades
- * to them.
- *
- * Routines to deal with Sprites. I hope to expand this later.
- */
- #include "includes.h"
-
- #define MAXAREA 8 /* we may search 8 sprite areas */
-
- static int **areaslist[MAXAREA] = { &haswin_usersprites,
- &haswin_haswinsprites,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0 };
-
- /*
- * add a new user sprite area for HASWIN to search for sprites.
- */
- int haswin_addspritearea(int **area) {
-
- int i;
-
- for (i=0; i<MAXAREA; i++) {
- if (areaslist[i] == 0) {
- areaslist[i] = area;
- return(HASWIN_TRUE);
- }
- }
- return(HASWIN_FALSE);
- }
-
- /*
- * remove a user sprite area from HASWINs search list.
- */
- int haswin_removespritearea(int **area) {
-
- int i;
-
- for (i=0; i<MAXAREA; i++) {
- if (areaslist[i] == area) {
- areaslist[i] = 0;
- return(HASWIN_TRUE);
- }
- }
- return(HASWIN_FALSE);
- }
-
- /*
- * perform a sprite operation.
- * We take the sprite name given and look it up in the different
- * sprite areas. We set R0, R1 and R2 according to what we find
- * and then do the operation.
- */
- int haswin_spriteop(char *name, _kernel_swi_regs *regs) {
-
- int i;
- _kernel_swi_regs tmpregs, ans;
-
- if (name == 0) {
- /* no sprite name, just do operation as it is */
- return(haswin_swi(OS_Sprite_operation, regs));
- }
- /*
- * search through the areaslist list and try the operation.
- */
- for (i=0; i<MAXAREA; i++) {
- if ((areaslist[i] == 0) || (*areaslist[i] == 0))
- /* unused areas have the pointer =0 */
- continue;
- tmpregs.r[0] = 0x118;
- tmpregs.r[1] = (int)(*areaslist[i]);
- tmpregs.r[2] = (int)name;
- if (_kernel_swi(OS_Sprite_operation, &tmpregs, &ans) == 0) {
- if (tmpregs.r[2] == ans.r[2])
- regs->r[0] = (regs->r[0] & 0xFF) | 0x100;
- else {
- regs->r[0] = (regs->r[0] & 0xFF) | 0x200;
- regs->r[2] = ans.r[2];
- }
- regs->r[1] = (int)(*areaslist[i]);
- return(haswin_swi(OS_Sprite_operation, regs));
- }
- }
- /*
- * try the operation in the WIMP area.
- */
- tmpregs.r[0] = 0x18;
- tmpregs.r[2] = (int)name;
- if (_kernel_swi(HASWIN_Sprite_operation, &tmpregs, &ans) == 0) {
- regs->r[0] = (regs->r[0] & 0xFF);
- regs->r[2] = (int)name;
- return(haswin_swi(HASWIN_Sprite_operation, regs));
- }
- /*
- * try the operation in the SYSTEM area.
- */
- regs->r[0] = (regs->r[0] & 0xFF);
- regs->r[2] = (int)name;
- return(haswin_swi(HASWIN_Sprite_operation, regs));
- }
-
- int haswin_getspritearea(int area) {
-
- area &= SPRITE_AREA_MASK;
- switch (area) {
- case SPRITE_SYSTEM_AREA:
- return(0);
- case SPRITE_USER_AREA:
- /* unused areas have the pointer =0 */
- if (haswin_usersprites)
- return((int)haswin_usersprites);
- else
- return(-1);
- case SPRITE_WIMP_AREA:
- case SPRITE_RISCOS_AREA:
- return(1);
- case SPRITE_HASWIN_AREA:
- /* unused areas have the pointer =0 */
- if (haswin_haswinsprites)
- return((int)haswin_haswinsprites);
- else
- return(-1);
- default:
- return(-1);
- }
- }
-
- /*
- * find the sprite named 'name'. Return the area it is in, else
- * return (-1).
- */
- int haswin_findsprite(char *name) {
-
- int i;
- _kernel_swi_regs regs, ans;
-
- /*
- * search through the areaslist list.
- */
- regs.r[0] = 0x128;
- regs.r[2] = (int)name;
- for (i=0; i<MAXAREA; i++) {
- if ((areaslist[i] == 0) || (*areaslist[i] == 0))
- continue;
- regs.r[1] = (int)(*areaslist[i]);
- /* unused areas have the pointer =0 */
- if (regs.r[1]) {
- if (_kernel_swi(OS_Sprite_operation,®s,&ans) == 0)
- return((int)(*areaslist[i]));
- }
- }
- /*
- * search the WIMP area.
- */
- regs.r[0] = 0x028;
- regs.r[2] = (int)name;
- if (_kernel_swi(HASWIN_Sprite_operation, ®s, &ans) == 0)
- return(1);
- /*
- * search the system area.
- */
- regs.r[0] = 0x028;
- regs.r[1] = 0;
- regs.r[2] = (int)name;
- if (_kernel_swi(OS_Sprite_operation, ®s, &ans) == 0)
- return(0);
- return(HASWIN_UNKNOWN);
- }
-
- /*
- * clear the sprite area given and change it to "size" bytes.
- * Return a pointer to the possibly moved area. If the "area" pointer
- * is 0 on entry then a new area is created.
- */
- int *haswin_clearsprites(int size, int *area) {
-
- _kernel_swi_regs regs;
-
- if (size <= 0) {
- if (area)
- haswin_free(area);
- return(0);
- }
- size += 16; /* add space for sprite area header */
- area = haswin_realloc(area, size, "haswin_clearusersprites", "sprite area");
- area[0] = size;
- area[1] = 0;
- area[2] = 16;
- area[3] = 16;
- regs.r[0] = 0x109;
- regs.r[1] = (int)area;
- haswin_spriteop(0, ®s);
- return(area);
- }
-
- /*
- * add sprites to the area given. The area pointer might change
- * because we check the file size and ensure that there is enough
- * room by re-allocating if required. Return the area pointer.
- */
- int *haswin_addsprites(char *filename, int *area) {
-
- _kernel_swi_regs regs;
- int size;
-
- if ((!filename) || (filename[0] == '\0'))
- return(area);
- /* get catalogue entry for file */
- regs.r[0] = 17;
- regs.r[1] = (int)filename;
- if ((!haswin_swi(OS_File, ®s)) || (regs.r[0] != 1)) {
- haswin_interrorprintf("cannot find sprite file '%s'",filename);
- return(area);
- }
- size = regs.r[4] + 4; /* + 1 word for luck */
- /* if no sprite area then create one to fit file */
- if (!area)
- area = haswin_clearsprites(size, 0);
- if (!area) {
- haswin_interrorprintf("cannot create sprite area for '%s'", filename);
- return(HASWIN_FALSE);
- }
- /* add size to that of existing sprites in sprite area +16 for
- sprite control block */
- size += area[3] + 16;
- if (size > area[0]) {
- /* bigger than area, so extend area */
- area = haswin_realloc(area, size, "haswin_addusersprites", "sprite area");
- area[0] = size;
- }
- regs.r[0] = 0x10B;
- regs.r[1] = (int)area;
- regs.r[2] = (int)filename;
- haswin_spriteop(0, ®s);
- return(area);
- }
-
- void haswin_clearusersprites(int size) {
-
- haswin_usersprites = haswin_clearsprites(size, haswin_usersprites);
- }
-
- void haswin_clearhaswinsprites(int size) {
-
- haswin_haswinsprites=haswin_clearsprites(size,haswin_haswinsprites);
- }
-
- int haswin_addusersprites(char *name) {
-
- if ((haswin_usersprites=haswin_addsprites(name, haswin_usersprites)) == 0)
- return(HASWIN_FALSE);
- return(HASWIN_TRUE);
- }
-
- int haswin_addhaswinsprites(char *name) {
-
- if ((haswin_haswinsprites=haswin_addsprites(name, haswin_haswinsprites)) == 0)
- return(HASWIN_FALSE);
- return(HASWIN_TRUE);
- }
-
- int haswin_loadusersprites(char *filename) {
-
- if ((!filename) || (filename[0] == '\0'))
- return(HASWIN_FALSE);
- haswin_clearusersprites(0);
- return(haswin_addusersprites(filename));
- }
-
- int haswin_saveusersprites(char *filename) {
-
- _kernel_swi_regs regs;
-
- if ((!filename) || (filename[0] == '\0'))
- return(HASWIN_FALSE);
- regs.r[0] = 0x10C;
- regs.r[1] = (int)haswin_usersprites;
- regs.r[2] = (int)filename;
- haswin_spriteop(0, ®s);
- return(HASWIN_TRUE);
- }
-
- int haswin_makesprite(char *name, int *area, int x, int y, int mode) {
-
- _kernel_swi_regs regs;
-
- if ((!name) || (x <= 0) || (y <= 0) || (mode < 0))
- return(HASWIN_FALSE);
- /* create a new sprite for the window. The size is the size of the
- window and the mode, palette etc. are setup */
- regs.r[0] = 0x10F; /* create a new sprite */
- regs.r[1] = (int)area;
- regs.r[2] = (int)name;
- regs.r[3] = 1; /* include palette data */
- regs.r[4] = x; /* width */
- regs.r[5] = y; /* height */
- regs.r[6] = mode; /* screen mode */
- return(haswin_spriteop(0, ®s));
- }
-
- int haswin_makeusersprite(char *name, int x, int y, int mode) {
-
- return(haswin_makesprite(name, haswin_usersprites, x, y, mode));
- }
-
- int haswin_makehaswinsprite(char *name, int x, int y, int mode) {
-
- return(haswin_makesprite(name, haswin_haswinsprites, x, y, mode));
- }
-
- int haswin_deletesprite(char *name, int *area) {
-
- _kernel_swi_regs regs;
-
- if ((!name) || (haswin_findsprite(name) != (int)area))
- return(HASWIN_FALSE);
- regs.r[0] = 0x119; /* delete a sprite */
- regs.r[1] = (int)area;
- regs.r[2] = (int)name;
- return(haswin_spriteop(0, ®s));
- }
-
- int haswin_deleteusersprite(char *name) {
-
- return(haswin_deletesprite(name, haswin_usersprites));
- }
-
- int haswin_deletehaswinsprite(char *name) {
-
- return(haswin_deletesprite(name, haswin_haswinsprites));
- }
-
- /*
- * create a new sprite called "name" in area "area" and then remember
- * the sprite so that redraws in the window cause the sprite to be
- * updated. Then force a complete redraw of the window as if it were
- * on top. When this is done VDU redirection is switched off by
- * haswin_poll() called routines by setting the sprite field "win" to 0.
- * Then force a complete redraw of the window as it was.
- * If called as haswin_windowtosprite(0,0) initialise.
- * If called with either win or sname 0 then do nothing.
- */
- int haswin_windowtosprite(window *win, char *sname, int *area) {
-
- _kernel_swi_regs regs;
- int wptr[11], oldbhan, flgs, winx, winy;
- window *slide, *pane;
-
- if ((!win) && (!sname)) {
- /* no window, or name so initialise and cancel everything */
- haswin_spritejob.savearea = 0;
- haswin_spritejob.name = 0;
- haswin_spritejob.win = 0;
- return(HASWIN_TRUE);
- }
- if ((!win) || (!sname))
- return(HASWIN_FALSE);
-
- flgs = haswin_getwindowflags(win);
- if (haswin_findsprite(sname) == (int)area)
- /* sprite already exists */
- return(HASWIN_FALSE);
- /* get all the window info needed into the window block */
- haswin_updatefullwindowinfo(win);
- wptr[ 0] = ((int *)win->win)[ 0];
- wptr[ 1] = ((int *)win->win)[ 1];
- wptr[ 2] = ((int *)win->win)[ 2];
- wptr[ 3] = ((int *)win->win)[ 3];
- wptr[ 4] = ((int *)win->win)[ 4];
- wptr[ 5] = ((int *)win->win)[ 5];
- wptr[ 6] = ((int *)win->win)[ 6];
- wptr[ 7] = ((int *)win->win)[10];
- wptr[ 8] = ((int *)win->win)[11];
- wptr[ 9] = ((int *)win->win)[12];
- wptr[10] = ((int *)win->win)[13];
- oldbhan = wptr[6];
- /* create a new sprite for the window. The size is the size of the
- window and the mode is the current screen mode */
- winx = wptr[ 9]-wptr[7];
- if (flgs & WINDOW_V_SCROLL)
- winx+=40;
- winx = (winx>>haswin_readvduvariable(VDUVAR_XEigFactor))+2;
- winy = wptr[10]-wptr[8];
- if (flgs & WINDOW_TITLE_BAR)
- winy+=40;
- if (flgs & WINDOW_H_SCROLL)
- winy+=40;
- winy = (winy>>haswin_readvduvariable(VDUVAR_YEigFactor))+2;
- haswin_makesprite(sname, area, winx, winy,
- haswin_readvduvariable(VDUVAR_ModeNumber));
-
- regs.r[0] = 0x3E; /* get size of sprite area */
- if (!haswin_spriteop(sname, ®s))
- return(HASWIN_FALSE);
- haswin_spritejob.savearea = haswin_malloc(regs.r[3],
- "haswin_windowtosprite", "save area");
- haswin_spritejob.name = haswin_malloc(strlen(sname)+1,
- "haswin_windowtosprite", "sprite name");
- strcpy(haswin_spritejob.name, sname);
- haswin_spritejob.savearea[0] = 0;
-
- /* disconnect this window from any slides or panes */
- slide = win->slide;
- pane = win->pane;
- win->slide = win->pane = 0;
-
- /* now close the window and poll until it is closed */
- haswin_closewindow(win);
- while ((win->flags & WINDOW_OPEN))
- haswin_poll();
-
- haswin_spritejob.win = win->handle;
- /* now open the window on top and redraw it */
- haswin_openwindow(win, 0, 0, wptr[ 9]-wptr[ 7], wptr[10]-wptr[ 8],
- 0, 0, -1);
- haswin_redrawwindow(win, wptr[0]-win->orgx, wptr[2]-win->orgx,
- wptr[1]-win->orgy, wptr[3]-win->orgy);
-
- /* poll until the sprite redirection is turned off */
- while (haswin_spritejob.win)
- haswin_poll();
- /* the WIMP is now wrong! It thinks the window is on top, but it
- doesn't know that the window was not actually drawn on the screen
- but just in the sprite. */
-
- /* now close the window again and poll until it is closed */
- haswin_closewindow(win);
- while ((win->flags & WINDOW_OPEN))
- haswin_poll();
-
- /* finally open the window back where it was and redraw it */
- haswin_openwindow(win, wptr[0], wptr[1], wptr[2], wptr[3],
- wptr[4], wptr[5], oldbhan);
- if (flgs & WINDOW_OPEN) {
- haswin_redrawwindow(win,wptr[0]-win->orgx,wptr[2]-win->orgx,
- wptr[1]-win->orgy,wptr[3]-win->orgy);
- } else
- haswin_closewindow(win);
- haswin_free(haswin_spritejob.name);
- haswin_free(haswin_spritejob.savearea);
- win->slide = slide;
- win->pane = pane;
- return(HASWIN_TRUE);
- }
-
- /*
- * create a new sprite called "sname" in the area "area". We make a
- * window the size of the icon with no borders, title or scroll bars.
- * Then we place a copy of the icon in it and redirect into a sprite.
- * We redraw the window, then delete it and bingo, icon in sprite!
- */
- int haswin_icontosprite(icon *ic, char *sname, int *area) {
-
- window *twin;
- _kernel_swi_regs regs;
- int blk[9];
- int winx, winy;
-
- if (haswin_findsprite(sname) == (int)area)
- /* sprite already exists in area */
- return(HASWIN_FALSE);
- twin=haswin_findwindowhandle(ic->whandle);
- if ((int)twin <= 0)
- /* icon must be in window, not on icon bar */
- return(HASWIN_FALSE);
- /*
- * make a window to put the icon in, this window is like
- * the real one it is in, except that this window has no
- * title or scroll bars.
- */
- twin=haswin_makewindow("", ic->ic[2]-ic->ic[0], ic->ic[3]-ic->ic[1],
- 0, 0, 0, 0, haswin_getwindowflags(twin) & ~(WINDOW_TITLE_BAR|WINDOW_V_SCROLL|WINDOW_H_SCROLL));
- /* put a copy of the icon into this window, at 0,0 */
- blk[0] = twin->handle;
- blk[1] = 0;
- blk[2] = ic->ic[1]-ic->ic[3];
- blk[3] = ic->ic[2]-ic->ic[0];
- blk[4] = 0;
- blk[5] = ic->ic[4];
- blk[6] = ic->ic[5];
- blk[7] = ic->ic[6];
- blk[8] = ic->ic[7];
- regs.r[1] = (int)blk;
- haswin_swi(HASWIN_Create_icon, ®s);
- /* create the new sprite. The size is the size of the icon and the
- mode is the current screen mode */
- winx = (ic->ic[2]-ic->ic[0])>>haswin_readvduvariable(VDUVAR_XEigFactor);
- winy = (ic->ic[3]-ic->ic[1])>>haswin_readvduvariable(VDUVAR_YEigFactor);
- haswin_makesprite(sname, area, winx, winy,
- haswin_readvduvariable(VDUVAR_ModeNumber));
-
- regs.r[0] = 0x3E; /* get size of sprite area */
- if (!haswin_spriteop(sname, ®s))
- return(HASWIN_FALSE);
- haswin_spritejob.savearea = haswin_malloc(regs.r[3],
- "haswin_windowtosprite", "save area");
- haswin_spritejob.name = haswin_malloc(strlen(sname)+1,
- "haswin_windowtosprite", "sprite name");
- strcpy(haswin_spritejob.name, sname);
- haswin_spritejob.savearea[0] = 0;
-
- haswin_spritejob.win = twin->handle;
- /* now open the window on top and redraw it */
- haswin_openwindow(twin,0,0,ic->ic[2]-ic->ic[0],ic->ic[3]-ic->ic[1],
- 0, 0, -1);
-
- /* poll until the sprite redirection is turned off */
- while (haswin_spritejob.win)
- haswin_poll();
- /* the WIMP is now wrong! It thinks the window is on top, but it
- doesn't know that the window was not actually drawn on the screen
- but just in the sprite. */
- /* so close the window again and poll until it is closed */
- haswin_closewindow(twin);
- while ((twin->flags & WINDOW_OPEN))
- haswin_poll();
- /* finished, so delete the window and free the used space */
- haswin_deletewindow(twin);
- haswin_free(haswin_spritejob.name);
- haswin_free(haswin_spritejob.savearea);
- return(HASWIN_TRUE);
- }
-
-