Initial revision
[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