Viva Las Vegas!

Quando o sujeito fica velho pensar no passado consome boa parte do tempo que ainda resta. Nesse meu último aniversário comecei a lembrar da época que era milionário, explorava minha e apostava tudo no vermelho 36. Eu devia ter uns 11 anos.

Las Vegas

Quando era pirralho alguém da minha rua (e “minha rua” aqui significa todas as ruas ao redor até as bordas do cemitério, que às vezes era incluído no território) teve a genialíssima idéia de inventar o dinheiro! Da mesma forma que alguém decidiu que um metal amarelo brilhante aparentemente inútil (eles não tinham processadores naquela época) valia mais que muitas vidas humanas, nós crianças decidimos que carteiras vazias de cigarro valiam algo. Lembro mais ou menos da escala: Hollywood valia 5 (tinha um cigarro bem ruinzinho que valia 1), Carlton valia 10, Camel e Marlboro eram 50, e um outro lá que todos chamavam de “capa preta” valia 100 (uma nota preta!). Quanto mais bling mais valor.

A senhora minha mãe é fumante antiga, acho até que tragava líquido aminiótico pelo cordão umbilical (por falar nisso, ela jura que não fumou na gravidez, mas não consigo acreditar nela porque isso explicaria muita coisa), e eu como mau filho que era estimulava seu vício pra pegar as carteiras vazias. O problema é que ela só fumava Hollywood o que me garantia uma renda muito baixa. Os moleques Bicho Solto eram mais empreendedores, andavam pelos bares e pelas ruas mais agitadas e faziam verdadeiras fortunas. Eu tinha de me contentar em andar olhando as sarjetas e ir pra casa às 9. Eu era classe média. Sim, a parte sobre ser milionário foi uma mentira pra prender sua atenção.

Mesmo todo esse dinheiro de carteiras de cigarro não podia comprar o mais reles chiclete, além de nossas necessitades básicas serem plenamente atendidas pelos pais. Então, o que nos restava fazer com o dinheiro? Ver quem era o mais rico é uma das primeiras coisas pra fazer num grupo de pessoas com dinheiro em excesso. Não tínhamos um top 100 da Forbes, mas Moacir era sem sombra de dúvida nicotinicamente podre de rico, tinha até carteira de cigarro importado. Todos se admiravam. Ele era o cara mais de rua que podia existir, e também era muito doido, do tipo Forrest Gump (me lembro agora da história de como ele ficou comovido quando meu primo o levou no puteiro — mas isso aqui não é mil e uma noites, então vamos voltar à história). E claro que foi Moacir, bilionário entrepreneur, que nos levou pro próximo nível das pessoas com dinheiro e sem ter com que gastar: o jogo!

Roleta

Moacir passou a andar com uma caixa, que desdobrada bem embaixo da luz de um dos poucos postes da grande ladeira no fim da rua, se tornava um cassino completo. Não exatamente completo, não tínhamos cartas, mas os dados e a roleta estavam lá pra quem quisesse apostar. “Derby?! Pode ir tirando esses couros-de-rato daqui que a aposta é alta: Carlton pra cima!”, “Porra, Moacir, aceita aí meus Hollywoods que ainda tá valendo.”, “Tá, tá, tá, então aposta logo essa miséria!” Cara, perdi tantos Hollywoods, mas foi melhor assim, em troca aprendi uma importante lição vendo Moacir enriquecer e todos os outros ficando pobres: no fim a casa leva.

Só tem um nível que nós ricaços das carteiras de cigarro não alcançamos: as putas. Nunca apareceu uma menina pra dançar no meio-fio do lado do cassino me permitindo colocar minhas carteiras vazias de Hollywood (provavelmente eu economizaria botando umas de Derby) na sua enorme calcinha de algodão.

Shiboken

