/$1,DEF$2,ACC$3,798$4,488$5,AAC$6,88A$7,668$8,657$9,CAC$A,978$B,756$C,9BD$D,7AC$E,68A$F,568
=3#76,06
=2T3                  Chungui to Platanal (1)


T2=D                     (en busca de un método perita)
T2

             =5                                        por  Xele / Odrusba
T1=E
  Hola,  soy =D Xele =E de=D Odrusba=E y tras leer, meditar y comprender el artículo
que=D Peskanov=E de=D Zaborra=E escribió para mi revista =DTrashcan #1=E, me he decidido
a  comenzar una investigación profunda (bueno, medio profunda) sobre el tema
=6C2P=E.  Lo que =6voy a tratar de=E hacer aquí es=6 plasmar todas las ideas que se me
ocurran  sobre  el  asunto=E  e incluso poner fragmentos del código que idee a
partir  de dichas ideas ideadas ideales.  Espero que algún día esto caiga en
manos de alguien y al menos le resulte entretenido.

 =6 Es  la  primera vez que me meto en el tema C2P=E, por eso supongo que de vez
en  cuando  meteré la gamba...  espero que lo comprendáis.  De todas formas,
si  alguien  encuentra  algún error que me lo comente y corregiré lo que sea
necesario para la próxima versión de este texto.
=C
----------------------------------------------------------------------------=E
Leyenda:

=C	PR:=E Pregunta que el=D Xele=E se hace o bien hace a alguien.
=C	RE:=E Respuesta a la anterior pregunta.
=C	CO:=E Conclusión que se saca de lo anterior.
=C	XH:=D Xele =EHabla... (Er=D Xele=E cuenta sus experiencias sexuales=D C2P=E)
=C	RP:=E Reflexión Profundísima...
=C
  Nota:=E   Algunas  partes  del  texto  ocupan  más de=D 80 =Ecaracteres, así que
deberéis  usar  un tipo de letra más pequeño o en su defecto un programa que
permita scrollear el texto en horizontal (=DCED=E,=D AmigaGuide=E,=D GoldEd=E, etc)
=C
----------------------------------------------------------------------------
=2
Fecha:=3 29=4 de=3 Septiembre=4 de=3 1996=2
Lugar:=4 Mi habitación.=3 Córdoba=4.=3 España=4.
=2Estado:=4  Me siento cansado, ya que hoy me he pegado catorce caminatas por la
ciudad  y  tengo  los  pies para el arrastre, el sábado ha sido un verdadero
aburrimiento, espero que en lo sucesivo se anime la cosa.
=E
Bien, empezaré con mis preguntas retóricas paranoicas:
=2
PR:=3 ¿ Para qué voy a usar el Chunky 2 Planar ?
=C
RE:=E   Pues  sobre  todo  para rutinas que empleen texture mapping, y también
para  poder  hacer  conversiones  de  algoritmos  de =D PC=E  para el mamoneo de
gráficos en=D 2D =E(lo de las ondas, el morphing, las rotaciones, etc..).
=2
PR:=3  ¿ Qué exige el modo Chunky ?
=C
RE:=E   Que  la  codificación  del  registro  de  color  de un pixel pueda ser
almacenada  en  un  sólo  byte,  de  forma  que  la escritura de un pixel en
pantalla  necesite  sólo  un  acceso  a  memoria. =6  Dichos  Bytes-pixels van
organizados  secuencialmente  en  la memoria=E.  Exige también que le den paga
extra en navidad ...
=2
PR:=3  ¿ Es posible un modo Chunky verdadero en Amiga ?
=C
RE:=E  Con la=D Grafitti=E y otras tarjetas que valen un huevo, sí.  Con los chips
=DAGA =E no.   Existen  formas de acercarse a una especie de=D Chunky=E, por ejemplo
poniendo  una pantalla=D SHRES=E en la cual escribir un byte tendría como salida
en  pantalla  de un pixel del doble de ancho que uno de baja resolución.  Si

