Category Archives: c++

Here is a Selfie C++ class example.

AKA Singleton (because “Selfie is so 2013″, people are saying).

// Ego.h
class Ego
{
public:
  static Ego *Selfie();

  uint32_t GetLikes() const { return mLikes; }
  void Like() { ++mLikes; }

private:
  uint32_t mLikes;

  Ego() : mLikes(0) { }
  Ego(const Ego&);
  Ego& operator=(const Ego&);
  ~Ego() { }
};

// Ego.cpp
Ego *Ego::Selfie()
{
  static Ego selfie;
  return &selfie;
}

// anywhere_you_go.cpp
#include "Ego.h"
Ego::Selfie()->Like();
Be Sociable, Share!

Windows Media Player, WM_MOUSEMOVE e seu aplicativo

Hoje me deparei com um comportamento estranho num projeto Windows nativo: no começo não tinha percebido, mas o aplicativo estava processando o movimento do mouse constantemente (cerca de 1,5 vezes por segundo). Na Win32 API, isso significa que o loop do aplicativo estava obtendo (do sistema) e despachando a mensagem WM_MOUSEMOVE, que passaria pela WindowProc do aplicativo. O pior é que o mouse estava parado e as coordenadas do mouse sempre vinham iguais.

Verifiquei se o mouse estava com problema e também desconectei dispositivos USB da máquina. Nada. Verifiquei se poderia ser bug introduzido no código depois de algumas alterações recentes e certifiquei que o loop do aplicativo estava correto. Aparentemente, o código estava OK.

Resolvi ver quais aplicativos e serviços estavam rodando no sistema e fui encerrando um por um. Estava ouvindo música no Windows Media Player e, assim que fechei o Media Player, meu aplicativo parou de processar o WM_MOUSEMOVE. Hum, quem diria.

Já percebeu que quando o Windows Media Player está tocando algum arquivo de mídia, o screensaver nunca é executado? Porém, quando o Media Player está aberto mas não está tocando nada, o screensaver chega a ser executado. Aí está a explicação tanto do comportamento do Windows Media Player vs Screensaver como do “bug” do meu aplicativo: o Media Player fica gerando a mensagem WM_MOUSEMOVE a todo momento (simulando que o mouse se movimentou), enquanto algum arquivo de mídia estiver sendo executado.

Fica a dica caso o seu aplicativo/jogo realize muito processamento em resposta ao movimento do mouse ou tenha alguma operação que dependa do movimento do mouse. Dependendo do quão crítico esse tipo de interferência seja para o seu projeto, é melhor responder ao movimento do mouse somente quando o mesmo se deslocar acima de um threshold.

Esse comportamento também é interessante para evitar que o screensaver seja ativado no meio de uma partida do seu jogo, por exemplo. Entretanto, não recomendo essa abordagem, principalmente para mobile, pois isso consumirá mais bateria do aparelho (acho melhor lidar com as interrupções do aparelho e com o ciclo de vida do aplicativo).

PS: antes que alguém me diga para usar outro aplicativo como Winamp ou VLC, vale lembrar que os seus usuários podem estar usando o Windows Media Player junto com seu aplicativo/jogo ou mesmo ter outros aplicativos que interferem de maneira similar ao comentado aqui.

Be Sociable, Share!

Análise de livro: Getting Started with C++ Audio Programming for Game Development (Packt Publishing)

BookCppAudioProgramming

Esse é um livro introdutório para desenvolvedores C++ (intermediário) que querem iniciar em programação de áudio, mais especificamente usando FMOD. O autor começa apresentando no primeiro capítulo alguns conceitos universais de áudio, como volume, pitch, frequência, bit depth e formatos de arquivos de áudio. Em seguida, introduz o FMOD e explica como adiciona-lo a um projeto (Visual Studio C++), como iniciar o FMOD, carregar e reproduzir áudio e verificar erros. Após essa introdução do FMOD, há um projeto para criar um simples gerenciador de áudio através de uma classe C++. No capítulo 3, o autor expande o gerenciador para incluir controle de áudio, isto é, playback, controle de volume, pitch, panning, agrupamento de canais.

Com o básico de áudio explicado, o autor parte para áudio 3D e como trabalhar com áudio posicional, reverb e efeitos no FMOD. Ao trabalhar com áudio posicional, o desenvolvedor precisa lidar com oclusão e obstáculos que afetam a maneira como o áudio é percebido pelo jogador. Este é um tópico que poderia ser explorado com mais detalhes pelo autor, pois ele comenta sobre o assunto em apenas duas páginas. O mesmo vale para efeitos via DSP (processamento de sinais digitais), que é comentado nas 3 últimas páginas do mesmo capítulo de áudio 3D.