Last week PySide was launched, the team was glad to see the project finally go public and receive the community feedback, be it positive, negative or both. Many questions arose, like “Why duplicate efforts?” Well, I can’t say much more than what is already answered on PySide FAQ. For us (the team) the fact is that we had a task to accomplish and must perform it the best we can. That said, allow me to remind you that this is my personal blog and many of the views here written are my very own cherished opinion.

The other question that we’re waiting for, and my personal favorite, was “Why Boost.Python?”. Though one. First of all, Boost.Python eases very much the creation of C++ libraries bindings for Python. How to infer which method signature to call based on the Python arguments passed to the method wrapper? Boost.Python will take care of it. Inheritance? Type conversion (in opposition to type wrapping)? You bet: Boost.Python will take care of all this for you. The feature full Boost.Python gave us a great kick start and at first we progressed very fast. Occasionally some strange bug appeared and took some time to figure out the problem through the jungle of template error messages. Part of the job anyhow, and after that: fast pace again.

At some point somebody checked the size of the produced binary modules. “Hey guys, is that correct?”, “Ah, just strip the file.”, “Still huge.”, “Holy cow…”. Next task: size reduction. Some redesigns reduced a good deal of megabytes, g++ flags were also helpful, but these things weren’t enough. Then a new idea: “Let’s try it with the Intel C++ compiler and see what gives.” It gave binary modules with feasible sizes. Good, but the test just proved that it was possible to achieve the reductions. Besides, there were still other new ideas to try, and the fact that as soon as the project was launched the community would step in and say “I had this size problem with Boost.Python before. Here is how I solved it…”. (Which reminds me how limited, communication wise, a project is in its non-open phase. And don’t point your finger, mister — for every open source project has it’s non-open phase, even in your head!)

Part of the team was growing skeptical about the size reduction problem. Why not to try CPython code generation right now? Well, some say you can’t change the plane’s motor while flying, and this is true. Feature wise we were almost there and the reduction was possible. Also some of us had mixed feelings about CPython. In a past project a comparison was made about writing bindings with different technologies, including CPython, to check for speed, size and the burden imposed on the developer. At the end the guy with CPython had good numbers (not stunningly better than the others, at least for the case that mattered back then), but his personal impression was that he was suffering the Stockholm syndrome: he knew CPython abused him, but he developed a bond with his kidnapper.

Still, almost every one started personal (and voluntary, aka “made at home”) experimentation with different CPython generators (even a ctypes one!), and in the end all the ideas (including the ones from the Boost.Python generator) were merged into a single CPython generator, called Shiboken.

Shiboken

Before going on with this, allow me to explain that Shiboken means absolutely nothing. Not buddhist void, I just mean that the word Shiboken has no meaning attached to it. Except, of course, “generator of CPython based binding code for C/C++ libraries”.

Disclaimer: I don’t know a thing about Japanese language and the above kanjis are just something that I found at wikitionary to match the sounds of Shiboken. Forgive me, Lauro. 🙂

The conspirators’ plan was to develop the alternative generator to a point that could generate PySide bindings that pass all our unit tests, run the apps, etc, thus beign able to replace the Boost.Python front-end. For PySide users, i.e. Python programmers, the replacement would bring no impact, since the API should remain the same. The Shiboken generator is based on the same principles of the Boost.Python one: built using the API Extractor library, how the C++ library should be exported to Python is described on a Type System file, and so on.

Shiboken Generator

The power of Lego-fu!

When Shiboken reached a point that we’d think was good enough to start working with it at work, we presented it to our bosses and the green light was given. The Boost.Python generator will continue as the tool to generate the official PySide bindings, but with the parallel efforts we hope that Shiboken takes its place, the size reduction is achieved, and the Occam’s razor cut off the unnecessary entities.

noboost

Occam's razor demands that Boost.Python go

C/C++ Bindings

Another fix that we aim to achieve with Shiboken is to allow non-Qt C++ and C libraries to be wrapped with the generator scheme. The problem with the current Boost.Python generator is that even a non-Qt library wrapped with it will depend on Qt. Of course this is not the best we can do, but the fixing task had low priority since the PySide bindings are the main target of the work. For Shiboken we make it library agnostic from the start, specially because we do not get our chances trying to wrap the whole Qt from start: a test library with all the problems that could arise was made and is the source of all Shiboken unit tests.

