Al filo del mañana

Después de Godzilla, fui a ver Edge of Tomorrow.

Se aplican las de siempre.

Edge of Tomorrow

Edge of Tomorrow

En algún punto en el futuro, extraterrestes malos malos invaden la Tierra comenzando por Alemania, y avanzan inexorablemente hasta una batalla en Verdún, donde Emily Blunt les parte su mandarina en gajos a un montón de alienígenas, y el mando unido terrestre supone que es porque es muy chingona (además de bien mami), y por un exoesqueleto mecánico que inventan.

Tom Cruise es un pobre diablo experto en relaciones públicas, que al tronar su empresa se mete al ejército a falta de una mejor idea, y lo ponen a convencer al público de que todo está chingón. El jefe supremo de las fuerzas terrestres (un espectacular, aunque algo desperdiciado, Brendan Gleeson), decidiendo correctamente que es un cobarde, le ordena “cubrir” la contraofensiva terrestre mandándolo al frente. Tom Cruise trata de huir para no tener que hacerlo, y es prontamente arrestrado y degradado a soldado raso.

La famosa contraofensiva es un desastre; matan a mami Emily Blunt como a los cinco minutos, y Tom Cruise trata desesperadamente de sobrevivir, y de milagro consigue matar a un extraterrestre más feo que los normales, sólo para ser morido cuando queda bañado en su sangre. Inmediatamente, Tom Cruise “despierta” en el día anterior, y algunas repeticiones después por fin comprende que está reviviendo en el mismo lugar en el tiempo cada vez que lo matan.

La película es fabulosa; no voy a decir que es la mejor película de ciencia ficción que he visto en mucho tiempo, excepto que totalmente lo voy a decir, porque lo es. En particular, es como catorce millones de veces mejor que Oblivion, el último intento de Tom Cruise por hacer ciencia ficción.

Además, no sé si los productores así lo planearon, pero esta película refleja perfectamente cómo muchas veces trata con videojuegos: Vive. Muere. Repite.

Yo sé que mucha gente detesta a Tom Cruise, por estar loco y pertenecer a un culto criminal. Y ciertamente está loco, y pertenece a un culto criminal: pero también es de los actores más profesionales de Hollywood, y siempre le echa muchas ganas a sus películas, aún cuando sean unos churrotes. Así que dejen eso de lado, y vayan a ver Edge of Tomorrow, porque está súper chida.

No quiero tener envidia

Comencé a armar mis propias computadoras (que no fueran laptops) hace más o menos quince años. Casi desde la primera que tuve la oportunidad de decidir qué tendría, le puse una tarjeta de video Nvidia; lo hice de manera impulsiva, porque entonces todavía estaba verde, y no verifiqué que la tarjeta estuviera soportada por Linux. De manera fortuita, Nvidia (la compañía) sacó justo por esos tiempos su primer controlador para Linux, lo que me salvó la vida porque de otra manera no hubiera podido correr X. Era una Nvidia RIVA TNT2, que me imagino muchos de mis contemporáneos conocieron.

A partir de ese momento todas mis computadoras de escritorio (y varias de mis laptops) tuvieron tarjeta de video Nvidia; y cada vez que compré una nueva, era mucho más poderosa que la anterior. He de haber tenido del orden de 5 o 6 tarjetas Nvidia; la última fue una GT 8800, que en su momento era ruda, aunque no de las más rudas.

Como estoy trabajando de nuevo (quiero decir, además de dar clases), y me están pagando relativamente bien, decidí actualizar mi computadora de escritorio, que hacía años no la había modificado. Por primera vez en mi vida, armé la computadora sin una tarjeta de video Nvidia.

Las razones son múltiples; en mis varias estancias de investigación en Europa, Canadá y Estados Unidos, trabajé únicamente con laptops, que desde hace años he comprado únicamente con las tarjetas de video Intel integradas, porque con tarjetas de video Nvidia el precio aumentaba considerablemente, y la vida de la batería disminuía casi en la misma proporción. Rápidamente comencé a apreciar que en Linux las cosas de Intel generalmente funcionan sin que uno tenga que hacer absolutamente nada, y que su desempeño ha ido mejorando lenta, pero inexorablemente.

En cambio los controladores binarios de Nvidia han tenido un comportamiento errático desde hace años; de repente funcionan de manera impecable, para luego comenzar a dar broncas que es medio imposible descifrar. Su tamaño ha también aumentado de forma ridícula a lo largo de los años; la última versión mide 67 megabytes comprimidos, y un montón de eso termina ejecutándose en la memoria del kernel.

Que fue la otra cosa que comenzó a molestarme; durante más de una década le he estado dando mi dinero a Nvidia, y la compañía no ha hecho nada en lo más mínimo para abrir el código de sus tarjetas a los programadores de Linux (lo que llevó a Linus a decirle a Nvidia que chingaran a su madre).

Así que ahora que actualicé mi máquina, decidí que suficiente era suficiente, y decidí utilizar el GPU integrado de Intel en mi Core i7.

La verdad, estoy encantado. Al igual que en mis laptops, funciona de pelos sin que yo tuviera que hacer nada, y el desempeño es igual (y en algunos casos, mejor) que el de Nvidia para mi escritorio GNOME. Me refiero al uso normal del escritorio, incluyendo reproducción de video y las ligeras animaciones que se incluyen. Para OpenGL en bruto, sin duda Nvidia le gana; pero yo realmente ya no juego en mi PC, sólo en mi PlayStation 3, así que no es gran pérdida.

Y desde el punto de vista tecnológico aparentemente no importa, pero ideológicamente sí me alegra que mis computadoras Linux ya todas tienen controladores que son software libre. Y digo que en lo tecnológico es aparente que no importa, porque me parece que al final sí importa; hace años que no tengo ningún problema con mis tarjetas de video Intel, y no puedo decir lo mismo de las Nvidia.

Si por alguna razón llego a necesitar poder OpenGL en bruto, voy a comprarme una Radeon (que también ofrece controladores de software libre), y si sólo necesito OpenGL “normal”, Intel me basta y sobra.

A partir de ahora, ya no quiero tener envidia.

Godzilla

Hace unos meses vi Godzilla. Se aplican ya saben.

Godzilla

Godzilla

Yo nunca he sido gran fan de Godzilla. En general mostros que consisten de un pobre güey dentro de un traje de plástico me resultan más bien risibles. Dicho eso, esta película es como que una infinidad de veces mejor que la de 1998, que tampoco tenía a un pobre güey dentro de un traje de plástico. Aunque claro, no es muy difícil superar la última versión del siglo pasado.

La película no tiene (ni hace) mucho sentido, y el titular mostro aparece como quince minutos en ella (y es posible que esté siendo generoso). Toda la historia es dolorosamente previsible en cada una de sus escenas, incluyendo aquellas que uno no ve venir. Los personajes son completamente bidimensionales, y Bryan Cranston tiene el descaro de morirse después de como media hora (y de nuevo es posible que esté siendo generoso)… y Juliette Binoche a los diez minutos. Kick-Ass no le patea el trasero a nadie.

Pero es altamente entretenida, y cuando el viejo (en todos los sentidos de la palabra) lagarto aparece en la pantalla y da su espectacular rugido, el pinche cine se calló por completo porque no mamen qué chingona escena. Y sé que a muchos no les gustó, pero cuando Godzilla vomita radiación azul sobre el otro mostro, yo me vine un poquito porque pues así soy yo.

No estoy seguro de que esas dos escenas justifiquen las dos horas de película, pero pues la verdad no me arrepiento de haberla visto en el cine. Ah, y me resultó simpático que, desde esta primer entrega, Godzilla sea casi desde el inicio considerado uno de los “buenos”.

Así que véanla, porque es probable que hagan unas cuarenta y tres secuelas.

Como Pedro por su casa

Como comentaba hace unos días, leí de nuevo Cien años de soledad. El punto de esta entrada es cómo lo leí; inicialmente no pensaba leerlo, sólo quería la cita que andaba buscando. Lo que hice fue lo que he hecho en otras ocasiones: me puse a buscar un PDF pirata de la novela.

He comprado Cien años de soledad varias veces en mi vida, generalmente para regalarlo, porque me parece trágico cuando encuentro a alguien que no la ha leído; no siento el menor remordimiento de conciencia de también haberlo conseguido (en múltiples ocasiones) de forma pirata en PDF, generalmente justo porque quiero una cita exacta.

Pero esta vez no pude, así que me metí a Google Play y lo compré en 89 pesotes. No me arrepiento en lo más mínimo; si hay libros que quiero tener siempre disponibles en mis dispositivos ligados a mi cuenta de Google, Cien años de soledad es sin duda alguna el primero en la lista. Me sacó un poco de onda que le piqué a “Comprar”, y Google lo hizo de inmediato, sin en ningún momento pedir mis datos o una contraseña. Ya había comprado antes ahí, así que no es que sacaran los datos de mi tarjeta de crédito del éter; pero de todas maneras fue ligeramente desconcertante picarle “Comprar”, y que Google alegremente me informara que ya tenía un nuevo libro en mi tableta, y que el cargo correspondiente a mi tarjeta de crédito ya se había realizado. Se metió a mi cuenta de banco como Pedro por su casa.

No me preguntó ninguna contraseña, ningún dato, un CCV, nada. Sólo de repente Google agarró y se metió en mi cuenta del banco y dijo “banco, dame dinero”, y el banco dijo “chingón”, y yo quedé 89 pesos más pobre, pero con una versión digital bastante bonita de la obra maestra de Gabo.

Como ya dije, no me arrepiento. Sólo no me gusta tanto la idea de que gastar dinero sea tan sencillo en un dispositivo amarrado a mi tarjeta de crédito.

