Allegro para Iniciantes
Objetivo: O objetivo deste tutorial é contribuir para que interessados em desenvolvimento de jogos possam iniciar seus estudos de maneira objetiva. Este tutorial apresenta os conceitos básicos de programação gráfica 2D, voltada para jogos. Por sua simplicidade, o Allegro é o ponto de partida para iniciação à programação de jogos, mas é bom ressaltar que jogos comerciais são desenvolvidos com API's mais avançadas que oferecem muitos outros recursos. Para o desenvolvimento de um jogo, por mais simples que seja, é necessário muito estudo e dedicação. Este tutorial não ensina a criar jogos, mas provavelmente vai dar uma boa noção do funcionamento de funções comuns em muitas das bibliotecas gráficas recomendadas para o desenvolvimento. Ao final deste estudo, o leitor deverá ser capaz de:
Requerimentos:
Instalação: Iniciando nosso estudo, vamos instalar o DevC++ e o pacote do Allegro. Depois iremos testar um código padrão para verificar se a instalação foi feita corretamente.
- Clique duas vezes no programa de instalação do BloodShed DevC++ e faça a instalação;
- Clique duas vezes no pacote do Allegro e faça a instalação utilizando o Packman*;
(* Packman é o gerenciador de pacotes de atualização do DevC++, é apenas um assistente de instalação).
- Se você preferir, pode instalar o pacote do Allegro pelo próprio DevC++, para isso, clique no menu Ferramentas e escolha Package Manager:
(Essa opção irá abrir um assistente de instalações de pacotes do DevC++)
- Clique no botão Install e selecione o caminho onde você salvou o pacote de instalação do Allegro:
- Siga todo o processo de instalação:
(DevC++ Package Installation Wizard)
- Agora, certifique-se de que o Allegro foi instalado com sucesso. Crie um Novo Projeto no DevC++, Selecione a aba MultiMedia, e clique em Allegro Application(static):
(Selecione o tipo de aplicação na aba MultiMedia, nomeie o Projeto e clique em OK)
Após selecionar o Tipo de projeto e nomeá-lo, clique em Ok. O programa pedirá que você salve o projeto. Considere criar uma pasta com o nome do projeto onde você irá salvar todos os arquivos fonte e classas do programa, assim como imagens e sons. Neste projeto não iremos gerar tantos arquivos, pois é apenas um projeto teste para verificar se o pacote foi instalado corretamente. Então escolha um diretório, salve o projeto e o arquivo main.cpp.
Agora pressione F9 ou clique no botão Compilar & Executar. O código padrão será compilado e executado pelo DevC++ e se tudo estiver correto, seu programa não apresentará erros nem warnings, e uma janela vazia será mostrada:
(Janala vazia gerada pelo código padrão da aplicação Allegro)
- Utilize a tecla ESC para fechar a janela.
- Apenas a título de conhecimento, veja o código gerado com comentários:
#include <allegro.h> /* Adiciona as funções do Allegro */ |
- Vamos carregar protótipos e as difinições do Allegro, carregando o arquivo allegro.h:
#include <allegro.h> |
- Como sabemos, ao declarar o arquivo de cabeçalho, teremos acesso às funções pré programadas que facilitam o desenvolvimento do código. O arquivo incluído foi allegro.h, que é a biblioteca gráfica a qual estamos estudando.
- Vamos agora declarar a função principal do nosso programa, a main():
#include <allegro.h> } |
- Agora vamos fazer as definições e chamadas de funções importantes para a utilização do Allegro. A primeira função que devemos chamar é allegro_init(), que inicializará as funções da biblioteca. Logo após esta função, devemos chamar uma função para interpretar os comandos dos dispositivos de entrada, no nosso caso, a função install_keyboard(), referente ao teclado, e se for necessário, outros dispositivos de entrada, como por exemplo o mouse. A função install_keyboard() interpreta os valores do teclado de forma diferente das funções de input padrão de outras bibliotecas, como por exemplo, stdio.h entre outras. Mais definições da função, serão abordadas no tópico referente a movimentação de bitmaps com o teclado. Vejamos agora a utilização das funções:
#include <allegro.h> |
- O próximo passo, está relacionado às definições de video. Vamos definir atravéz da utilização da função set_color_depth(), qual será a profundidade de cores utilizada. Essa função pode receber valores pré estabelecidos de 8, 15, 16, 24 e 32 cores. Este número, é regido por RGB, ou seja, variação de tonalidade de 3 cores primárias que possibilitam a utilização de outras cores. O significado de RGB é na verdade Vermelho(Red), Verde(Green) e Azul(Blue), e é utilizado como padrão para preenchimento de cores em Bitmaps. Exemplo:
(A côr vermelha é formada atravez da RGB [255,0,0] como mostra a imagem)
- Na imagem acima, vemos o princípio da utilização de RGB. Ao Vermelho foi atribuido o número máximo de tonalidade, enquanto ao Verde e Azul, não foi atribuido nenhum número. Como a tonalidade do Verde e Azul é nula, o Vermelho não se mistura com nenhuma outra cor, permanacendo nesta tonalidade.
- Voltando ao Allegro, o que temos que fazer, é informar à função set_color_depth(), quantos bits de cores serão utilizados:
set_color_depth(32); |
set_gfx_mode(GFX_AUTODETECT, 640 , 480 , 0 , 0 ); |
GFX_TEXT | retorna para o modo texto |
GFX_AUTODETECT | faz com que o Allegro escolha o driver gráfico mais apropriado (normalmente tem problemas com placas de vídeo mais recentes) |
GFX_VGA | modo VGA (320x200, 320x100, 160x120, 80x80) |
GFX_MODEX | uma versão planar do modo VGA (tweaked) |
GFX_VESA1 | usa o driver VESA 1.x |
GFX_VESA2B | usa o driver VBE 2.0 em modo banked |
GFX_VESA2L | usa o driver VBE 2.0 com framebuffer linear |
GFX_VESA3 | usa o driver VBE 3.0 |
GFX_VBEAF | usa o acelerador de hardware API VBE/AF |
GFX_XTENDED | usa o driver 640x480 unchained |
- Como podemos perceber, os modos de video acima são definições divididas em duas partes, GFX, que se refere ao modo gráfico, e os modos propriamente ditos, como por exemplo AUTODETECT. Porém, existe outro sub-parâmetro pode ser utilizado; caso você queira deixar seu jogo em modo fullscreen(tela cheia), você deve declarar o modo, e no final acrescentar o sub-parâmetro FULLSCREEN. Caso não o faça, a função irá assumir default, executando seu jogos em uma janela. Você pode especificar que quer seu programa especificamente em uma janela acrescentando WINDOWED. Veja exemplos:
set_gfx_mode(GFX_AUTODETECT, 640 , 480 , 0 , 0 ); /* default */ |
- Uma vez definidos estes parâmetros, podemos iniciar uma rotina para inserir os gráficos. Como estamos utilizando a biblioteca allegro.h, não podemos exibir texto da mesma forma que fazemos com cout ou printf(), pois não fazem parte desta biblioteca. Para imprimir texto utilizaremos o seguinte comando:
textout(screen, font, "texto", 1,1, makecol(255,0,0 ) ); |
- Vamos analizar a função textout() e seus parâmetros:
- Existem outras funções para exibição de texto, porém, não serão exploradas neste tuturial introdutório. Mais informações sobre exibição de texto podem ser encontradas nos links relacionados no final desta página.
- Vamos ver como fazer para inserir estes códigos em nosso programa utilizando a diretiva de condição while():
#include <allegro.h> |
- Agora vamos ver como fazer para inserir uma imagem na janela.
O procedimento é um pouco mais complexo, porém, é muito simples de se fazer. O primeiro passo para se exibir uma imagem, é ter uma imagem, então, vamos criar uma para nosso exemplo:
(Imagem a ser utilizada no exemplo, formato bmp de 24 bits)
O procedimento para adicionar a imagem são:
1 2 3 |
PALETTE pal; /* declaração uma variável tipo PALETTE */ |
#include <allegro.h> |
No código acima, pode-se notar a diferença do código padrão do Allegro mostrado anteriormente, isto por que várias outras funções que não utilizaremos foram retiradas, assim como install_mouse(), clear_keybuf() entre outras; ou seja, o código que você está vendo acima é o mais enxuto possível para imprimir uma imagem e um texto numa janela. A definição da janela está em 640x480, mas poderia ser mudada para qualquer resolução desejada, contanto que a placa de vídeo seja capaz de executar na resolução desejada.
- Um ultimo comando deve ser incluso ao código para para que o programa execute corretamente. A função END_OF_MAIN() faz com que o Allegro entenda que é o fim da função main(), ou seja, o fim do programa. A não inclusão da função END_OF_MAIN() fará com que o DevC++ apresente uma mensagem de erro. Observe o código completo com comentários:
#include <allegro.h> /* Adiciona as funções do Allegro */ |
- Ao executarmos este código, a seguinte janela será exibida:
(Janela de aplicação Allegro exibindo a palavra 'Exemplo' e o desenho de um Aviãozinho)
Desenhando Bitmaps: Agora vamos ver algumas das funções de desenho geométrico primitivo do Allegro. Estas funções são utilizadas para desenhar retas, circulos, retangulos e diversas outras formas atravez de pixels. O que se deve saber a respeito deste tipo de desenho, é a forma com que ele é exibido.
- Vamos apagar uma parte de nosso código, deixando apenas a inicialização das funções do Allegro e a diretiva while():
#include <allegro.h> |
- Para desenhar uma imagem, é necessário criar um ponteiro do tipo BITMAP, que será utilizado como um buffer para a execução da função. Neste ponteiro, será definido o tamanho máximo da imagem que será desenhada. A definição e feita atravéz da função create_bitmap(), que recebe como parâmetro dois números inteiros referente à resolução utilizada na janela. Iremos então criar um BITMAP:
#include <allegro.h> |
- O próximo passo será definir a dimensão e a cor de nossa linha. Para isto, iremos utilizar a função padrão de criação de linha do Allegro, line(), que recebe como parâmetro o ponteiro que criamos(BITMAP), os pontos de início e fim da linha(int), e a função de côr da linha(makecol()). Desta forma a sintaxe da função seria esta:
line(BITMAP *img, int x_inicial, int y_inicial ,int x_final,int y_final, makecol(int,int,int )); |
- E esta seria sua utilização:
line(img, 10,10, 100,100, makecol(255,0,0 ) ); |
#include <allegro.h> |
blit(BITMAP *bitmap, BITMAP *bitmap,int,int,int,largura,altura); |
blit(img, screen,0,0,0,0,640,480); |
#include <allegro.h> |
(Código comentado para geração de uma linha em diagonal utilizando Allegro)
- Executando este código, teremos o seguinte resultado:
(Janela de aplicação Allegro exibindo uma linha diagonal com base nos valores de X e Y iniciais e finais da função)
- Como mencionado anteriormente, existem outras funções gráficas específicas para construção de figuras geométricas. Estas funções funcionam da mesma forma que funções matemáticas e são relativamente simples de se executar, basta que o programador tenha conhecimento de matemática, especificamente de geometria. Vamos ver alguns exemplos das funções:
- Círculo: O circulo, é feito atravéz da função circle(), que tem como parâmetro o ponteiro BITMAP, sua posição X e Y, seu raio e finalmente sua côr:
circle(img, 15,150,100, makecol(255,0,0 ) ); |
- Retângulo: O retângulo, é construido com a função rect(), e recebe como parâmetros um ponteiro de tipo BITMAP, as posições de X e Y do seu início que é no lado superior esquerdo, a posição de terminação, que é o lado inferior direito, e sua côr:
rect(img, 10,10, 100,100, makecol(255,0,0 ) ); |
#include <allegro.h> |
rectfill(img, 11,11,99,99, makecol(0,0,255 ) ); |
- Note que na função rectfill(), os valores das posições de X e Y estão diferentes da função anterior. As coordenadas do preechimento devem ser calculadas para que desenho não sobreponha sua borda. O preenchimento será um pixel menor em todos os lados. O retângulo está sendo desenhado um pixel abaixo no eixo Y e um pixel a frente no eixo X; e sua terminação está um pixel acima no eixo Y e um pixel antes no eixo X. Desta forma temos a seguinte imagem:
(Janela de aplicação Allegro exibindo um retângulo de bordas vermelhas e preenchimento azul)
- Triângulo: O triângulo é uma figura geométrica com 3 pontas, isto significa que para desenharmos um triângulo, além de chamar o ponteiro BITMAP para a construção da imagem, deveremos declarar 3 vértices, de posições X e Y, e por último a côr do triângulo. Esta figura geométrica não é formada por linhas, e sim uma imagem sólida, não podendo ser utilizada a função de preenchimento como nos desenhos anteriores. A função do triângulo é triangle(), e sua sintaxe é:
triangle(img,150,150,350,350,10,350, makecol(255,0,0 ) ); |
- Retas: Além da linha desenhada no primeiro exemplo, com a função line(), existem dois outros tipos de linhas que podem ser utilizados no Allegro; linhas verticais, vline(), e linhas horizontais, hline(), que tem como parâmetro o ponteiro que fará a contrução da imagem, o ponto onde será iniciada a reta, de acôrdo com o tipo escolhido, os pontos X e Y que definirão a extensão da reta, e por último, a cor da linha:
// sintaxe |
- Exisitem outras funções para gráficos geométricos no Allegro, porém neste Tutorial, apenas estas serão abordadas. Se quiser aprender mais sobre estas e outras funções, visite um dos links relacionados no final desta página.
Mover Bitmaps com o Teclado: Agora chegamos numa parte um pouco mais complexa, e para obter resultados com a leitura e necessário que tenha lido os tópicos anteriores. Vamos falar do input pelo teclado, especificamente da forma com que os valores das teclas são obtidos. Vamos aprender como movimentar bitmaps atravez do teclado. Antes de começar, é importante seber de alguns conceitos de utilização do teclado.
- A biblioteca Allegro não possui uma função que armazena o valor digitado pelo usuário em uma variável, como por exemplo a função scanf(). O Allegro tem uma forma diferente de representar os valores das teclas, e para ler as mesmas, é necessário a utilzação de uma estrutura alternativa.
- Primeiramente, vamos observar uma forma de utilização da array key, que é uma espécie de índice de caracteres do Allegro. Cada tecla tem um valor constante correspondente a ela. Para exemplificar, vamos utilizar uma parte do código que fizemos anteriormente, porém, vamos nos concentrar nos parâmetros da função while():
while(!key[KEY_ESC]) { /* Enquanto a tecla não for Esc faça o que está no bloco */ |
- O parâmetro desta função é uma array, key, que está na posição [KEY_ESC], que corresponde a tecla ESC de seu teclado. Esta array é utilizada dentro de uma função da biblioteca Allegro, para detectar, por meio de scancode, se uma certa tecla está pressionada ou não(0 ou 1). Atravéz de valores do ponteiro key, pode-se utilizar teclas específicas para certas interações entre o programa e o usuário. Para isso, o programador deverá saber quais são os valores correspondentes as teclas. Vejamos então o conteúdo da array nesta tabela:
Tecla |
Código na Array |
A, B ... Z |
KEY_A, KEY_B...KEY_Z |
Teclado Numérico 0 a 9 | KEY_0_PAD ... KEY_9_PAD |
Teclado Normal 0 a 9 | KEY_0 ... KEY_9 |
Esc | KEY_ESC |
Enter | KEY_ENTER |
Seta para a Direita | KEY_RIGHT |
Seta para a Esquerda | KEY_LEFT |
Seta para Cima | KEY_UP |
Seta para Baixo | KEY_DOWN |
Pause | KEY_PAUSE |
Barra de Espaço | KEY_SPACE |
Print Screen | KEY_PRTSCR |
Shitf Esquerdo | KEY_LSHIFT |
Shift Direito | KEY_RSHIFT |
Control Esquerdo | KEY_LCONTROL |
Control Direito | KEY_RCONTROL |
Alt esquerdo | KEY_ALT |
Alt Direito | KEY_ALTGR |
- Existem outras teclas que não são mencionadas neste tutorial, pois não serão usadas; mas acredito que esta explicação superficial a respeito da array key, é suficiente por enaquanto.
- Vamos escrever um código que use algumas das teclas mencionadas acima. Mas para isso, vamos entender como fazer para movimentar um Bitmap da forma mais simples.
- Para se desenhar um Bitmap, é necessário informar certos parâmetros à sua função. O principal parâmetro para se movimentar um Bitmap, é a sua posição na tela, ou seja, suas coordenadas X e Y, que dirão onde o Bitmap será desenhado. Então, podemos escrever uma estrutura que vai modificar o valor de X e Y, caso seja pressionada uma tecla de movimentação, definida pelo programador. Vamos exemplificar:
if(key[KEY_RIGHT]) { |
- O código acima, verifica se a seta para direita foi pressionada; como vimos na tabela de valores da array key, a tecla para direita é representada por KEY_RIGHT. A função circlefill() utiliza variáveis no lugar de valores para X e Y. Caso a seta para direita seja pressionada, o valor de X, será acrecido em 1(um), a circunferência será apagada e redesenhada de acordo com o novo valor de X. Essa estrutura é a estrutura básica para movimento de Bitmaps ou sprites, porém pode ser amplamente melhorada. Vamos criar um código que mostre a leitura das quatro setas direcionais do teclado:
#include <allegro.h> #include <stdio.h> |
- O código utiliza sprintf(), uma função da biblioteca stdio.h que guada texto e valores de variáveis em uma string. Essa string foi usada para que a função textout() pudesse imprimir as posições de X e Y dinamicamente.
Colização entre Bitmaps: Agora estudaremos a Colizao entre Bitmaps; para isso, vamos entender o que vem a ser o termo colisão de bitmaps antes de criarmos nosso código de simples colisão.
- O que nós entendemos por colisão no mundo real, é o encontro físico de dois ou mais objetos ou superficies; pode ser considerado colisão, o momento que um veículo se choca com um poste, ou quando uma pessoa pisa no chão ao caminhar. A colisão no mundo real pode ser explicada por uma das leis da física que diz que dois corpos não poderm ocupar o mesmo espaço ao mesmo tempo. Da mesma forma que a colisão física; a colisão de bitmaps acontece quando dois ou mais objetos ou superfícies se tocam, ou seja, quando existem pixels de diferentes bitmaps sendo desenhados em uma mesma coordenada. Na colisão virtual, as leis da física tem que ser ensinadas ao computador para que os bitmaps não se sobreponhão.
- Como forma de ilustração rústica e superficial, vamos considerar um retângulo que foi definido com quatro pontos no plano de Bitmaps: 260,190(x e y superiores),360 e 290(x e y inferiores). Para esse retângulo, as coordenadas não serão alteradas. Criaremos então outro retângulo, que será movido pelo teclado, sendo baseado no código utilizado para movimentação do circulo visto anteriormente. Neste código, o círculo será substituido por um retângulo. Este retângulo terá coordenadas que serão armazenadas nas variáveis tipo x, y, x2 e y2.
- O que iremos fazer, é definir uma área na tela que o retângulo manipulável reconhecerá como barreira. Para fazer este tipo de definição, vamos comparar o valor de X e Y do nosso retângulo com as posições do retângulo estático, e se o nosso retângulo invadir esta barreira, ele será empurrado para fora de acordo com a direção que ele tentou entrar. Vamos ver o código completo para depois analizarmos:
#include <allegro.h> |
- Depois de executar o código pudemos perceber que o retângulo menor, de cor azul, pode ser movido pelas cetas do teclado, porém não entra na área do retângulo vermelho. Como podemos observar no código, existe uma sequencia de diretivas condicionais que comparam os valores das coordenadas dos dois retângulos, em todos os lados, fazendo com que eles sejam afastados para dar uma ideia de colisão física.
- O que fizemos foi uma simples comparação das posições, e definimos um procedimento que será executado no caso de um retângulo invadir o outro.
- Claro que este não é o melhor exemplo de uma detecção de colisão, porém, dá uma ideia superficial de como as colizões funcionam. Neste exemplo, foram utilizados retângulos por serem mais fáceis de se trabalhar, e evitam cálculos matemáticos mais compléxos, porém existem algorítimos específicos para certos tipos de colizao, os quais são mais trabalhosos e complexos para um tutorial destinado a iniciantes, que por sua vez foi escrito por um iniciante.
Utilização de Timer, Mouse e Som: Nesta ultima parte de nosso tutorial, vamos entrar em um conteúdo ainda mias complexo. Por isso, é necessário que os conceitos dos tópicos apresentados acima tenham sido compreendidos, e claro, atenção.
- Neste tópico, vamos estudar o funcionamento das funções install_mouse() e install_sound(), que dependem da função install_timer() para funcionar. Então, vamos ver uma a uma:
Timer: O Timer, é basicamente a função contadora de tempo no Allegro. Os eventos de tempo podem ter diversas utilizações, como por exemplo, contar o tempo que o jogador levou para passar um level de um jogo, ou coisas do tipo, porém, outras funções podem utilizar recursos do Timer.
- Os eventos de tempo, simulam um relógio, ou seja, contam o tempo atravéz de interrupção e retomada constante de uma determinada ação. O intervalo entre execução, parada e retomada de execução, é pré-estabelecido pelo programador. Num relógioa, os ponteiros são analógicamente programados, para executarem um movimento que será interrompido e logo em seguida executado novamente e assim por diante.
- Vamos ver os principais comandos de utilização do Timer e sua sintaxe correta, para isso, vamos utilizar nosso primeiro código, de criação de janela vazia e vamos alterá-lo:
#include <allegro.h> |
install_timer();
|
- Agora vamos inserir uma função que utilizaremos como um callback. Esta função não terá retorno, por que o mesmo não é relevante para a execução do programa; é uma função utilizada apenas constar na sintaxe, neste caso é recomendado que se utilize o modificador volatile como vemos na função. Exitem casos, onde a função callback utilizada pelo Timer tem utilidade real.
|
- O programa não tem como definir por si só, qual a função a ser utilizada pelo Timer, então, próximo passo é informar ao qual será a função e a variável a ser utilizada. Estas declarações são feitas dentro da função main():
|
|
|
- Vejamos agora como fica o código acima com as funções de Timer inclusas:
#include <allegro.h> |
- Após este procedimento, a execução deste programa será uma janela vazia, assim como a janela padrão gerada pela Allegro, a diferença é que as funções que utilizam eventos de tempo podem ser utilizadas agora.
Mouse: Agora que o Timer foi executado, vamos ver o procedimento para iniciar o mouse. O mouse nunca funciona sem o Timer.
- Após ter certeza de que o Timer está funcionando, podemos iniciar o Mouse. A função a seguir, serve para carregar os procedimentos do inicialização do Mouse
|
- O próximo passo é criar um ponteiro do tipo Bitmap onde o cursor do mouse será desenhado, da mesma forma que as figuras geométricas primitivas. O comando utilizado para isso é:
|
- Para exibir o cursor utilizaremos uma função que recebe como parâmetro o ponteiro que criamos acima:
|
- Vamos ver o código completo para que tenhamos uma idéia.
|
- O Allegro tem procedimentos próprio para detectar qual botão foi pressionado, para isso, a função vai atribuir valores aos botões; que são 1 para o botão esquerdo e 2 para o botão direito. Para detectar o botão, o Allegro faz uma verificação do valor de mouse_b; a estrutura if() é a mais indicada para este tipo de verificação por questões de praticidade:
|
- Num jogo, as posições X e Y do cursor do mouse são extremamente importantes em quase 100% dos casos. Por isso, a função do Mouse no Allegro, já tem essas posições dinamicamente armazenadas nas vairáveis mouse_x e mouse_y. Vejamos a utilização:
|
- Ao executar este programa, as posições X e Y do cursor serão guardadas toda vez que o botão esquerdo for pressionado, e novamente armazenadas quando o direito for pressionado, e por fim desenhará um retângulo.
- Estas são as formas mais básicas de utilização do Mouse.
Sound: Agora veremos o procedimento de utilização do som. A função de som necessita do Timer para funcionar. Existem duas finalidades primárias para utilização de som; a música de fundo e os efeitos sonoros relacionados com ações do jogador. Para música de fundo o Allegro utiliza sons no formato Midi, e para os outros sons decorrentes de ações, podem ser utilizados outros tipos de arquivos, porém, formato Wave é o mais comum. Vamos agora ver como é o procedimento de inicialização do som e execução de arquivos de som.
- Assim como os outros dispositivos de entrada, temos que inicializar o som. Para isto vamos utilizar a função install_sound(), porém com alguns parâmetros:
|
- Como parâmetros desta função temos digi_card, que detecta driver de som digital que a placa está usando, em seguida temos midi_card, que detecta o driver de MIDI a ser utilizado. Por último temos cfg_path, que é utilizado para manter compatibilidade de versões mais antigas do Allegro; vamos deixar seu valor em NULL, pois não o utilizaremos.
- Assim como o vídeo, a configuração de som tem alguns valores pré-estabelecidos para entrar como parâmentros desta função. Vejamos alguns dos possíveis valores para digi_card e midi_card:
digi_card:
DIGI_AUTODETECT | instrui o Allegro a escolher o driver de som |
DIGI_NONE | sem som digital |
DIGI_SB | auto-deteccção de placas Sound Blaster |
DIGI_SB10 | Sound Blaster 1.0 (8 bit mono) |
DIGI_SB15 | Sound Blaster 1.5 (8 bit mono) |
DIGI_SB20 | Sound Blaster 2.0 (8 bit mono) |
DIGI_SBPRO | Sound Blaster Pro (8 bit stereo) |
DIGI_SB16 | Sound Blaster 16 (16 bit stereo) |
DIGI_AUDIODRIVE | ESS AudioDrive |
DIGI_SOUNDSCAPE | Ensoniq Soundscape |
midi_card:
MIDI_AUTODETECT | instrui o Allegro a escolher o driver de MIDI |
MIDI_NONE | sem som MIDI |
MIDI_ADLIB | auto-detecção de sintetizadores Adlib ou Sound Blaster FM |
MIDI_OPL2 | sintetizador OPL2 (mono, usado em Adlib e Sound Blaster) |
MIDI_2XOPL2 | sintetizador OPL2 dual (stereo, usado em Sound Blaster Pro-I) |
MIDI_OPL3 | sintetizador OPL3 (stereo, usado em Sound Blaster Pro-II e acima) |
MIDI_SB_OUT | interface MIDI Sound Blaster |
MIDI_MPU | interface MIDI MPU-401 |
MIDI_DIGMID | sample-based software wavetable player |
MIDI_AWE32 | AWE32 (EMU8000 chip) |
- Vejamos como fica nossa função com um dos valores contidos nas tabelas:
|
- Vamos ver como carregar e executar arquivos do tipo Wave com o Allegro. Primeiramente, devemos ter um arquivo de som compatível com o Allegro. Os arquivos Wave podem ter até 16 bits, e devem ser carregados em ponteiros do tipo Sample.
- Vamos criar um ponteiro do tipo SAMPLE onde será carregado o nosso arquivo de som. Este ponteiro recebe uma função que indica o caminho do arquivo, load_wav().
|
- Para executar este som, vamos utilizar a função play_sample(), que recebe como parâmetro o ponteiro criado acima, o volume(0 à 255), o balanço(0 a 255), a frequência(que tem várias configurações, por exemplo 1000 que utiliza a mesma frequência que o arquivo foi gravado) e loop(0:sem loop, 1: loop infinito).
|
- Para parar de tocar um sample, utiliza-se a função:
|
- Onde som é o ponteiro carregado com o som.
- Vamos agora carregar e executar um arquivo no formato Midi. A execução de Midi é mais simples que a de um Sample, pois tem uma outra finalidade que consistem apenas em executar o arquivo com loop infinito, ou executá-lo apenas uma vez até que chegue ao fim do arquivo.
- Primeiramente, vamos criar o ponteiro onde será carregado o conteúdo do nosso arquivo de som; esse ponteiro é será do tipo MIDI, vamos chamá-lo de mid. Para carregar o arquivo de som, utilizaremos a função load_midi(), que tem como parâmetro a localização do arquivo:
|
- Como vimos, o carregamento é similiar ao de um Sample. A execução também é similar, porém não requer a mesma quantidade de parâmetros; apenas o ponteiro do Midi, e se ele vai ter loop ou não:
|
- Na linha acima vemos a função que executará o Midi até que o programa seja encerrado. Caso o segundo parâmetro fosse zero, o arquivo seria executado apenas uma vez.
- Para parar a execução de um Midi, utiliza-se a função:
stop_midi(); |
- Como o Allegro só executa um Midi de cada vez, não é necessário parâmetro para esta função. Este comando fará com que qualquer arquivo Midi em execução páre imediatamente.
- Vejamos agora um exemplo de utilização de um arquivo de som:
#include <allegro.h> |