1 /************************************************************************/
2 /* © Acorn Computers Ltd, 1992. */
4 /* This file forms part of an unsupported source release of RISC_OSLib. */
6 /* It may be freely used to create executable images for saleable */
7 /* products but cannot be sold in source form or as an object library */
8 /* without the prior written consent of Acorn Computers Ltd. */
10 /* If this file is re-distributed (even if modified) it should retain */
11 /* this copyright notice. */
13 /************************************************************************/
17 * Purpose: provide access to RISC OS sprite facilities
18 * History: IDJ: 07-Feb-92: prepared for source release
29 /* Basic primitive used by sprite_xxx calls */
31 #define OS_SpriteOp 0x2E
36 #define ReadAreaCB 8 /* *SInfo */
37 #define ClearSprites 9 /* *SNew */
38 #define LoadSpriteFile 10 /* *SLoad <filename> */
39 #define MergeSpriteFile 11 /* *SMerge <filename> */
40 #define SaveSpriteFile 12 /* *SSave <filename> */
42 #define GetSprite 14 /* *SGet <n> */
43 #define CreateSprite 15
44 #define GetSpriteUserCoords 16
46 #define SelectSprite 24 /* *SChoose <n> [<m>] */
47 #define DeleteSprite 25 /* *SDelete <n> */
48 #define RenameSprite 26 /* *SRename */
55 #define FlipAboutXAxis 33
56 #define PutSpriteUserCoords 34
57 #define AppendSprite 35
58 #define SetPointerShape 36
60 #define ReadSpriteSize 40
61 #define ReadPixelColour 41
62 #define WritePixelColour 42
63 #define ReadPixelMask 43
64 #define WritePixelMask 44
67 #define FlipAboutYAxis 47
69 #define PlotMaskUserCoords 49
71 #define PlotMaskScaled 50
72 #define PaintCharScaled 51
73 #define PutSpriteScaled 52
74 #define PutSpriteGreyScaled 53
75 #define RemoveLeftHandWastage 54
76 #define PlotMaskTransformed 55
77 #define PutSpriteTransformed 56
78 #define InsertDeleteRows 57
79 #define InsertDeleteColumns 58
81 #define SwitchOutputToSprite 60
82 #define SwitchOutputToMask 61
83 #define ReadSaveAreaSize 62
85 #define BadReasonCode 63
87 #pragma no_check_stack
89 static os_error * sprite__op(os_regset *r)
91 return os_swix(OS_SpriteOp, r);
95 /******** Simple operations, use no sprite area, no name/sprite pointer ***/
98 os_error * sprite_screensave(const char *filename, sprite_palflag palflag)
104 r.r[2] = (int) filename;
106 result = sprite__op(&r);
111 os_error * sprite_screenload(const char *filename)
117 r.r[2] = (int) filename;
118 result = sprite__op(&r);
123 /****** Operations on either system/user area, no name/sprite pointer *****/
125 static void setfromarea(int op, sprite_area *area, os_regset *r)
127 if (area == sprite_mainarea)
135 r->r[1] = (int) area;
140 void sprite_area_initialise(sprite_area *area, int length)
142 area->size = length; /* No SpriteOp to do this ! */
149 os_error * sprite_area_readinfo(sprite_area *area, sprite_area *resultarea)
153 setfromarea(8, area, &r);
154 result = sprite__op(&r);
155 if (result == NULL) /* Only return result if no error */
157 resultarea->size = r.r[2];
158 resultarea->number = r.r[3];
159 resultarea->sproff = r.r[4];
160 resultarea->freeoff = r.r[5];
166 os_error * sprite_area_reinit(sprite_area *area)
170 setfromarea(9, area, &r);
171 result = sprite__op(&r);
176 os_error * sprite_area_save(sprite_area *area, const char *filename)
180 setfromarea(12, area, &r);
181 r.r[2] = (int) filename;
182 result = sprite__op(&r);
187 os_error * sprite_area_load(sprite_area *area, const char *filename)
191 setfromarea(10, area, &r);
192 r.r[2] = (int) filename;
193 result = sprite__op(&r);
198 os_error * sprite_area_merge(sprite_area *area, const char *filename)
202 setfromarea(11, area, &r);
203 r.r[2] = (int) filename;
204 result = sprite__op(&r);
209 os_error * sprite_getname(sprite_area *area, void *buffer,
210 int *length, int index)
214 setfromarea(13, area, &r);
215 r.r[2] = (int) buffer;
218 result = sprite__op(&r);
219 if (result == NULL) /* Only return result if no error */
227 os_error * sprite_get(sprite_area *area, char *name, sprite_palflag palflag)
231 setfromarea(14, area, &r);
234 result = sprite__op(&r);
239 os_error * sprite_get_rp(sprite_area *area, char *name, sprite_palflag palflag,
240 sprite_ptr *resultaddress)
244 setfromarea(14, area, &r);
247 result = sprite__op(&r);
248 if (result == NULL) /* Only return result if no error */
250 *resultaddress = (void *) r.r[2];
256 os_error * sprite_get_given(sprite_area *area, char *name,
257 sprite_palflag palflag,
258 int x0, int y0, int x1, int y1)
262 setfromarea(16, area, &r);
269 result = sprite__op(&r);
274 os_error * sprite_get_given_rp(sprite_area *area, char *name,
275 sprite_palflag palflag, int x0, int y0,
276 int x1, int y1, sprite_ptr *resultaddress)
280 setfromarea(16, area, &r);
287 result = sprite__op(&r);
288 if (result == NULL) /* Only return result if no error */
290 *resultaddress = (void *) r.r[2];
296 os_error * sprite_create(sprite_area *area, char *name, sprite_palflag palflag,
297 int width, int height, int mode)
301 setfromarea(15, area, &r); /* NB. Not all done in numeric order !! */
307 result = sprite__op(&r);
312 os_error * sprite_create_rp(sprite_area *area, char *name,
313 sprite_palflag palflag,
314 int width, int height, int mode,
315 sprite_ptr *resultaddress)
319 setfromarea(15, area, &r); /* NB. Not all done in numeric order !! */
325 result = sprite__op(&r);
326 if (result == NULL) /* Only return result if no error */
328 /* spriteop 15 doesn't return pointer to sprite in r2, so....*/
329 /* select the sprite just created (gets its address in r2) */
330 setfromarea(24, area, &r);
332 result = sprite__op(&r);
334 *resultaddress = (void *) r.r[2];
340 /*********** Operations on system/user area, name/sprite pointer **********/
342 /* Modify op if using sprite address is address, not name */
343 /* But only if using own sprite area */
345 static void setfromtag(int op, sprite_area *area, sprite_id *spr, os_regset *r)
347 if (area == sprite_mainarea)
354 r->r[1] = (int) area;
355 if ((spr->tag) == sprite_id_addr)
358 r->r[2] = (int) (spr->s.addr);
363 r->r[2] = (int) (spr->s.name);
369 os_error * sprite_readinfo(sprite_area *area, sprite_id *spr,
370 sprite_info *resultinfo)
374 setfromtag(40, area, spr, &r);
375 result = sprite__op(&r);
376 if (result == NULL) /* Only return result if no error */
378 resultinfo->width = r.r[3];
379 resultinfo->height = r.r[4];
380 resultinfo->mask = r.r[5];
381 resultinfo->mode = r.r[6];
387 os_error * sprite_select(sprite_area *area, sprite_id *spr)
391 setfromtag(24, area, spr, &r);
392 result = sprite__op(&r);
397 os_error * sprite_select_rp(sprite_area *area, sprite_id *spr,
398 sprite_ptr *resultaddress)
402 setfromtag(24, area, spr, &r);
403 result = sprite__op(&r);
404 if (result == NULL) /* Only return result if no error */
406 *resultaddress = (void *) r.r[2];
412 os_error * sprite_delete(sprite_area *area, sprite_id *spr)
416 setfromtag(25, area, spr, &r);
417 result = sprite__op(&r);
422 os_error * sprite_rename(sprite_area *area, sprite_id *spr, char *newname)
426 setfromtag(26, area, spr, &r);
427 r.r[3] = (int) newname;
428 result = sprite__op(&r);
433 os_error * sprite_copy(sprite_area *area, sprite_id *spr, char *copyname)
437 setfromtag(27, area, spr, &r);
438 r.r[3] = (int) copyname;
439 result = sprite__op(&r);
444 os_error * sprite_put(sprite_area *area, sprite_id *spr, int gcol_action)
448 setfromtag(28, area, spr, &r);
449 r.r[5] = gcol_action;
450 result = sprite__op(&r);
455 os_error * sprite_put_given(sprite_area *area, sprite_id *spr, int gcol_action,
460 setfromtag(34, area, spr, &r);
463 r.r[5] = gcol_action;
464 result = sprite__op(&r);
469 os_error * sprite_put_scaled(sprite_area *area, sprite_id *spr,
472 sprite_factors *factors,
473 sprite_pixtrans *pixtrans)
477 setfromtag(52, area, spr, &r);
480 r.r[5] = gcol_action;
481 r.r[6] = (int) factors;
482 r.r[7] = (int) pixtrans;
483 result = sprite__op(&r);
488 os_error * sprite_put_greyscaled(sprite_area *area, sprite_id *spr,
490 sprite_factors *factors,
491 sprite_pixtrans *pixtrans)
495 setfromtag(53, area, spr, &r);
498 r.r[5] = 0; /* doesn't support mask or gcol action */
499 r.r[6] = (int) factors;
500 r.r[7] = (int) pixtrans;
501 result = sprite__op(&r);
506 os_error * sprite_put_mask(sprite_area *area, sprite_id *spr)
510 setfromtag(48, area, spr, &r);
511 result = sprite__op(&r);
516 os_error * sprite_put_mask_given(sprite_area *area, sprite_id *spr,
521 setfromtag(49, area, spr, &r);
524 result = sprite__op(&r);
529 os_error * sprite_put_mask_scaled(sprite_area *area, sprite_id *spr,
531 sprite_factors *factors)
535 setfromtag(50, area, spr, &r);
538 r.r[6] = (int) factors;
539 result = sprite__op(&r);
544 os_error * sprite_put_char_scaled(char ch,
546 sprite_factors *factors)
554 r.r[6] = (int) factors;
555 result = sprite__op(&r);
560 os_error * sprite_create_mask(sprite_area *area, sprite_id *spr)
564 setfromtag(29, area, spr, &r);
565 result = sprite__op(&r);
570 os_error * sprite_remove_mask(sprite_area *area, sprite_id *spr)
574 setfromtag(30, area, spr, &r);
575 result = sprite__op(&r);
580 os_error * sprite_insert_row(sprite_area *area, sprite_id *spr, int row)
584 setfromtag(31, area, spr, &r);
586 result = sprite__op(&r);
591 os_error * sprite_delete_row(sprite_area *area, sprite_id *spr, int row)
595 setfromtag(32, area, spr, &r);
597 result = sprite__op(&r);
602 os_error * sprite_insert_column(sprite_area *area, sprite_id *spr, int column)
606 setfromtag(45, area, spr, &r);
608 result = sprite__op(&r);
613 os_error * sprite_delete_column(sprite_area *area, sprite_id *spr, int column)
617 setfromtag(46, area, spr, &r);
619 result = sprite__op(&r);
624 os_error * sprite_flip_x(sprite_area *area, sprite_id *spr)
628 setfromtag(33, area, spr, &r);
629 result = sprite__op(&r);
634 os_error * sprite_flip_y(sprite_area *area, sprite_id *spr)
638 setfromtag(47, area, spr, &r);
639 result = sprite__op(&r);
643 os_error * sprite_readsize(sprite_area *area, sprite_id *spr,
644 sprite_info *resultinfo)
648 setfromtag(40, area, spr, &r);
649 result = sprite__op(&r);
650 /* now copy returned data */
651 resultinfo->width = r.r[3] ;
652 resultinfo->height = r.r[4] ;
653 resultinfo->mask = r.r[5] ;
654 resultinfo->mode = r.r[6] ;
658 os_error * sprite_readpixel(sprite_area *area, sprite_id *spr, int x, int y,
659 sprite_colour *resultcolour)
663 setfromtag(41, area, spr, &r);
666 result = sprite__op(&r);
667 if (result == NULL) /* Only return result if no error */
669 resultcolour->colour = r.r[5];
670 resultcolour->tint = r.r[6];
676 os_error * sprite_writepixel(sprite_area *area, sprite_id *spr, int x, int y,
677 sprite_colour *colour)
681 setfromtag(42, area, spr, &r);
684 r.r[5] = colour->colour;
685 r.r[6] = colour->tint;
686 result = sprite__op(&r);
691 os_error * sprite_readmask(sprite_area *area, sprite_id *spr, int x, int y,
692 sprite_maskstate *resultmaskstate)
696 setfromtag(43, area, spr, &r);
699 result = sprite__op(&r);
700 if (result == NULL) /* Only return result if no error */
702 *resultmaskstate = r.r[5];
708 os_error * sprite_writemask(sprite_area *area, sprite_id *spr, int x, int y,
709 sprite_maskstate *maskstate)
713 setfromtag(44, area, spr, &r);
716 r.r[5] = (int) (*maskstate); /* Use pointer here for consistent interface */
717 result = sprite__op(&r);
721 os_error *sprite_restorestate(sprite_state state)
731 result = sprite__op(&r);
735 os_error *sprite_outputtosprite(sprite_area *area, sprite_id *id,
736 int *save_area, sprite_state *state)
741 setfromtag(0x3c, area, id, &r);
742 r.r[3] = (int) save_area;
744 result = sprite__op(&r);
747 state->r[0] = r.r[0];
748 state->r[1] = r.r[1];
749 state->r[2] = r.r[2];
750 state->r[3] = r.r[3];
755 os_error *sprite_outputtomask(sprite_area *area, sprite_id *id,
756 int *save_area, sprite_state *state)
761 setfromtag(0x3d, area, id, &r);
762 r.r[3] = (int) save_area;
764 result = sprite__op(&r);
767 state->r[0] = r.r[0];
768 state->r[1] = r.r[1];
769 state->r[2] = r.r[2];
770 state->r[3] = r.r[3];
775 os_error *sprite_outputtoscreen(int *save_area, sprite_state *state)
782 r.r[3] = (int)save_area;
784 result = sprite__op(&r);
787 state->r[0] = r.r[0];
788 state->r[1] = r.r[1];
789 state->r[2] = r.r[2];
790 state->r[3] = r.r[3];
796 os_error *sprite_sizeof_spritecontext(sprite_area *area, sprite_id *id,
802 setfromtag(0x3e, area, id, &r);
804 result = sprite__op(&r);
813 os_error *sprite_sizeof_screencontext(int *size)
821 result = sprite__op(&r);
829 os_error *sprite_removewastage(sprite_area *area, sprite_id *id)
834 setfromtag(0x36, area, id, &r);
836 result = sprite__op(&r);
841 os_error *sprite_change_size (sprite_area *area,
848 setfromtag (rows? InsertDeleteRows: InsertDeleteColumns, area, id, ®_set);
850 reg_set.r [4] = number;
851 return sprite__op (®_set);
854 os_error *sprite_put_mask_trans (sprite_area *area,
857 sprite_transmat *trans_mat)
860 setfromtag (PlotMaskTransformed, area, id, ®_set);
861 reg_set.r [3] = box == NULL? 0: 1 << 1;
862 reg_set.r [4] = (int) box;
863 reg_set.r [6] = (int) trans_mat;
864 return sprite__op (®_set);
867 os_error *sprite_put_mask_pgm (sprite_area *area,
873 setfromtag (PlotMaskTransformed, area, id, ®_set);
874 reg_set.r [3] = (box == NULL? 0: 1 << 1) | (1 << 0);
875 reg_set.r [4] = (int) box;
876 reg_set.r [6] = (int) pgm;
877 return sprite__op (®_set);
880 os_error *sprite_put_trans (sprite_area *area,
884 sprite_transmat *trans_mat,
885 sprite_pixtrans *pix_trans)
888 setfromtag (PutSpriteTransformed, area, id, ®_set);
889 reg_set.r [3] = box == NULL? 0: 1 << 1;
890 reg_set.r [4] = (int) box;
891 reg_set.r [5] = gcol_action;
892 reg_set.r [6] = (int) trans_mat;
893 reg_set.r [7] = (int) pix_trans;
894 return sprite__op (®_set);
897 os_error *sprite_put_pgm (sprite_area *area,
902 sprite_pixtrans *pix_trans)
905 setfromtag (PutSpriteTransformed, area, id, ®_set);
906 reg_set.r [3] = (box == NULL? 0: 1 << 1) | (1 << 0);
907 reg_set.r [4] = (int) box;
908 reg_set.r [5] = gcol_action;
909 reg_set.r [6] = (int) pgm;
910 reg_set.r [7] = (int) pix_trans;
911 return sprite__op (®_set);
916 /* end of c.sprite */