El lector de libros digitales de Google está poca madre; en mi Nexus 7 al pasar las páginas, hay una animación como si uno literalmente pasara la página. Hay marcadores, se pueden hacer anotaciones, búsquedas, y hasta donde pude ver no tenía un solo error la edición; lo más que puedo quejarme es que de repente una “página” se quedaba en blanco a la mitad, para continuar en la siguiente. No tengo idea de por qué; un error en el algoritmo espaciador de párrafos, me imagino.

Leer en el Nexus 7 es la neta; mucho más ligero que un libro y sin problemas de iluminación (ya sea en la calle o bajo techo). Por supuesto ya había leído PDFs antes; pero este es el primer libro digital que de hecho compré, y debo admitir que me apantalló bastante. Estoy pensando seriamente comprar otros libros usando Google Play; lamentablemente, muchos de los que me interesan son en inglés, y no tengo ni puta idea de cómo conseguirlos en su idioma original. Google Play sólo me ofrece versiones en español.

Si logro resolver eso, voy a comenzar a hacerme de una copiosa biblioteca digital.

El Gran Hotel Budapest

Después de ver 12 Years a Slave, fui con mi mamá a ver The Grand Budapest Hotel. Se aplican las de siempre, si es que acaso no la han visto.

The Grand Budapest Hotel

The Grand Budapest Hotel

Antes de empezar a hablar de esta película, quiero hacer la mención de que yo jamás en mi vida había visto una película de Wes Anderson, hasta a inicios de este año o finales del anterior (la memoria me falla al respecto).

Recuerdo que me recomendaron ampliamente The Royal Tenenbaums, y que yo tenía ganas de ver The Life Aquatic with Steve Zissou (en gran medida porque soy fan de Bill Murray); pero por alguna razón nunca vi ninguna de las dos. Aunque había oído críticas favorables, la verdad no tenía mucho interés en ver nada de Anderson por él mismo.

Todo esto cambió cuando mi mamá (yo no, mi mamá) rentó Moonrise Kingdom, y me convenció de verla (la verdad, no se me antojaba tanto de los avances). La película me dejó completamente bañado de asiento: dícese, anonadado.

Se ha convertido rápidamente en una de mis películas favoritas; me parece espectacular en casi todos los aspectos. Y aunque el hecho de que aparezcan varios de mis actores favoritos (Bruce Willis, Edward Norton, Bill Murray, Frances McDormand y Harvey Keitel, por mencionar a algunos) no le hace daño, son los dos jóvenes protagonistas, y el candor y verosimilitud con el cual interpretan su inocente romance, los que hicieron que me enamorara de esta película.

Si no fuera porque no he tenido tiempo (y, hasta recientemente, tampoco dinero), ya habría visto todas las películas de Wes Anderson.

Como sea, vi con mi mamá The Grand Budapest Hotel. Podría tratar de hacer una sinopsis de la trama, pero no le veo mucho sentido; es una mamada, como probablemente también podría categorizarse la trama de Moonrise Kingdom. Lo importante es que está bonita, magistralmente actuada (especialmente por Ralph Fiennes y Tony Revolori), y es delirantemente hilarante la mayor parte del tiempo (Agatha, interpretada por la maravillosa Saoirse Ronan, tiene un lunar en la mejilla con la forma de la República Mexicana… porque por qué no).

Así que váyanla y véanla; pero también vean Moonrise Kingdom, porque me sigue gustando más.

Los años de soledad

Ahora que me encuentro soltero una vez más, comencé a leer de nuevo Cien años de soledad. Lo hago al menos cada dos o tres años, desde que tengo ocho años; pero esta vez fue precipitado porque andaba buscando la cita exacta de la entrada pasada. Tuve que hojear el libro buscando la cita (ya sabía cuál, sólo no recordaba las palabras exactas), y pues terminé por empezar a leerlo de nuevo.

Como el nombre de la novela indica, la característica principal de la historia es la soledad al parecer genética de los Buendía; el aire de soledad de la familia. Exceptuando a José Arcadio Buendía y Úrsula Iguarán, los patriarcas de la extirpe, ninguna pareja que se ame realmente consigue tener un hijo que sobreviva: el coronel Aureliano Buendía y Remedios Moscote se amaban, pero sus gemelos mueren al momento de su nacimiento (y de paso matan a su madre, y desencadenan la serie de eventos que causa que el coronel inicie 32 guerras civiles, todas fallidas); Jose Arcadio y Rebeca se amaban, pero nunca tuvieron un hijo; Aureliano Segundo y Petra Cotes se amaban también, pero tampoco pudieron tener un hijo… y así durante cien años, hasta que Aureliano Babilonia y Amaranta Úrsula tienen al fatídico niño con cola de puerco, que es devorado por las hormigas por la negligencia de su padre.

Casi todos los Buendía entonces son engendros de uniones generalmente fortuitas y sin amor real o duradero, condenados a la soledad que los persigue durante toda la vida.

Gabo describe la soledad básicamente como el peor estado de la condición humana. En el mejor de los casos, los Buendía consiguen llevar una existencia semifuncional dentro de la aplastante soledad, como el coronel Aureliano Buendía en sus años de vejez, haciendo pescaditos de oro; o Amaranta bordando y recociéndose en sus rencores contra Rebeca, contra Pietro Crespi, contra el coronel Gerineldo Márquez, contra todos los sobrinos a los que abusó sexualmente. Otros se pudren en vida dentro de su soledad, como José Arcadio Segundo reviviendo toda la vida la matanza de las bananeras, o Meme en un hospital de Cracovia, añorando a Mauricio Babilonia.

Aureliano José es un personaje interesante en ese aspecto. No sólo es el único que combina los nombres de los hijos varones de los patriarcas; también es el único que supera de forma mental y emocionalmente sana los abusos sexuales de Amaranta; es el único que regresa de la guerra sin haber sido destruido interiormente por ella; y finalmente es el único que pudo haber sido feliz, engendrando siete hijos con Carmelita Montiel, muriendo en sus brazos de viejo, si la bala destinada al capitán Aquiles Ricardo no le hubiera destrozado el pecho.

Yo no concuerdo con Gabo. Tampoco me voy a ir al extremo de decir que estar solo es lo mejor del universo (he pasado mi justa cuota de años de soledad para saber que esto no es cierto); pero sí creo que a veces es lo que uno necesita.

No sé cuánto tiempo vaya a estar solo esta vez; uno nunca lo sabe (y es parte de lo divertido), pero incluso si termina siendo mucho tiempo, creo que trataré de disfrutar los años de soledad que me toquen en esta ocasión.

12 años de esclavo

Después de tener una buena racha actualizando mi blog, durante casi todo agosto estuve en chinga haciendo Cosas Muy Importantes®. El lunes de hecho terminé con eso, pero entonces tuve que ponerme al día con todo lo que dejé de hacer durante tres semanas.

Como sea; después de ver The Amazing Spider-Man 2, fui a ver con Mina 12 Years a Slave.

No se aplica nada, porque me imagino que ya todo mundo la vió.

12 años de esclavo

12 años de esclavo

La película me gustó mucho, obviamente; es básicamente impecable en todos los aspectos obvios (dirección, actuación, producción, escenografía, vestuarios, etc.) Y sin embargo, es algo irónico que una película que retrata de manera brutalmente directa el crimen de los Estados Unidos de construir gran parte de su poderío económico sobre la espalda de negros esclavos, tenga un póster como el de arriba.

Si no lo alcanzan a leer, la lista de actores es:

  1. Chiwetel Ejiofor
  2. Michael Fassbender
  3. Benedict Cumberbatch
  4. Paul Dano
  5. Paul Giamatti
  6. Lupita Nyong’o
  7. Sarah Paulson
  8. Brad Pitt
  9. Alfre Woodard

Nueve actores listados en el póster de una película denunciando la injusticia contra los negros. Y de esos nueve actores, únicamente dos son negros. Uno es el principal, porque no podía ser de otra forma (es la historia de un esclavo). La otra es la maravillosa (y de rebote mexicana) Lupita Nyong’o… que aparece debajo de Paul Giamatti, aunque el personaje de ella sea mucho más importante y aparezca mucho más tiempo y actúe mucho mejor ella que él.

Ese póster dice mucho más acerca de la situación racial en los Estados Unidos que la misma película; explica cosas como lo que pasó en Ferguson, Missouri las semanas pasadas. Han avanzado los gringos, les concedo eso; pero están muy lejos de pagar sus crímenes contra la humanidad que vivía en su mismo suelo (después de robárselo a los indios, por supuesto).

Me encontré un artículo fascinante hace unas semanas, y les recomiendo que lo lean si tienen tiempo; me parece que es un análisis muy interesante del sur “profundo” gringo: Not a Tea Party, a Confederate Party.

Regresando a la película; sí, está padre. Pero no es una historia de un “trágico” pasado que ha quedado atrás; es una historia de un pasado que los sigue permeando hasta nuestros días.

La colección de trofeos

(Esta entrada es la octava parte de una serie que cubre un proyecto personal que realicé en el verano de 2014; pueden ver todas las partes aquí).

Mi hermano me regaló mi PlayStation 3 hace casi seis años en 2008. Lo primero que hice fue ir y comprar GTA4, como lo relaté en esta entrada. Al final de la misma comentaba que me interesaba comprar Rock Band o Guitar Hero, y de hecho la actualicé (no sé exactamente cuánto después, pero debieron ser un par de días) para comentar que ya había comprado una guitarra de plástico y el primer Rock Band.