Shiboken Features Worth Noting

Abandoning Boost.Python means abandoning some features already provided by it. One that is worth mentioning is the decision of which signature of a method should be called depending on the Python arguments passed on the call. For this to work we have to write a decisor that progressively checks the argument types until the correct signature is found. Just this? Of course not, the binding developer can use the Type System description to remove method signatures, remove/change the type of its arguments, even remove/change/set its default values! The method call decisor must take everything into account.

Overloaded Method

Debugging a multiple signature method call decisor is easier with the "dumpGraph" method.

No Boost.Python also means that would be harder to convert types and containers back and forth between C++ and Python. The template specialization technique was used to solve this one.

template <> struct Converter<bool> {
  static PyObject* toPython(ValueHolder<bool> holder) {
    return PyBool_FromLong(holder.value);
  }
  static bool toCpp(PyObject* pyobj) {
    return pyobj == Py_True;
  }
};

Why not generating “pyobj == Py_True” directly, you say? The above code scales better, since it will be the same for types that are composed of some primitive types inside containers inside containers, etc. Besides, the compiler could be counted on to inline short methods.

“They have a plan”

Right now Hugo (from PySide fame) started working on generating bare QtCore bindings without QObject and signals, then go to QObject. After that we should solve the signals problem, re-write the pieces of custom code and so on. I think after QtCore is completely done we can make a comparison with the one produced by the Boost.Python generator and see if the whole Shiboken idea can stand to its promise. The best should win for the honor and glory of open source.

We encourage everyone interested in the creation of Python bindings for C++ libraries to test Shiboken, report problems (we now have a component on OpenBossa bugzilla!), and tell us if something is missing for your library to work. Patches are always welcome as usual. 🙂

Shiboken on gitorious: http://qt.gitorious.org/pyside/shiboken

PySide

A few days ago the project that I worked on for sometime finally went public: PySide was launched!

PySide - Python for QtAnd “what is PySide?”, you ask me. It is a binding of the Qt4 framework for the Python language created by INdT and Nokia (Moi, tamperelaiset!) under a LGPL license. My team (not that I’m the owner, “mine” in the sense of “our not including the listener” — I think there is a plural for that in Finnish or Quenya) worked as mad and the launching was smooth: we have a positive reception from the community and the news are popping up everywhere.

And we give not only the fish but also the fishing rod: the binding generator was also made available. But what is the importance of this? Since the news was given, the explanation follows.

But before I continue, pay attention to the little Prince of Persia like bottle on the PySide logo. This nice image is a branding used in projects from the Qt Labs Americas.

The Bindings

The main motivation to start the PySide project was to provide Python bindings of the Qt4 library under a LGPL license, to follow the very own Qt4 LGPL license offer from Nokia. Many possibilities on how this should be done where analysed, and before this sentence start an endless technical discussion I must say that all the options have strengths and weaknesses, but aren’t that much different. In the end it was a mix of right-tool-for-the-job, team’s acquaintance with the technologies involved and personal taste. Just to mention a personal favorite, I really appreciate Smoke. In the end we choose to alter an existing binding generator (more on this later) and use Boost.Python as the middle-man to talk to CPython API. To express this with colored boxes this is PySide right now:

PySide architecture with Boost.Python

The Generator

Writing bindings for a library so massively huge as Qt is a task… no, it’s not a task, it is a punishment. Beign reasonable people as we are, a previous research has been made and we opt to adapt the code from QtScript Generator,which is a fork of the Qt Jambi’s Generator, and both are binding generators for QtScript and Java, respectively. They’re developed by Trolltech (when it was called Trolltech).

The binding generation scheme works like this:

Binding Generator Scheme

