chiark / gitweb /
JPEG support and other fixes from Nick Clark
[ssr] / StraySrc / Libraries / Sapphire / s / sprite
1 ;
2 ; sprite.s
3 ;
4 ; Nice operations on sprites
5 ;
6 ; © 1994-1998 Straylight
7 ;
8
9 ;----- Licensing note -------------------------------------------------------
10 ;
11 ; This file is part of Straylight's Sapphire library.
12 ;
13 ; Sapphire is free software; you can redistribute it and/or modify
14 ; it under the terms of the GNU General Public License as published by
15 ; the Free Software Foundation; either version 2, or (at your option)
16 ; any later version.
17 ;
18 ; Sapphire is distributed in the hope that it will be useful,
19 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 ; GNU General Public License for more details.
22 ;
23 ; You should have received a copy of the GNU General Public License
24 ; along with Sapphire.  If not, write to the Free Software Foundation,
25 ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26
27 ;----- Standard header ------------------------------------------------------
28
29                 GET     libs:header
30                 GET     libs:swis
31
32 ;----- External dependencies ------------------------------------------------
33
34                 GET     sapphire:resspr
35                 GET     sapphire:screen
36
37 ;----- Main code ------------------------------------------------------------
38
39                 AREA    |Sapphire$$Code|,CODE,READONLY
40
41 ; --- sprite_op ---
42 ;
43 ; On entry:     R0,R2-R7 ==  SpriteOp parameters (R1 set up here)
44 ;
45 ; On exit:      Registers and flags altered as for the SpriteOp
46 ;
47 ; Use:          Performs an OS_SpriteOp with the given arguments, using
48 ;               the appication's Sprites resource as the sprite area.
49
50                 EXPORT  sprite_op
51 sprite_op       ROUT
52
53                 STMFD   R13!,{R0,R14}           ;Stack some registers
54
55                 ; --- Get the current resource sprite area ---
56
57                 BL      resspr_area             ;Get area in R0
58                 MOV     R1,R0                   ;Put it in R1
59                 LDMFD   R13!,{R0}               ;Get the SpriteOp back
60
61                 ; --- Is it the WIMP sprite area (Yrggg...) ---
62
63                 CMP     R1,#1                   ;Is it WIMP area?
64                 BEQ     %00sprite_op            ;Yes -- deal with it
65
66                 ; --- We must be using the user sprite area ---
67
68                 ORR     R0,R0,#&100             ;Use user area
69                 SWI     XOS_SpriteOp            ;Do the SpriteOp
70                 LDMFD   R13!,{PC}               ;And return to the user
71
72                 ; --- Use the WIMP sprite area ---
73
74 00sprite_op     SWI     XWimp_SpriteOp          ;Do SpriteOp on WIMP area
75                 LDMFD   R13!,{PC}               ;And return to the user
76
77                 LTORG
78
79 ; --- sprite_getTable ---
80 ;
81 ; On entry:     R0 == pointer to a sprite
82 ;               R1 == pointer to buffer for translate table
83 ;
84 ; On exit:      --
85 ;
86 ; Use:          Creates a colour translate table for the given sprite in
87 ;               the specified buffer.
88 ;
89 ;               If you have a sprite name but no pointer, use OS_SpriteOp
90 ;               24 to find the pointer -- this will make further sprite ops
91 ;               on the sprite much quicker.
92
93                 EXPORT  sprite_getTable
94 sprite_getTable ROUT
95
96                 STMFD   R13!,{R0-R9,R14}        ;Save some registers
97                 MOV     R7,R0                   ;Keep the sprite pointer
98                 MOV     R8,R1                   ;Keep the buffer pointer
99
100                 ; --- Find out how many colours the sprite has ---
101
102                 MOV     R2,R7                   ;Get the sprite pointer
103                 MOV     R1,#&1000               ;No particular sprite area
104                 MOV     R0,#40                  ;Get sprite information
105                 ADD     R0,R0,#512              ;Tell it I have a sprite ptr
106                 SWI     OS_SpriteOp             ;Read the sprite information
107                 MOV     R0,R6                   ;Get the sprite's mode
108                 MOV     R1,#3                   ;Read number of colours
109                 SWI     OS_ReadModeVariable     ;Read the mode value nicely
110                 MOV     R9,R2                   ;Keep number of colours
111
112                 ; --- Handle the Wimp palette ---
113                 ;
114                 ; If the sprite has 16 colours and no palette, we assume it
115                 ; should have the Wimp palette, and so use that.
116
117                 CMP     R2,#15                  ;Does it have 16 colours?
118                 LDREQ   R14,[R7,#32]            ;Get the sprite offset
119                 CMPEQ   R14,#44                 ;Is there no palette?
120                 BNE     %10sprite_getTable      ;No to either -- skip it out
121
122                 ; --- Read the WIMP palette, and use that ---
123
124                 SUB     R13,R13,#80             ;Drop the stack pointer
125                 MOV     R1,R13                  ;Point to the block
126                 SWI     Wimp_ReadPalette        ;Read the Wimp palette
127                 MOV     R0,R6                   ;Source mode set up
128                 MOV     R2,#-1                  ;Use current mode
129                 MOV     R3,#-1                  ;Use current palette too
130                 MOV     R4,R8                   ;Create in caller's buffer
131                 SWI     ColourTrans_SelectTable ;Set up the table nicely
132                 ADD     R13,R13,#80             ;Restore the stack pointer
133                 B       %90sprite_getTable      ;And skip to the end
134
135                 ; --- Try and use the RISC OS 3 way ---
136
137 10              MOV     R0,#&1000               ;No sprite area in particular
138                 MOV     R1,R7                   ;Point to my sprite
139                 MOV     R2,#-1                  ;Output in current mode
140                 MOV     R3,#-1                  ;And into current palette
141                 MOV     R4,R8                   ;Into the caller's buffer
142                 MOV     R5,#1                   ;And output a sprite table
143                 SWI     XColourTrans_SelectTable ;Try and read the table
144                 BVC     %90sprite_getTable      ;If it worked, finish
145
146                 ; --- If the sprite has no palette, just assume default ---
147
148                 CMP     R9,#15                  ;Is the number of colours>16?
149                 BGT     %15sprite_getTable      ;Yes -- assume def palette
150                 LDR     R14,[R7,#32]            ;Get the sprite offset
151                 CMP     R14,#44                 ;Is there a palette?
152                 BNE     %20sprite_getTable      ;Yes -- handle it then
153
154 15              MOV     R0,R6                   ;Source mode set up
155                 MOV     R1,#0                   ;Assume default palette
156                 MOV     R2,#-1                  ;Use current mode
157                 MOV     R3,#-1                  ;Use current palette too
158                 MOV     R4,R8                   ;Create in caller's buffer
159                 SWI     ColourTrans_SelectTable ;Set up the table nicely
160                 B       %90sprite_getTable      ;And skip to the end
161
162                 ; --- Read the palette from the sprite ---
163
164 20              ADD     R0,R7,#44               ;Point to first palette entry
165                 SUB     R13,R13,R9,LSL #2       ;And make space for palette
166                 MOV     R1,R13                  ;Point to palette buffer
167                 MOV     R2,R9                   ;Copy the colour count
168
169 25              LDR     R14,[R0],#8             ;Load a palette word
170                 STR     R14,[R1],#4             ;Save it into the buffer
171                 SUBS    R2,R2,#1                ;Decrement the counter
172                 BGE     %25sprite_getTable      ;If more to do, go round
173
174                 MOV     R0,R6                   ;Source mode set up
175                 MOV     R1,R13                  ;Point to my nice palette
176                 MOV     R2,#-1                  ;Use current mode
177                 MOV     R3,#-1                  ;Use current palette too
178                 MOV     R4,R8                   ;Create in caller's buffer
179                 SWI     ColourTrans_SelectTable ;Set up the table nicely
180                 ADD     R13,R13,R9,LSL #2       ;Reclaim the stack again
181
182                 ; --- Return to caller ---
183
184 90              LDMFD   R13!,{R0-R9,PC}^        ;Return to caller
185
186                 LTORG
187
188 ; --- sprite_plot ---
189 ;
190 ; On entry:     R0 == pointer to a sprite
191 ;               R1 == x coordinate to plot at
192 ;               R2 == y coordinate to plot at
193 ;               R3 == pointer to scale block, or 0 for 1:1
194 ;
195 ; On exit:      CS if the sprite was plotted OK, else CC
196 ;
197 ; Use:          Plots a sprite on the screen.  The scaling refers to the
198 ;               sprite proper: /this/ routine takes care of odd pixel
199 ;               sizes and things, so sprites don't appear squashed or
200 ;               stretched unless you really want them to.
201 ;
202 ;               We return C clear on exit if we couldn't plot the sprite;
203 ;               typically this would be if the sprite's mode is undefined.
204
205                 EXPORT  sprite_plot
206 sprite_plot     ROUT
207
208                 STMFD   R13!,{R0-R9,R14}        ;Save some registers
209
210                 CMP     R3,#0                   ;Has he given a scaling?
211                 ADREQ   R3,sprite__scale        ;No -- use our own one
212                 LDMIA   R3,{R5-R8}              ;Load the scaling out
213
214                 ; --- Fiddle with the scale factors ---
215
216                 MOV     R3,R1                   ;Remember this position
217                 MOV     R4,R2                   ;And this one please
218                 MOV     R9,R0                   ;Remember the sprite addr
219                 BL      screen_getInfo          ;Read the screen info
220                 ADD     R14,R0,#screen_xEig     ;Find the EIG factors
221                 LDMIA   R14,{R0,R1}             ;Load them out nicely
222                 MOV     R7,R7,LSL R0            ;Scale down by this resn
223                 MOV     R8,R8,LSL R1            ;So go and do that
224                 LDR     R0,[R9,#40]             ;Load the mode gadget
225                 MOV     R1,#4                   ;Read the x EIG factor
226                 SWI     OS_ReadModeVariable     ;Read that then
227                 BCS     %90sprite_plot          ;If it failed, return
228                 MOV     R5,R5,LSL R2            ;Bump up the scaling by this
229                 MOV     R1,#5                   ;Read the y EIG factor
230                 SWI     OS_ReadModeVariable     ;Read that then
231                 BCS     %90sprite_plot          ;If it failed, return
232                 MOV     R6,R6,LSL R2            ;Bump up the scaling again
233                 STMFD   R13!,{R5-R8}            ;Save them away for later
234
235                 ; --- Now read the translation table and plot ---
236
237                 MOV     R0,R9                   ;Point to the sprite
238                 MOV     R1,R11                  ;Build table in R11-space
239                 BL      sprite_getTable         ;Go and do that then
240
241                 MOV     R0,#52                  ;Put sprite scaled
242                 ORR     R0,R0,#512              ;Use my pointed-at sprite
243                 MOV     R1,#&1000               ;A bogus sprite area
244                 MOV     R2,R9                   ;Point to the sprite
245                 MOV     R5,#8                   ;Plot with a mask
246                 MOV     R6,R13                  ;Point to scale factors
247                 MOV     R7,R11                  ;And to the translate table
248                 SWI     XOS_SpriteOp            ;Plot and ignore error
249                 ADD     R13,R13,#16             ;Restore stack pointer
250                 BVS     %90sprite_plot          ;If it failed, abort
251                 LDMFD   R13!,{R0-R9,R14}        ;Restore registers
252                 ORRS    PC,R14,#C_flag          ;And return to caller
253
254 90sprite_plot   LDMFD   R13!,{R0-R9,R14}        ;Restore registers
255                 BICS    PC,R14,#C_flag          ;And return to caller
256
257 sprite__scale   DCD     1,1,1,1
258
259                 LTORG
260
261 ;----- That's all, folks ----------------------------------------------------
262
263                 END