Al inicio no utilicé mucho mi PS3; avancé bastante en GTA4 (aunque no lo acabé), y jugué mucho Rock Band (aunque básicamente jugando nada más las canciones que conocía y me gustaban), pero un par de meses después me fui a mi primera estancia de investigación en Europa, y mi PlayStation 3 acumuló polvo durante tres meses.

Cuando regresé a México, mi PS3 pasó a ser usado principalmente como reproductor de películas Blu-ray durante los próximos dos años; continué jugando Rock Band, y terminé la historia de GTA4 (después de reiniciarlo porque ya se me había olvidado lo que llevaba), pero sin duda alguna lo que más hice con mi consola fue ver películas.

En retrospectiva, esto es por la naturaleza de cómo me gusta consumir medios: estoy básicamente loco. Lo cual por supuesto no debería sorprender a nadie.

Me gusta consumir cultura popular de forma ligeramente obsesiva; tengo que leer todos los libros de una serie (Harry Potter, Dunas, el legendario de Tolkien, la serie de Fundación de Asimov, Terramar de Ursula K. Le Guin, y un largo etcétera); tengo que ver todas las películas de una serie (demasiadas como para listarlas); tengo que ver todos los capítulos de una serie de televisión (ídem); etc., etc.

No me queda claro por qué hago esto; sencillamente así es. Nota interesante; es posible que esta sea la razón por la cual la música no juega un papel más importante en mi vida: casi por definición, su naturaleza es no serial, y generalmente no tiene una “historia” no trivial. Lo que sí, es que cuando una canción me gusta, suelo escucharla unas catorce millones de veces seguidas antes de pasar a otra.

Ahora, muchos videojuegos (incluyendo varios que me han encantado) tienen una única parte, así que a primera vista no es trivial encontrar la conexión entre ellos y mi consumo de medios seriales.

A lo mejor estoy inventándome cosas, o intelectualizando alguna otra obsesión mía, pero creo que el equivalente que tengo con videojuegos es que me gusta jugar todo el videojuego. Me explico: los videojuegos modernos son (en general) tan grandes, que es posible (y de hecho ocurre casi siempre) terminar la historia, sin haber descubierto gran parte del videojuego. Aunque viene ocurriendo desde hace décadas; Super Mario Bros. y muchos de sus contemporáneos tenían niveles secretos, easter eggs, y otras cosas del estilo.

Recuerdo claramente cuando acabé la historia de GTA 4, que me quedé con la impresión de que quedaba muchísimo por descubrir de Liberty City, y que no sabía exactamente cómo continuar. Y no digamos en Rock Band, donde para motivos prácticos no hay historia.

Supongo que pude haber continuado así el resto de mi vida, usando principalmente mi PS3 para ver películas, y jugando de vez en cuando uno que otro GTA o juego musical, hasta un día que en su casa, Juan me enseñó el demo de God of War III. Es chistoso, porque todas mis manías se conjugaron para que yo acabara persiguiendo trofeos.

Como comenté en otra entrada, después de que Juan me enseñara el demo, yo llegando a mi casa lo bajé y casi casi lo memoricé. Es un gran juego, así que decidí que lo compraría y lo jugaría y lo acabaría.

Sólo había un pequeño detalle. Era God of War III… yo no podía ponerme a jugar la tercera parte del juego si no había jugado las otras dos antes. Por… razones.

Así que fui a comprar GoW1, que por suerte venía en paquete con GoW2. Me chuté el primero, y me encantó, así que lo jugué de hecho varias veces, y luego me eché los retos de los dioses, y cuando me di cuenta, me faltaban un par de trofeos en el juego para obtener mi platino. Mi primer platino. Y luego me chuté GoW2, y obtuve mi segundo platino.

Y entonces vi una manera de acallar a las voces en mi cabeza que exigen sacrificios paganos si no consumo algo al 100%: los trofeos, en general, me permiten disfrutar un juego al 100%; ver todos sus secretos, ver toda la historia, y matar hasta la última paloma. No voy a explicar eso último.

A partir de ese momento, decidí que obtendría el 100% de los trofeos de todos mis juegos, así me llevara años. Y luego salí de México, por lo que de hecho comenzar a hacer esto tuvo que esperar seis meses.

Debo hacer hincapié que yo no me considero trophy hunter. No me he puesto a comprar juegos facilísimos sólo para poder tener más trofeos de platino (al parecer a Hannah Montana: The Movie es muy fácil sacarle el platino), ni he dejado de jugar juegos sólo porque sus trofeos sean muy difíciles (tengo el 100% de trofeos en GTA4 y WipeOut HD; todo mundo está de acuerdo en que son de los juegos más difíciles de completar sus trofeos).

Sí me he negado a jugar algunos juegos porque ya no se pueden sacar el 100% de trofeos; FIFA 09, que venía con mi PS3, es un ejemplo: los servidores en línea dejaron de funcionar en 2011, así que sencillamente no tengo un solo trofeo de ese juego. Que la verdad, fue suerte borracha; según yo sí lo llegué a jugar, pero por alguna razón nunca se registró un trofeo del mismo en mi cuenta. A lo mejor sólo fui muy malo al jugar.

Como sea, los juegos que no se pueden completar sus trofeos son en general pocos, y además de hecho no me interesan mucho.

No me llevó mucho tiempo descubrir que alcanzar el 100% de trofeos en mis juegos era no sólo posible, sino de hecho humanamente realizable. Podía completar el 100% de mi colección trofeos con algo de esfuerzo, en todos y cada uno de mis juegos.

Excepto por los musicales. Pero de esos escribiré luego.

El Sorprendente Hombre Araña 2

Hace unos meses Mina y yo fuimos a ver The Amazing Spider-Man 2.

Se aplican las de siempre, pero como ya la vieron, no importa.

The Amazing Spider-Man 2

The Amazing Spider-Man 2

Esta película tiene serios problemas, y el menor de ellos no es que sea la quinta película de Spidey en doce años.

La historia se tambalea entre Preter y Gwen, Peter y el misterio de sus padres, Spidey peleando contra tres distintos enemigos, y la introducción de demasiados personajes como para darle a ninguno el tiempo que merece.

El guión, con nueve distintos autores acreditados (sepan cuántos más le metieron mano sin crédito), es un desastre absoluto, y el diálogo, desarrollo de personajes, coherencia de la historia, y otros etcéteras, sufre consecuentemente.

Y yo, como Luz Casal no me importa nada; la película me encantó. Es un accidente de trenes en cámara lenta, pero de cualquier forma es altamente entretenida.

Andrew Garfield continúa siendo perfecto como Spidey; desde el sentido de humor fácil hasta la angustia adolescente idiota, Garfield encarna a Peter Parker como Tobey Maguire jamás hubiera podido. Y ni hablemos de Emma Stone como Gwen Stacy; es idéntica en espíritu (y más que pasable físicamente) a su contraparte en los cómics, y la escena de su muerte (hey, advertí de spoilers) es básicamente igual la versión impresa, incluyendo (graciosamente, por eso de la ciclicidad de la moda) el vestuario.

Jamie Foxx en cambio no tiene casi nada que ver con el Electro de los cómics, pero eso es de hecho algo bueno; convierte un personaje más bien intrascendente en un villano realmente temible. A Dane DeHaan le cometieron el crimen de sacarse los antecedentes de su personaje de la manga, y de darle los peores diálogos que he visto en mucho tiempo; pero el muchacho (que me encanta como villano desde que vi Chronicle), consigue rescatar una actuación decente de las migajas que le dieron. Incluso Felicity Jones y Paul Giamatti, con sus trece segundos combinados en la pantalla, consiguen dejar una agradable impresión de sus personajes, y con ganas de volverlos a ver.

Así que esta película es en gran medida paradójica; es mala, pero entretenida; con un pésimo guión, pero excelentes actuaciones; e increíblemente apresurada en su producción, pero preparando el terreno para, esperemos, mucho mejores secuelas.

Así que véanla; me parece que vale la pena, si no por otra cosa por las posibilidades que da a secuelas maravillosas, si los productores de Sony consiguen sacar sus cabezas de sus respectivos traseros.

12ba:0200

(Esta entrada es la séptima parte de una serie que cubre un proyecto personal que realicé en el verano de 2014; pueden ver todas las partes aquí).

El dispositivo USB-HID con identificador de vendedor 0x12ba e identificador de producto 0x0200 (y que por lo tanto aparece como 12ba:0200 al invocar lsusb) tiene el siguiente reporte descriptivo en C:

