Página 5 de 10

Re: Z88DK (curso Radastan) - Dudas Varias

Publicado: Mar, 20 May 2014, 16:14
por Hark0
$this->bbcode_second_pass_quote('radastan', '')$this->bbcode_second_pass_quote('na_th_an', 'M')añana podrás pillarla del código.


HYPEx2
:mrgreen:

Entonces copiopego o me voy de tapas?

Re: Z88DK (curso Radastan) - Dudas Varias

Publicado: Mar, 20 May 2014, 16:26
por na_th_an
Venga, va

$this->bbcode_second_pass_code('', '// random.h
// New random routines. Code by Patrik Rak, adapted by na_th_an

extern unsigned int seed1 [0];
extern unsigned int seed2 [0];
extern unsigned char randres [0];
#asm
._seed1 defw 0
._seed2 defw 0
._randres defb 0
#endasm

unsigned char rand (void) {
#asm
.rnd
ld hl,0xA280
ld de,0xC0DE
ld a,h ; t = x ^ (x << 1)
add a,a
xor h
ld h,l ; x = y
ld l,d ; y = z
ld d,e ; z = w
ld e,a
rra ; t = t ^ (t >> 1)
xor e
ld e,a
ld a,d ; w = w ^ ( w << 3 ) ^ t
add a,a
add a,a
add a,a
xor d
xor e
ld e,a
ld (rnd+1),hl
ld (rnd+4),de
ld (_randres), a
#endasm
return randres [0];
}

void srand (void) {
#asm
ld hl, (_seed1)
ld (rnd+1),hl
ld hl, (_seed2)
ld (rnd+4),hl
#endasm
}')

Para iniciar, hacer:
$this->bbcode_second_pass_code('', 'seed1 [0] = a; seed2 [0] = b;
srand ();')

Con a y b los dos numericos que más os gusten.

Luego cada vez que queráis un random, llamad a rand. Da un valor entre 0 y 255. Con módulos y ANDs tenéis lo que necesitéis. Un número entre 0 y 3...

$this->bbcode_second_pass_code('', 'c = rand () & 3;')

Ya que hay cuatro posibilidades y 4 es potencia de 2, podemos usar un AND aritmético y volar.

Un número entre 0 y 11, como 11 no es potencia de 2 ni nada...

$this->bbcode_second_pass_code('', 'c = rand () % 12;')

Un número entre a y b, ambos inclusive, con a < b

$this->bbcode_second_pass_code('', 'c = a + (rand () % (b - a + 1));')

Lo bueno es que para a y b fijos, la secuencia aleatoria siempre es la misma, lo cual viene muy bien para hacer güegos. Si queréis a y b más o menos aleatorios, asignadles los valores de la variable de sistema FRAMES (23672), por ejemplo.

Es mejor procurar que tus randoms sean en rangos que sean potencias de 2 porque así no tienes que dividir, que es lento y costoso. Por ejemplo, para seleccionar una columna de la pantalla al azar, al ser 32 los posibles valores y ser 32 potencia de 2, podemos hacer:

$this->bbcode_second_pass_code('', 'c = rand () & 31;')

Un AND aritmético es inmediato, mientras que para dividir y hacer un módulo hay que tirar de una función porque el z80 no divide.

Re: Z88DK (curso Radastan) - Dudas Varias

Publicado: Mar, 20 May 2014, 16:37
por Hark0
:cheer:

Re: Z88DK (curso Radastan) - Dudas Varias

Publicado: Mar, 20 May 2014, 18:03
por antoniovillena
@na_th_an creo que puedes prescindir del return, una rutina en ensamblador siempre retorna el resultado en HL (o en L si es un byte). En resumen, puedes cambiar esto:

$this->bbcode_second_pass_code('', '
blablabla
ld (_randres), a
#endasm
return randres [0];
}
')

Por esto otro:

$this->bbcode_second_pass_code('', '
blablabla
ld l, a
#endasm
}
')

Re: Z88DK (curso Radastan) - Dudas Varias

Publicado: Mar, 20 May 2014, 18:05
por na_th_an
Bueno, para el próximo juego ;)

Re: Z88DK (curso Radastan) - Dudas Varias

Publicado: Mié, 21 May 2014, 06:23
por Hark0
Bueno he implementado el rand() de @na_th_an, pero con el sutil cambio de Antonio.

Al principio del programa inicializo las semillas con:

seed1 [0] = 32; seed2 [0] = 64;
srand ();

Y luego he generado un bucle for-next para ver que tal.

En mis pruebas, SIEMPRE obtengo los 13 primeros RAND con 0... a partir de ahí si que parece generar número aleatorios... no me supone más problemas que al iniciar srand, generar ya los 13 números para "descartar los ceros inútiles"...

¿como le indico que quiero usar FRAMES u otra dirección a la semilla?

Re: Z88DK (curso Radastan) - Dudas Varias

Publicado: Mié, 21 May 2014, 06:42
por Hark0
Acerca de las rutinas @Radastan,

He añadido las dos funciones put_char y put_sprite_x8.

Si hago un put_char("A",x,y); obtengo un tile de 8x8 pixels con el color de tinta del CLS(x); pero claro, basura porque no tengo declarado "A"...
Si hago un put_char(sprite8x8,x,y); obtengo el tile esperado de 8x8 pixels con el color de tinta del CLS(x);
Si hago un put_sprite_x8(sprite8x8,x,y); sin problemas... pinta el tile esperado y con el color declarado al cargar los datos del gráfico.

Y por otro lado tengo el "addon" de na_th_an para usar la rutina draw_fast (unsigned char x, unsigned char y, unsigned char clr, unsigned char *s)

hmmm ¿cual es la mejor opción para el texto?

:roll:

Re: Z88DK (curso Radastan) - Dudas Varias

Publicado: Mié, 21 May 2014, 08:36
por radastan
$this->bbcode_second_pass_quote('Hark0', 'A')cerca de las rutinas @Radastan,

He añadido las dos funciones put_char y put_sprite_x8.

Si hago un put_char("A",x,y); obtengo un tile de 8x8 pixels con el color de tinta del CLS(x); pero claro, basura porque no tengo declarado "A"...
Si hago un put_char(sprite8x8,x,y); obtengo el tile esperado de 8x8 pixels con el color de tinta del CLS(x);
Si hago un put_sprite_x8(sprite8x8,x,y); sin problemas... pinta el tile esperado y con el color declarado al cargar los datos del gráfico.

Y por otro lado tengo el "addon" de na_th_an para usar la rutina draw_fast (unsigned char x, unsigned char y, unsigned char clr, unsigned char *s)

hmmm ¿cual es la mejor opción para el texto?

:roll:


put_sprite_x8 es útil para poder poner gráficos de 8x8 pixels, es muy útil.
put_char es un arma de doble filo, ya que te permite usar esos mismos gráficos sin color (puedes cambiar su aspecto) y usarlo para caracteres

Te falta print_at, que es la que estoy haciendo, que pone directamente un texto a partir de un set de caracteres que puedes definir y usa put_char para imprimir cada letra. Es decir, no tendrás que hacer nada y será como usar el print at de BASIC de toda la vida.

Re: Z88DK (curso Radastan) - Dudas Varias

Publicado: Mié, 21 May 2014, 08:51
por na_th_an
CUIDADO. El carácter A no es "A" sino 'A'. Esto es MUY IMPORTANTE.

"A" es una cadena. En C no existen las cadenas en sí como tipo de datos, es más bien una ristra de bytes terminada en 0 y apuntada por un puntero. Si pasas "A" a una función, estás pasando un puntero a esa función, no la letra "A".

'A' es un char. En C, 'A' es equivalente a pasar el número 65, que es su código ASCII.

Creo que no vendrían mal unas pequeñas nociones de C básico :)

Sobre el print, pues la función que te he pasado imprime, ¿no? :)

Re: Z88DK (curso Radastan) - Dudas Varias

Publicado: Mié, 21 May 2014, 10:34
por Hark0
Tienes toda la razón del mundo... :oops: