Consegui, após muito esforço e trabalho, finalizar a classe de sound effects (sfx) sincronizada com o resto das classes de som. Lembra do tempo perdido com as funcionalidades inúteis de paSDLMusic? Pois é, aqui elas foram aproveitadas!
Diferente das músicas, existem vários sfx tocando ao mesmo tempo no jogo, ou seja, agora a dificuldade de controlar o que se esta reproduzindo e como se esta reproduzindo é bem maior.
Inicialmente, utilizei a mesma estrutura de paSDLMusic para criar a classe de sfx, modificando apenas as funções e pesquisando as melhores maneiras de controlar cada sfx. Felizmente, a SDL_Mixer oferece opções para controle dos canais, cabendo a mim atribuir cada sfx a um canal.
O problema surge quando os sfx são deletados e quando se necessita utilizar a maldita função que chama um ponteiro para uma função quando o sfx estiver totalmente reproduzido para atualizar a variável boleana stoped (som_parado != som_tocando && som_pausado ).
Diversas foram minhas tentativas de deixar esta classe da forma mais bonita e encapsulada possível, mas não obtive sucesso. Tive que recorrer às funções friend, declarando também esta classe como friend de paSDLAudio para ter acesso ao valor da quantidade de canais desejados pelo usuário, e também recorrer às famosas variáveis estáticas.
O meu plano inicial era criar um alocador dinâmico, onde se pudesse inserir quantos canais se bem entendesse e a memória suportasse. O maior problema disso tudo, além do trabalho árduo com alocação dinâmica de memória, seria usar corretamente a função Mix_AllocateChannels, pois não há como reduzir o canal exato da alocação, e tentar ferir esse princípio da SDL_Mixer seria um trabalho árduo demais.
A solução que encontrei foi estabelecer um limite máximo de 1000 canais, e permitir ao usuário inserir um valor menor se o mesmo desejar.
Dessa forma, consegui especificar o tamanho dos vetor contendo a boleana que indica se o sfx está parado ou não, e do vetor contendo boleanos para cada posição dos canais, indicando falso para não ocupado e true para ocupado. A partir dai fica fácil prever: Usa-se um for para percorrer o vetor boleano, e quando encontrar uma posição vazia, atribui esse numero ao canal utilizado pelo sfx correspondente, atualizando os valores do vetor para true (ocupado) e false (não ocupado) quando o objeto for deletado.
Outro problema que tive foi com relação a sempre tediosa função que chama o ponteiro de uma função quando o sfx estiver terminado. No caso das músicas é fácil porque só uma música toca por vêz, mas como controlar uma variável estática só para todos os sfx?
Além desse problema, perdi um bom tempo tentando desvendar a sintaxe para passar a função como parâmetro para a função SDL que recebe o ponteiro (Mix_ChannelFinished), já que esta recebe uma função que recebe um parâmetro (diferentemente do caso anterior em que nao havia parâmetro recebido). No fim das contas, acabei descobrindo que era exatamente a mesma coisa e fiquei alguns minutos me recuperando da tremenda humilhação perante a máquina rsrsrsrs...
A solução encontrada foi criar uma variável estática que aponta para sua respectiva variável stoped. Tendo o tamanho fixo do vetor e os pontos de atualização do vetor boleano dos canais, ficou fácil saber o momento exato de anular e apontar essa variável.
Ainda tive problemas de compatibilidade com alguns formatos aceitos pela SDL_Mixer. Portanto, ainda estou estudando maneiras de evitar o uso de músicas de formato FLAC e MOD, limitando apenas os formatos que são recomendados para as funcionalidades. Também quero adicionar alguma maneira de tocar sfx em MP3, mas provavelmente estabelecerei o padrão MP3 para músicas, e OGG e WAV para sfx.
Ainda tive problemas com um maldito caso de "_BLOCK_TYPE_IS_VALID pHead nBlockUse" causado quando deletamos de maneira errada alguma variável alocada. Demorei umas duas horas para perceber o erro, que também foi estúpido:
ERRADO:
fileName = new char[tmp] + 1;
CERTO:
fileName = new char[tmp + 1];
Felizmente o encontrei e tudo ocorreu bem.
Ainda pretendo adicionar mais algumas funcionalidades à paSDLAudio que está pouco trabalhada, e também explorar alguns recursos interessantes para sfx, como panning.
Até a próxima!
Nenhum comentário:
Postar um comentário