0x05, 0x01,       /* Usage Page (Generic Desktop Controls) */
0x09, 0x05,       /* Usage (Gamepad) */
0xa1, 0x01,       /* Collection (Application) */
0x15, 0x00,       /*   Logical Minimum (0) */
0x25, 0x01,       /*   Logical Maximum (1) */
0x35, 0x00,       /*   Physical Minimum (0) */
0x45, 0x01,       /*   Physical Maximum (1) */
0x75, 0x01,       /*   Report Size (1) */
0x95, 0x0d,       /*   Report Count (13) */
0x05, 0x09,       /*   Usage Page (Button) */
0x19, 0x01,       /*   Usage Minimum (Button 1) */
0x29, 0x0d,       /*   Usage Maximum (Button 13) */
0x81, 0x02,       /*   Input 2 (Data, Variable, Abs) */
0x95, 0x03,       /*   Report Count (3) */
0x81, 0x01,       /*   Input 1 (Data, Var, Abs) */
0x05, 0x01,       /*   Usage Page (Generic Desktop) */
0x25, 0x07,       /*   Logical Minimum (7) */
0x46, 0x3b, 0x01, /*   Physical Maximum 315 */
0x75, 0x04,       /*   Report Size (4) */
0x95, 0x01,       /*   Report Count (1) */
0x65, 0x14,       /*   Unit 20 (English rotation, degrees) */
0x09, 0x39,       /*   Usage (Hat switch) */
0x81, 0x42,       /*   Input 66 (Data, Var, Abs,Null) */
0x65, 0x00,       /*   Unit (None) */
0x95, 0x01,       /*   Report Count 1 */
0x81, 0x01,       /*   Input (Const, Array, Abs) */
0x26, 0xff, 0x00, /*   Logical Maximum 255 */
0x46, 0xff, 0x00, /*   Physical Maximum 255 */
0x09, 0x30,       /*   Direction-X 48 */
0x09, 0x31,       /*   Direction-Y 49 */
0x09, 0x32,       /*   Direction-Z 50 */
0x09, 0x35,       /*   Rotate-Z 53 */
0x75, 0x08,       /*   Report Size 8 */
0x95, 0x04,       /*   Report Count 4 */
0x81, 0x02,       /*   Input 2 (Data, Var, Abs) */
0x06, 0x00, 0xff, /*   Usage Page 65280 (null) */
0x09, 0x20,       /*   Usage 32 (null) */
0x09, 0x21,       /*   Usage 33 (null) */
0x09, 0x22,       /*   Usage 34 (null) */
0x09, 0x23,       /*   Usage 35 (null) */
0x09, 0x24,       /*   Usage 36 (null) */
0x09, 0x25,       /*   Usage 37 (null) */
0x09, 0x26,       /*   Usage 38 (null) */
0x09, 0x27,       /*   Usage 39 (null) */
0x09, 0x28,       /*   Usage 40 (null) */
0x09, 0x29,       /*   Usage 41 (null) */
0x09, 0x2a,       /*   Usage 42 (null) */
0x09, 0x2b,       /*   Usage 43 (null) */
0x95, 0x0c,       /*   Report Count 12 */
0x81, 0x02,       /*   Input 2 (Data, Var, Abs) */
0x0a, 0x21, 0x26, /*   Usage 9761 (null) */
0x95, 0x08,       /*   Report Count 8 */
0xb1, 0x02,       /*   Feature 2 (Data, Var, Abs) */
0x0a, 0x21, 0x26, /*   Usage 9761 (null) */
0x91, 0x02,       /*   Output 2 (Data, Var, Abs) */
0x26, 0xff, 0x03, /*   Logical Maximum 1023 */
0x46, 0xff, 0x03, /*   Physical Maximum 1023 */
0x09, 0x2c,       /*   Usage 44 (null) */
0x09, 0x2d,       /*   Usage 45 (null) */
0x09, 0x2e,       /*   Usage 46 (null) */
0x09, 0x2f,       /*   Usage 47 (null) */
0x75, 0x10,       /*   Report Size 16 */
0x95, 0x04,       /*   Report Count 4 */
0x81, 0x02,       /*   Input 2 (Data, Var, Abs) */
0xc0              /* End_Collection */

Como lo hice con el DualShock 3, veámoslo por partes.

0x05, 0x01,       /* Usage Page (Generic Desktop Controls) */
0x09, 0x05,       /* Usage (Gamepad) */
0xa1, 0x01,       /* Collection (Application) */

Comienza igual que el DualShock 3, la única diferencia es que se identifica como gamepad, no como joystick. La verdad en estos días, para una computadora (incluyendo al PlayStation 3), no existe realmente diferencia entre joystick y gamepad; ambos tienen 2 o más ejes, y un montón de botones.

0x15, 0x00,       /* Logical Minimum (0) */
0x25, 0x01,       /* Logical Maximum (1) */
0x35, 0x00,       /* Physical Minimum (0) */
0x45, 0x01,       /* Physical Maximum (1) */
0x75, 0x01,       /* Report Size (1) */
0x95, 0x0d,       /* Report Count (13) */
0x05, 0x09,       /* Usage Page (Button) */
0x19, 0x01,       /* Usage Minimum (Button 1) */
0x29, 0x0d,       /* Usage Maximum (Button 13) */
0x81, 0x02,       /* Input 2 (Data, Variable, Abs) */

Esta parte codifica 13 botones (“Report Count (13)”) binarios (“Report Size (1)”), no “analógicos”; o sea, el dispositivo sólo avisa si uno de estos botones está o no apachurrado, no da información acerca de qué tanto lo está apretando el usuario.

0x95, 0x03,       /* Report Count (3) */
0x81, 0x01,       /* Input 1 (Data, Var, Abs) */

Luego el dispositivo mete tres bits de relleno (padding); de esta manera, los primeros dos bytes que envía el dispositivo (13 + 3 = 16 bits = 2 bytes), llevan la información de qué botones están o no presionados. Obviamente, 1 (bit prendido) significa que el botón está apretado, y 0 (bit apagado) que no lo está.

0x05, 0x01,       /* Usage Page (Generic Desktop) */
0x25, 0x07,       /* Logical Minimum (7) */
0x46, 0x3b, 0x01, /* Physical Maximum 315 */
0x75, 0x04,       /* Report Size (4) */
0x95, 0x01,       /* Report Count (1) */
0x65, 0x14,       /* Unit 20 (English rotation, degrees) */
0x09, 0x39,       /* Usage (Hat switch) */
0x81, 0x42,       /* Input 66 (Data, Var, Abs,Null) */
0x65, 0x00,       /* Unit (None) */
0x95, 0x01,       /* Report Count 1 */
0x81, 0x01,       /* Input (Const, Array, Abs) */
0x26, 0xff, 0x00, /* Logical Maximum 255 */
0x46, 0xff, 0x00, /* Physical Maximum 255 */

Luego vienen 4 bits (“Report Size (4)”, “Report Count (1)”) que codifican el “hat switch“, la crucecita que tienen casi todos los gamepads que sirven para mover a Mario a la derecha, izquierda, que se agache, o que se meta al tubo del techo después de brincar.

Siendo yo programador, yo hubiera esperado que cada bit codificara una de las cuatro direcciones; algo como 0001 = norte, 0010 = sur, 0100 = este, 1000 = oeste, y 0000 que el usuario no está tocando ninguna… o algo del estilo. Esto también permitiría las combinaciones pertinentes: 0101 sería noreste, etc.

Los ingenieros que diseñaron esto, sin embargo, se les ocurrió que lo que tenía sentido es que 0000 fuera norte, 0001 noreste, 0010 este, 0011 sureste, 0100 sur, 0101 suroeste, 0110 este, 0111 noreste, y 1000 nada presionado. Siendo honesto, la verdad esto puede venir desde el estándar USB-HID, pero como no lo leí completo, no tengo idea. De cualquier forma, me suena a algo que se le ocurriría a un ingeniero.

Al definir el máximo como 255, se le asignan 8 bits al hat switch, así que 4 de ellos quedan también como relleno.

0x09, 0x30,       /* Direction-X 48 */
0x09, 0x31,       /* Direction-Y 49 */
0x09, 0x32,       /* Direction-Z 50 */
0x09, 0x35,       /* Rotate-Z 53 */
0x75, 0x08,       /* Report Size 8 */
0x95, 0x04,       /* Report Count 4 */
0x81, 0x02,       /* Input 2 (Data, Var, Abs) */

Parecido al DualShock 3, este gamepad define dos joysticks con dos ejes cada uno, usando 4 bytes para enviar su estado. Hasta donde he podido ver, el dispositivo 12ba:0200 no hace uso del primer joystick, enviando siempre la información correspondiente a como si estuviera centrado. El segundo joystick sí es usado; diré cómo más adelante.

0x06, 0x00, 0xff, /* Usage Page 65280 (null) */
0x09, 0x20,       /* Usage 32 (null) */
0x09, 0x21,       /* Usage 33 (null) */
0x09, 0x22,       /* Usage 34 (null) */
0x09, 0x23,       /* Usage 35 (null) */
0x09, 0x24,       /* Usage 36 (null) */
0x09, 0x25,       /* Usage 37 (null) */
0x09, 0x26,       /* Usage 38 (null) */
0x09, 0x27,       /* Usage 39 (null) */
0x09, 0x28,       /* Usage 40 (null) */
0x09, 0x29,       /* Usage 41 (null) */
0x09, 0x2a,       /* Usage 42 (null) */
0x09, 0x2b,       /* Usage 43 (null) */
0x95, 0x0c,       /* Report Count 12 */
0x81, 0x02,       /* Input 2 (Data, Var, Abs) */

Aquí es donde esto se pone interesante; todo ese relajo (que lsusb en Linux no puede reconocer, y por lo tanto yo le puse “null”), codifica 12 bytes que, hasta donde yo adivino, deberían codificar qué tanto están presionados 12 de los 13 botones que reportan los primeros 2 bytes. Deberían siendo la palabra clave.

0x0a, 0x21, 0x26, /* Usage 9761 (null) */
0x95, 0x08,       /* Report Count 8 */
0xb1, 0x02,       /* Feature 2 (Data, Var, Abs) */
0x0a, 0x21, 0x26, /* Usage 9761 (null) */
0x91, 0x02,       /* Output 2 (Data, Var, Abs) */
0x26, 0xff, 0x03, /* Logical Maximum 1023 */
0x46, 0xff, 0x03, /* Physical Maximum 1023 */
0x09, 0x2c,       /* Usage 44 (null) */
0x09, 0x2d,       /* Usage 45 (null) */
0x09, 0x2e,       /* Usage 46 (null) */
0x09, 0x2f,       /* Usage 47 (null) */
0x75, 0x10,       /* Report Size 16 */
0x95, 0x04,       /* Report Count 4 */
0x81, 0x02,       /* Input 2 (Data, Var, Abs) */

