Create readable text `.bas' for each tokenized BASIC `,ffb' file.
[ssr] / StraySrc / Utilities / b / resgen.bas
1 REM
2 REM resGen
3 REM
4 REM Convert resource files into linkable format
5 REM
6 REM © 1995-1998 Straylight
7 REM
8
9 REM ----- Licensing note ----------------------------------------------------
10 REM
11 REM This file is part of Straylight's core utilities (coreutils)
12 REM
13 REM Coreutils is free software; you can redistribute it and/or modify
14 REM it under the terms of the GNU General Public License as published by
15 REM the Free Software Foundation; either version 2, or (at your option)
16 REM any later version
17 REM
18 REM Coreutils is distributed in the hope that it will be useful,
19 REM but WITHOUT ANY WARRANTY; without even the implied warranty of
20 REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 REM GNU General Public License for more details.
22 REM
23 REM You should have received a copy of the GNU General Public License
24 REM along with Coreutils. If not, write to the Free Software Foundation,
25 REM 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26
27 ON ERROR ERROR EXT 0,REPORT$+" ["+STR$(ERL)+"]"
28
29 DIM q% 1024
30
31 SYS "OS_GetEnv" TO comm$
32 IF INSTR(comm$,"-quit")=0 THEN ERROR 1,"resGen must be started using *Run"
33 comm$=MID$(comm$,INSTR(comm$,"""")+1)
34 comm$=MID$(comm$,INSTR(comm$," ")+1)
35 comm$=LEFT$(comm$,INSTR(comm$,"""")-1)
36
37 res$=FNword(comm$)
38 out$=FNword(comm$)
39 IF res$="" OR out$="" THEN ERROR 0,"Syntax: resGen <resDir> <aofFile>"
40
41 LIBRARY "libs:bas"
42 PROCbas_init
43
44 PROCassembleAux
45
46 PROCbas_aofInit(256*1024)
47 FOR pass=4 TO 6 STEP 2
48 [ opt pass
49 FNpass
50 FNarea("Resources$$Data","CODE,READONLY")
51 ]
52
53 PROCsprites(res$+".Sprites")
54 PROCmessages(res$+".Messages")
55 PROCtemplates(res$+".Templates")
56
57 NEXT
58 PROCbas_aofSaveAs(out$)
59 END
60
61 REM ----- Sprites -----------------------------------------------------------
62
63 DEF PROCsprites(spr$)
64 [ opt pass
65 FNexport("rsc_sprites")
66 .rsc_sprites
67 dcd (FNfSize(spr$)+4+3) AND -4
68 FNbin(spr$)
69 FNalign
70 ]
71 ENDPROC
72
73 REM ----- Messages ----------------------------------------------------------
74
75 DEF PROCmessages(msg$)
76 [ opt pass
77 FNexport("rsc_msgBase")
78 .rsc_msgBase
79 ]
80 A%=O%
81 B%=A%+FNfSize(msg$)
82 SYS "OS_File",16,msg$,A%,0
83 l%=USR(msgs)-A%
84 O%+=l%
85 P%+=l%
86 [ opt pass
87 dcb 0
88 FNexport("rsc_msgLimit")
89 .rsc_msgLimit
90 FNalign
91 ]
92 ENDPROC
93
94 REM ----- Templates ---------------------------------------------------------
95
96 DEF FNlabel(l$)=EVAL("FNassign("+l$+","+STR$(P%)+")")
97 DEF FNref(l$)=EVAL(l$)
98 DEF FNassign(RETURN x%,y%)
99 x%=y%
100 =0
101
102 DEF PROCtemplates(tpl$)
103 IF pass=4 THEN
104 SYS "OS_File",17,tpl$ TO ,,,,tsize%
105 DIM tfile% tsize%
106 SYS "OS_File",16,tpl$,tfile%,0
107 ENDIF
108
109 REM --- Build the name table ---
110
111 [ opt pass
112 FNexport("rsc_tplBase")
113 .rsc_tplBase
114 ]
115
116 index%=tfile%+16
117 WHILE index%!0
118 CASE index%!8 OF
119 WHEN 1
120 name$=FNgetString(index%+12)
121 [ opt pass
122 dcb name$
123 dcb 0
124 FNalign
125 dcd FNref("__"+name$)
126 ]
127 OTHERWISE
128 ERROR 1,"Template type "+STR$(index%!0)+" unrecognised"
129 ENDCASE
130 index%+=24
131 ENDWHILE
132
133 [ opt pass
134 FNexport("rsc_tplLimit")
135 .rsc_tplLimit
136 ]
137
138 REM --- Now write out the window definitions ---
139
140 B%=tfile%+16
141 C%=tfile%
142 WHILE B%!0
143 CASE B%!8 OF
144 WHEN 1
145 name$=FNgetString(B%+12)
146 [ opt pass
147 FNlabel("__"+name$)
148 ]
149 A%=O%
150 l%=USR(tpl_window)-A%
151 P%+=l%
152 O%+=l%
153 [ opt pass
154 FNalign
155 ]
156 OTHERWISE
157 ERROR 1,"Template type "+STR$(index%!0)+" unrecognised"
158 ENDCASE
159 B%+=24
160 ENDWHILE
161 ENDPROC
162
163 REM ----- Other useful functions --------------------------------------------
164
165 DEF FNgetString(a%)
166 LOCAL s$
167 WHILE ?a%>=32
168 s$+=CHR$(?a%)
169 a%+=1
170 ENDWHILE
171 =s$
172
173 DEF FNword(RETURN line$)
174 LOCAL word$
175 IF INSTR(line$," ") THEN
176 word$=LEFT$(line$,INSTR(line$," ")-1)
177 line$=MID$(line$,INSTR(line$," ")+1)
178 ELSE
179 word$=line$
180 line$=""
181 ENDIF
182 =word$
183
184 DEF FNupper(line$)
185 LOCAL i%
186 $q%=line$
187 FOR i%=0 TO LEN(line$)-1
188 IF q%?i%>=97 AND q%?i%<=122 THEN q%?i%-=32
189 NEXT
190 =$q%
191
192 REM ----- Auxiliary assembler bits ------------------------------------------
193
194 DEF PROCassembleAux
195 DIM aux% 4096
196 FOR o=0 TO 2 STEP 2
197 P%=aux%
198 [ opt o
199
200 ; --- msgs ---
201 ;
202 ; entry; r0 == pointer to file
203 ; r1 == limit of file
204 ; exit; r0 == new output pointer
205
206 .msgs
207 stmfd r13!,{r14}
208 mov r2,r0
209
210 .msgs_newline
211 cmp r2,r1
212 bcs msgs_end
213 ldrb r14,[r2],#1
214 cmp r14,#&21
215 bcc msgs_newline
216
217 cmp r14,#ASC(";")
218 cmpne r14,#ASC("#")
219 cmpne r14,#ASC("|")
220 beq msgs_skipline
221
222 .msgs_writeline
223 cmp r14,#&20
224 movcc r14,#0
225 strb r14,[r0],#1
226 ldrcsb r14,[r2],#1
227 bcs msgs_writeline
228
229 b msgs_newline
230
231 .msgs_skipline
232 ldrb r14,[r2],#1
233 cmp r14,#&20
234 bcs msgs_skipline
235
236 b msgs_newline
237
238 .msgs_end
239 ldmfd r13!,{pc}^
240
241
242 ; --- tpl_window ---
243 ;
244 ; entry; r0 == output pointer
245 ; r1 == pointer to index entry
246 ; r2 == pointer to template file base
247 ; exit; r0 == new output pointer
248
249 .tpl_window
250 stmfd r13!,{r14}
251 add r11,r0,#12
252 mov r10,r0
253 mov r9,r2
254 ldr r14,[r1,#0]
255 add r8,r9,r14
256
257 ; --- Build relocation table ---
258
259 mov r14,#64
260 orr r14,r14,#1<<28
261 str r14,[r11],#4
262
263 ldr r0,[r8,#56]
264 add r1,r8,#72
265 bl tpl_doReloc
266
267 ldr r7,[r8,#84]
268 add r6,r8,#88
269
270 .loop
271 subs r7,r7,#1
272 ldrcs r0,[r6,#16]
273 addcs r1,r6,#20
274 blcs tpl_doReloc
275 addcs r6,r6,#32
276 bcs loop
277
278 ; --- Add in offset entry for window definition ---
279
280 sub r14,r11,r10
281 str r14,[r10,#0]
282
283 ; --- Now copy over the window definition ---
284
285 mov r14,r8
286 mov r7,#72
287
288 .loop
289 subs r7,r7,#16
290 ldmcsia r14!,{r0-r3}
291 stmcsia r11!,{r0-r3}
292 bcs loop
293 ldmia r14!,{r0,r1}
294 stmia r11!,{r0,r1}
295
296 ldr r0,[r8,#56]
297 add r1,r8,#72
298 mov r5,#0
299 bl tpl_writeData
300
301 ldr r7,[r8,#84]
302 str r7,[r11],#4
303 add r6,r8,#88
304
305 .loop
306 subs r7,r7,#1
307 ldmcsia r6,{r0-r3,r14}
308 stmcsia r11!,{r0-r3,r14}
309 ldrcs r0,[r6,#16]
310 addcs r1,r6,#20
311 blcs tpl_writeData
312 addcs r6,r6,#32
313 bcs loop
314
315 ; --- Add in offset for this ---
316
317 sub r14,r11,r10
318 str r14,[r10,#4]
319
320 ; --- Finally copy over the indirected data ---
321
322 ldr r0,[r8,#56]
323 add r1,r8,#72
324 bl tpl_copyData
325
326 ldr r7,[r8,#84]
327 add r6,r8,#88
328
329 .loop
330 subs r7,r7,#1
331 ldrcs r0,[r6,#16]
332 addcs r1,r6,#20
333 blcs tpl_copyData
334 addcs r6,r6,#32
335 bcs loop
336
337 ; --- Put in the last offset and return ---
338
339 sub r14,r11,r10
340 str r14,[r10,#8]
341
342 mov r0,r11
343 ldmfd r13!,{pc}^
344
345
346 ; --- tpl_doReloc ---
347 ;
348 ; entry; r0 == icon flags word
349 ; r1 == pointer to icon data
350 ; r8 == base of window definition
351 ; r11 == output pointer
352 ; exit; r0-r5 corrupted
353
354 .tpl_doReloc
355 tst r0,#&100
356 moveqs pc,r14
357
358 stmfd r13!,{r14}
359 sub r14,r1,r8
360 str r14,[r11],#4
361
362 and r14,r0,#&3
363 cmp r14,#&2
364 beq tpl_drSprite
365
366 ldr r14,[r1,#4]
367 cmn r14,#-(-1)
368 subne r14,r1,r8
369 addne r14,r14,#4
370 strne r14,[r11],#4
371 ldmfd r13!,{pc}^
372
373 .tpl_drSprite
374 sub r14,r8,r1
375 add r14,r14,#4
376 orr r14,r14,#(2<<28)
377 str r14,[r11],#4
378 ldmfd r13!,{pc}^
379
380
381 ; --- tpl_writeData ---
382 ;
383 ; entry; r0 == icon flags word
384 ; r1 == pointer to icon data
385 ; r5 == indirection offset
386 ; r8 == base of window definition
387 ; r11 == output pointer
388 ; exit; r5 updated
389 ; r0-r4 corrupted
390
391 .tpl_writeData
392 tst r0,#&100
393 beq tpl_wdNotInd
394
395 stmfd r13!,{r14}
396 str r5,[r11],#4
397 ldr r14,[r1,#8]
398 add r5,r5,r14
399
400 and r14,r0,#&3
401 cmp r14,#&2
402 beq tpl_wdSprite
403 ldr r14,[r1,#4]
404 cmn r14,#-(-1)
405 beq tpl_wdNoValid
406
407 str r5,[r11],#4
408 add r2,r8,r14
409
410 .loop
411 ldrb r14,[r2],#1
412 add r5,r5,#1
413 cmp r14,#&20
414 bcs loop
415
416 b tpl_wdCont
417
418 .tpl_wdSprite
419 mov r14,#1
420 .tpl_wdNoValid
421 str r14,[r11],#4
422
423 .tpl_wdCont
424 ldr r14,[r1,#8]
425 str r14,[r11],#4
426
427 ldmfd r13!,{pc}^
428
429 .tpl_wdNotInd
430 ldmia r1,{r0-r2}
431 stmia r11!,{r0-r2}
432 movs pc,r14
433
434
435 ; --- tpl_copyData ---
436 ;
437 ; entry; r0 == icon flags
438 ; r1 == pointer to icon data
439 ; r8 == base of window definition
440 ; r11 == output pointer
441 ; exit; r0-r5 corrupted
442
443 .tpl_copyData
444 tst r0,#&100
445 moveqs pc,r14
446
447 stmfd r13!,{r14}
448 mov r2,r11
449 ldr r14,[r1,#0]
450 add r3,r8,r14
451
452 .loop
453 ldrb r14,[r3],#1
454 cmp r14,#&20
455 movcc r14,#0
456 strb r14,[r2],#1
457 bcs loop
458
459 ldr r14,[r1,#8]
460 add r11,r11,r14
461 mov r14,#0
462
463 .loop
464 cmp r2,r11
465 strccb r14,[r2],#1
466 bcc loop
467
468 tst r0,#1
469 ldrne r14,[r1,#4]
470 cmnne r14,#-(-1)
471 beq tpl_cdSkip
472
473 add r2,r8,r14
474
475 .loop
476 ldrb r14,[r2],#1
477 cmp r14,#&20
478 movcc r14,#0
479 strb r14,[r11],#1
480 bcs loop
481
482 .tpl_cdSkip
483 ldmfd r13!,{pc}^
484
485 ]
486 NEXT
487 ENDPROC