The global.h file includes all headers (or at least the desired ones) from the library beign wrapped, and is also used to define (and undefine) preprocessor macros. typesystem.xml files contains descriptions of how the library should be exported to the target language and other semantic information: rejeted classes, renames methods, types to be converted, which methods move object ownership from Python to C++ and the otherway around, and specifies where handwritten code for special cases should be inserted. If there is no need for changes, this XML will be a simple list of classes, enums and functions.

Notice that we not only forked the QtScript Generator, we also converted it from an monolithic application to a library + front-end generator scheme. And here is another picture to show the idea:

BoostPythonGenerator

Theoretically the projects from where we derived code could be changed to use the API Extractor and share this code base (and bugs, and fixes, and improvements). Nevertheless this will not be that straightforward, since we have made a number of changes to the typesystem format, from simple things like tag renaming (mostly changing “java” to “targetlang”) to more complex things that I’ll not exemplify here. Besides that, one could write front-ends that use API Extractor to generate things other than bindings: class diagrams with GraphViz, statistics, something-that-i-did-not-thought-about.

Now for the not so beauty part. In a perfect world the C++ to Python binding generator could generate bindings for any C++ library, although, in the way it is right now the generator is useful only for Qt based libraries. Shame on us! Anyhow, taking into account that our main target was to create Qt bindings and that a beta version of them was released, I suggest you forgive us. 🙂 Of course that it is in our plans to solve this and make the generator a useful tool for as many people as possible.

To much information for now! For the time beign download, test, report bugs and enjoy. And, if you’re feeling social, go to #pyside channel on FreeNode and subscribe to the mailing list. Everybody is welcome.

Bugzilla

PySide

Agora sim, chega de trabalhar na moitinha igual contra-regra, o negócio agora é público: PySide foi lançado!

PySide - Python for Qt

Sim! E o que é PySide, você pergunta? São bindings da biblioteca Qt4 para linguagem Python criados pelo INdT e a Nokia (Moi, tamperelaiset!) sob licença LGPL. Minha equipe (não sou dono dela, minha no sentido de “nossa sem incluir o interlocutor”) trabalhou feito louca e o lançamento foi uma beleza: tivemos um retorno positivo da comunidade e as notícias estão aparecendo em toda parte.

E fornecemos não apenas o peixe mas também a vara (na boa): o gerador de bindings também está disponível. Mas qual a importância disso? Dada a notícia vou explicar com calma.

Antes de continuar repare na garrafinha de Prince of Persia no logo do PySide. É a marca usada em projetos do Qt Labs Americas.

Os Bindings

O motivo primário da criação do PySide foi prover bindings Python da Qt4 sob a licença LGPL, para se alinhar com a oferta da Nokia da própria Qt4. Várias possibilidades de como fazer foram analisadas, e antes dessa frase começar uma discussão técnica infinita, todas as opções tinham pontos bons e ruins, mas não tão diferentes assim. A idéia do Smoke foi uma das que mais gostamos e vale uma menção. No fim optamos por alterar um gerador de bindings existente (mais sobre isso abaixo) e usar o Boost.Python para fazer meio-campo com a API CPython. Trocando em diagramas coloridos esse é o PySide:

PySide architecture with Boost.Python

O Gerador

Escrever bindings pra uma biblioteca tão massivamente grande quanto Qt é uma tarefa… não, não é uma tarefa, é uma punição. Pessoas de bom senso que somos demos uma pesquisada por aí e optamos por adaptar o código do QtScript Generator, que por sua vez é um fork do Qt Jambi Generator, e ambos são geradores de bindings QtScript e Java, respectivamente, desenvolvidos pela Trolltech (quando ela se chamava Trolltech).

O esquema de geração de bindings funciona assim:

Binding Generator Scheme

O arquivo global.h inclui todos os headers (pelo menos os desejados) da biblioteca sendo processada, e também define e desdefine flags do preprocessador. Arquivos typesystem.xml são descrições de como a biblioteca deve ser exportada para a linguagem alvo: classes rejeitadas, métodos renomeados, tipos convertidos e, muito importante, códigos escritos à mão para casos especiais e onde eles devem ser inseridos. Se não houver necessidade de alterações esse xml será apenas uma simples lista de classes, enums e funções.