Por último, se definen 4 doble bytes, que son parecidos a los que usa el DualShock 3 para codificar los acelerómetros X, Y y Z, y el giroscopio.

0xc0      /* End_Collection */

Ese byte sólo cierra la colección y con ello el descriptor.

Este descriptor entonces codifica 13 botones, dos joysticks, presiones de los botones, acelerómetros, y giroscopio, utilizando 27 bytes: 2 bytes para los 13 botones (contando 3 bits de relleno), 1 byte para el hat switch, 4 bytes para los dos joysticks, 12 bytes para (supongo) la presión de 12 de los 13 botones, y 8 bytes para los acelerómetros y el giroscopio.

¿Cuál es entonces el dispositivo 12ba:0200, este famoso “gamepad”? Es este:

RockBand Stratocaster

RockBand Stratocaster

El bit 0 del primer byte es el botón azul, el bit 1 es el verde, el bit 2 es el rojo, etc. El primer joystick es ignorado; pero el segundo toma un eje para el whammy bar, y el otro para el “estilo del solo”… lo que sea que es eso.

La información básica del controlador (especialmente los primeros 7 bytes que envía el dispositivo) los encontré en esta página, pero casi todo lo demás lo tuve que averiguar (o adivinar) yo solo. Y no estoy 100% seguro de que tenga todo correctamente.

Sin embargo, lo que he sí tengo correcto sirvió perfectamente para que llevara a cabo mi proyecto… que esperaría que en este punto ya todo mundo pudiera adivinar cuál fue.

Capitán América y el Soldado del Invierno

Hace una vida entera, Mina y yo fuimos a ver Captain America: The Winter Soldier.

Se aplican las de siempre.

Captain America: The Winter Soldier

Me gustó mucho esta película; sería trivial hacer una película del Capitán Mamérica insoportablemente progringa y alabando a las barras y las estrellas, pero los realizadores consiguen evitarlo por completo.

En gran medida, me parece, la película funciona por Chris Evans; el tipo es de verdad encantador, y genuinamente consigue explayar un aire de buena gente y de querer hacer lo correcto. Ayuda también Anthony Mackie siendo básicamente igual, pero sin dosis del súpersoldado; y la Scarlett Johansson dando de patadas y Samuel L. Jackson interpretando a Samuel L. Jackson lo mejoran aún más. La presencia de Robert Redford haciéndola de malo malévolo lo termina de redondear. Ah, y están simpáticos los catorce segundos que aparece Cobie Smulders.

Por lo demás, es lo mismo que ha venido prefabricando Marvel desde hace más de media década. Esto último no es queja: a mí me encanta, y ellos se hinchan de todo el dinero en existencia, al parecer. Lo interesante será saber cuánto tiempo lo logran mantener.

Así que véanla; está simpática.

GIMX

(Esta entrada es la sexta parte de una serie que cubre un proyecto personal que realicé en el verano de 2014; pueden ver todas las partes aquí).

Originalmente iba a escribir acerca de una de las piezas del rompecabezas de mi proyecto que haría explícito exactamente a dónde iba con él. Decidí tomar una pequeña desviación hoy, sin embargo; porque si no mencionar a GIMX más tarde tal vez le quitaría méritos.

El proyecto GIMX (Game Input MultipleXer) obviamente está relacionado a mi proyecto, pero tiene suficientes diferencias como para que yo no considere al mío una modificación. El diseño del hardware (que lo pueden ver aquí) sí lo tomé completamente de ellos, porque yo no sé realmente de hardware. Es por eso que estudié Ciencias de la Computación y no Ingeniería en Computación; todo lo de los fierritos y alambritos me da una hueva mortal.

El software de GIMX al final sólo me sirvió de base para yo hacer lo mío; GIMX utiliza LUFA, que aunque se ve que tiene un montón de cosas bien chidas, al final yo decidí que me daba mucha hueva estudiar un marco de trabajo tan complejo para lo casi trivial que hago yo con mi Teensy++ 2.0. Aunque sí estudié algo del código de GIMX, terminé yo escribiendo mi propia versión del firmware para mi Teensy++ 2.0, basada en otro cuerpo de código (el ejemplo Raw HID de la página de Teensy).

De cualquier forma, enterarme de la existencia de GIMX fue lo que me hizo percatarme de que mi proyecto era posible, y nada más por el diseño de hardware y la guía de qué componentes comprar bastarían para que yo estuviera infinitamente agradecido con ellos.

La idea principal de GIMX es crear un firmware para el Teensy++ 2.0 (o cualquier tarjeta similar; al parecer hay chorrocientas parecidas) que emule a un controlador de PlayStation 3 (también de PlayStation 4 y de Xbox 360, pero esos no me importan). También la idea es emular un control a través de Bluetooth, pero eso no me servía de nada para mi proyecto, así que lo ignoré olímpicamente.

Como el Teensy++ 2.0 tiene el poder de cómputo equivalente a dos calculadoras más o menos, GIMX utiliza el CP2102 (o cualquier otro adaptador USB ↔ serial) para que una computadora le pueda mandar los “movimientos” del control al Teensy++ 2.0. El Teensy++ 2.0 y el CP2102 se conectan como se puede ver en el tutorial de GIMX.

La cosa se ve (esquemáticamente) así al final:

El diagrama

El diagrama

Yo uso exactamente la misma configuración de hardware; pero mi software es bastante distinto, incluyendo el firmware del Teensy++ 2.0.

La idea de GIMX es, básicamente, poder reemplazar un control del PlayStation 3 por el ratón y teclado de una computadora. En particular, esto permite jugar juegos FPS (first-person shooter) como dios manda, no con la desgracia que es el DualShock 3 (y me imagino el 4) cuando uno trata de destripar desconocidos en línea.

No me gustan muchas de las decisiones que tomaron los escritores de GIMX; su software toma control por completo de un teclado y ratón conectados a la computadora, y me parece que utilizan demasiado interfaces gráficas cuando un montón de cosas saldrían mejor con la línea de comandos o archivos de texto. En particular, que para configurar el mapeo de teclas del teclado a botones del DualShock 3 haya que usar una interfaz gráfica, o que tuviera que meterme al código de GIMX para ver qué opciones de línea de comandos toma el principal ejecutable, porque está pensado para ser ejecutado todo por ventanas, se me hacen ligeramente heréticas en Linux. Aunque claro, el software está pensado para gamers, no programadores.

Que tomen control absoluto del ratón tiene sentido; para que GIMX jala bien bien, uno necesita un ratón con una resolución altísima (recomiendan 5000 DPI), porque tienen que hacer transformaciones sobre cómo se está moviendo el ratón para que el Teensy++ 2.0 pueda emular movimientos fluidos y naturales de un DualShock 3. Que tomen control absoluto del teclado no tiene sentido, pero pues eso hacen.

Como sea; para mi proyecto no utilicé GIMX, pero sí me inspiré en ellos. De cualquier forma, GIMX me permitirá en un futuro tal vez comenzar a jugar juegos FPS en mi PlayStation 3 (o 4, cuando lo tenga); la verdad el DualShock 3 me pone de malas para FPSs, pero hay juegos FPS que sí me gustaría jugar en mi PS3 (BioShock y Fallout los más prominentes).

GIMX también resulta útil de vez en cuando en TPSs (third-person shooter, que son los que más juego), y de hecho ya lo usé para una cosilla. Sólo que para usarlo regularmente, sí voy a necesitar meterle mano al código, porque me parece terriblemente agresivo.

Así que para terminar esta parte; no utilicé el código de GIMX para mi proyecto, pero sí me inspiré en ellos, y su diseño de cómo acoplar el hardware sí se los fusilé por completo. Más adelante tal vez lo utilice para jugar FPSs, y de vez en cuando TPSs; pero sí cuestiono ciertas decisiones de diseño que tomaron al escribirlo.

De cualquier forma, GIMX es un proyecto súper chido porque me inspiró para yo poder hacer el mío.

Noé

Hace, literalmente, como mil años, fuimos a ver Noah.

Se aplican ya saben.

Noah

Noah

Esta nueva versión cinematográfica del mito abrahámico tiene un montón de cosas a su favor: un elenco espectacular; unos efectos fabulosos; que se toma a la biblia como lo que es, un libro de cuentos; y a un Dios (mis lectores de mucho tiempo notarán mi raro uso de mayúscula para el término) que dice “nah, a la verga; que se chinguen todos excepto Noé, porque necesito chofer para mis bestias”.

A mí me encantó; y se me hizo fabulosa la escena extendida donde el big bang y la evolución son bellísimamente entrelazados con los mitos del génesis abrahámico… hasta que se topa con una pared con Adán y Eva, porque eso sí no tiene ningún sentido. Pero bueno, no se puede todo en este mundo.

Dado que, desde el punto de vista fundamentalista de cualquier religión abrahámica, esta película es más blasfema que Marx, me hubiera gustado que los realizadores lidiaran de forma más interesante con Génesis 9:22:

Y Cam, padre de Canaán, vio la desnudez de su padre, y lo dijo a sus dos hermanos que estaban afuera.

La película básicamente lo escenifica a pie juntillas (después de agregar ángeles de piedra y cambiar docenas de cosas), cuando un montón de estudiosos de la biblia creen que el sentido original era mucho más interesante (sólo como un ejemplo, Cecil menciona dos en The Straight Dope).

Y también hubiera estado padre que el mundo tuviera más que gente blanca antes de ser destruido, y que alguien que no fuera blanco fuera salvado.

Pero son cosas menores; la película se me hizo espectacular, y yo la recomiendo ampliamente.

Teensy++ 2.0

(Esta entrada es la quinta parte de una serie que cubre un proyecto personal que realicé en el verano de 2014; pueden ver todas las partes aquí).

La parte crucial de mi proyecto, sin la cual nada más podía llevarse a cabo, fue comprar un Teensy++ 2.0.

Teensy++ 2.0

Teensy++ 2.0

Esto sí no tengo ni la más remota idea de cómo conseguirlo en México. Debe ser posible, pero maldito si acaso sé dónde preguntar al menos.

El Teensy++ 2.0 es un sistema de desarrollo microcontrolador… definición que probablemente les sirva tanto a ustedes como inicialmente me sirvió a mí. Para la gente que sabe de desarrollo en hardware, lo más sencillo tal vez sea decirles que el Teensy++ 2.0 es básicamente un Arduino; puede utilizar las bibliotecas de Arduino, e incluso el ambiente de desarrollo, y es (hasta donde tengo entendido) casi 100% compatible con Arduino.

Para la gente (como yo) con antecedentes de programación, la mejor descripción del Teensy++ 2.0 es que es hardware “programable”. La chingaderita (mide como 5×2 centímetros) tiene un montón de compuertas lógicas; yo como programador escribo un programa en C, y una versión especial de gcc (el compilador normal de C de Linux) genera un ejecutable que puedo convertir a un binario, el cual puedo quemar (flash, le dicen) en el Teensy++ 2.0 como firmware.

En otras palabras, aunque Turing completo (la tarjeta es capaz de ejecutar cualquier programa, si tiene suficiente memoria), el Teensy++ 2.0 no es un CPU dado que no tiene realmente un conjunto de instrucciones… pero podría programarle un CPU con el conjunto de instrucciones que se me diera la gana, como hicimos en mi proyecto final de Arquitectura en la maestría. Aunque probablemente necesitaría más memoria.

Programar el Teensy++ 2.0 es deliciosamente restrictivo; olvídense de asignar memoria, mejor ni intentar utilizar recursión, y casi todas las variables más vale que sean globales y estáticas. También hace cosas raras para un programador como yo que casi nunca piensa en el hardware; por ejemplo, transmitir un bit por uno del montón de pines que tiene, se consigue asignándole 0 o 1 a una variable especial (por ejemplo, UEDATX).

Hay una comunidad bastante grande de gente que utiliza el Teensy++ 2.0 para cualquier cantidad de proyectos; échenles un ojo si quieren.

El hardware es realmente restrictivo; desde el punto de vista de software, no puede hacer mucho… y si somos justos, de hecho casi no puede hacer nada. ¿Para qué podría interesarme entonces a mí, que soy programador antes que nada? Pues obviamente me interesaba por lo que puede hacer desde el punto de vista de hardware.

¿Ven el conector mini USB que tiene el Teensy++ 2.0 en la imagen de arriba? Ahí se le conecta el cable USB con el cual quemo mis “programas” en la tarjeta. Pero no es para lo único que sirve.

El Teensy++ 2.0 tiene la capacidad de emular un dispositivo USB.

Y en particular, puede emular un dispositivo HID-USB.

Estrellita en la frente a mis lectores que puedan adivinar a dónde voy con todo esto.

American Hustle

Fuimos a ver hace tanto tiempo American Hustle, que ya ni me acuerdo de cómo le pusieron en español.

Se aplican las de siempre.

American Hustle

American Hustle

La historia relata (apócrifamente) los sucesos de la operación Abscam donde el FBI gringo engatuzó a varios políticos para que aceptaran dinero incriminatoriamente. Casi como a Bejarano, de hecho.

Eso no importa mucho; lo que importa son las actuaciones, especialmente de Amy Adams y Jennifer Lawrence… aunque siendo honesto creo que la segunda se come a la primera enterita, aunque es ciertamente un papel muy lucidor. Los güeyes también actúan chido, por cierto.

Además de las actuaciones, la película está ambientada de forma casi caricaturesca en los setentas (como dijo Tina Fey: “Explosión en la fábrica de pelucas”), y le permite a los actores hacer ese tipo de cosas que por alguna razón a mucha gente apantalla, como usar pelucas, vestirse en la moda de otra década, y subir unos kilos de peso.

A mí eso no me entretiene tanto; pero sí me parece que está muy divertida la película, y que la historia está chistosa y bien contada, aunque sea casi toda básicamente un invento.

Así que vayan y véanla, que probablemente ya hicieron.

El control DualShock 3

(Esta entrada es la cuarta parte de una serie que cubre un proyecto personal que realicé en el verano de 2014; pueden ver todas las partes aquí).

El control DualShock 3 es el control que, a partir de 2008, viene por omisión con el PlayStation 3, reemplazando (o mejor sería decirlo, extendiendo) al control SixAxis. Casi universalmente reconocido como uno de los mejores controles para videojuegos en existencia, ahora está siendo reemplazado por el DualShock 4, que es el que viene incluido con el PlayStation 4.

El DualShock 3 tiene muchas características que lo hacen interesante incluso fuera del ámbito de videojuegos; es un dispositivo Bluetooth y USB-HID casi estándar, lo que nos permite usarlo de forma casi inmediata en cualquier computadora moderna. El “casi” es porque la conectividad Bluetooth tiene un paso no estándar para autenticar al control con un PlayStation 3; y en el caso de USB-HID, existe al menos una función del dispositivo que yo no he logrado entender, pero que no es muy importante.

Lo de Bluetooth no me importa demasiado; que el dispositivo sea USB-HID en cambio lo hizo una de las piezas más en el rompecabezas de mi proyecto veraniego.

Continuando la introducción que dí de USB-HID, como el DualShock 3 es un dispositivo ídem, podemos analizar su reporte descriptivo en Linux utilizando lsusb. En esa entrada comentaba que para lograrlo hay que utilizar un truquito; la cosa es que si el dispositivo ya está controlado por el módulo usbhid del kernel (que ocurre de forma automática), el reporte descriptivo queda invisible, entonces hay que “liberar” al dispositivo del módulo. La explicación técnica se puede leer en este artículo de LWN.net, pero la manera rápida y sucia de hacerlo es haciendo

echo -n '3-1:1.0' > /sys/bus/usb/drivers/usbhid/unbind

en una terminal como superusuario; por supuesto, 3-1:1.0 es la dirección física donde conecté el DualShock 3 en mi computadora, tienen que usar la correcta en la suya.

Como sea, hecho el truco, el reporte descriptivo del DualShock 3 es este:

