<html><head><style type="text/css"><!-- DIV {margin:0px;} --></style></head><body><div style="font-family:'times new roman', 'new york', times, serif;font-size:12pt"><div></div><div>Excelente Steven lo he entendido todo, muchas gracias por tu tiempo y esfuerzo :-D</div><div><br></div><div>Muchos saludos,</div><div>David Lastra.<br> </div><span><a target="_blank" href="http://xdrtas.coolpage.biz/">http://xdrtas.coolpage.biz/</a></span><br><span><a target="_blank" href="http://xdrtas.blogspot.com/">http://xdrtas.blogspot.com/</a></span><div><br></div><div style="font-family:times new roman, new york, times, serif;font-size:12pt"><br><div style="font-family:arial, helvetica, sans-serif;font-size:10pt"><font size="2" face="Tahoma"><hr size="1"><b><span style="font-weight: bold;">De:</span></b> Steven Davidson <srd4121@njit.edu><br><b><span style="font-weight: bold;">Para:</span></b> Lista de correo sobre C y C++
 <cconclase@listas.conclase.net><br><b><span style="font-weight: bold;">Enviado:</span></b> sáb,26 febrero, 2011 14:06<br><b><span style="font-weight: bold;">Asunto:</span></b> Re: [C con Clase] SDL operaciones bitwise y punteros.<br></font><br>Hola David,<br><br>On 2/26/2011 7:23 AM, David wrote:<br>> Steven, en serio muchísimasgracias<br>> <br><br>De nada; para eso estamos.<br><br>> (Uint16 *)p -> realiza el casting; una vez realizado el casting<br>> entonces que vuelva a apuntar a la dirección de memoria *p, juntando<br>> las dos cosas da como resultado la expresión *(Uint16 *)p.<br>> <br>> En base a esto, permíteme tratar de explicar la siguiente expresión:<br>> <br>> Nota: superficie->pixels está definido dentro de la estructura<br>> SDL_Surface como un puntero a void, o sea, "void *pixels".<br>> <br>> Uint8 *p = (Uint8 *)superficie->pixels + y * superficie->pitch + x *<br>>
 bpp;<br>> <br>> 1.- Se realiza el casting de (void *) a (Uint8 *) sobre el puntero<br>> superficie->pixels.<br>> 2.- Se multiplica x * bpp<br>> 3.- Se multiplica y * superficie->pitch<br>> 4.- Se suma el resultado del punto 2 y 3<br>> 5.- Y por último el resultado del punto 4 es sumado a la dirección de<br>> memoria de superficie->pixels.<br>> <br><br>Correcto.<br><br>> Otra forma de verlo sería así:<br>> Uint8 *p = (Uint8 *)superficie->pixels; //p apunta a la dirección<br>> superficie->pixels.<br>> p[ (y * superficie->pitch) + (x * bpp) ]; //obtener la dirección del<br>> pixel.<br>> <br><br>Esto último no es correcto. Recuerda que los corchetes [] son un operador de acceso. Aquí accederías al píxel del índice 'y*superficie->pitch + x*bpp'.<br><br>Sin embargo, esto no es lo que hacemos, sino que obtenemos la dirección de memoria que apunta a un píxel; o mejor dicho, a un
 'Uint8' que representa 1 solo byte.<br><br>> Así se obtiene la posición del pixel y nos permite luego ir a p[R],<br>> p[G] y p[B] sin mayor riesgo ya que para este caso cada uno de los<br>> pixeles está compuesto por 24 bits y p es de 8 bits, por lo que 8 x 3<br>> = 24. Entonces teniendo la posición del pixel en la superficie,<br>> podemos movernos entre los 24 bits que componen el pixel sin<br>> problemas debido a que R=0 G=1 B=2 son consecutivos.<br>> <br><br>Exacto.<br><br>> <br><br>[CORTE]<br><br>> Una pregunta más, la función GetPixel en mi arquitectura me devuelve<br>> [B, G, R], sin embargo cuando el resultado en una variable,<br>> llamemosle color, al verlo en hexadecimal me muestra [R, G, B]. El<br>> compilador hace una transformación de forma automática por ser<br>> little-endian?<br>> <br><br>Sí; claro. Al fin y al cabo, el compilador DEBE conocer la arquitectura del procesador al cual va a
 compilar y traducir el código fuente. Si usas un compilador para Intel, entonces debe saber que Intel usa "little-endian".<br><br>Ahora bien, al decir que "muestra" algo (en pantalla), entonces estamos hablando de las funciones, segurametne estándares, de las bibliotecas que controlan la consola (y la pantalla). Aquí, el compilador no tiene nada que ver, ya que esa funcionalidad ya está compilada, en la mayoría de los casos. Por consiguiente, si la función que usas muestra información, ésta puede ser diferente a su representación interna.<br><br>> Para que veas más claro a lo que me refiero te coloco la porción de<br>> código:<br>> <br>> //Defino el color que quiero mostrar en la pantalla o superficie...<br>> Uint32 color = SDL_MapRGB(pantalla->format, 255, 0, 0); //Color rojo..<br>> <br>> //Pinto el pixel del color rojo en la superficie:<br>> PutPixel(pantalla, 100, 100, color);<br>> <br>> //Obtengo el valor
 del color de la pantalla...<br>> Uint32 comprobar = GetPixel(pantalla, 100, 100); //Aquí se obtiene el<br>> valor rojo...<br>> <br>> //Muestro el valor hexadecimal de la variable "comprobar"...<br>> cout << "Valor hex: " << hex << comprobar << endl;<br>> <br>> El resultado que me da es:<br>> Valor hex: ff 00 00<br>> <br>> Sin embargo, si te fijas en el retorno de la función (return p[R] |<br>> p[G] << 8 | p[B] << 16;) lo que interpreto es lo siguiente<br>> <br>> Devuelve el rojo ff, desplázate 8 bits hacia la izquierda y devuelve<br>> el valor del verde 00, desplázate 16 bits y devuelve el valor de azul<br>> 00 dejando como resultado:<br>> <br>> 00 00 ff<br>> <br><br>Correcto, para una arquitectura de "little-endian", como es Intel.<br><br>> Y claro aquí me confundo porque una cosa es lo que estoy<br>> interpretando y otra muy distinta el valor real
 devuelto.<br>> ff 00 00 <> 00 00 ff<br>> <br><br>La explicación involucra, como he dicho anteriormente, en la funcionalidad de 'cout <<' pero ésta depende del tipo de dato que pases como parámetro. Al tratarse de un 'Uint32', se pasan los primeros 4 bytes contenidos en la variable, 'comprobar', que representan el número entero (no negativo). Por lo tanto, convierte correctamente el número 16711680 a hexadecimal: 0x00FF0000. Esto no tiene por qué representar los valores de cada byte en memoria. Por eso, el tipo de dato es muy importante en cuanto a la interpretación de las secuencias de bits y las operaciones que pueden involucrar esos valores.<br><br>En resumen, la secuencia de bytes: 0x00, 0xff, 0x00, y 0x00 es representada en memoria, en una arquitectura de "little-endian" como es Intel, como: 0x00, 0x00, 0xff, y 0x00. Su interpretación depende del tipo de dato:<br><br>- Si tratas esta secuencia como un entero (no negativo)
 de 32 bits, entonces el valor es: 16711680.<br>- Si tratas esta secuencia como dos números enteros (no negativos) de 16 bits cada uno, entonces los valores son: 0, y 255.<br>- Si tratas esta secuencia como cuatro números enteros (no negativos) de 8 bits cada uno, entonces los valores son: 0, 0, 255, y 0.<br><br>Puedes hacer esta comprobación realizando un cásting apropiado al puntero, 'p', o incluso a la variable 'comprobar'. Por ejemplo,<br><br>cout << "Como Uint32: " << hex << comprobar << endl;<br><br>Uint16 *p16 = ((Uint16 *)&comprobar);<br>cout << "Como Uint16: " << hex << p16[0] << ' ' << p16[1] << endl;<br><br>Uint8 *p8 = ((Uint8 *)&comprobar);<br>cout << "Como Uint8: " << hex<br>     << p8[0] << ' ' << p8[1] << ' ' << p8[2] << ' ' << p8[3] << endl;<br><br>> Un cordial saludo, y Steven de nuevo
 muchísimas gracias, cada vez<br>> entiendo más y mejor.<br>> <br><br>De nada.<br><br><br>Espero que lo anterior aclare más este tema.<br><br>Steven<br><br><br>_______________________________________________<br>Lista de correo Cconclase <a ymailto="mailto:Cconclase@listas.conclase.net" href="mailto:Cconclase@listas.conclase.net">Cconclase@listas.conclase.net</a><br><a href="http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net" target="_blank">http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net</a><br>Bajas: <a href="http://listas.conclase.net/index.php?gid=2&mnu=FAQ" target="_blank">http://listas.conclase.net/index.php?gid=2&mnu=FAQ</a><br></div></div><div style="position:fixed"></div>


</div><br>



      </body></html>