/************************************************************************/ /* © Acorn Computers Ltd, 1992. */ /* */ /* This file forms part of an unsupported source release of RISC_OSLib. */ /* */ /* It may be freely used to create executable images for saleable */ /* products but cannot be sold in source form or as an object library */ /* without the prior written consent of Acorn Computers Ltd. */ /* */ /* If this file is re-distributed (even if modified) it should retain */ /* this copyright notice. */ /* */ /************************************************************************/ /* * Title : c.sprite * Purpose: provide access to RISC OS sprite facilities * History: IDJ: 07-Feb-92: prepared for source release * */ #include #include "h.os" #include "h.sprite" /* Basic primitive used by sprite_xxx calls */ #define OS_SpriteOp 0x2E #define ScreenSave 2 #define ScreenLoad 3 #define ReadAreaCB 8 /* *SInfo */ #define ClearSprites 9 /* *SNew */ #define LoadSpriteFile 10 /* *SLoad */ #define MergeSpriteFile 11 /* *SMerge */ #define SaveSpriteFile 12 /* *SSave */ #define ReturnName 13 #define GetSprite 14 /* *SGet */ #define CreateSprite 15 #define GetSpriteUserCoords 16 #define SelectSprite 24 /* *SChoose [] */ #define DeleteSprite 25 /* *SDelete */ #define RenameSprite 26 /* *SRename */ #define CopySprite 27 #define PutSprite 28 #define CreateMask 29 #define RemoveMask 30 #define InsertRow 31 #define DeleteRow 32 #define FlipAboutXAxis 33 #define PutSpriteUserCoords 34 #define AppendSprite 35 #define SetPointerShape 36 #define ReadSpriteSize 40 #define ReadPixelColour 41 #define WritePixelColour 42 #define ReadPixelMask 43 #define WritePixelMask 44 #define InsertCol 45 #define DeleteCol 46 #define FlipAboutYAxis 47 #define PlotMask 48 #define PlotMaskUserCoords 49 #define PlotMaskScaled 50 #define PaintCharScaled 51 #define PutSpriteScaled 52 #define PutSpriteGreyScaled 53 #define RemoveLeftHandWastage 54 #define PlotMaskTransformed 55 #define PutSpriteTransformed 56 #define InsertDeleteRows 57 #define InsertDeleteColumns 58 #define SwitchOutputToSprite 60 #define SwitchOutputToMask 61 #define ReadSaveAreaSize 62 #define BadReasonCode 63 #pragma no_check_stack static os_error * sprite__op(os_regset *r) { return os_swix(OS_SpriteOp, r); } /******** Simple operations, use no sprite area, no name/sprite pointer ***/ os_error * sprite_screensave(const char *filename, sprite_palflag palflag) { os_regset r; os_error *result; r.r[0] = 2; /*r.r[1] unused */ r.r[2] = (int) filename; r.r[3] = palflag; result = sprite__op(&r); return result; } os_error * sprite_screenload(const char *filename) { os_regset r; os_error *result; r.r[0] = 3; /*r.r[1] unused */ r.r[2] = (int) filename; result = sprite__op(&r); return result; } /****** Operations on either system/user area, no name/sprite pointer *****/ static void setfromarea(int op, sprite_area *area, os_regset *r) { if (area == sprite_mainarea) { r->r[0] = op; /* r->r[1] unused */ } else { r->r[0] = op + 256; r->r[1] = (int) area; } } void sprite_area_initialise(sprite_area *area, int length) { area->size = length; /* No SpriteOp to do this ! */ area->number = 0; area->sproff = 16; area->freeoff = 16; } os_error * sprite_area_readinfo(sprite_area *area, sprite_area *resultarea) { os_regset r; os_error *result; setfromarea(8, area, &r); result = sprite__op(&r); if (result == NULL) /* Only return result if no error */ { resultarea->size = r.r[2]; resultarea->number = r.r[3]; resultarea->sproff = r.r[4]; resultarea->freeoff = r.r[5]; } return result; } os_error * sprite_area_reinit(sprite_area *area) { os_regset r; os_error *result; setfromarea(9, area, &r); result = sprite__op(&r); return result; } os_error * sprite_area_save(sprite_area *area, const char *filename) { os_regset r; os_error *result; setfromarea(12, area, &r); r.r[2] = (int) filename; result = sprite__op(&r); return result; } os_error * sprite_area_load(sprite_area *area, const char *filename) { os_regset r; os_error *result; setfromarea(10, area, &r); r.r[2] = (int) filename; result = sprite__op(&r); return result; } os_error * sprite_area_merge(sprite_area *area, const char *filename) { os_regset r; os_error *result; setfromarea(11, area, &r); r.r[2] = (int) filename; result = sprite__op(&r); return result; } os_error * sprite_getname(sprite_area *area, void *buffer, int *length, int index) { os_regset r; os_error *result; setfromarea(13, area, &r); r.r[2] = (int) buffer; r.r[3] = *length; r.r[4] = index; result = sprite__op(&r); if (result == NULL) /* Only return result if no error */ { *length = r.r[3]; } return result; } os_error * sprite_get(sprite_area *area, char *name, sprite_palflag palflag) { os_regset r; os_error *result; setfromarea(14, area, &r); r.r[2] = (int) name; r.r[3] = palflag; result = sprite__op(&r); return result; } os_error * sprite_get_rp(sprite_area *area, char *name, sprite_palflag palflag, sprite_ptr *resultaddress) { os_regset r; os_error *result; setfromarea(14, area, &r); r.r[2] = (int) name; r.r[3] = palflag; result = sprite__op(&r); if (result == NULL) /* Only return result if no error */ { *resultaddress = (void *) r.r[2]; } return result; } os_error * sprite_get_given(sprite_area *area, char *name, sprite_palflag palflag, int x0, int y0, int x1, int y1) { os_regset r; os_error *result; setfromarea(16, area, &r); r.r[2] = (int) name; r.r[3] = palflag; r.r[4] = x0; r.r[5] = y0; r.r[6] = x1; r.r[7] = y1; result = sprite__op(&r); return result; } os_error * sprite_get_given_rp(sprite_area *area, char *name, sprite_palflag palflag, int x0, int y0, int x1, int y1, sprite_ptr *resultaddress) { os_regset r; os_error *result; setfromarea(16, area, &r); r.r[2] = (int) name; r.r[3] = palflag; r.r[4] = x0; r.r[5] = y0; r.r[6] = x1; r.r[7] = y1; result = sprite__op(&r); if (result == NULL) /* Only return result if no error */ { *resultaddress = (void *) r.r[2]; } return result; } os_error * sprite_create(sprite_area *area, char *name, sprite_palflag palflag, int width, int height, int mode) { os_regset r; os_error *result; setfromarea(15, area, &r); /* NB. Not all done in numeric order !! */ r.r[2] = (int) name; r.r[3] = palflag; r.r[4] = width; r.r[5] = height; r.r[6] = mode; result = sprite__op(&r); return result; } os_error * sprite_create_rp(sprite_area *area, char *name, sprite_palflag palflag, int width, int height, int mode, sprite_ptr *resultaddress) { os_regset r; os_error *result; setfromarea(15, area, &r); /* NB. Not all done in numeric order !! */ r.r[2] = (int) name; r.r[3] = palflag; r.r[4] = width; r.r[5] = height; r.r[6] = mode; result = sprite__op(&r); if (result == NULL) /* Only return result if no error */ { /* spriteop 15 doesn't return pointer to sprite in r2, so....*/ /* select the sprite just created (gets its address in r2) */ setfromarea(24, area, &r); r.r[2] = (int)name; result = sprite__op(&r); if (result == NULL) *resultaddress = (void *) r.r[2]; } return result; } /*********** Operations on system/user area, name/sprite pointer **********/ /* Modify op if using sprite address is address, not name */ /* But only if using own sprite area */ static void setfromtag(int op, sprite_area *area, sprite_id *spr, os_regset *r) { if (area == sprite_mainarea) { r->r[0] = op; /* r->r[1] unused */ } else { r->r[1] = (int) area; if ((spr->tag) == sprite_id_addr) { r->r[0] = 512 + op; r->r[2] = (int) (spr->s.addr); } else { r->r[0] = 256 + op; r->r[2] = (int) (spr->s.name); } } } os_error * sprite_readinfo(sprite_area *area, sprite_id *spr, sprite_info *resultinfo) { os_regset r; os_error *result; setfromtag(40, area, spr, &r); result = sprite__op(&r); if (result == NULL) /* Only return result if no error */ { resultinfo->width = r.r[3]; resultinfo->height = r.r[4]; resultinfo->mask = r.r[5]; resultinfo->mode = r.r[6]; } return result; } os_error * sprite_select(sprite_area *area, sprite_id *spr) { os_regset r; os_error *result; setfromtag(24, area, spr, &r); result = sprite__op(&r); return result; } os_error * sprite_select_rp(sprite_area *area, sprite_id *spr, sprite_ptr *resultaddress) { os_regset r; os_error *result; setfromtag(24, area, spr, &r); result = sprite__op(&r); if (result == NULL) /* Only return result if no error */ { *resultaddress = (void *) r.r[2]; } return result; } os_error * sprite_delete(sprite_area *area, sprite_id *spr) { os_regset r; os_error *result; setfromtag(25, area, spr, &r); result = sprite__op(&r); return result; } os_error * sprite_rename(sprite_area *area, sprite_id *spr, char *newname) { os_regset r; os_error *result; setfromtag(26, area, spr, &r); r.r[3] = (int) newname; result = sprite__op(&r); return result; } os_error * sprite_copy(sprite_area *area, sprite_id *spr, char *copyname) { os_regset r; os_error *result; setfromtag(27, area, spr, &r); r.r[3] = (int) copyname; result = sprite__op(&r); return result; } os_error * sprite_put(sprite_area *area, sprite_id *spr, int gcol_action) { os_regset r; os_error *result; setfromtag(28, area, spr, &r); r.r[5] = gcol_action; result = sprite__op(&r); return result; } os_error * sprite_put_given(sprite_area *area, sprite_id *spr, int gcol_action, int x, int y) { os_regset r; os_error *result; setfromtag(34, area, spr, &r); r.r[3] = x; r.r[4] = y; r.r[5] = gcol_action; result = sprite__op(&r); return result; } os_error * sprite_put_scaled(sprite_area *area, sprite_id *spr, int gcol_action, int x, int y, sprite_factors *factors, sprite_pixtrans *pixtrans) { os_regset r; os_error *result; setfromtag(52, area, spr, &r); r.r[3] = x; r.r[4] = y; r.r[5] = gcol_action; r.r[6] = (int) factors; r.r[7] = (int) pixtrans; result = sprite__op(&r); return result; } os_error * sprite_put_greyscaled(sprite_area *area, sprite_id *spr, int x, int y, sprite_factors *factors, sprite_pixtrans *pixtrans) { os_regset r; os_error *result; setfromtag(53, area, spr, &r); r.r[3] = x; r.r[4] = y; r.r[5] = 0; /* doesn't support mask or gcol action */ r.r[6] = (int) factors; r.r[7] = (int) pixtrans; result = sprite__op(&r); return result; } os_error * sprite_put_mask(sprite_area *area, sprite_id *spr) { os_regset r; os_error *result; setfromtag(48, area, spr, &r); result = sprite__op(&r); return result; } os_error * sprite_put_mask_given(sprite_area *area, sprite_id *spr, int x, int y) { os_regset r; os_error *result; setfromtag(49, area, spr, &r); r.r[3] = x; r.r[4] = y; result = sprite__op(&r); return result; } os_error * sprite_put_mask_scaled(sprite_area *area, sprite_id *spr, int x, int y, sprite_factors *factors) { os_regset r; os_error *result; setfromtag(50, area, spr, &r); r.r[3] = x; r.r[4] = y; r.r[6] = (int) factors; result = sprite__op(&r); return result; } os_error * sprite_put_char_scaled(char ch, int x, int y, sprite_factors *factors) { os_regset r; os_error *result; r.r[0] = 51; r.r[1] = ch; r.r[3] = x; r.r[4] = y; r.r[6] = (int) factors; result = sprite__op(&r); return result; } os_error * sprite_create_mask(sprite_area *area, sprite_id *spr) { os_regset r; os_error *result; setfromtag(29, area, spr, &r); result = sprite__op(&r); return result; } os_error * sprite_remove_mask(sprite_area *area, sprite_id *spr) { os_regset r; os_error *result; setfromtag(30, area, spr, &r); result = sprite__op(&r); return result; } os_error * sprite_insert_row(sprite_area *area, sprite_id *spr, int row) { os_regset r; os_error *result; setfromtag(31, area, spr, &r); r.r[3] = row; result = sprite__op(&r); return result; } os_error * sprite_delete_row(sprite_area *area, sprite_id *spr, int row) { os_regset r; os_error *result; setfromtag(32, area, spr, &r); r.r[3] = row; result = sprite__op(&r); return result; } os_error * sprite_insert_column(sprite_area *area, sprite_id *spr, int column) { os_regset r; os_error *result; setfromtag(45, area, spr, &r); r.r[3] = column; result = sprite__op(&r); return result; } os_error * sprite_delete_column(sprite_area *area, sprite_id *spr, int column) { os_regset r; os_error *result; setfromtag(46, area, spr, &r); r.r[3] = column; result = sprite__op(&r); return result; } os_error * sprite_flip_x(sprite_area *area, sprite_id *spr) { os_regset r; os_error *result; setfromtag(33, area, spr, &r); result = sprite__op(&r); return result; } os_error * sprite_flip_y(sprite_area *area, sprite_id *spr) { os_regset r; os_error *result; setfromtag(47, area, spr, &r); result = sprite__op(&r); return result; } os_error * sprite_readsize(sprite_area *area, sprite_id *spr, sprite_info *resultinfo) { os_regset r; os_error *result; setfromtag(40, area, spr, &r); result = sprite__op(&r); /* now copy returned data */ resultinfo->width = r.r[3] ; resultinfo->height = r.r[4] ; resultinfo->mask = r.r[5] ; resultinfo->mode = r.r[6] ; return result; } os_error * sprite_readpixel(sprite_area *area, sprite_id *spr, int x, int y, sprite_colour *resultcolour) { os_regset r; os_error *result; setfromtag(41, area, spr, &r); r.r[3] = x; r.r[4] = y; result = sprite__op(&r); if (result == NULL) /* Only return result if no error */ { resultcolour->colour = r.r[5]; resultcolour->tint = r.r[6]; } return result; } os_error * sprite_writepixel(sprite_area *area, sprite_id *spr, int x, int y, sprite_colour *colour) { os_regset r; os_error *result; setfromtag(42, area, spr, &r); r.r[3] = x; r.r[4] = y; r.r[5] = colour->colour; r.r[6] = colour->tint; result = sprite__op(&r); return result; } os_error * sprite_readmask(sprite_area *area, sprite_id *spr, int x, int y, sprite_maskstate *resultmaskstate) { os_regset r; os_error *result; setfromtag(43, area, spr, &r); r.r[3] = x; r.r[4] = y; result = sprite__op(&r); if (result == NULL) /* Only return result if no error */ { *resultmaskstate = r.r[5]; } return result; } os_error * sprite_writemask(sprite_area *area, sprite_id *spr, int x, int y, sprite_maskstate *maskstate) { os_regset r; os_error *result; setfromtag(44, area, spr, &r); r.r[3] = x; r.r[4] = y; r.r[5] = (int) (*maskstate); /* Use pointer here for consistent interface */ result = sprite__op(&r); return result; } os_error *sprite_restorestate(sprite_state state) { os_regset r; os_error *result; r.r[0] = state.r[0]; r.r[1] = state.r[1]; r.r[2] = state.r[2]; r.r[3] = state.r[3]; result = sprite__op(&r); return result; } os_error *sprite_outputtosprite(sprite_area *area, sprite_id *id, int *save_area, sprite_state *state) { os_regset r; os_error *result; setfromtag(0x3c, area, id, &r); r.r[3] = (int) save_area; result = sprite__op(&r); if (result == NULL) { state->r[0] = r.r[0]; state->r[1] = r.r[1]; state->r[2] = r.r[2]; state->r[3] = r.r[3]; } return result; } os_error *sprite_outputtomask(sprite_area *area, sprite_id *id, int *save_area, sprite_state *state) { os_regset r; os_error *result; setfromtag(0x3d, area, id, &r); r.r[3] = (int) save_area; result = sprite__op(&r); if (result == NULL) { state->r[0] = r.r[0]; state->r[1] = r.r[1]; state->r[2] = r.r[2]; state->r[3] = r.r[3]; } return result; } os_error *sprite_outputtoscreen(int *save_area, sprite_state *state) { os_regset r; os_error *result; r.r[0] = 0x3c; r.r[2] = 0; r.r[3] = (int)save_area; result = sprite__op(&r); if (result == NULL) { state->r[0] = r.r[0]; state->r[1] = r.r[1]; state->r[2] = r.r[2]; state->r[3] = r.r[3]; } return result; } os_error *sprite_sizeof_spritecontext(sprite_area *area, sprite_id *id, int *size) { os_regset r; os_error *result; setfromtag(0x3e, area, id, &r); result = sprite__op(&r); if (result == NULL) *size = r.r[3]; return result; } os_error *sprite_sizeof_screencontext(int *size) { os_regset r; os_error *result; r.r[0] = 0x3e; r.r[2] = 0; result = sprite__op(&r); if (result == NULL) *size = r.r[3]; return result; } os_error *sprite_removewastage(sprite_area *area, sprite_id *id) { os_regset r; os_error *result; setfromtag(0x36, area, id, &r); result = sprite__op(&r); return result; } os_error *sprite_change_size (sprite_area *area, sprite_id *id, BOOL rows, int at, int number) { os_regset reg_set; setfromtag (rows? InsertDeleteRows: InsertDeleteColumns, area, id, ®_set); reg_set.r [3] = at; reg_set.r [4] = number; return sprite__op (®_set); } os_error *sprite_put_mask_trans (sprite_area *area, sprite_id *id, sprite_box *box, sprite_transmat *trans_mat) { os_regset reg_set; setfromtag (PlotMaskTransformed, area, id, ®_set); reg_set.r [3] = box == NULL? 0: 1 << 1; reg_set.r [4] = (int) box; reg_set.r [6] = (int) trans_mat; return sprite__op (®_set); } os_error *sprite_put_mask_pgm (sprite_area *area, sprite_id *id, sprite_box *box, sprite_pgm *pgm) { os_regset reg_set; setfromtag (PlotMaskTransformed, area, id, ®_set); reg_set.r [3] = (box == NULL? 0: 1 << 1) | (1 << 0); reg_set.r [4] = (int) box; reg_set.r [6] = (int) pgm; return sprite__op (®_set); } os_error *sprite_put_trans (sprite_area *area, sprite_id *id, int gcol_action, sprite_box *box, sprite_transmat *trans_mat, sprite_pixtrans *pix_trans) { os_regset reg_set; setfromtag (PutSpriteTransformed, area, id, ®_set); reg_set.r [3] = box == NULL? 0: 1 << 1; reg_set.r [4] = (int) box; reg_set.r [5] = gcol_action; reg_set.r [6] = (int) trans_mat; reg_set.r [7] = (int) pix_trans; return sprite__op (®_set); } os_error *sprite_put_pgm (sprite_area *area, sprite_id *id, int gcol_action, sprite_box *box, sprite_pgm *pgm, sprite_pixtrans *pix_trans) { os_regset reg_set; setfromtag (PutSpriteTransformed, area, id, ®_set); reg_set.r [3] = (box == NULL? 0: 1 << 1) | (1 << 0); reg_set.r [4] = (int) box; reg_set.r [5] = gcol_action; reg_set.r [6] = (int) pgm; reg_set.r [7] = (int) pix_trans; return sprite__op (®_set); } #pragma check_stack /* end of c.sprite */