Report Descriptor: (length is 148)
  Item(Global): Usage Page, data= [ 0x01 ] 1
                  Generic Desktop Controls
  Item(Local ): Usage, data= [ 0x04 ] 4
                  Joystick
  Item(Main  ): Collection, data= [ 0x01 ] 1
                  Application
  Item(Main  ): Collection, data= [ 0x02 ] 2
                  Logical
  Item(Global): Report ID, data= [ 0x01 ] 1
  Item(Global): Report Size, data= [ 0x08 ] 8
  Item(Global): Report Count, data= [ 0x01 ] 1
  Item(Global): Logical Minimum, data= [ 0x00 ] 0
  Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255
  Item(Main  ): Input, data= [ 0x03 ] 3
                  Constant Variable Absolute No_Wrap Linear
                  Preferred_State No_Null_Position Non_Volatile Bitfield
  Item(Global): Report Size, data= [ 0x01 ] 1
  Item(Global): Report Count, data= [ 0x13 ] 19
  Item(Global): Logical Minimum, data= [ 0x00 ] 0
  Item(Global): Logical Maximum, data= [ 0x01 ] 1
  Item(Global): Physical Minimum, data= [ 0x00 ] 0
  Item(Global): Physical Maximum, data= [ 0x01 ] 1
  Item(Global): Usage Page, data= [ 0x09 ] 9
                  Buttons
  Item(Local ): Usage Minimum, data= [ 0x01 ] 1
                  Button 1 (Primary)
  Item(Local ): Usage Maximum, data= [ 0x13 ] 19
                  (null)
  Item(Main  ): Input, data= [ 0x02 ] 2
                  Data Variable Absolute No_Wrap Linear
                  Preferred_State No_Null_Position Non_Volatile Bitfield
  Item(Global): Report Size, data= [ 0x01 ] 1
  Item(Global): Report Count, data= [ 0x0d ] 13
  Item(Global): Usage Page, data= [ 0x00 0xff ] 65280
                  (null)
  Item(Main  ): Input, data= [ 0x03 ] 3
                  Constant Variable Absolute No_Wrap Linear
                  Preferred_State No_Null_Position Non_Volatile Bitfield
  Item(Global): Logical Minimum, data= [ 0x00 ] 0
  Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255
  Item(Global): Usage Page, data= [ 0x01 ] 1
                  Generic Desktop Controls
  Item(Local ): Usage, data= [ 0x01 ] 1
                  Pointer
  Item(Main  ): Collection, data= [ 0x00 ] 0
                  Physical
  Item(Global): Report Size, data= [ 0x08 ] 8
  Item(Global): Report Count, data= [ 0x04 ] 4
  Item(Global): Physical Minimum, data= [ 0x00 ] 0
  Item(Global): Physical Maximum, data= [ 0xff 0x00 ] 255
  Item(Local ): Usage, data= [ 0x30 ] 48
                  Direction-X
  Item(Local ): Usage, data= [ 0x31 ] 49
                  Direction-Y
  Item(Local ): Usage, data= [ 0x32 ] 50
                  Direction-Z
  Item(Local ): Usage, data= [ 0x35 ] 53
                  Rotate-Z
  Item(Main  ): Input, data= [ 0x02 ] 2
                  Data Variable Absolute No_Wrap Linear
                  Preferred_State No_Null_Position Non_Volatile Bitfield
  Item(Main  ): End Collection, data=none
  Item(Global): Usage Page, data= [ 0x01 ] 1
                  Generic Desktop Controls
  Item(Global): Report Size, data= [ 0x08 ] 8
  Item(Global): Report Count, data= [ 0x27 ] 39
  Item(Local ): Usage, data= [ 0x01 ] 1
                  Pointer
  Item(Main  ): Input, data= [ 0x02 ] 2
                  Data Variable Absolute No_Wrap Linear
                  Preferred_State No_Null_Position Non_Volatile Bitfield
  Item(Global): Report Size, data= [ 0x08 ] 8
  Item(Global): Report Count, data= [ 0x30 ] 48
  Item(Local ): Usage, data= [ 0x01 ] 1
                  Pointer
  Item(Main  ): Output, data= [ 0x02 ] 2
                  Data Variable Absolute No_Wrap Linear
                  Preferred_State No_Null_Position Non_Volatile Bitfield
  Item(Global): Report Size, data= [ 0x08 ] 8
  Item(Global): Report Count, data= [ 0x30 ] 48
  Item(Local ): Usage, data= [ 0x01 ] 1
                  Pointer
  Item(Main  ): Feature, data= [ 0x02 ] 2
                  Data Variable Absolute No_Wrap Linear
                  Preferred_State No_Null_Position Non_Volatile Bitfield
  Item(Main  ): End Collection, data=none
  Item(Main  ): Collection, data= [ 0x02 ] 2
                  Logical
  Item(Global): Report ID, data= [ 0x02 ] 2
  Item(Global): Report Size, data= [ 0x08 ] 8
  Item(Global): Report Count, data= [ 0x30 ] 48
  Item(Local ): Usage, data= [ 0x01 ] 1
                  Pointer
  Item(Main  ): Feature, data= [ 0x02 ] 2
                  Data Variable Absolute No_Wrap Linear
                  Preferred_State No_Null_Position Non_Volatile Bitfield
  Item(Main  ): End Collection, data=none
  Item(Main  ): Collection, data= [ 0x02 ] 2
                  Logical
  Item(Global): Report ID, data= [ 0xee ] 238
  Item(Global): Report Size, data= [ 0x08 ] 8
  Item(Global): Report Count, data= [ 0x30 ] 48
  Item(Local ): Usage, data= [ 0x01 ] 1
                  Pointer
  Item(Main  ): Feature, data= [ 0x02 ] 2
                  Data Variable Absolute No_Wrap Linear
                  Preferred_State No_Null_Position Non_Volatile Bitfield
  Item(Main  ): End Collection, data=none
  Item(Main  ): Collection, data= [ 0x02 ] 2
                  Logical
  Item(Global): Report ID, data= [ 0xef ] 239
  Item(Global): Report Size, data= [ 0x08 ] 8
  Item(Global): Report Count, data= [ 0x30 ] 48
  Item(Local ): Usage, data= [ 0x01 ] 1
                  Pointer
  Item(Main  ): Feature, data= [ 0x02 ] 2
                  Data Variable Absolute No_Wrap Linear
                  Preferred_State No_Null_Position Non_Volatile Bitfield
  Item(Main  ): End Collection, data=none
  Item(Main  ): End Collection, data=none

Eso se ve medianamente intimidante; pero después de perder el tiempo con el estándar USB-HID, de hecho se vuelve legible. Voy a comentar algunas partes del reporte descriptivo, pero siguiendo su notación en bytes con comentarios en C:

0x05, 0x01,        /* Usage Page (Generic Desktop Ctrls) */
0x09, 0x04,        /*/ Usage (Joystick) */
0xA1, 0x01,        /* Collection (Physical) */

Este es sencillamente el encabezado donde especifica que lo que sigue es la descripción del un joystick.

0xA1, 0x02,        /*   Collection (Application) */
0x85, 0x01,        /*     Report ID (1) */
0x75, 0x08,        /*     Report Size (8) */
0x95, 0x01,        /*     Report Count (1) */
0x15, 0x00,        /*     Logical Minimum (0) */
0x26, 0xFF, 0x00,  /*     Logical Maximum (255) */
0x81, 0x03,        /*     Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) */

El DualSock 3 reserva el primer byte; no tengo idea para qué, pero al menos en mis controles nunca envía nada distinto a 0x00.

0x75, 0x01,        /*     Report Size (1) */
0x95, 0x13,        /*     Report Count (19) */
0x15, 0x00,        /*     Logical Minimum (0) */
0x25, 0x01,        /*     Logical Maximum (1) */
0x35, 0x00,        /*     Physical Minimum (0) */
0x45, 0x01,        /*     Physical Maximum (1) */
0x05, 0x09,        /*     Usage Page (Button) */
0x19, 0x01,        /*     Usage Minimum (0x01) */
0x29, 0x13,        /*     Usage Maximum (0x13) */
0x81, 0x02,        /*     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) */
0x75, 0x01,        /*     Report Size (1) */
0x95, 0x0D,        /*     Report Count (13) */
0x06, 0x00, 0xFF,  /*     Usage Page (Vendor Defined 0xFF00) */
0x81, 0x03,        /*     Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) */

4 bytes, o un entero de 32 bits (es exactamente lo mismo), para representar potencialmente 32 botones; actualmente sólo 19 de hecho son considerados (bits 0-18), y 13 reservados para uso futuro (bits 19-31).

0x15, 0x00,        /*     Logical Minimum (0) */
0x26, 0xFF, 0x00,  /*     Logical Maximum (255) */
0x05, 0x01,        /*     Usage Page (Generic Desktop Ctrls) */
0x09, 0x01,        /*     Usage (Pointer) */
0xA1, 0x00,        /*     Collection (Undefined) */
0x75, 0x08,        /*       Report Size (8) */
0x95, 0x04,        /*       Report Count (4) */
0x35, 0x00,        /*       Physical Minimum (0) */
0x46, 0xFF, 0x00,  /*       Physical Maximum (255) */
0x09, 0x30,        /*       Usage (X) */
0x09, 0x31,        /*       Usage (Y) */
0x09, 0x32,        /*       Usage (Z) */
0x09, 0x35,        /*       Usage (Rz) */
0x81, 0x02,        /*       Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) */
0xC0,              /*     End Collection */

Cuatro ejes: X, Y, Z, y rotación de Z. Cada eje es un byte (“Report Size (8)”), y se toma el valor del byte menos 127 como el valor del eje; en otras palabras, 0 – 127 = -127 es el eje en su posición más baja (o a la izquierda), 127 – 127 = 0 es el eje en “reposo” (centrado), y 255 – 127 = 128 es el eje en su posición más alta (o a la derecha). El DualShock 3 utiliza el estándar HID para definir eje Z y rotación de Z, pero esos dos realmente son los ejes del joystick derecho, y los dos primeros ejes son los del joystick izquierdo.

0x05, 0x01,        /*     Usage Page (Generic Desktop Ctrls) */
0x75, 0x08,        /*     Report Size (8) */
0x95, 0x27,        /*     Report Count (39) */
0x09, 0x01,        /*     Usage (Pointer) */
0x81, 0x02,        /*     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) */
0x75, 0x08,        /*     Report Size (8) */
0x95, 0x30,        /*     Report Count (48) */
0x09, 0x01,        /*     Usage (Pointer) */
0x91, 0x02,        /*     Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) */
0x75, 0x08,        /*     Report Size (8) */
0x95, 0x30,        /*     Report Count (48) */
0x09, 0x01,        /*     Usage (Pointer) */
0xB1, 0x02,        /*     Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) */
0xC0,              /*   End Collection */
0xA1, 0x02,        /*   Collection (Application) */
0x85, 0x02,        /*     Report ID (2) */
0x75, 0x08,        /*     Report Size (8) */
0x95, 0x30,        /*     Report Count (48) */
0x09, 0x01,        /*     Usage (Pointer) */
0xB1, 0x02,        /*     Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) */
0xC0,              /*   End Collection */
0xA1, 0x02,        /*   Collection (Application) */
0x85, 0xEE,        /*     Report ID (238) */
0x75, 0x08,        /*     Report Size (8) */
0x95, 0x30,        /*     Report Count (48) */
0x09, 0x01,        /*     Usage (Pointer) */
0xB1, 0x02,        /*     Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) */
0xC0,              /*   End Collection */
0xA1, 0x02,        /*   Collection (Application) */
0x85, 0xEF,        /*     Report ID (239) */
0x75, 0x08,        /*     Report Size (8) */
0x95, 0x30,        /*     Report Count (48) */
0x09, 0x01,        /*     Usage (Pointer) */
0xB1, 0x02,        /*     Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) */
0xC0,              /*   End Collection */
0xC0,              /* End Collection */

Esta última parte explica cómo el reporte entero del dispositivo utiliza 48 bytes (más uno de identificador): 3 colecciones de 8 bytes de “controles de escritorio genérico” (“Generic Desktop Ctrls”), y tres colecciones de 8 bytes de aplicación.

El byte 0 sirve de identificador y (hasta donde he visto) es siempre 1.

El byte 1 (como dije arriba) está reservado; los siguientes 4 bytes (bytes 2-5) tienen información de los botones: bit prendido siginifica que el botón está presionado; apagado implica no presionado. Aunque son 32 bits en total (4 bytes), realmente sólo se usan 19, con 13 reservados.