la  profundidad  de  la  pantalla  fuese de=D 1=E plano, estariamos ante un modo
=Dchunky  monocromo=E  de=D  2x1 =E de  resolución.   Lo  malo  es que el modo=D SHRES=E
sobrecarga  bastante  el=D  DMA=E,  y  tampoco  es que sea nada del otro jueves.
También  se  puede  tener una especie de pantalla chunky mediante el=D copper=E,
pero  las  máximas  resoluciones  que se alcanzan son de=D 4x1=E y reduciendo el
tamaño visible=D 2x1=E (=D1x1 =Esería ya un área demasiado pequeña).
=C
XH:=E Si tú me dices ven, lo dejo todo... si tú me dices ven... si tú...
=C
CO:=E   No  existen  modos  chunky en los=D AGA.=C
XH:=E   Pero hay que pintar en=D Chunky=E por huevos, así que vamos allá..
=C
CO:=E   Habrá  que usar una pantalla virtual chunky en la cual hacer todos los
mamoneos  y  después  convertirla  lo  más rápido posible y pintar sobre una
pantalla física en planar. La memoria más rápida en la actualidad para=D Amiga=E
es  la=D FAST=E, luego la pantalla virtual deberá ir en memoria=D Fast=E.  Lo que la
pantalla  virtual  ocupará  será =D =  PixelsAncho  x  PixelsAlto (Bytes)=E, ¡ya
empezamos  a  gastar  memoria!.   Una pantalla normal y corriente de=D 320x256=E
gastaría=D  81920  bytes=E,  o  sea =D 80 =E kilobytes.   A partir de ahora Pantalla
Virtual Chunky ==D PVC=E y Pantalla Física Planar = =DPFP=E.
=2
PR:=3 ¿ Habrá que programar rutinas específicas para dibujar en la PVC ?
=C
RE:=6   Sin  duda=E.   Son  necesarias  como  mínimo  para poder hacer algo, las
siguientes:   una  rutina  para escribir puntos, una rutina de líneas por el
método  de =D Bresenham=E y una rutina de=D fill=E rápida.  Todas ellas por supuesto
usarán el procesador, por ello es necesario un procesador rápido para el=D C2P=E
de los cojones.
=C
CO:=E   Descartar en principio trabajar para el=D 68000=E e incluso para el=D 68020=E.
Hay que ver cómo he cambiado, antes cuando tenía el=D 500 =Eme jodía un taco que
todo  el  mundo pididiera un=D 030=E para sus demos, ahora que yo lo tengo y veo
que  la  diferencia  de  potencia  es  abismal  y para el texture mapping es
esencial dicha potencia ... creo que ya no puedo ir para atrás, si me vuelvo
a  quedar  estancado  me  callaré  y  ahorraré  pelas para comprarme un buen
equipo,  y  hasta  que  las tenga, simplemente programaré en papel hasta que
llegue  el  momento de poder probar mis rutinas.  Pero mientras tanto, voy a
tratar es de explotar al máximo mi maquina.
=C
XH:=E   Acabo  de  adaptar  el  código inicializador que hice para la=D Demonoia=E
(=DOdrusba=E  Rulez!!)  para  que  me sirva de soporte a la hora de realizar mis
experimentos  =DChunky=E.   Para  no complicarme la vida no he reservado memoria
para  la =D PVC =Eni para la=D PFP=E, sino que las he definido como bloques de datos
declarados  en  sus  respectivas secciones=D (FAST y CHIP)=E mediante =Ddcb.b.=E  Lo
que  pasa es que luego cuando ya todo funcione perfectamente tendré que usar
=Dallocmem =E para  que  no  ocupe  memoria  en  el disco, así que declararé dos
variables  puntero  y trabajaré en mis rutinas a partir de ellas, pasando de
=DLEA's =E o  de =D move.l  #<ea>,ax  's=E.   Bien,  por  último  me  queda hacer la
=Dcopperlist=E que me permita ver la=D PFP=E e ir comprobando los resultados.  Se me
está  ocurriendo la idea de usar las =DCIAs =Epara calcular el tiempo que tardan
las rutinas, pero eso será más adelante.  Bueno, voy a currar un poquito...
=2
Fecha:=3 30 =4de=3 Septiembre=2
Lugar:=4 el de siempre=2
Estado  del  coder:=4   Pues sigo soltero...  no, hoy tengo la cabeza un tanto
revuelta  porque he tenido un problemilla con una echaporvo que se lo quería
montar  conmigo  y al final cuando ya estabamos en harina yo no he querido y
vamos  que  ha sido un poco violenta la situación...  y encima me he portado
como  un cabrón porque ni la he acompañado a su casa...  en fin, un númerito
que te cagas...  desde luego esto de ser el coder más sexy de la escena trae
más problemas de los que uno se imagina... en fin, seguiré con el=3 C2P=E.
=C
XH:=6   Bien,  la  copperlist  está  ya  a punto=E.  Ahora mismo trabajaré en =D16=E
colores  sólo para simplificar el tema.  Luego añadiré planos hasta llegar a
los=D 256 =Ecolores.
=C
XH:=E   Ahora  uso =6"los inclusos"=E, unos includes que me he hecho a mi bola y a
los  cuales  he  añadido  unas cuantas macros graciosas que me ahorran mucho
trabajo,  los  inclusos  no  son  ni  de  lejos  comparables  a=D Xsystem=E, son
simplemente  un arreglo temporal para ir tirando y poder hacer cosillas.  La
verdadera  caña la pillaré cuando termine el=D Xsystem converter=E ... ¡era sólo
por decir algo, joder!
=2
PR:=3  Hola, Xele ¿ qué idea te ronda por la mente en estos momentos ?
=C
RE:=E  Pues ahora mismo pienso en el=D self modifying code=E ... estoy tratando de
concentrarme  para  ver  si habría alguna forma de emplearlo en el=D C2P=E.  Con
ello  se conseguiría mucha más velocidad, ya que el=D s.m.c=E es un método ideal
para optimizar bucles interiores aparentemente=6 "insalvables"=E.
=C
CO:=E  Estudiar formatos de instrucciones y ver que se puede sacar de provecho
de  ello.   Estudiar  formatos  de:=D  ROL=E,=DROR=E,=DLSL=E,=DLSR=E,=DSWAP=E,=DEXG=E,=DOR=E,=DAND=E,=DBSET=E...
para  empezar  y  luego  pensar  sobre  posibles usos.  Como tú digas, amo y
señor...
=2
PR:=3 ¿ Alguna idea sobre s.m.c aplicado a C2P ?
=C