Notem que não apenas forkamos o QtScript Generator, mas a convertemos de uma aplicação monolítica num esquema lib (que chamamos de API Extractor) + front-end gerador. E mais uma figura pra explicar a idéia:

BoostPythonGenerator Teoricamente os projetos dos quais derivamos código poderiam ser alterados para usar o API Extractor e compartilhar essa base de código (e bugs, e fixes, e melhorias). Além disso, o sujeito pode escrever front-ends que gerem outras coisas que não código: grafos de relacionamento entre as classes, estatísticas, algo-que-eu-não-pensei.

Agora a parte não tão bela. Num mundo perfeito o gerador de bindings C++ para Python geraria bindings de qualquer biblioteca C++ para Python, contudo da forma que se encontra agora o gerador serve apenas para bibliotecas baseadas em Qt. Grande vergonha! Considerando que o foco era criar o bindings Qt e os lançamos em versão beta, sugiro nos perdoar. 🙂 Claro que está nos planos resolver isso e tornar o gerador uma ferramente genérica e útil para mais pessoas.

Informação demais! Por hora, baixem, testem, relatem bugs e aproveitem. E se estiverem se sentindo sociais entrem no canal #pyside no FreeNode e assinem a lista de discussão.

Bugzilla

Mensapocalypto

Existe essa associação chamada MENSA, ela aceita apenas as pessoas muito inteligentes como membros. Os candidatos fazem uma prova, parecida com aquelas de Q.I., e apenas os 2% melhores são aceitos.
Reza a lenda que o governo dos EUA levaria os membros da MENSA para abrigos nucleares especiais de onde sairiam para ajudar a reconstruir a civilização.

Dr. Egon Boiffard
Então um dia alguém da Junta de Chefes declara DEFCON 1. Todos os gênios cadastrados pela MENSA são arrancados de suas casas por caras do serviço secreto, deixando pra trás seus menos dotados entes queridos. Lógico.

Depois do choque inicial os escolhidos passam o tempo comendo comida enlatada, jogando xadrez e montando cenários hipotéticos do que iam encontrar quando saíssem do bunker.

Qual o sistema de governo ideal? Como gerir a economia para garantir crescimento e prosperidade para todos sempre? Como manter as pessoas inteligentes e instruídas? Como manter alguma categoria de pessoas burras enquanto não desenvolvem robôs trabalhadores braçais?

Nenhuma surpresa que o excesso de testosterona intelectual mais a falta de pessoas menos inteligentes com as quais ficar se medindo levou à atritos. As rusgas iam desde a instituição de fábricas de bebês perfeitos ao uso de *really* smart drugs até mesmo a criação de notas de 42 dólares.

Quando todos estavam prestes a se matar eis que os indicadores dizem que é seguro sair e as portas se abrem automaticamente. Os geniosinhos mimados correm para fora onde encontram destruição mas também uma multidão maltrapilha. Os do mundo exterior ficam curiosos a respeito dessas pessoas de aspecto tão bem cuidado dadas as circunstâncias e se interessam por sua história. Os cabeçudos tentam todos contar a história ao mesmo tempo, cada um se considerando mais capacitado para tarefa.

Alguns dias depois a multidão acampada finalmente consegue discernir o sentido do que os escolhidos representam e da sua proposta. Sendo assim tomam a atitude mais inteligente que uma multidão de indivíduos bem adaptados o suficiente para sobreviver ao pior de uma guerra atômica sem toda a parafernália tomaria: matar a todos numa frenética orgia de sangue, vísceras e cérebros. Muito feio de se ver, mas pessoas têm de extravasar depois de serem lançadas num inverno nuclear enquanto tentavam levar suas vidas, não?