Los bytes 6, 7, 8 y 9 son los ejes de los joysticks, y a partir del 10 (realmente 13; 10, 11 y 12 sólo me reportan ceros) hasta el 24 son las presiones de cada botón: 0 es el botón casi no está presionado, 255 es el botón está completamente presionado. Esas son las 3 colecciones de escritorio genérico (24 bytes). Los otros 24 bytes contienen las colecciones de aplicación, pero hasta donde entiendo sólo se usan los bytes 41-48; 2 bytes para el acelerómetro X, 2 bytes para el acelerómetro Y, 2 bytes para el acelerómetro Z, y dos bytes para el giroscopio. No tengo idea qué carajo hagan los bytes 25-40, pero en uno de mis controles siempre reporta:

00 00 00 00 03 ef 16 00 00 00 00 33 ae 77 00 40

A lo mejor ahí estarán las presiones de los 13 botones reservados. Por cierto, todo esto es como yo lo he entendido; si estoy entendiendo algo mal, por favor díganme.

¿Para qué sirve todo esto? Para mi proyecto de verano, no me sirvió de mucho; pero sí será de utilidad (de hecho ya lo fue) para otro miniproyecto relacionado. Con la información de arriba puedo leer bit a bit la información que un DualShock 3 envía; pero esto, además de que hay formas mucho más sencillas de hacerlo (por no decir de mucho más alto nivel), cualquier güey lo hace. Yo quería hacer algo más interesante (y lo hice).

En la siguiente parte de esta serie explicaré la pieza principal del rompecabezas. No sé si con ello ya quede claro mi proyecto; pero si no, la entrada que le seguirá debería dejarlo claro.

Jazmín Azul

Después de Ender’s Game, Mina y yo vimos Blue Jasmine; fue hace tanto, que ya van a estrenar la próxima de Woody Allen.

No se aplica nada, porque se estrenó hace meses.

Blue Jasmine

Blue Jasmine

La película narra la historia del viaje de ida de una mujer snob hacia la locura, en gran medida por su incapacidad de poder lidiar con el mundo cuando éste se comporta distinto a la imagen perfecta de él que ella tiene en su cabeza.

Es lo de menos; aún cuando tiene un giro inesperado cerca del final, la historia realmente no es lo interesante de esta película. Tampoco lo son el montón de actores comparsas que aparecen en ella; incluido Louis C.K., que es mi ídolo (da una actuación decente en los cuatro minutos que aparece).

Lo interesante es la espectacular actuación de Cate Blanchett, que hizo que básicamente se ganara todos los premios a mejor actriz del año pasado. La mujer brinca de ser una burguesita insoportable, a ser una vieja desquiciada de un momento a otro, dependiendo de la escena y el marco temporal de la misma (la película es narrada de forma no lineal). Uno casi puede sentir cómo su personaje va perdiendo la cordura.

Yo siempre sido fan de Woody Allen, aunque soy el primero en reconocer que sus películas brincan por todos lados respecto a qué tan buenas o no son; en ese marco, Blue Jasmine no es ni mi película preferida de Woody Allen, ni la que menos me haya gustado. Anda literalmente por en medio; pero la actuación de Cate Blanchett es tan extraordinaria que realmente eleva a la película a mucho más de lo que por sí misma habría llegado.

Así que réntenla, si no la han visto.

CP2102 UART Bridge

(Esta entrada es la tercera parte de una serie que cubre un proyecto personal que realicé en el verano de 2014; pueden ver todas las partes aquí).

La familia de adaptadores USB ↔ serial cp210x es bastante común para la gente que quiere comunicarse con hardware de forma serial. Hace unos años (tal vez habría que decir décadas) no era necesario utilizar este tipo de adaptadores: todas las computadoras tenían al menos un conector de este estilo incluido, llamado (imaginativamente) el puerto serial (serial port); en el mundo de DOS se le conocía como COM1 (y si había más eran COM2, etc.), y yo todavía llegué a conectar algún módem de esta manera a una computadora.

Como decía en la entrada anterior de esta serie, el estándar USB ha reemplazado a casi todos los conectores de la antigüedad; los conectores PS1, paralelo, y serial incluidos. Por lo tanto, si alguien quiere (como yo quería) comunicarse de forma serial usando una computadora moderna, uno necesita un adaptador USB ↔ serial.

Leyendo en Internet, rápidamente me decidí por un CP2102 UART Bridge, que encontré a precio de ganga en Amazon; el que ligo cuesta casi 7 dólares, pero el que de hecho compré me salió en menos de 3, con envío incluido. Lamentablemente, no sé dónde conseguir este tipo de cosas en México, así que lo pedí por Amazon y lo envié a la dirección de Omar en Boston (Amazon generalmente no envía electrónicos fuera del gabacho), donde lo recogí cuando pasé a verlo a finales de mayo.

CP2102

CP2102

(Siendo 100% honesto, sí lo encontré en MercadoLibre; pero el precio era más del doble).

Me decidí por el CP2102 básicamente porque es muy barato, y porque está muy bien soportado en Linux (niguna de esas razones me sorprende; no hace nada terriblemente interesante). En Gentoo, sencillamente tuve que habilitar el módulo del kernel cp210x (funciona para el CP2101 y el CP2103 también), con la opción USB_SERIAL_CP210X, y después sencillamente lo conecté a mi computadora. Inmediatamente el adaptador queda registrado con el dispositivo /dev/ttyUSB0, y uno puede comenzar a usarlo sin problemas.

Bueno, casi; el dispositivo por omisión tiene permisos de escritura únicamente para root, así que usando la siguiente regla de udev:

SUBSYSTEMS=="usb", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", MODE:="0666"
KERNEL=="ttyUSB*", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", MODE:="0666"

puedo darle permisos a todo mundo de forma automática, lo que me permite que mis aplicaciones corran para cualquier usuario.

Como sea; el CP2102 es bastante sencillo de usar (si es que acaso el hardware está bien conectado), uno únicamente abre el dispositivo, y puede empezar a escribir y leer información de él sin muchos problemas:

#include <termios .h>
#include <unistd .h>
#include <errno .h>
#include <fcntl .h>
#include <stdio .h>
#include <stdlib .h>
#include <stdint .h>

#define TTY_BAUDRATE   B38400

int
main(int argc, char* argv[])
{
        struct termios options;
        int fd;

        if ((fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0) {
                return -1;
        } else {
                tcgetattr(fd, &options);
                cfsetispeed(&options, TTY_BAUDRATE);
                cfsetospeed(&options, TTY_BAUDRATE);
                cfmakeraw(&options);
                if (tcsetattr(fd, TCSANOW, &options) < 0) {
                        close(fd);
                        return -1;
                }
                tcflush(fd, TCIFLUSH);
        }

        uint8_t byte = 0xff;

        /* Envía byte. */
        int r = write(fd, &byte, 1);
        tcflush(fd, TCIFLUSH);

        /* Recibe byte. */
        fd_set readfds;

        struct timeval timeout = {
                .tv_sec = 1,
                .tv_usec = 0
        };

        FD_ZERO(&readfds);
        FD_SET(fd, &readfds);

        int status = select(fd+1, &readfds, NULL, NULL, &timeout);
        if (!status)
                return -1;
        
        if (FD_ISSET(fd, &readfds)) {
                r = read(fd, &byte, 1);
        } else if(status == EINTR) {
                return -1;
        }

        return (int)byte;
}

Obviamente se pueden transmitir secuencias de bytes más largas que 1, pero para lo que quería hacer 1 bastaba… o al menos no he necesitado más.

Por supuesto, el chiste de todo esto es, ¿a dónde van esos bytes que estoy enviando? El adaptador CP2120 únicamente me permite comunicarme de forma serial vía USB; es sólo una pieza más del rompecabezas que estuve armando para mi proyecto. Y, en retrospectiva, de hecho fue la pieza más sencilla; casi no tuve que hacer nada para que funcionara.

Del resto de las piezas escribiré más adelante.

El Juego de Ender

Poco después de ver The Wolf of Wall Street, vimos Ender’s Game.

Se aplican las de siempre, aunque como esta película llegó y se fue sin dejar mucha huella, no creo que importe demasiado.

Ender's Game

Ender’s Game

Leí la novela sobre la cual se basa la película por recomendación de mi hermano. Me gustó, pero nada del otro mundo; la película la puedo calificar igual, me parece.

La idea central, sobre la cual gira el clímax de la novela y la película, es que a Ender (el geniecillo militar al que le encargan la armada terrestre) le hacen creer que está jugando una simulación, cuando realmente está comandando a seres humanos reales para que vayan y maten a seres bichosos también reales. Es una idea interesante en ciencia ficción, que plantea dudas y conflictos morales y éticos bastante profundos. Como idea, es mucho mejor que los bichos de Starship Troopers de Heinlein, a los cuales la única opción que existe es exterminarlos a todos y cada uno de ellos.

La ejecución deja que desear, sin embargo; en ambas la película y la novela. La ejecución es mucho mejor en Starship Troopers; en particular las escenas de acción son mucho mejores porque ocurren donde de hecho acaece la acción, no en un centro de comandos escondido en una roca a millones de kilómetros de las batallas.

El protagonista, Ender, además es un chilletas. Sí, sé que es parte de la premisa central de la historia: un niño inocente y en el fondo pacifista que, por eso justamente, es capaz de pensar en estrategias para ganarles a los bichos. Eso no hace al personaje más agradable; todo lo contrario, es insoportable.

Como sea, y como dije al inicio, la película me gustó; sólo no dejó ninguna huella en mí… ni en nadie más, me parece; por lo que se ve no habrá ninguna otra película basada en las novelas que continúan la historia de Ender. Lo cual no me molesta demasiado; de hecho, al terminar la novela, no me dieron nada de ganas de leer ninguna de sus secuelas.

Así que si quieren véanla; pero no se pierden mucho si no lo hacen.