Ae galera!
Se você chegou aqui e não sabe exatamente o porque, leia a
primeira parte deste tutorial para poder acompanhar tudo certinho.
Agora se você está aqui em plena consciência, então bem vindo a bordo do navio dos loucos!
Brincadeiras a parte, depois de ter
instalado o
Cygwin com a
OSLib e o
editor de código, vamos botar mão à massa e fazer o nosso primeiro programa com a OSLib.
No site oficial da OSLib (
http://brunni.dev-fr.org/index.php?page=pspsoft_oslib) existem vários exemplos que, se você acha que pode ir pra uma coisa mais avançada, pode pegar e começar a estudá-los. Mas se você é apenas um mero mortal tentando aprender algo novo, então vamos por partes.
Em primeiro lugar, é importante saber o que você precisa ter no seu projeto para ele rodar no PSP.
Para compilar o projeto, você precisa do código (geralmente um arquivo
main.c ou
main.cpp) e um arquivo chamado
Makefile, que é ele que vai dizer ao Cygwin o que ele deve fazer com o arquivo main.
Para facilitar, vou colocar um modelo de Makefile que você pode usar em qualquer projeto que você for fazer, fazendo as devidas mudanças quando necessárias.
Além do Makefile, todos os arquivos de imagem que você colocar no jogo devem acompanhar o
EBOOT.PBP, como em qualquer jogo e seu executável. Esse EBOOT.PBP é o arquivo que será gerado depois que você compilar o seu código. Para melhor organização, toda vez que o seu projeto tiver imagens, crie uma pasta chamada "imagens", "imgs" ou qualquer coisa parecida, para que você possa identificar e achar os seus arquivos de imagem mais facilmente. Faça isso para outros tipos de arquivos, como os arquivos de áudio.
Para facilitar na compilação (mais tarde você vai agradecer), vá na pasta que você instalou o Cygwin, depois vá em
home/nomedousuáriodowindows e crie uma pasta para cada projeto que você for fazer. Vou dar um exemplo de como deve ficar o caminho dos seus projetos (supondo que você tenha instalado no drive C: ):
C:\Cygwin\home\Fernando\JogoSuperBruto/main.c
C:\Cygwin\home\Fernando\JogoSuperBruto\imagens/background.png
C:\Cygwin\home\Fernando\JogoSuperBruto\imagens/personagem.png
C:\Cygwin\home\Fernando\JogoSuperBruto\audio/musica.wav
Não se apegue muito à extensão dos arquivos por enquanto, isso é um detalhe que veremos mais a frente. A única sugestão é que o nome da pasta do seu projeto
não tenha espaços (você pode usar o _ se quiser).
Outra coisa que você deve sempre lembrar é o tamanho da
tela do PSP. O PSP tem uma tela de
480 pixels de largura por
272 pixel de altura, por esse motivo as imagens devem ter tamanhos aceitáveis de acordo com a realidade do PSP. Para ser mais preciso, o
tamanho máximo de um arquivo de imagem que pode ser carregado no PSP é de
512x512 pixels e qualquer imagem que tenha tamanho maior não será carregada. Mas mesmo assim, você consegue encontrar sprites e charsets na internet com tamanho menor que isso, além de você ter uma imaginação muito boa para contornar esse pequeno "detalhe" de algum jeito.
- Fazendo o nosso "Hello World"
Como não poderia deixar de ser, o nosso primeiro projeto será um Hello World, mas será um Hello World mais "sofisticado". Eu fiquei algum tempo pensando em como poderia ser esse Hello World para que, com esse exemplo, todo mundo possa começar a brincar com o PSP com recursos mais avançados.
Só para lembrar, para programar para o PSP você precisa saber pelo menos os conceitos básicos da
linguagem C. Se você acha que não sabe o suficiente, procure algum livro ou tutorial na internet e faça uns testes para você ir se habituando à linguagem e suas
funções básicas (if-else, switch, for, while, struct etc).
Vou explicar como será o nosso Hello World.
O nosso super projeto de Hello World terá uma imagem fixa de fundo (
download aqui), do tamanho da tela do PSP (480x272). Terá também um texto escrito "manualmente", isto é, como se você estivesse programando para Console (DOS). Isso é útil porque você não precisa ficar criando imagens pra tudo o que você querer que apareça na tela. Além dessas coisas revolucionárias, terá uma simples demonstração de como reconhecer os botões pressionados. A minha idéia é que depois disso você consiga fazer uma imagem se mover pela tela de acordo com os botões pressionados. Pode ser que o meu tutorial tenha partes semelhantes de outros tutoriais encontrados na internet, por isso, se você achar que eu estou usando um código de sua autoria, é só me falar que os devidos créditos serão dados.
Crie um arquivo
main.c numa pasta chamada
HelloWorld. Vamos ao código:
Código:
/*
Hello World Versão 1.0
Data Início: 30/05/08
Data Fim: 30/05/08
Feito por: Fernando (Falken)
*/
#include <oslib/oslib.h> //Inclui a biblioteca OSLib. Dentro dela estão todas as outras bibliotecas necessárias.
PSP_MODULE_INFO("Hello World",0,1,1); //"Hello World" - nome do projeto, o resto deixe assim sempre
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU); //Nunca mexa nisso!
//Inicio do método main
int main(int argc, char* argv[])
{
//Inicializa os componentes necessários para a execução da OSLib
oslInit(0); //Inicia a biblioteca
oslInitGfx(OSL_PF_8888, 1); //Não mexa aqui tabém (Nota 1)
//Finaliza o jogo caso algum arquivo não consiga ser carregado
oslSetQuitOnLoadFailure(1);
int apertou = 0; //Aqui é uma gambiarra porque não tem variável do tipo BOOL em C, então 0 = false e 1 = true
OSL_IMAGE *imgFundo; //Cria a variável que vai carregar a imagem de fundo
imgFundo = oslLoadImageFilePNG("imagens/fundo.png", OSL_IN_RAM, OSL_PF_5551); //Carrega a imagem do arquivo (Nota 2)
imgFundo->x = 0; //A imagem será posicionada no canto esquerdo da tela
imgFundo->y = 0; //A imagem será posicionada no canto superior da tela
//Desta forma, a imagem que tem 480x272 pixels irá ocupar toda a tela do PSP
//Agora vamos definir as cores do texto
oslSetBkColor(RGBA(0,0,0,0)); //Esse método define a cor de fundo do texto (Nota 3)
oslSetTextColor(RGBA(255,255,0,255)); //A cor do texto será amarela e não terá transparência
//Looping principal do jogo
while(!osl_quit)
{
if(!osl_skip) //Isso garante que o sistema não tente desenhar as imagens se ocorrer algum problema (Nota 4)
{
oslStartDrawing(); //Você deve chamar esse método para poder desenhar as imagens na tela
oslDrawImageSimple(imgFundo); //Desenha a imagem nas coordenadas que foram definidas antes
oslPrintf_xy(10,10,"Hello World - Meu primeiro programa para o PSP"); //Escreve o texto na tela na posição definida
oslPrintf_xy(10,20,"Aperte algum botao ou aperte START para sair.");
oslReadKeys(); //Se uma tecla for pressionada, então ele guarda o valor
if(osl_pad.pressed.cross)
{
oslPrintf_xy(10,40,"Voce apertou o botao x");
apertou = 1; //Guarda o valor 1 (true) dizendo que o usuário apertou algum botão
}
if(osl_pad.pressed.circle)
{
oslPrintf_xy(10,40,"Voce apertou o botao circulo");
apertou = 1;
}
if(osl_pad.pressed.square)
{
oslPrintf_xy(10,40,"Voce apertou o botao quadrado");
apertou = 1;
}
if(osl_pad.pressed.triangle)
{
oslPrintf_xy(10,40,"Voce apertou o botao triangulo");
apertou = 1;
}
if(osl_pad.pressed.start)
{
break; //Esse break vai fazer o programa sair do while(!osl_skip)
}
if(apertou==1) //Se o usuário apertou algum botão, então...
{
oslPrintf_xy(10,50,"Aperte qualquer botao para continuar");
oslSyncFrame(); //Atualiza a tela
oslWaitKey(); //Aguarda que algum botão seja pressionado (Nota 5)
apertou=0; //Volta a variável ao seu estado original, ou seja, dizendo que o usuário não apertou nada
}
oslEndDrawing(); //Finaliza o método que desenha as imagens
oslEndFrame(); //Informa ao PSP que aquele frame foi executado
oslSyncFrame(); //Atualiza a tela novamente
}
}//Fim do looping principal
oslDeleteImage(imgFundo); //Apaga a imagem da memória
oslEndGfx(); //Finaliza a biblioteca
oslQuit(); //Sai do programa e volta para a Home do PSP
return 0;
}
Notas:1 - O primeiro valor de parâmetro
(OSL_PF_8888) é o "pixel format", que define o tamanho do pixel que você quer desenhar, nesse caso, ele usa o tamanho padrão. O segundo parâmetro
(1) é o tamanho do double buffering (eu nunca vi algum código com esse número diferente de 1, por esse motivo eu aconselho a nunca mudar esse valor).
2 - A OSLib permite trabalhar com alguns formatos de imagem, mas vamos trabalhar com imagens
PNG por possuírem uma qualidade melhor sem sobrecarregar a memória. No segundo parâmetro, onde está escrito
OSL_IN_RAM, significa que a imagem ficará carregada na memória
RAM do PSP. O terceiro parâmetro é o pixel format da imagem, veremos sobre ele mais adiante, por enquanto vamos usar o
OSL_PF_5551.
3 - RGBA(0,0,0,0) - isto é, os
3 valores de RGB mais
um valor para transparência (red, green, blue, alpha) (todos podem ser de 0 a 255). Se o último valor for 0, significa que a cor será totalmente transparente. Se for 255, nenhuma transparência será aplicada.
4 - Geralmente, na condição if(!osl_skip) são colocadas apenas as chamadas de métodos que desenham as figuras na tela, com o
oslStartDrawing e o
oslEndDrawing dentro da condição. Nesse caso estamos fazendo diferente para que quando um botão seja pressionado o resultado apareça na tela imediatamente.
5 - Sempre que puder, evite usar esse comando. Nesse caso eu uso para que o usuário possa ver a mensagem anterior (Aquela que mostra qual botão foi pressionado). Num jogo normal, você dificilmente vai precisar dessa "parada" de execução. O método
oslReadKeys(); resolve todos os seus problemas sem precisar parar a execução.
Agora vamos ver o arquivo
Makefile desse projeto, sendo que eu já vou explicar o que você precisa mudar para usar em outro projeto. Para fazer o Makefile, crie um
arquivo novo sem extensão e copie esse conteúdo dentro do arquivo. Depois salve o arquivo com o nome de Makefile, não esquecendo de tirar a extensão do arquivo (alguns editores já vêm com uma opção de você criar um novo arquivo Makefile).
Código:
TARGET = helloworld
OBJS = main.o
INCDIR =
CFLAGS = -G4 -Wall -O2
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)
LIBDIR =
LDFLAGS =
STDLIBS= -losl -lmikmod -lpng -lz \
-lpspsdk -lpspctrl -lpspumd -lpsprtc -lpsppower -lpspgu -lpspaudiolib -lpspaudio -lm
LIBS=$(STDLIBS)$(YOURLIBS)
EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = Hello World
PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak
Os itens que você pode mudar são:
TARGET = nomedoprojeto - esse nomedoprojeto não é nada de mais, mas coloque para você não se confundir.
OBJS = main.o - quando compilado, o arquivo main.c vai virar um arquivo main.o e é esse arquivo que o EBOOT.PBP usa. Caso você use mais arquivos, coloque o nome de todos (por exemplo: OBJS = main.o ai.o game.o)
PSP_EBOOT_TITLE = Hello World - esse é o nome que irá aparecer no menu do seu PSP.
O resto fica tudo igual.
Agora vamos à parte legal! Vá até o diretório que você instalou o cygwin e execute ele (
cygwin.bat). Nessa parte você precisa de alguns conhecimentos de comandos linux, mas são coisas simples.
Se você não se lembra o nome da pasta em que você criou seu projeto, digite o seguinte comando:
Citação:
ls
Agora que você já sabe o nome da pasta, digite:
Citação:
cd NomeDaPasta
Feito isso, digite:
Citação:
make
Se aparecer um monte de coisa escrita e no final algo como uma
tabela com numeração à esquerda, significa que
você conseguiu! Se não aparecer, de uma lida e tente identificar os erros encontrados, geralmente é muito simples para corrigi-los.
Agora uma coisa importante. Para executar a sua homebrew, você precisa ter um PSP com
Firmware 1.5 ou algum
Custom Firmware. Se o seu PSP tiver um Custom Firmware, vá até a pasta
PSP\GAME, crie uma pasta nova (o nome dessa pasta não é muito importante, mas nunca coloque espaços) e dentro dessa nova pasta copie o arquivo
EBOOT.PBP, que apareceu na pasta original do projeto, e a pasta
imagens com todo o seu conteúdo. O diretório deve ficar assim:
Citação:
X:\PSP\GAME\HELLOWORLD/EBOOT.PBP
X:\PSP\GAME\HELLOWORLD\imagens/fundo.png
Vá até o menu do PSP e tente executar o novo ícone que apareceu. Se não funcionar, existem duas possíveis soluções:
1 - Vá até o menu Recovery do Firmware (Desligue o PSP, segure o botão R e ligue ele) e mude o kernel para 1.50. Tente novamente.
2 - Mude a sua pasta para X:\PSP\GAME150\HELLOWORLD, e tente novamente.
O
meu PSP tem a versão de
Firmware 3.80 M33-5 e tem algumas homebrews antigas que não rodam nele, mas até agora todas as que eu fiz rodaram normalmente. Se você estiver com dificuldades para executar sua homebrew, me avise que farei o possível para te ajudar.
Para as pessoas que conseguirem fazer esse HelloWorld funcionarem, fica um
desafio:
- Crie 4 imagens diferentes, com o mesmo tamanho, de um personagem, sendo que cada imagem vai conter o personagem numa direção diferente.
- Crie duas variáveis inteiras (x e y) e posicionem o personagem na tela de acordo com o valor dessas variáveis.
- Faça a leitura dos botões pressionados e vá aumentando/diminuindo os valores de x e y de acordo com os botões.
Dicas: Os botões das setas são left,right,up e down. Experimente mudar a condição if(osl_pad.pressed.BOTAO) para if(osl_pad.held.BOTAO). Faça um teste com os dois casos.
Espero que tenham gostado! No próximo tutorial eu vou mostrar um exemplo de movimentação de personagem na tela e vou adicionar uma música de fundo!
Agradecimento especial: Oldrider, pela documentação da OSLib traduzida (http://www.neyestrabelli.com/blog/)
Baixe os arquivos deste exemplo aqui:
http://rapidshare.com/files/125286429/HelloWorld.zip.html (se o link sair do ar, por favor avise por PM para evitar flood no fórum)
Arquivo de imagem:
http://rapidshare.com/files/125286568/imagens.zip.html
Obs.: Peço desculpa pela demora de postar a segunda parte do tutorial. Como vocês devem ter reparado no código, eu já tinha quase tudo pronto no final de maio, mas a faculdade e o trabalho acabaram tomando todo o meu tempo. Agradeço ao meu amigo (bro) Tydres pelas cobranças e incentivos para eu postar o tutorial o mais rápido possivel!