RE:=E  Joder, mamón, espérate que aun ni he empezado a ver los formatos de las
instrucciones...   no,  en  serio  ya,  pues sí, por lo que veo el número de
registro  de  datos  casi siempre va almacenado en los=D 3=E primeros bits de la
=DWORD =E descriptora.   Eso  podría ser interesante...  pensaré en que se puede
usar...
=2
Fecha:=3 30=4 de =3Septiembre=4 de=3 1996=2
Lugar:=3 Playas de California=2
Estado:=4   Preocupado...   mañana  empieza  el  instituto y...  ¡yo con estos
pelos!
=C
RP:=E   Vamos  a  ver...   si  en  vez  de  escribir en una=D PVC=E, crearamos una
pantalla  virtual  que  en  vez de bytes contenga mnemónicos=6 "en blanco"=E que
fuesen  rellenados al pintar=6 DIRECTAMENTE=E desde las rutinas chunky, entonces
luego  ejecutariamos  a partir de dicha pantalla y tendriamos el sistema más
rápido posible para hacer=D C2P=E, no habría bucles internos y reorganizando los
mnemónicos  ni  siquiera  habría  tiempos  muertos.   Pero  claro,  esto  es
utópico...   ¿  o no ?  Veamos, hasta donde podemos llegar y si estamos ante
un  método  práctico.   Esto  se  podría llamar algo así como=6 Conversión por
Pantalla de Código=E.
=C