E pra história ficar mais freak ainda, imaginem algo como um final do He-man ou dos Thundercats, onde todo mundo pára pra dar a moral da história. Isso mesmo, a moral da história! Essa coisa meio vitoriana que de alguma maneira ressurgiu  nos desenhos dos anos 80. Vejamos…

Um dos sobreviventes maltrapilhos olhando pra câmera, o festim sangrento ao fundo. Ele sorri, brincando com um coração em suas mãos vermelhas: “Crianças, lembrem-se de também pensar com o coração.” Ele sorri, pisca, e corre em direção da animação.

There’s a Starman waiting in the sky

Conversa com minha filha, deitado com ela num banco e olhando pra um céu de poucas estrelas.

ela: “Olha, tem uma estrela ali.”
eu: “Só tem uma.”
ela: “Não, tem mais duas, mas são bem pequenininhas.”
eu: “É mesmo. Sabia que elas podem estar mais longe que essa que parece grande? Pode ser que chegando bem perto a pequenininha seja mais brilhante que essa maior. Só tem que chegar perto.”
ela: “Eu posso ir num foguete.”
eu: “É, um foguete pode servir.”
ela: “Ou um avião.”
eu: “Um avião que voa no espaço.”
ela: “Não, um avião que voa de noite!”

Redenção em Shawshank

Numa madrugada dessas da vida assisti um filme aleatório, se chamava “Um Sonho de Liberdade”, e é baseado num conto de Stephen King, mas só reparei no autor muitos anos depois. Eu pensava que ele só escrevia histórias com horrores alienígenas. Esse filme é um desses que se ninguém avisar você não dá nada por ele, pelo menos assim me parecia na época, passando na sessão guarda noturno/insone crônico.

É a história de como o rico banqueiro Andy Dufresne pegou vinte anos na prisão de Shawshank por assassinar sua amada esposa e o cara que estava comendo ela. Na verdade ele não assassinou, mas ora, todo mundo é inocente em Shawshank.

Red e Andy assistindo um filme em Shawshank

Ele então conhece Red (que eu teimo em chamar de Morgan Freeman e, cara, se você quer fazer um filme bom ficar melhor, coloque Morgan Freeman na narração, mas tenha o cuidado do casting parecer casual, ou as pessoas dirão “putz, o diretor quis Morganfreemizar o filme”), que é um muambeiro em Shawshank. Red não ficou muito impressionado com Andy

“Tenho de admitir, não achei grande coisa de Andy a primeira vez que pus os olhos nele. Parecia que uma leve brisa podia soprá-lo pra longe. Esta foi minha primeira impressão sobre o homem.”

Toda prisão tem tarados (deve ser um esquema de cotas), e estes sim acharam grande coisa de Andy, que era mesmo ruim de briga. Ele foi ruim de briga por cerca de um ano. Depois muita coisa que você só vai saber assistindo acontece, e tudo culmina (atenção spoiler!) na fuga de Andy da prisão descrita assim por Red:

“Andy rastejou para liberdade por quinhentas jardas de merda tão fedida que nem posso imaginar. Ou talvez eu só não queira.”

Foi mesmo uma fuga espetacular. Mas o legal do filme é o tema de como os muros da prisão ficam mais na cabeça dos detentos do que ao redor deles. Como Brooks, que é liberado com seus 70 e tantos anos, a maior parte vividos em Shawshank, e não consegue se adaptar no mundo exterior, logo cometendo suicídio. Red tem medo que isso aconteça com ele, mas sente que o processo já começou. Andy é o único que mantém a integridade psicológica, ele é o único que nunca esteve preso ali, e foi capaz de executar um plano de fuga de quase vinte anos. Não seria nem uma fuga, ele só estava indo embora.