A ferramenta FMOD Designer também é apresentada. É uma ótima ferramenta da Firelight Technologies (desenvolvedora do FMOD) para aqueles que são mais focados em design. O autor explica como criar eventos simples de som (como efeitos de passos e vidro quebrando), evento multi-trilha (passos interativos, motor de carro) e música interativa, além de como chamar os eventos via código. Para projetos maiores ou que precisam de algo além do controle básico de áudio, essa ferramenta é obrigatória (ou ao menos valerá muito a pena usa-la).

O último capítulo envolve programação de áudio em baixo nível, isto é, como trabalhar com os bytes de um arquivo de som digital – carregar, tocar, alterar propriedades, etc. Embora FMOD ainda seja usado para o controle de áudio, o leitor tem uma visão “por trás dos panos” sobre APIs de áudio de alto nível.

Com ~100 páginas, esse é um bom livro introdutório para desenvolvedores que não estão familiarizados com programação de áudio, principalmente porque não há muitos livros sobre o assunto (há alguns que focam em programação DirectSound/XACT, mas essas tecnologias parecem estar mortas -ou estão morrendo- e são apenas para plataforma Microsoft). É um livro de C++, mas desenvolvedores de outras linguagens (como C#) também podem se beneficiar do conteúdo, uma vez que o FMOD suporta outras linguagens. A decisão do autor em usar o FMOD é boa também: é uma tecnologia multiplataforma, suporta vários formatos de áudio e é adotado em vários jogos de sucesso, por empresas e game engines (como Unity e UE3). Eu já trabalhei em um jogo multiplataforma usando FMOD para áudio e os resultados foram muito bons.

Para iniciar com programação de áudio, acho que o conteúdo e tamanho do livro estão OK, embora o autor poderia se aprofundar mais em áudio 3D e efeitos via DSP (e incluir código de áudio 3D na classe gerenciadora de áudio; o código-fonte só está disponível para os capítulos 2, 3 e 6).

Vale a pena mencionar que o FMOD Studio não é discutido no livro e, para qualquer tarefa não relacionada a áudio (gerenciamento de janela, render e input), o autor usa o SFML (Simple and Fast Multimedia Library).

Gostaria de ver outro livro do autor/editora com assuntos mais avançados de programação de áudio, como mais detalhes sobre como trabalhar com áudio 3D (e suas implicações), efeitos DSP em tempo real, áudio dinâmico e performance. Seria bom também ver um projeto que inclui FMOD Designer (ou FMOD Studio) e código, não apenas exemplos no livro.

Be Sociable, Share!

Análise de livro: Windows Phone 8 Game Development (Packt Publishing)

No meu antigo blog, vez e outra fazia breves análises sobre livros de desenvolvimento de jogos e artbooks. Nesse novo blog, não cheguei a fazer nenhuma análise – até agora. Eu até poderia escrever sobre algum livro que tenho ou que comprei recentemente, mas… Bom, há alguns dias atrás, surgiu a oportunidade de eu escrever um review, pois a editora Packt Publishing me enviou a versão digital do Windows Phone 8 Game Development (Marcin Jamro) para avaliar. Espero que com essa análise, eu volte a escrever mais sobre livros.

BookWindowsPhone8GameDevelopment

Conforme a descrição do livro, este é um guia prático para desenvolvimento de jogos para Windows Phone 8. Diferente de alguns livros que apresenta um “Hello, World!” para cada tópico apresentado, o autor escolheu desenvolver o projeto de um jogo completo (apresentado no primeiro capítulo), que é incrementado a cada capítulo.

O autor mostra uma visão geral da plataforma Windows Phone 8, do ciclo de vida dos aplicativos, assim como das diferentes maneiras de desenvolver (managed, nativa e híbrida). A abordagem híbrida, usada no livro, me chamou a atenção, pois como desenvolvedor cross-platform acostumado com C++ (ou mesmo C#/XNA), acho interessante ter uma maneira mais fácil/rápida de criar a UI ao mesmo tempo em que é possível desenvolver nativo para performance e processamento mais pesado.

Nesse sentido, o livro usa um misto de C#, C++, C++/CX, XAML e Direct3D, algo que achei meio incomum. C# e XAML para UI, C++/CX e Direct3D para o core do jogo, com uma classe Direct3DInterop fazendo a comunicação entre código nativo e gerenciado.

A abordagem passo-a-passo é boa para iniciantes e há algumas dicas que podem economizar tempo de desenvolvedores com mais experiência (mesmo avançados que vêm de outras plataformas). Há um capítulo sobre o padrão de projeto MVVM (model-view-view model), aplicado ao jogo, e o último capítulo lida com a parte de publicação.

Sobre tópicos atuais, o livro trabalha com localização, mapas, geolocalização, web services e redes sociais (usando API’s do Facebook e Twitter). O jogo desenvolvido no livro também implementa leitor de RSS. Duas features que gostaria de ver rodando em aparelhos reais são realidade aumentada e reconhecimento de voz, pois pareceram ser fáceis de implementar.

Há duas coisas que poderiam ter no livro:
- Algumas features são implementadas só com código gerenciado: o autor poderia explicar brevemente como implementar nativamente ou dar direções (apesar que há alguns links no apêndice), ou mesmo implementar a versão nativa e disponibilizar no código-fonte do livro;
- Apesar de ser um livro de Windows Phone 8, poderia ter alguma discussão (ou comparação) sobre como cada feature do aparelho/SO está relacionado com os concorrentes (iOS e Android), pois atualmente é muito comum o lançamento de apps e jogos em diferentes SO’s e stores.

No geral, o livro cumpre o que promete e recomendaria para qualquer um que tem interesse em aprender a desenvolver jogos para Windows Phone 8.

Be Sociable, Share!

Quando alocação de memória falha (C++)

Talvez por costume com linguagem C e trabalhar com legacy code (alocando com malloc), já vi (e também fiz) isso em alguns projetos:

#include <iostream>

int main(int argc, char *argv[])
{
  const int MB = 1048576;

  char *mem = new char[2047 * MB];

  if (mem)
  {
    std::cout << "Almost 2GB of memory successfully allocated!" << std::endl;
    delete[] mem;
  }
  else
  {
    std::cout << "Bad allocation!" << std::endl;
  }
}

Verificar se a variável mem é válida após alocar memória é algo correto a se fazer, não? Quase. No código C++ acima, o else nunca será executado: quando os quase 2GB alocados acima são realmente alocados, o if é executado. Mas quando não é possível alocar a memória, o que ocorre é uma exceção (std::bad_alloc) e o else não é executado.

Poderia reescrever com um try-catch:

#include <iostream>

int main(int argc, char *argv[])
{
  const int MB = 1048576;

  try
  {
    char *mem = new char[2047 * MB];

    if (mem)
    {
      std::cout << "Almost 2GB of memory successfully allocated!" << std::endl;
      delete[] mem;
    }
  }
  catch(const std::bad_alloc &exception)
  {
    std::cerr << "Exception: " << exception.what() << std::endl;
    return 666;
  }
}

Ou então poderia alocar usando new(std::nothrow), que retorna um ponteiro null quando não é possível alocar memória:

#include <iostream>

int main(int argc, char *argv[])
{
  const int MB = 1048576;

  char *mem = new(std::nothrow) char[2047 * MB];
  
  if (mem)
  {
    std::cout << "Almost 2GB of memory successfully allocated!" << std::endl;
    delete[] mem;
  }
  else
  {
    std::cout << "Bad allocation!" << std::endl;
    return 666;
  }
}
Be Sociable, Share!

Visual Assist X = produtividade++;

logoWTS
Dica para quem usa o Microsoft Visual Studio para qualquer linguagem (com exceção das versões Express) e ainda não usa o Visual Assist X (VAX): compre a licença e sua vida de programador nunca mais será a mesma. Dinheiro muito bem gasto.

O mesmo vale para empresas que usam a IDE; a produtividade dos seus programadores com certeza aumentará e eles ficarão mais felizes (e ao mesmo tempo ficarão P da vida porque terão que comprar uma licença pessoal para usarem na máquina pessoal deles).

Não, não estou recebendo nada para fazer essa “propaganda” :).

O VAX é uma daquelas ferramentas que, depois que você a conhece, fica se perguntando “Como vivi sem você até agora?”. Ela adiciona novas features ao Visual Studio que facilitam diversas tarefas de programação, como por exemplo: melhora no IntelliSense, sugestões de auto-completar, opções de refatoração, navegação entre arquivos mais rápida, correção de digitação, highlight de código e até conversão de . (ponto) para -> em C/C++. Vale a pena ver mais detalhes no site oficial.

Uma feature que sentia falta no Visual Studio é a possibilidade de alternar entre os arquivos h/cpp de maneira rápida (= via teclado), como acontece no XCode. Com o VAX, é só usar o atalho Alt+O.

Algumas features que uso bastante no dia-a-dia:

  • Alt+M para abrir um dropdown com os métodos (e logo em seguida, digitar parte do nome do método e apertar enter para ir pro método).
  • Shift+Alt+F para encontrar referências de símbolos (que é diferente do “Find in Files”).
  • Shift+Alt+R para renomear variáveis, métodos, etc., seja por erro de digitação ou nome mais apropriado (isso mais quando estou refatorando).
  • Fora aquelas que já funcionam automaticamente (IntelliSense, auto-complete, highlight, etc).

    Jogo dos 7 erros

    Segue abaixo duas imagens do VS2010, uma sem o VAX e outra com o VAX. Consegue listar as diferenças? (considerando o highlight de sintaxe como uma única diferença, realmente há 7 itens diferentes entre as duas versões).

    WithoutVax

    WithVax

    Sobre o código acima, é outro assunto que pretendo comentar futuramente aqui no blog.

    Até!

    Be Sociable, Share!