XH:=E   No  hago  más  que  darle vueltas pero no sé por donde meterle mano...
mejor dejo lo del=D s.m.c=E por ahora.
=C
CO:=E  A otra cosa, mariposa...
=2
PR:=3 Te veo confuso, Xele. ¿ Sabes lo que tienes que hacer ?
=C
RE:=E   Sí,  en  resumidas cuentas se trata de convertir=D 32=E bytes consecutivos
=DChunky=E en=D 8=E registros de=D 32=E bits para copiarlos directamente a=D Planar=E, esto
sería en=D 256=E colores (=D8 =Eplanos).
=2
PR:=3 Entonces ¿ cuál es el problema ?
=C
RE:=E   Pues  que  no  quiero  hacer  el  típico  método  de las tablitas, los
enmascaramientos  y  los desplazamientos, sino algo más simple, más rápido y
que  gaste  menos memoria=6 (pues no pides tú ná, pringao)=E.  Y claro, no tengo
ni  puta  idea  de  cómo  hacer eso, y me estoy quedando pillado, así que me
aguantaré  y=6 empezaré haciendo una rutina facilita=E que no necesite consultar
tablas, supongo que al principio va a ser lenta pero da igual porque es sólo
para propósitos demostrativos, después iré optimizándola poco a poco.
=C
»»»»»»»»»»»»»»»»»»»»»»»»»»» RUTINA_C2P_1
=E
00004321000043210000432100004321=D ==E D2 =D(=E4 pixels chunky=D = =E32 bits=D)=E
=D |
=D V=E
44440000000000000000000000000000 D4 MASK=D ==E %11111000 o %00001000=D ($F8 o $08)=E
33330000000000000000000000000000 D5 MASK=D ==E %11110100 o %00000100=D ($F4 o $04)=E
22220000000000000000000000000000 D6 MASK=D ==E %11110010 o %00000010=D ($F2 o $02)=E
11110000000000000000000000000000 D7 MASK=D ==E %11110001 o %00000001=D ($F1 o $01)=E
=E
	MOVE.L	D2,D0	    =D  = =E(0000432100004321)(0000432100004321)
				     1       2         3       4
	AND.L  	D4,D0=D = =E	(0000400000004000)(0000400000004000)
				     1       2         3       4
 	SWAP    D0=D            = =E(0000400000004000)(0000400000004000)
				     3       4         1       2
	LSR.W   #1,D0 	    =D  ==E (00000400)(00000400)
       	              		      1         2
	MOVE.B	D0,D1	    =D  ==E (0000000000000000)(00000000)(00000400)=D ==E D1
		                                                  2
	LSR.W 	#7,D0 	    =D  ==E (00000000)(00004000)
			 	      0        1 
	OR.B    D0,D1	=D      ==E (0000000000000000)(00000000)(00004400)=D ==E D1
			                                         12
	SWAP	D0	   =D   ==E (0000040000000400)(0000400000004000)
				      1       2        3       4
	LSR.W	#3,D0	=D      ==E (0000000400000004)
				        3       4
	OR.B	D0,D1	   =D   ==E (0000000000000000)(00000000)(00004404)=D ==E D1
				                                 12 4	
	LSR.W	#7,D0	 =D     ==E (0000000000000040)
					       3
	OR.B	D0,D1	   =D   ==E (0000000000000000)(00000000)(00004444)=D = =ED1
				                                 1234=D
Los tiempos de ejecución en un 68030 son:
=E
2	MOVE.L	D2,D0
2	AND.L  	D4,D0
4	SWAP    D0
4	LSR.W   #1,D0
2	MOVE.B	D0,D1
4	LSR.W 	#7,D0
2	OR.B    D0,D1
4	SWAP	D0
4	LSR.W	#3,D0
2	OR.B	D0,D1
4	LSR.W	#7,D0
2	OR.B	D0,D1=D
--=E
36
=C
CO:=E   Teniendo  en  cuenta que éso es sólo para=D 4=E pixels y que para un plano
necesitamos  una=D  Long=E,  el  resultado final serían: =6 36*8 = 288 ciclos=E.  Lo
cual  es  extremadamente lento, ya que este tiempo es sólo el empleado en la
conversión,  luego  hay que añadirle las operaciones necesarias para mezclar
los  resultados  de=D  8 =E llamadas  a esta rutina en una sola=D LONG =Ey el tiempo
empleado  en copiar en la=D PFP=E.=6  Vamos, que la rutina tiene sólo una ventaja:
no  necesita  tablas=E.   Supongo  que  podría ser útil para intros de=D 4K =E(que
necesiten un =D040=E para rular=D ;-)=E o cosas por el estilo.

