chiark / gitweb /
JPEG support and other fixes from Nick Clark
[ssr] / StraySrc / Libraries / Sapphire / s / banner
1 ;
2 ; banner.s
3 ;
4 ; A startup banner window
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                 GET     libs:stream
33
34 ;----- External dependencies ------------------------------------------------
35
36                 GET     sapphire:alloc
37                 GET     sapphire:dbox
38                 GET     sapphire:divide
39                 GET     sapphire:event
40                 GET     sapphire:flex
41                 GET     sapphire:heap
42                 GET     sapphire:hour
43                 GET     sapphire:nopoll
44                 GET     sapphire:res
45                 GET     sapphire:sapphire
46                 GET     sapphire:screen
47                 GET     sapphire:wimp
48
49                 GET     sapphire:dbx.dbx
50                 GET     sapphire:dbx.slider
51
52                 [       :LNOT::DEF: bnr__dynaLink
53
54                 IMPORT  |Image$$RW$$Base|,WEAK
55                 IMPORT  |Image$$RW$$Limit|,WEAK
56                 IMPORT  |Sapphire$$ClientData$$Base|,WEAK
57                 IMPORT  |Sapphire$$ClientData$$Limit|,WEAK
58                 IMPORT  |Sapphire$$ExtTable$$Base|,WEAK
59                 IMPORT  |Sapphire$$ExtTable$$Limit|,WEAK
60
61                 ]
62
63                 IMPORT  |Sapphire$$LibData$$Base|,WEAK
64                 IMPORT  |Sapphire$$LibData$$Limit|,WEAK
65
66 ;----- Main code ------------------------------------------------------------
67
68                 AREA    |Sapphire$$Code|,CODE,READONLY
69
70                 [       :LNOT::DEF: bnr__dynaLink
71
72 ; --- banner ---
73 ;
74 ; On entry:     R0 == pointer to definition block, or 0
75 ;               R1 == R12 value to pass to setup routine, if present
76 ;
77 ; On exit:      --
78 ;
79 ; Use:          Displays a startup banner and initialises the library and
80 ;               client.  This call should be used as a replacement for
81 ;               sapphire_libInit.
82 ;
83 ;               If R0 is 0 on entry, no banner window is used; instead
84 ;               an hourglass percentage is displayed to indicate the
85 ;               amount of initialisation performed so far.
86 ;
87 ;               Alternatively, it should point to a table consisting of
88 ;               a flags word and optional arguments specified by the flags
89 ;               in order.  The options you can specify are a slider and
90 ;               percentage count icon (used to display current progress),
91 ;               a setup routine, and the leafname of a sprites file to
92 ;               attach to the banner window.
93 ;
94 ;               The setup routine is passed the banner dialogue handle in
95 ;               R0.  It should fill in parts of the banner window, such as
96 ;               the licencee name and serial number that can't be determined
97 ;               until runtime (for safeness), and maybe version information
98 ;               too.
99
100                 EXPORT  banner
101 banner          ROUT
102
103                 STMFD   R13!,{R2,R14}           ;Save some registers
104                 ADR     R2,bnr__initList        ;Point to the list
105                 BL      bnr_doBanner            ;Do the job
106                 LDMFD   R13!,{R2,PC}^           ;And return to caller
107
108 bnr__initList   DCD     |Image$$RW$$Limit|
109                 DCD     |Sapphire$$ClientData$$Base|
110                 DCD     |Sapphire$$ClientData$$Limit|
111                 DCD     -1
112                 DCD     |Sapphire$$ExtTable$$Base|
113                 DCD     |Sapphire$$ExtTable$$Limit|
114
115                 LTORG
116
117                 ]
118
119 ; --- bnr_doBanner ---
120 ;
121 ; On entry:     R0 == pointer to definition block, or 0
122 ;               R1 == R12 value to pass to setup routine, if present
123 ;               R2 == pointer to library initialisation table
124 ;
125 ; On exit:      --
126 ;
127 ; Use:          Displays a startup banner and initialises the library and
128 ;               client.
129
130                 EXPORT  bnr_doBanner
131 bnr_doBanner    ROUT
132
133                 STMFD   R13!,{R0-R10,R12,R14}   ;Save some registers
134
135                 ; --- Initialise required parts of library ---
136
137                 LDR     R0,sapph_appName        ;Find the application name
138                 BL      hour_init               ;Initialise hourglass
139                 BL      hour_on                 ;Turn on the hourglass
140                 BL      alloc_init              ;Initialise heap functions
141                 BL      wimp_init               ;Initialise WindowManager
142                 BL      screen_init             ;Initialise screen info
143                 BL      res_init                ;Find our resources
144                 BL      nopoll_init             ;We need nonpolling dialogues
145                 BL      dbox_init               ;Initialise dialogue boxes
146                 BL      flex_init               ;Initialise nemory manager
147                 BL      heap_init               ;And the heap manager too
148
149                 ; --- Unpack the definition block ---
150
151                 SUB     R13,R13,#36             ;Make a bit of workspace
152                 MOV     R1,#0                   ;Clear two words
153                 MOV     R2,#0
154                 STMFD   R13!,{R1,R2}            ;Make two flex anchors
155                 STR     R1,[R13,#40]            ;Initial percentage is 0
156                 MOV     R10,#0                  ;Not created the block yet
157                 LDR     R9,[R13,#44]            ;Load the block pointer
158                 CMP     R9,#0                   ;Is there a block?
159                 BEQ     %05bnr_doBanner         ;No -- don't bother then
160
161                 ; --- Load the template file ---
162
163                 MOV     R0,R13                  ;Point to this anchor
164                 MOV     R1,#2048                ;Guess the size of the file
165                 BL      flex_alloc              ;Try to allocate
166                 BCS     %05bnr_doBanner         ;If it failed, ignore window
167
168                 ADRL    R0,bnr__tfile           ;Point to template file name
169                 MOV     R1,R11                  ;Build name in scratchpad
170                 BL      res_find                ;Try to find the file
171                 BCC     %05bnr_doBanner         ;If it failed, ignore window
172                 MOV     R1,R0                   ;Point to the name
173                 SWI     XWimp_OpenTemplate      ;Try to open the file
174                 LDRVC   R1,[R13,#0]             ;Load the base of this block
175                 ADDVC   R2,R1,#1024             ;Indirected data in 2nd K
176                 ADDVC   R3,R1,#2048             ;And stop at the end please
177                 MOVVC   R4,#-1                  ;Pray there's no fonts
178                 ADRVCL  R5,bnr__template        ;Point to the template name
179                 LDMVCIA R5,{R6-R8}              ;Load 3 words of data
180                 ADDVC   R14,R13,#8              ;Point to some free space
181                 STMVCIA R14,{R6-R8}             ;It writes back the name!
182                 MOVVC   R5,R14                  ;So point to a copy
183                 MOVVC   R6,#0                   ;Start from beginning
184                 SWIVC   XWimp_LoadTemplate      ;Try to load the template
185                 MOVVS   R7,R0                   ;If error, remember pointer
186                 MOVVC   R7,#0                   ;Otherwise clear this
187                 SWI     Wimp_CloseTemplate      ;Close the template file
188                 MOVS    R0,R7                   ;Get the error back
189                 BNE     %05bnr_doBanner         ;And go off somewhere else
190
191                 ; --- Now load options from the block ---
192
193                 MOV     R1,R9                   ;Move this around a bit
194                 LDR     R0,[R1],#4              ;Load the flags word
195
196                 TST     R0,#bFlag_slider        ;Does he want a slider?
197                 LDRNE   R9,[R1],#4              ;Yes -- load the icon number
198                 MOVEQ   R9,#-1                  ;Otherwise remember this
199
200                 TST     R0,#bFlag_counter       ;Does he have a counter?
201                 LDRNE   R8,[R1],#4              ;Yes -- load the icon number
202                 MOVEQ   R8,#-1                  ;Otherwise remember this
203
204                 TST     R0,#bFlag_setup         ;Does he have a setup routine
205                 LDRNE   R7,[R1],#4              ;Yes -- load the address
206                 MOVEQ   R7,#0                   ;Otherwise remember this
207
208                 TST     R0,#bFlag_sprites       ;Does he have a sprite file
209                 BEQ     %03bnr_doBanner         ;No -- don't load it then
210
211                 ; --- Load the sprite file ---
212
213                 MOV     R0,R1                   ;Point to the leafname
214                 MOV     R1,R11                  ;Build name in scratchpad
215                 BL      res_find                ;Try to get a good name
216                 BCC     %03bnr_doBanner         ;If not there, don't worry
217                 MOV     R1,R0                   ;Put name in right register
218                 MOV     R0,#17                  ;Read information on file
219                 SWI     XOS_File                ;Try to get the information
220                 BVS     %03bnr_doBanner         ;Failed -- don't bother then
221                 TST     R0,#1                   ;Is this a file?
222                 BEQ     %03bnr_doBanner         ;No -- ignore it then
223                 ADD     R0,R13,#4               ;Point to other anchor
224                 ADD     R1,R4,#8                ;Get the file size
225                 BL      flex_alloc              ;Allocate the memory
226                 BCS     %03bnr_doBanner         ;Failed -- ignore it then
227                 MOV     R0,#16                  ;Load the file
228                 MOV     R1,R11                  ;Point to the filename
229                 LDR     R2,[R13,#4]             ;Load the block address
230                 ADD     R14,R4,#8               ;Get this block size
231                 STR     R14,[R2],#4             ;Save it in the block
232                 MOV     R3,#0                   ;Load where I said to load it
233                 SWI     OS_File                 ;Load the file then
234
235                 LDMIA   R13,{R0,R1}             ;Load the two anchors
236                 STR     R1,[R0,#64]             ;Save the sprite pointer
237
238                 ; --- Now create a dialogue box ---
239
240 03bnr_doBanner  LDR     R0,[R13,#0]             ;Load the window base address
241                 BL      dbox_fromDefn           ;Try to create a dialogue
242                 BVS     %05bnr_doBanner         ;If we couldn't, don't care
243                 MOV     R10,R0                  ;Get the dialogue handle
244
245                 ; --- If we need to, build a dbx block ---
246
247                 CMP     R9,#-1                  ;Do we have a slider icon?
248                 ADRNE   R14,bnr__dbx            ;Yes -- point to dbx skeleton
249                 ADDNE   R1,R13,#8               ;Point to some spare memory
250                 LDMNEIA R14!,{R3-R5}            ;Load some values out
251                 MOVNE   R2,R9                   ;Get the icon handle
252                 STMNEIA R1!,{R2-R5}             ;Store them away
253                 LDMNEIA R14!,{R2-R5}            ;Load some more values
254                 STMNEIA R1!,{R2-R5}             ;Save them away too
255                 ADDNE   R1,R13,#8               ;Point to the dbx block
256                 BLNE    dbx_declare             ;And attach the definition
257
258                 ; --- Set up an event handler ---
259
260                 MOV     R1,#0                   ;I don't have a handler
261                 ADD     R2,R13,#40              ;Point to spare word
262                 MOV     R3,#0                   ;Don't care about R12
263                 BL      dbox_eventHandler       ;Set up the event handler
264
265                 ; --- Now set up the dialogue box ---
266
267                 CMP     R7,#0                   ;Does he have a setup routine
268                 LDRNE   R12,[R13,#48]           ;Load caller's R12 value
269                 MOVNE   R14,PC                  ;Set up return address
270                 MOVNE   PC,R7                   ;And call his routine
271
272                 ADD     R7,R13,#40              ;Point to count word
273                 BL      bnr__count              ;Update the counter
274
275                 ; --- Display the dialogue box ---
276                 ;
277                 ; This is a horrible hack, but I don't care.
278
279                 MOV     R1,#dbOpen_centre+dbOpen_persist+dbOpen_nonSub
280                 BL      dbox_open               ;Set up the position nicely
281                 BL      dbox_window             ;Get the window handle
282                 ORR     R0,R0,#1<<31            ;Don't constrain the mouse
283                 BL      nopoll_open             ;Set up a fake redraw request
284                 MOV     R1,R11                  ;Do this in the scratchpad
285                 MOV     R0,#1                   ;Don't care about event mask
286                 BL      event_poll              ;Send that fake event
287                 BL      nopoll_close            ;Shut nopoll up now
288
289                 ; --- Now we need to count the things to initialise ---
290
291 05bnr_doBanner  ADD     R7,R13,#40              ;Point to count word (again)
292                 LDR     R5,[R13,#52]            ;Load the lib init block
293                 ADD     R5,R5,#4                ;Skip past program end
294
295                 ADR     R0,bnr__ownTable        ;Point to our own init table
296                 LDMIA   R0,{R0,R1}              ;Load the base and limit
297                 SUB     R0,R1,R0                ;Find the table size
298                 MOV     R6,R0,LSR #4            ;Divide by size of entry
299
300                 MOV     R2,R5                   ;Get a copy of his table
301 10bnr_doBanner  LDMIA   R2!,{R0,R1}             ;Load the base and limit
302                 CMP     R0,#-1                  ;Is this the end yet?
303                 SUBNE   R0,R1,R0                ;Find the table size
304                 ADDNE   R6,R6,R0,LSR #4         ;Add on number in this table
305                 BNE     %10bnr_doBanner         ;And carry on going
306
307                 SUB     R2,R2,#4                ;We overshot a bit
308                 LDMIA   R2,{R3,R4}              ;Load extension table values
309 12bnr_doBanner  CMP     R3,R4                   ;Reached the end yet?
310                 BCS     %15bnr_doBanner         ;Yes -- phew!
311                 MOV     R14,PC                  ;Set up return address
312                 LDR     PC,[R3],#4              ;Call finding routine
313                 SUB     R0,R1,R0                ;Find the table size
314                 ADD     R6,R6,R0,LSR #4         ;Add on number in this table
315                 B       %12bnr_doBanner         ;And carry on going
316
317                 ; --- Now actually initialise things ---
318
319
320 15bnr_doBanner  MOV     R4,#0                   ;Nothing initialised yet
321                 LDR     R2,sapph_workspace      ;Load the main workspace base
322                 ADR     R0,bnr__ownTable        ;Point to our own init table
323                 LDMIA   R0,{R0,R1}              ;Load the base and limit
324                 BL      bnr__init               ;Initialise these bits
325
326 20bnr_doBanner  LDMIA   R5!,{R0,R1}             ;Load base and limit from tbl
327                 CMP     R0,#-1                  ;Is this the end yet?
328                 BLNE    bnr__init               ;No -- initialise from here
329                 BNE     %20bnr_doBanner         ;And carry on going
330
331                 SUB     R5,R5,#4                ;We went a little too far
332                 LDMIA   R5,{R3,R5}              ;Find the extension table
333 25bnr_doBanner  CMP     R3,R5                   ;Have we finished yet?
334                 BCS     %30bnr_doBanner         ;Yes -- better stop then
335                 MOV     R14,PC                  ;Set up return address
336                 LDR     PC,[R3],#4              ;Call this routine
337                 LDR     R2,[R11,-R2]            ;Load the workspace base
338                 BL      bnr__init               ;Do some initialisation
339                 B       %25bnr_doBanner         ;And keep on going
340
341                 ; --- Ahhh -- finished ---
342
343                 CMP     R10,#0                  ;Do we have a dialogue box?
344                 BEQ     %32bnr_doBanner         ;No -- don't wait then
345 30bnr_doBanner  SWI     OS_ReadMonotonicTime    ;What's the time, Mr Computer
346                 ADD     R1,R0,#50               ;Wait for a second
347 31bnr_doBanner  SWI     OS_ReadMonotonicTime    ;What's the time, Mr Computer
348                 CMP     R0,R1                   ;Waited long enough?
349                 BMI     %31bnr_doBanner         ;No -- keep waiting then
350
351 32bnr_doBanner  MOVS    R0,R10                  ;Get the dialogue handle
352                 BLNE    dbox_destroy            ;Trash it if I created it
353                 LDR     R14,[R13,#0]            ;Load the dialogue anchor
354                 CMP     R14,#0                  ;Did I create it?
355                 ADDNE   R0,R13,#0               ;Yes -- point to the anchor
356                 BLNE    flex_free               ;And free the block
357                 LDR     R14,[R13,#4]            ;Load the sprite anchor
358                 CMP     R14,#0                  ;Did I create it?
359                 ADDNE   R0,R13,#4               ;Yes -- point to the anchor
360                 BLNE    flex_free               ;And free the block
361
362                 BL      hour_off                ;Turn off the hourglass now
363
364                 ADD     R13,R13,#44             ;Restore the stack pointer
365                 LDMFD   R13!,{R0-R10,R12,PC}^   ;And return to caller
366
367 bnr__template   DCB     "banner",0
368 bnr__tfile      DCB     "Templates",0
369
370 bnr__dbx        DCD     slider
371                 DCD     dbxFlag_dataR10+slFlag_horizontal
372                 DCD     28
373                 DCD     0
374                 DCB     8,1,1,0
375                 DCD     100
376                 DCD     -1
377
378 bnr__ownTable   DCD     |Sapphire$$LibData$$Base|
379                 DCD     |Sapphire$$LibData$$Limit|
380
381                 LTORG
382
383 ; --- bnr__init ---
384 ;
385 ; On entry:     R0 == base of initialisation table
386 ;               R1 == limit of initialisation table
387 ;               R2 == pointer to workspace base
388 ;               R4 == number of units initialised so far
389 ;               R6 == number of items to initialise
390 ;               R7 == address of count word
391 ;               R8 == counter icon number
392 ;               R9 == slider icon number
393 ;               R10 == banner dialogue handle
394 ;
395 ; On exit:      --
396 ;
397 ; Use:          Initialises a load of library units.
398
399 bnr__init       ROUT
400
401                 STMFD   R13!,{R0-R3,R5,R14}     ;Save some registers
402                 MOV     R3,R0                   ;Look after this pointer
403                 LDR     R0,sapph_appName        ;Find application's name
404 00bnr__init     CMP     R3,R1                   ;Have we finished yet?
405                 LDMCSFD R13!,{R0-R3,R5,PC}^     ;Yes -- then return
406                 LDR     R5,[R3,#12]             ;Load the init routine addr
407                 ADD     R3,R3,#16               ;Move the pointer on a bit
408                 CMP     R5,#0                   ;Is there an init routine?
409                 MOVNE   R14,PC                  ;Yes -- set up return address
410                 MOVNE   PC,R5                   ;And call the routine
411
412                 STMFD   R13!,{R0,R1}            ;Save some registers
413                 ADD     R4,R4,#100              ;Initialised another one
414                 MOV     R0,R4                   ;Get the value in R0
415                 MOV     R1,R6                   ;How many there actually are
416                 BL      div_round               ;Work out the percentage
417                 STR     R0,[R7,#0]              ;Save the count word away
418                 BL      bnr__count              ;Update the counter
419                 LDMFD   R13!,{R0,R1}            ;And restore the registers
420
421                 B       %00bnr__init            ;And go round again
422
423                 LTORG
424
425 ; --- bnr__count ---
426 ;
427 ; On entry:     R7 == address of current percentage
428 ;               R8 == count icon number
429 ;               R9 == slider icon number
430 ;               R10 == dialogue box handle
431 ;
432 ; On exit:      --
433 ;
434 ; Use:          Displays the count of how much we've done in some cunning
435 ;               way.
436
437 bnr__count      ROUT
438
439                 STMFD   R13!,{R0-R2,R14}        ;Save some registers
440                 CMP     R10,#0                  ;Do we have a dialogue box?
441                 BEQ     %50bnr__count           ;Yes -- handle that then
442
443                 CMP     R9,#-1                  ;Do we have a slider?
444                 MOVNE   R0,R10                  ;Yes -- get the dialogue
445                 MOVNE   R1,R9                   ;And the icon handle
446                 BLNE    dbx_update              ;And redraw the slider
447
448                 CMP     R8,#-1                  ;Do we have a count icon?
449                 LDRNE   R0,[R7,#0]              ;Yes -- get the current value
450                 MOVNE   R1,R11                  ;Point to the scratchpad
451                 MOVNE   R2,#256                 ;Give the size of the buffer
452                 SWINE   OS_ConvertInteger4      ;Convert it to an integer
453                 MOVNE   R2,R0                   ;Point to this text
454                 MOVNE   R0,R10                  ;Get the dialogue handle
455                 MOVNE   R1,R8                   ;And the icon handle
456                 BLNE    dbox_setField           ;And write in the data
457                 LDMFD   R13!,{R0-R2,PC}^        ;Return to caller
458
459 50bnr__count    LDR     R0,[R7,#0]              ;Get the current value
460                 SWI     Hourglass_Percentage    ;Put it in the hourglass
461                 LDMFD   R13!,{R0-R2,PC}^        ;And return to caller
462
463                 LTORG
464
465 ; --- Flags ---
466
467 bFlag_slider    EQU     (1<<0)                  ;Has a progress slider
468                                                 ;+0 icon number for slider
469                                                 ;+4
470
471 bFlag_counter   EQU     (1<<1)                  ;Has a percentage indicator
472                                                 ;+0 icon number for indicator
473                                                 ;+4
474
475 bFlag_setup     EQU     (1<<2)                  ;Needs a setup routine
476                                                 ;+0 == address of routine
477                                                 ;+4
478
479 bFlag_sprites   EQU     (1<<3)                  ;Load a sprite file
480                                                 ;+0 == name of sprite file
481                                                 ;+n
482
483 ;----- That's all, folks ----------------------------------------------------
484
485                 END