Outro personagem interessante é o Tommy, que vivia de pequenos delitos e roubos pouco habilidosos, entrando e saindo de prisões e reformatórios. Ele não conhecia outra vida, provavelmente nasceu com os muros da prisão na cabeça. Andy diz que ele é um ladrão muito incompetente e sugere uma mudança de carreira, se propondo a ajudá-lo a tirar um diploma supletivo. Numa conversa Tommy conta uma história que ouviu de um condenado em outra prisão que esteve, uma informação que poderia inocentar Andy. Então acontece uma tragédia… ah! Vá ver o filme do cara que rastejou por um rio de merda saiu limpo do outro lado.

Ouvindo uma musiquinha em Shawshank

E 500 jardas são 457,2 metros.

Crysis Warhead

Hoje devia ser um dia muito especial. Comprei Crysis Warhead. De verdade, na loja, de papel passado, diante de Deus! É a primeira vez que tenho um hardware decente pra jogar seriamente e não só ficar olhando nas revistas (é faz muito tempo, nem tinha internet quando eu já não podia jogar os melhores jogos).

Podia ter baixado o jogo como todo mundo faz, mas agora que a vida não está mais tão porcaria pensei ser interessante não mais agir de forma porcaria e pagar pelo jogo. (Esse pensamento foi um tanto marxista.)

Voltando ao raciocínio, isso era pra ser muito especial. Digitar serial é coisa que eu nem lembro pra que serve (só uso Windows pra jogos, o resto do tempo é “apt-get” ou “emerge”). Levou um longo tempo pra instalar a bagaça, fiquei pensando nos reviews que vi no YouTube, na diversão de jogar o primeiro Crysis por 7 horas seguidas no computador do dandrader. Cara, foi esse jogo que me fez comprar esse monstro de máquina cara com placa GeForce foda praticamente trazida do futuro pelo Conan! Depois de tudo pronto, o dedo coçando no mouse, essa porra de jogo me diz que as cinco instalações que eu tinha direito já foram feitas e por motivos de segurança o jogo não ia rodar. Segurança de quem CARALHO?!

O que fode tudo, tudinho mesmo, é que meu ódio poderia matar plantas, fazer vacas de duas cabeças nascerem e o Galvão Bueno pedir desculpas por todos esses anos sendo um idiota. Mas tuda essa energia não tem qualquer direção. Não é culpa da moça que me atendeu tão simpaticamente na Saraiva, não é culpa dos game designers, dos programadores, nem do hardware. Provavelmente é culpa de algum advogado de direitos autorais filho da puta que foi abusado quando criança por rottweilers num filme que só foi apreendido pelo FBI depois que todo mundo da escola dele assistiu. Um desses colegas de escola deve ter dividido quarto com ele na universidade de direito.

Bem pode ter sido outra pessoa. Não importa, ela é inatingível pra mim. Eu não posso ligar esporrando pra ninguém, tudo que posso fazer é baixar um crack no torrent com minha conexão sofrível e torcer pra que dê certo.

Claro que posso devolver na loja, pegar meu dinheiro de volta e minha reclamação débil subir a cadeia de consumo até algum lugar misterioso nos Himalayas. É como levar uma surra de olhos vendados. É tão broxante que não dá nem pra se masturbar como atividade compensatória.

Caras do DRM, vocês podem se achar o máximo mas vocês são todos filhos da puta e… pensando bem, eles não devem estar lendo isso aqui porque estão com as cabeças enfiadas em seus próprios cus. Então essa é pra você programador/game designer/etc aleatório que está lendo isso: NUNCA ponha ou deixe que outros coloquem DRM nos seus jogos. Toda vez que você faz isso um fã morre e seu árduo trabalho vira merda.

Update: consegui jogar o treco burlando o DRM e enfim jogar “as it meant to be played”, como diz o logo da NVidia. Baixe esse DLL[1] e coloque no diretório bin32 sobre um DLL de mesmo nome, lá onde o Crysis foi instalado. Ele vai quebrar o esquema de DRM e deixar você se divertir com seu jogo legalmente comprado com seu dinheiro honesto. Mesmo assim depois vou trocar o dvd lá na saraiva.

[1] http://rs498.rapidshare.com/files/146438698/tdm-cw.zip