=2
Fecha:=3 31=4 de=3 Septiembre=4,=3 13:00=2
Lugar:=4 Aquí en mi cuarto con=3 Pamela Anderson=4...
=2Estado: =4  Empanado,  no  he  dormido  en toda la noche.  Nervioso, he ido al
instituto  y  me  he  enterado  de que me han puesto un horario que me viene
fatal.  Hambriento, ¡a ver ese papeo, mamá!
=C
XH:=E   Hola  a todos!, ayer estuve toda la noche sin poder pegar ojo y lo más
gracioso es que no se ni por qué, supongo que habrá algo en mi subsconciente
metiendo  la pata...  el caso es que a las tantas de la madrugada cogí papel
y  lápiz  y  me  puse a darle vueltas al =DC2P=E de nuevo=6 (creo que este tema me
tiene  obsesionado)=E  y  al final escribí otra nueva rutina que usa tablas de
conversión  más  simples  que  las  de la rutina de=D Peskanov=E, os la plasmo a
continuación:
=C

»»»»»»»»»»»»»»»»»»»»»»»»»»» RUTINA_C2P_2
=D
Al igual que en la anterior rutina:
=E
00004321000043210000432100004321=D = =D(4 pixels chunky=D = =E32 bits=D)
 |
 V=E
11110000000000000000000000000000    MASK=D ==E %00000001 =D==E $01
22220000000000000000000000000000    MASK=D ==E %00000010 =D==E $02
33330000000000000000000000000000    MASK=D ==E %00000100 =D==E $04
44440000000000000000000000000000    MASK=D ==E %00001000 =D==E $08
=C
Nota:=E   En  la  rutina  anterior  puse  las  mascaras de otra forma, pero en
realidad  lo  más  lógico  es  ponerlas  por el orden que uso aquí, de todas
formas eso no es un hecho muy importante.

Supongamos  que=D  PVC=E  está en=D A5=E y que vamos cogiendo datos de ahí.  Vamos a
ver  el  proceso  completo  de  conversión  de =D 32 =E pixels=D Chunky=E en la =DLONG=E
correspondiente al=D Plano 1=E en =DPFP=E.

	MOVE.L	#$01010101,D5

	MOVE.L	(A5),D0	   =D   	==E (0000432100004321)(0000432100004321)
					  1	  2         3       4
	AND.L  	D5,D0 	=D	= =E(0000000100000001)(0000000100000001)
					  1       2         3       4
	MOVE.W	D0,D1		=D= =E(0000000100000001)
					  3       4
	SWAP	D0=D		= =E(0000000100000001)
					  1       2
	LSL.W	#1,D0=D		==E (0000001000000010)
					 1       2
	OR.W	D1,D0	=D	= =E(0000001100000011)
					 13      24
=C
XH:=D D0=E actuará ahora como índice para consultar en la primera tabla:
=D
	MOVE.W	(a0,d0.l),d2
=C
XH:=E   Tengo  que explicar un poco esto de las tablas.  Veamos, como=D D0=E es el
índice  para acceder la tabla, dicha tabla tendrá que tener tantos elementos
como el máximo número que pueda contener=D D0=E, dicho número será:
=D
	(0000001100000011)  que en decimal es: 771
