Caracteres definidos por el usuario (UDG) en QL

El único de Sinclair no puede no tener un foro dedicado

Moderador: Fundadores

Responder
Avatar de Usuario
cacharreo !Sinclair 1
Moderador
Moderador
Mensajes: 5879
Registrado: 09 Ago 2019, 10:17
Ubicación: /home/cacharreo/
Has thanked: 1210 times
Been thanked: 2834 times
Contactar:

Caracteres definidos por el usuario (UDG) en QL

Mensaje por cacharreo »

Con el propósito de añadir gráficos a los juegos en BASIC que hemos ido haciendo, he estado investigando cómo crear caracteres definidos por el usuario (UDG) en un QL sin extensiones y con la ROM estándar.

El proceso es un tanto lioso pero con las dos funciones (realmente procedimientos) de la siguiente demo, udgSet y udgUnset, espero que sirva para que cualquiera pueda hacerlo en sus programas.

Con esta demo la receta es sencilla,

1) crear las líneas con los datos raster para los nuevos caracteres (9 valores por carácter),
2) usar el comando RESTORE con el número de la primera de dichas líneas (p.e. RESTORE 400),
3) llamar a la función udgSet ch, n siendo ch el número de canal a utilizar y n el número de nuevos caracteres a definir, y
4) llamar a la función udgUnset ch al terminar el programa para dejar todo como estaba y restaurar el juego de caracteres del sistema.
5) Los nuevos caracteres quedan definidos a partir del carácter 128 y pueden utilizarse en BASIC con CHR$(128), CHR$(129),...

En código esta misma receta queda así,

Código: Seleccionar todo

400 DATA...
...
600 ch = 1: REMark canal a usar
620 RESTORE 400: REMark número de línea donde comienzan los datos para los nuevos caracteres
630 udgSet ch 9: REMark definir 9 nuevos caracteres
... 
690 REMark restaurar los caracteres del sistema
700 udgUnset ch
udg demo 0.00beta
Imagen

Código: Seleccionar todo

100 REMark UDG demo 0.00beta
110 :
120 REMark ##########################################
130 REMark functions
140 REMark ##########################################
150 :
160 DEFine PROCedure udgSet(ch, n)
170   REMark define UDG set (User Defined Graphics)
180   LOCal i, p, v
190   system_variables_base_address = 163840: REMark default QL ROM system variables address
200   v$ = VER$: IF v$ == "JSL1" OR v$ == "HBA" THEN system_variables_base_address = VER$(-2)
210   channel_base_address = PEEK_L(system_variables_base_address)
220   channel_header_address = PEEK_L(channel_base_address + 4*ch)
230   REMark get and save font2 base address
240   pointer_enviroment_offset = 0: REMark 0 or 48
250   font2_base_address = PEEK_L(46 + pointer_enviroment_offset + (PEEK_L(PEEK_L(system_variables_base_address + 120) + 4*ch)))
260   REMark get udg memory space & set udg address
270   udg_address = RESPR(9*(n + 2) + 2)
280   POKE_L 46 + pointer_enviroment_offset + (PEEK_L(PEEK_L(system_variables_base_address + 120) + 4*ch)), udg_address
290   p = udg_address
300   POKE p, 127: POKE p + 1, n: p = p + 2
310   FOR i = 1 TO 9: POKE p, 0: p = p + 1
320   FOR i = 1 TO 9*n: READ v: POKE p, v: p = p + 1
330   FOR i = 1 TO 9: POKE p, 0: p = p + 1
340 END DEFine udgSet
350 :
360 DEFine PROCedure udgUnset(ch)
370   REMark restore system font pointers
380   POKE_L 46 + pointer_enviroment_offset + (PEEK_L(PEEK_L(system_variables_base_address + 120) + 4*ch)), font2_base_address
390 END DEFine udgUnset
400 :
410 REMark ##########################################
420 REMark UDG data (9x6 pixels)
430 REMark ##########################################
440 :
450 DATA 252, 132, 132, 132, 132, 132, 132, 132, 252: REMark Character # 128
460 DATA 252, 252, 252, 252, 252, 252, 252, 252, 252: REMark Character # 129
470 DATA 224, 224, 224, 224, 224, 224, 224, 224, 224: REMark Character # 130
480 DATA   28, 28,  28,  28,  28,  28,  28,  28,  28: REMark Character # 131
490 DATA 252, 252, 252, 252,   0,   0,   0,   0,   0: REMark Character # 132
500 DATA   0,   0,   0,   0, 252, 252, 252, 252, 252: REMark Character # 133
510 DATA 120, 132, 132, 132, 132, 132, 132, 132, 120: REMark Character # 134
520 DATA 120, 132, 132, 132, 120, 132, 132, 132, 120: REMark Character # 135
530 DATA   0, 120, 252, 252, 252, 252, 252, 252, 120: REMark Character # 136
540 :
550 REMark ##########################################
560 REMark main program
570 REMark ##########################################
580 :
590 ch = 1: REMark channel
600 n = 9: REMark number of UDG to define
610 REMark show system font
620 AT #ch, 1, 1: PRINT "System:"
630 AT #ch, 2, 1: PRINT "   UDG:"
640 FOR i = 127 TO 127 + n : AT #ch, i-123, 1: PRINT #ch, i, " ";CHR$(i): AT #ch, 1, i-118: PRINT #ch, CHR$(i)
650 RESTORE 400: REMark UDG data line number
660 udgSet ch, n: REMark define UDG
670 REMark show UDG
680 FOR i = 127 TO 127 + n : AT #ch, i-123, 18: PRINT #ch, CHR$(i): AT #ch, 2, i-118: PRINT #ch, CHR$(i)
690 REMark restore system font
700 udgUnset ch
En la línea 240 la variable pointer_enviroment_offset se inicializa al valor 0. Según he leído, con ciertas configuraciones podría ser necesario cambiar su valor a 48 pero en las pruebas que he hecho con diferentes ROM no ha sido necesario.
© cacharreo
Avatar de Usuario
cacharreo !Sinclair 1
Moderador
Moderador
Mensajes: 5879
Registrado: 09 Ago 2019, 10:17
Ubicación: /home/cacharreo/
Has thanked: 1210 times
Been thanked: 2834 times
Contactar:

Re: Caracteres definidos por el usuario (UDG) en QL

Mensaje por cacharreo »

© cacharreo
Responder

Volver a “Sinclair QL”