=C
CO:=E  Por tanto, habrá=D 771 =Eelementos, sin embargo, pasa algo curioso y es que
en  realidad  como  sólo  hay =D 4 =E bits  que se pueden combinar, sólo hay=D 2^4=E
combinaciones,  es  decir=D  16=E.   En  realidad  la  tabla  tiene=D 771-16 = 755=E
elementos vacios que nunca serán accedidos mientras=D D0=E sea el índice...
=2
PR:=3 ¿ y qué hacemos entonces con tanto espacio en blanco ?
=C
RE:=E  Pues nada, si quieres puedes aprovechar estos huecos metiendo los datos
de  otra  de  las  tabla.   De  todas formas, ten en cuenta que al ser estos
espacios  todo=D  0=E,=6 se va a comprimir una barbaridad=E, por tanto las tablas ni
se notan, pero siempre es mejor aprovechar al máximo la memoria...
=C
XH:=E   Bueno,  pues  aclarado  eso, sigo.  En realidad no hay una sóla tabla,
sino =D 4=E tablas diferentes.  Esto es por supuesto para una resolución de=D 1x1=E,
para=D  2x2=E  sólo  hay =D 2=E  tablas  diferentes,  y  como ya he dicho, se pueden
aprovechar  los espacios en blanco para meter una tabla dentro de otra.  Por
lo  cual  el  número  de  tablas  se puede reducir, lo que no se reduce, sin
embargo, es el número de consultas:
=C
 Resolución 1x1:=D 8 consultas (2 veces cada tabla)  (W,W,B,B -Swap- W,W,B,B)
=C Resolución 2x2:=D 4 consultas  (W,B -Swap- W,B) (las tablas difieren)
=C
XH:=E   Con cada consulta convertimos=D 4=E pixels, es por ello que se necesita=D 8=E
consultas  para  tener  los =D 32 =Ebits que conforman la=D LONG =Eque irá a parar a
=DPFP=E, y a cuento de eso viene lo de=6 (W,W,B,B, etc)=E,=D W=E significa que se accede
a  una  tabla  que nos devolverá un valor=D WORD =Econ un=D nibble=E ya convertido y
colocado  (y  esto  es importante) en la posición adecuada dentro de la=D LONG=E
que  irá  a=D  PFP=E.   En el caso de=D B =Equiere decir lo mismo, el valor devuelto
será  un  byte  listo para que se haga un=D OR=E o lo que sea conveniente.  Creo
que con un ejemplo se verá mejor:

Supongamos  un  caso  hipotético  en  el  que  todos  los  pixels  devueltos
estuvieran a =D1=E, así veréis claramente el funcionamiento:
=3
(Llamada) (Valor devuelto)	  (Evolución LONG PFP)=2
----------------------------------------------------------------------------=3
   1a=4	 W (11110000)(00000000)	  (00000000)(00000000)(11110000)(00000000)
 	=3				==4 D2=3
   2a	= W (00001111)(00000000)   (00000000)(00000000)(11111111)(00000000)
		=3			= =4OR.W 2a,D2=3
   3a =4   B (11110000)		  (00000000)(00000000)(11111111)(11110000)
			=3		= =4OR.B 3a,D2=3
   4a=4    B (00001111)             (00000000)(00000000)(11111111)(11111111)
			=3		= =4OR.B 3a,D2=2
 -Swap-		=4		  (11111111)(11111111)(00000000)(00000000)
			=3		= =4SWAP D2=3
   5a	=4 W (11110000)(00000000)	  (11111111)(11111111)(11110000)(00000000)
=3					= =4OR.W 5a,D2=3
   6a	=4 W (00001111)(00000000)   (11111111)(11111111)(11111111)(00000000)
		=3			= =4OR.W 6a,D2=3
   7a =4   B (11110000)		  (11111111)(11111111)(11111111)(11110000)
		=3			= =4OR.B 7a,D2=3
   8a=4    B (00001111)             (11111111)(11111111)(11111111)(11111111)
 			=3		= =4OR.B 8a,D2
=E




Como  se  puede  apreciar,  sólo  se trata de ir pillando valores y hacer=D OR=E
consecutivos  y un=D SWAP=E a la mitad del camino.  Realmente es algo muy simple
de programar y las tablas de consulta ocupan muy poca memoria:
=2
+  =3 2 tablas W = 772*2*2=2 ==3 3088 bytes
    2 tablas B = 772*2 =2  = =31544 bytes=2
---------------------------------------
                 Total   ==3 4632 bytes=4 (un poco más de 4 Kb)
=E
En  teoria  mezclando  las  dos  tablas de=D WORDS=E por un lado y mezclando las
otras  dos  tablas  de=D  BYTES =E por  otro, se podría reducir el consumo de la
memoria a la mitad, es decir=D 2 Kb=E.=6  ¿ Alguien da más ?=2

                                            (Sigue en el siguiente artículo)
