Entrar
Últimos assuntos
» player não consegue andarpor lovn7 Qui 21 Nov 2024, 13:33
» É possível fazer istó no game maker
por William Lima Qui 21 Nov 2024, 10:56
» Rio Rise - novo launcher do Gta San Andreas SAMP Brasil
por Lua Sáb 16 Nov 2024, 20:22
» (Resolvido) Cenario longo x Texture Pages
por josuedemoraes Sáb 16 Nov 2024, 15:31
» Kids' band
por Adilson Lucindo Santos Sex 15 Nov 2024, 12:23
» (RESOLVIDO) Engasgos-Troca de Sprites/animações
por josuedemoraes Ter 12 Nov 2024, 01:49
» Block Room - DEMO
por Joton Qua 06 Nov 2024, 22:58
» Game Infinito vertical (subindo)
por macmilam Sáb 26 Out 2024, 12:36
» Retorno da GMBR!!!
por Dancity Ter 22 Out 2024, 16:36
» Máquina de estados
por aminaro Qui 10 Out 2024, 13:33
» como faço pra um objeto colidir com o outro e diminuir a vida do player ?
por josuedemoraes Qui 03 Out 2024, 16:51
» RESOLVIDO: Colisão com objetos moveis
por josuedemoraes Qua 02 Out 2024, 20:28
» Crypt of the Blood Moon
por divin sphere Qua 11 Set 2024, 18:18
» como fazer um objeto seguir?
por divin sphere Dom 18 Ago 2024, 18:08
» Procuro de alguém para Modelar/Texturizar/Animar objetos 3D
por un00brn Dom 11 Ago 2024, 11:10
» Destruição de cenário (estilo DD Tank)
por CoronelZeg Sex 09 Ago 2024, 17:16
» RESOLVIDO-Como destruir uma instancia especifica de um objeto
por josuedemoraes Ter 23 Jul 2024, 00:40
» Automatizar a coleta de id
por GabrielXavier Seg 22 Jul 2024, 18:01
» Preciso de ajuda para concluir um pequeno projeto
por lmoura Qui 27 Jun 2024, 15:45
» ANGULO ACOMPANHAR O OBJETO
por Klinton Rodrigues Qui 27 Jun 2024, 08:34
» Musica reinicia quando sala reinicia
por GabrielXavier Ter 18 Jun 2024, 07:28
» como fazer uma copia de gd
por generico_cube Sex 14 Jun 2024, 15:48
» Square Adventure
por guilherme551 Ter 11 Jun 2024, 09:54
» como posso definir limite de uma variavel
por GabrielXavier Sex 07 Jun 2024, 14:14
» [Resolvido] Dúvida, colisão única de objeto
por vdm842 Sex 24 maio 2024, 09:50
[Tutorial]GMAPI
+2
theguitarmester
Jiraya
6 participantes
Página 1 de 1
[Tutorial]GMAPI
a algum tempo atras um membro da gmc desenvolver uma biblioteca muito poderosa para c++
onde permite desenvolver dlls que acessem todas as funções do game maker direto no runner, provavelmente via injeção assembly no executavel.
bom, isso permite desevolvermos extensões extremamente poderosas e MUITO mais rapidas do que dlls comuns.
vou ensinar como instalar e criar uma simples dll exclusiva.
primeiro você ira precisar dos seguintes programas
Microsoft Visual C++ 2010
DirectX 8.1 SDK
GMAPI 0.0.6
eu ja recompilei as bibliotecas do gmapi com o microsoft visual studio 2012 para vocês, assim não terão problemas com isso.
1º Passo
instale o Microsoft Visual C++ 2010 express
2º Passo
instalando o directX sdk
é bem simples quando executa-lo, ira aparecer uma caixa de dialogo, clique em "Unzipe" extraia em umas pasta facil de achar
depois vá até essa pasta e execute o "Setup.exe"
então vai começar a instalar
3º Passo
Instalando o gmapi na visual c++
muito bem, após ter baixando o GMAPI
abra ele e copie os arquivos que estão na pasta includes para a pasta C:\Program Files\Microsoft Visual Studio 10.0\VC\include
copie os arquivos da pasta lib para C:\Program Files\Microsoft Visual Studio 10.0\VC\lib
4º Passo
Abra o microsoft visual c++
clique em New Project>Empty Project
agora clique na pastinha "Source Files>Add>New Item"
escolha "C++ File(.cpp)"
nomeie como "Main.cpp"
então clique no botão "Add" ou pressione Enter
digite o seguinte código
isso é meio que um código padrão, você sempre ira precisar dll quando quiser criar uma dll exclusiva.
[nota] eu me refiro a exclusiva, pelo fato dela só funcionar no game maker.
mude o target na barra de ferramentas para "Release"
agora vamos linkar a biblioteca précompilada ao seu projeto, assim a compilação será mais rapida
clique em Project>{Nome do seu Projeto} Properties na barra de ferramentas
clique em "Configuration Properties>General" clique no combobox Configuration Type e escolha o "Dynamic Link(.dll)"
agora clique em Linker>Input>Additional Dependencys, substitua o que tem lá por
gmapi-mt-dll.lib
clique em ok
e pressione F5 para ver se esta funcionando
se aparecer uma mensagem com "Unable to start program.....DLL" significa que funcionou
agora vamos criar uma função que funcione no game maker
digite o seguinte no final do código
agora pressione F5 para construir sua DLL
agora vá até a pasta onde sua dll foi criada
por exemplo a minha foi criada na seguinte pasta
C:\Users\Shiro\Documents\Visual Studio 2010\Projects\GMBR DLL\Release\GMBR DLL.dll
então agora abra o game maker
salve o .gmk na mesma pasta que a dll, ou seja na area de trabalho
agora crie um objeto e coloque o seguinte código no create evento desse objeto
coloque o seguinte código no evento draw desse objeto
crie uma room e coloque o objeto la, então teste ;)
parabéns você conseguiu criar sua primeira dll exclusiva para o game maker!
caso você não tenha conseguido, pergunte qual é a sua duvida, e onde teve problemas para entender.
espero que tenham gostado, como as funções são exatamente iguais a do gm, espero ver boas dlls por aqui : D!
onde permite desenvolver dlls que acessem todas as funções do game maker direto no runner, provavelmente via injeção assembly no executavel.
bom, isso permite desevolvermos extensões extremamente poderosas e MUITO mais rapidas do que dlls comuns.
vou ensinar como instalar e criar uma simples dll exclusiva.
primeiro você ira precisar dos seguintes programas
Microsoft Visual C++ 2010
DirectX 8.1 SDK
GMAPI 0.0.6
eu ja recompilei as bibliotecas do gmapi com o microsoft visual studio 2012 para vocês, assim não terão problemas com isso.
1º Passo
instale o Microsoft Visual C++ 2010 express
2º Passo
instalando o directX sdk
é bem simples quando executa-lo, ira aparecer uma caixa de dialogo, clique em "Unzipe" extraia em umas pasta facil de achar
depois vá até essa pasta e execute o "Setup.exe"
então vai começar a instalar
3º Passo
Instalando o gmapi na visual c++
muito bem, após ter baixando o GMAPI
abra ele e copie os arquivos que estão na pasta includes para a pasta C:\Program Files\Microsoft Visual Studio 10.0\VC\include
copie os arquivos da pasta lib para C:\Program Files\Microsoft Visual Studio 10.0\VC\lib
4º Passo
Abra o microsoft visual c++
clique em New Project>Empty Project
agora clique na pastinha "Source Files>Add>New Item"
escolha "C++ File(.cpp)"
nomeie como "Main.cpp"
então clique no botão "Add" ou pressione Enter
digite o seguinte código
- Código:
//desativa o modo 3d, ja que parece não funcionar muito bem
#define GMAPI_NO_D3D
//inclui o gmapi com todas as funções do game maker
#include <gmapi.h>
//uma definição para o prefixo, uma forma mais facil de tornar a função publica para chamadas externas
#define GML extern "C" __declspec(dllexport)
//objeto handler, que vai permitir o acesso ao runner
gm::CGMAPI* gmapi;
using namespace gm;
//esse é o controle sobre as reações da dll
BOOL WINAPI DllMain( HINSTANCE aModuleHandle, int aReason, int aReserved ) {
switch ( aReason ) {
case DLL_PROCESS_ATTACH: {
// Caso a dll esteja linkada ao programa e funcionando então executara isso
unsigned long result = 0;
//tentar acessar o executavel
gmapi = gm::CGMAPI::Create( &result );
//checa se houve falhas na inicialização
if ( result != gm::GMAPI_INITIALIZATION_SUCCESS ) {
return FALSE;
}
break;
}
case DLL_PROCESS_DETACH:
// Evento que ocorre quando a dll é liberada
//destroy o handler que acessa o runner
gmapi->Destroy();
break;
}
return TRUE;
}
isso é meio que um código padrão, você sempre ira precisar dll quando quiser criar uma dll exclusiva.
[nota] eu me refiro a exclusiva, pelo fato dela só funcionar no game maker.
mude o target na barra de ferramentas para "Release"
agora vamos linkar a biblioteca précompilada ao seu projeto, assim a compilação será mais rapida
clique em Project>{Nome do seu Projeto} Properties na barra de ferramentas
clique em "Configuration Properties>General" clique no combobox Configuration Type e escolha o "Dynamic Link(.dll)"
agora clique em Linker>Input>Additional Dependencys, substitua o que tem lá por
gmapi-mt-dll.lib
clique em ok
e pressione F5 para ver se esta funcionando
se aparecer uma mensagem com "Unable to start program.....DLL" significa que funcionou
agora vamos criar uma função que funcione no game maker
digite o seguinte no final do código
- Código:
//GML é um prefixo que criamos para indicar que a função será EXTERNA, ou seja o game maker poderá chama-la
//se observa-mos, a função tem 3 argumentos e retorna a um valor real(double), lembre-se disso
GML double DRAW_TEXT(double x,double y,char *str)
{
//gm:: é um namespace, sempre que você
draw_text(x,y,str);
return(0);//é obrigatório que as funções retornem a algum valor
}
agora pressione F5 para construir sua DLL
agora vá até a pasta onde sua dll foi criada
por exemplo a minha foi criada na seguinte pasta
C:\Users\Shiro\Documents\Visual Studio 2010\Projects\GMBR DLL\Release\GMBR DLL.dll
se encontrou sua dll tbm, copie ela para a area de trabalhoC:\Users\NOME DO SEU COMPUTADOR\Documents\Visual Studio 2010\Projects\NOME DO SEU PROJETO\Release\NOME DO SEU PROJETO.dll
então agora abra o game maker
salve o .gmk na mesma pasta que a dll, ou seja na area de trabalho
agora crie um objeto e coloque o seguinte código no create evento desse objeto
- Código:
DRAWTXT=external_define("GMBR DLL.dll","DRAW_TEXT",dll_stdcall,ty_real,3,ty_real,ty_real,ty_string);
//o primeiro parametro é o nome da dll
//o segundo parametro é o nome da função na dll
//o terceiro parametro é o tipo de chamada, vamos usar o dll_stcall que é o padrão
//o quarto parameto é o tipo de retorno, lembre-se que a função retorna a "DOUBLE" então devemos indicar como ty_real
//o quinto parametro é o numero argumentos que a função tem
//os outros parametros é o tipo de valor que cada parametro receberá
coloque o seguinte código no evento draw desse objeto
- Código:
external_call(DRAWTXT,mouse_x,mouse_y,"Olá! esse texto esta sendo desenho pela dll !");
crie uma room e coloque o objeto la, então teste ;)
parabéns você conseguiu criar sua primeira dll exclusiva para o game maker!
caso você não tenha conseguido, pergunte qual é a sua duvida, e onde teve problemas para entender.
espero que tenham gostado, como as funções são exatamente iguais a do gm, espero ver boas dlls por aqui : D!
Última edição por Jiraya em Dom 16 Set 2012, 12:15, editado 1 vez(es)
Re: [Tutorial]GMAPI
Desculpe se Sou Meio Ignorante(no sentido Burro!), mas Qual seria a Vantagem de Fazer DLLs usando as mesmas Funções do GM, é só fazer Scripts ou Fazer Usando o GameMaker Library/Extension Maker.
e, eu que não sei Criar nada de DLL, como aprender ou Descobrir os Codes Que Existem para criar as Dlls(não os do GM), como por Exemplo "mouse_x" "Move" "SET Y", no Game Maker você Tem a Lista Com As variaveis e o Auto Complete, mas no C+ não(pelo menos não vi), e nem em Alguns Outros Programas de Edição(por isso o que mais Gostei Foi do GM, alem do D&D que é algo Muito bom, e outras Coisas).
e, eu que não sei Criar nada de DLL, como aprender ou Descobrir os Codes Que Existem para criar as Dlls(não os do GM), como por Exemplo "mouse_x" "Move" "SET Y", no Game Maker você Tem a Lista Com As variaveis e o Auto Complete, mas no C+ não(pelo menos não vi), e nem em Alguns Outros Programas de Edição(por isso o que mais Gostei Foi do GM, alem do D&D que é algo Muito bom, e outras Coisas).
Re: [Tutorial]GMAPI
uma das vantagens é que c++ é uma linguagem compilada e gml como js é interpretada, é claro linguagens compiladas sempre serão mais rapidas que interpretadas ainda mais quando nos referimos ao c++/c.
o gmapi acessa as funções do game maker POREM você tambem pode usar todo o extremo poder do c++ como windows api,sockets,IOS, e todos os headers que existem para c++.
mesmo que a dll seja exclusiva para o game maker c++ prevalece, ou seja.
você pode construir todo um algoritimo em c++ puro
e enviar os resultados DIRETAMENTE à memoria do game maker
como
gm::CGMVariable result;
isso criaria uma variavel dentro do game maker.
outro ex:
com o gmapi, você pode acessar as sprites como bitmaps diretamente da memoria e edita-las em velocidade C++, como o GMTINT que o kabeção desenvolveu.
se você fosse fazer algo do tipo em gml puro iria ser tão lento que não seria nada animador usar.
isso não é nem 2% comparado à quantidade extraordinaria de vantagens que existem.
o gmapi acessa as funções do game maker POREM você tambem pode usar todo o extremo poder do c++ como windows api,sockets,IOS, e todos os headers que existem para c++.
mesmo que a dll seja exclusiva para o game maker c++ prevalece, ou seja.
você pode construir todo um algoritimo em c++ puro
e enviar os resultados DIRETAMENTE à memoria do game maker
como
gm::CGMVariable result;
isso criaria uma variavel dentro do game maker.
outro ex:
com o gmapi, você pode acessar as sprites como bitmaps diretamente da memoria e edita-las em velocidade C++, como o GMTINT que o kabeção desenvolveu.
se você fosse fazer algo do tipo em gml puro iria ser tão lento que não seria nada animador usar.
isso não é nem 2% comparado à quantidade extraordinaria de vantagens que existem.
Re: [Tutorial]GMAPI
Isso é realmente últil pra quem não pretende desenvolver para outra plataforma senão o windows pois amarra o codigo nesta plataforma, mas mesmo assim se eu fosse criar alguma DLL criaria em Delphi 7 (Win32) pois é bem mais simples e posso fazer qualquer coisa com ele também.
Flws!
Flws!
Re: [Tutorial]GMAPI
Pode ser que agora comecem a aparecer novas dlls por aqui.
Legal o tutorial. É bem útil mesmo.
Estou baixando o DirectX SDK. Que pesado...
--------------------------
Encontrei dois erros:
O outro erro:
Até mais!
Legal o tutorial. É bem útil mesmo.
Estou baixando o DirectX SDK. Que pesado...
--------------------------
Encontrei dois erros:
Se você substituir, vai dar erro de Unresolved Externals. Tem que adicionar ao já existente, separando por ponto-e-vírgula.agora clique em Linker>Input>Additional Dependencys, substitua o que tem lá por
gmapi-mt-dll.lib
O outro erro:
Esses dois asteriscos estão forçando a conversão para true ou false, então o GM tá desenhando "1" em vez de uma string. Removendo um asterisco o problema é resolvido.GML double DRAW_TEXT(double x,double y, char **str)
Até mais!
Leia o Manual do Iniciante e a Lista de Tutoriais, para aprender bastante sobre o GM.
Recomendo o Manual completo das colisões, bem útil.
O exemplo Criar um chat (banir, kickar, etc) é interessante.
Para seu jogo ficar rápido e legal, aprenda a Aumentar o desempenho do seu jogo.
Aprenda a calcular a velocidade de suas animações
Entre para o Clube do Inglês:
Re: [Tutorial]GMAPI
bom, a limitação da gmapi é que ela só funciona no game maker 8.0
Isso é realmente últil pra quem não pretende desenvolver para outra plataforma senão o windows pois amarra o codigo nesta plataforma, mas mesmo assim se eu fosse criar alguma DLL criaria em Delphi 7 (Win32) pois é bem mais simples e posso fazer qualquer coisa com ele também.
Flws!
versões mais recentes como 8.1 e studio tem um runner MUITO diferente, então o injetor não funciona corretamente.
o GMS é uma plataforma para poucos, logo maioria esta "amarrada" ao windows...
Pedro
obrigado pela observação!
eu estou desenvolvendo uma dll com o gmapi, é uma GUI melhorada, e EXTREAMAMENTE rapida, com gml puro eu rodei 500 objetos a 10 de fps
com a dll rodei 500 objetos a 30 de fps
Re: [Tutorial]GMAPI
bacana, quer dizer que se alguém aqui usar essa técnica pra fazer uma extensão com todas as funções do GM, teremos uma espécie de Runner em C++ para o GM!! o que deixaria os jogos muito mais rápidos!!
Muito bom!!
Muito bom!!
Re: [Tutorial]GMAPI
Realmente muito interessantes isso jiraya parabéns, o bom de se usar essas dlls é que elas aumentam e muito a velocidade no processamento de algo, já estou pensando até em usar em projetos futuros.
Kapoty- Games Ranking :
Notas recebidas : E + D + C + B + D +B + A
Data de inscrição : 05/11/2011
Reputação : 22
Número de Mensagens : 635
Prêmios :
x 0 x 0 x 0
x 1 x 0 x 1
x 0 x 0 x 0
Re: [Tutorial]GMAPI
bom, n é bem assim ,a ideia é rodar o seu algoritimo dentro da dll
bacana, quer dizer que se alguém aqui usar essa técnica pra fazer uma extensão com todas as funções do GM, teremos uma espécie de Runner em C++ para o GM!! o que deixaria os jogos muito mais rápidos!!
Muito bom!!
ex:
se você fosse desenhar uma lista de textos com gml usaria algo assim
- Código:
for(i=0;i<9999;i+=1;)
draw_text(x,y+i*16,"Item:"+string(i));
mas se passar isso para o c++ seria executado mais rapido.
por exemplo
- Código:
GML double DrawList(double x,double y)
{
std::stringstream parser;
for(unsigned int i=0;i<9999;i++)
{parser<<"Item:"<<i;
gm::draw_text(x,y+i*16,parser.str());
parser.str("");
}
}
é mais complicado, porem a vantagem é que você ganha muito mais velocidade em processo de execução.
Realmente muito interessantes isso jiraya parabéns, o bom de se usar essas dlls é que elas aumentam e muito a velocidade no processamento de algo, já estou pensando até em usar em projetos futuros.
sim, no caso, poderiamos reescrever um script como o "CreateFromObject"
aquele famoso script que carrega modelos 3d (wavefront).obj para o gm, em c++, assim carregaria muito mais rapido e poderia passar o modelo diretamente para a memoria do game maker.
ou seja o que antes leva-va 80 segundos para carregar um modelo de 400 kbts, com a dll levaria menos de 2 segundos.
Re: [Tutorial]GMAPI
Bom, estou, através da DLL, transferindo vários códigos GML para C++. E acabei inventando alguns também, mas com puro C++, sem o uso do GM, mas com uso de outras bibliotecas (SFML no caso). O bacana é que funciona mesmo. Não havia criado uma DLL ainda, mas agora que vi que é bem legal vou começar a fazer.
Até mais!
Até mais!
Leia o Manual do Iniciante e a Lista de Tutoriais, para aprender bastante sobre o GM.
Recomendo o Manual completo das colisões, bem útil.
O exemplo Criar um chat (banir, kickar, etc) é interessante.
Para seu jogo ficar rápido e legal, aprenda a Aumentar o desempenho do seu jogo.
Aprenda a calcular a velocidade de suas animações
Entre para o Clube do Inglês:
Re: [Tutorial]GMAPI
Uma pergunta jiraya, como propriamente dito antes a dll reproduz o código mais rápido do que o game maker, mas eu queria saber o por que que quando eu reproduzo este código na dll :
ele executa o código mais lentamente do que no game maker?
- Código:
GML double CODE(char* x)
{
execute_string(x);
return(0);
}
ele executa o código mais lentamente do que no game maker?
Kapoty- Games Ranking :
Notas recebidas : E + D + C + B + D +B + A
Data de inscrição : 05/11/2011
Reputação : 22
Número de Mensagens : 635
Prêmios :
x 0 x 0 x 0
x 1 x 0 x 1
x 0 x 0 x 0
Re: [Tutorial]GMAPI
Kapoty
por que você só esta usando a dll para chamar uma função padrão do gm...
ou seja a dll não esta fazendo NADA de mais...
você não esta aproveitando praticamente NADA do c++ para melhorar o desempenho...
eu estou fazendo uma dll com o gmapi
esse é um bom exemplo de como aproveitar o poder do c++ no gm
por que você só esta usando a dll para chamar uma função padrão do gm...
ou seja a dll não esta fazendo NADA de mais...
você não esta aproveitando praticamente NADA do c++ para melhorar o desempenho...
eu estou fazendo uma dll com o gmapi
esse é um bom exemplo de como aproveitar o poder do c++ no gm
- Código:
#define GMAPI_NO_D3D
#include <gmapi.h>
#include <vector>
#include <sstream>
gm::CGMAPI* gmapi;
#define GML extern "C" __declspec(dllexport)
struct GW;
std::vector<GW*>GList,DepthBuffer;
void UpdateDepth();
void StayOnTop(GW *Win);
GW* HOVER=NULL;
GW* FOCUS=NULL;
GW* DRAG=NULL;
std::string keyboard_string="";
int Vector2[2]={0,0},Mouse[2]={0,0},MouseState[3]={0,0,0};
struct THEME
{
int base,background,border,text,fonts[2],c;
THEME():base(gm::make_color_rgb(64,128,255)),background(gm::c_white),border(gm::make_color_rgb(32,64,128)),text(gm::make_color_rgb(32,32,32))
{
this->fonts[0]=gm::font_add("Constantina",10,0,0,32,127);
this->fonts[1]=gm::font_add("Lucida Console",10,0,0,32,127);
gm::draw_set_font(this->fonts[1]);
c=(int)gm::string_width("_");
gm::draw_set_font(this->fonts[0]);
}
};
THEME *Theme;
inline bool M(double x,double y,double w,double h)
{
if(Mouse[0]>=x && Mouse[1]>=y)
return(Mouse[0]<=x+w && Mouse[1]<=y+h);
return(0);
}
int getDepth(GW *Win)
{
for(unsigned int i=0;i<DepthBuffer.size();i++)
if(DepthBuffer[i]==Win)return(i);
return(-1);
}
/***Commands***
0=normal
1=hover
2=click
3=out
4=release
**************/
struct GW
{
public:int x,y,w,h,id,ctx,commands,depth,nx,ny,drag,flags,bgImage[8],GHDC,sel[2],Scroll[2];
public:GW *parent;
public:GW *ChildTarget;
std::string text;
std::vector<GW*>Childs;
bool Overlap,Refreshed,AutoUpdate,Active,PassWord,OnlyReal,ReadOnly;
GW():Refreshed(false),text("undefined"),x(0),y(0),w(64),h(64),id(GList.size()),ctx(NULL),parent(NULL),commands(0),depth(DepthBuffer.size()),nx(0),ny(0),Overlap(false),drag(true)
{
GList.push_back(this);
DepthBuffer.push_back(this);
bgImage[0]=NULL;
bgImage[1]=0;
bgImage[2]=0;
bgImage[3]=1;
bgImage[4]=1;
bgImage[5]=0;
bgImage[6]=gm::c_white;
bgImage[7]=1;
AutoUpdate=false;
GHDC=NULL;
sel[0]=0;
sel[1]=sel[0];
Active=false;
Scroll[0]=0;
Scroll[1]=0;
PassWord=false;
OnlyReal=true;
ReadOnly=false;
ChildTarget=NULL;
}
bool Over()
{
if(this->parent!=NULL)
{
if(M(max(x+nx,parent->x+parent->nx),max(y+ny,parent->y+parent->ny),min(w,parent->w),min(h,parent->h)))return(this->parent->Over());else return(0);
}else return(M(x+nx,y+ny,w,h));
}
bool Inside()
{
if(this->parent!=NULL)
{
if(parent->Inside())
return !((x+nx>parent->x+parent->nx+parent->w||y+ny>parent->y+parent->ny+parent->h||x+nx+w<parent->x+parent->nx||y+ny+h<parent->ny));else return(false);
}else return(true);
}
void DEFAULTSTYLES()
{
switch(flags)
{
case 0://Windows
if(bgImage[0]!=NULL)gm::draw_background_tiled(bgImage[0],bgImage[1],bgImage[2]);else gm::draw_clear(Theme->background);
gm::draw_rectangle(0,0,w-1,h-1,1);
if(GHDC!=NULL)gm::draw_surface(GHDC,0,0);
break;
case 1://Buttons
gm::draw_set_color(Theme->border);
gm::draw_rectangle(0,0,w-1,h-1,1);
gm::draw_set_halign(gm::fa_center);gm::draw_set_valign(gm::fa_middle);
gm::draw_text(w/2,h/2,this->text);
gm::draw_set_halign(0);gm::draw_set_valign(0);
break;
case 2://text
gm::draw_clear(Theme->background);
gm::draw_set_color(gm::c_blue);
gm::draw_set_alpha(0.2);
gm::draw_rectangle(sel[0]*Theme->c,2,sel[1]*Theme->c,h-3,0);
gm::draw_set_alpha(1);
gm::draw_rectangle(sel[0]*Theme->c,2,sel[1]*Theme->c,h-3,1);
gm::draw_set_color(0);
gm::draw_set_font(Theme->fonts[1]);
gm::draw_set_valign(gm::fa_middle);
if(PassWord)
{
std::string nstr;
while(nstr.length()<text.length())nstr+="*";
gm::draw_text(0,h/2,nstr);
}else
gm::draw_text(0,h/2,text);
gm::draw_set_valign(gm::fa_top);
gm::draw_set_font(Theme->fonts[0]);
gm::draw_rectangle(0,0,w-1,h-1,1);
break;
case 3://radiobox
gm::draw_set_color(Theme->base);
gm::draw_circle_color(5,h/2,5,gm::c_white,gm::c_ltgray,0);
gm::draw_circle_color(5,h/2,5,gm::c_blue,Theme->base,1);
if(parent!=NULL)ChildTarget=parent->ChildTarget;
gm::draw_circle_color(5,h/2,3,0,Theme->base,ChildTarget==this);
gm::draw_set_valign(gm::fa_middle);
gm::draw_text(16,h/2,this->text);
gm::draw_set_valign(gm::fa_top);
break;
}
}
void CSSTYLE(int css)
{
int cols[2]={gm::make_color_rgb(152,221,4),gm::make_color_rgb(96,148,32)};
switch(flags)
{
case 1://button
gm::surface_set_target(this->ctx);
//gm::draw_clear_alpha(Theme->base,1);
switch(css)
{
case 0://normal
gm::draw_rectangle_color(0,0,w-1,h-1,cols[0],cols[0],cols[1],cols[1],0);
DEFAULTSTYLES();
break;
case 1://hover
gm::draw_rectangle_color(0,0,w-1,h-1,cols[0],cols[0],cols[1],cols[1],0);
gm::draw_set_color(gm::c_white);
gm::draw_set_blend_mode(gm::bm_add);gm::draw_set_alpha(0.5);
gm::draw_ellipse_color(0,h/2,w,h*1.2,gm::c_white,0,0);
gm::draw_set_blend_mode(0);gm::draw_set_alpha(1);
DEFAULTSTYLES();
break;
case 2://click
gm::draw_rectangle_color(0,0,w-1,h-1,cols[0],cols[0],cols[1],cols[1],0);
gm::draw_set_color(gm::c_white);
gm::draw_set_blend_mode(gm::bm_add);
gm::draw_ellipse_color(0,h/2,w,h*1.2,gm::c_white,0,0);
gm::draw_set_blend_mode(0);
DEFAULTSTYLES();
break;
case 3://release
CSSTYLE(1);
break;
}
gm::surface_reset_target();
break;
case 2://edit box
gm::draw_set_font(Theme->fonts[1]);
gm::surface_set_target(this->ctx);
switch(css)
{
case 0://normal
DEFAULTSTYLES();
if(MouseState[0])
if(HOVER==this)
{
sel[0]=(int)min(max(floor((double)Mouse[0]-(double)(x+nx-Scroll[0]))/Theme->c,0),text.length());
sel[1]=sel[0];
Active=true;
}
break;
case 1://focus
gm::draw_clear(Theme->background);
gm::draw_set_color(gm::c_green);
if(Active)
{
sel[1]=(int)min(max(floor((double)Mouse[0]-(double)(x+nx-Scroll[0]))/Theme->c,0),text.length());
if(MouseState[1])Active=0;
}else
if(MouseState[0])
{
sel[0]=(int)min(max(floor((double)Mouse[0]-(double)(x+nx-Scroll[0]))/Theme->c,0),text.length());
sel[1]=sel[0];
Active=true;
}
if(!ReadOnly)
if(gm::keyboard_check_direct(37))
{
sel[0]=(int)max(min(sel[0],sel[1])-1,0);
while(sel[0]*Theme->c<Scroll[0]+Theme->c)if(Scroll[0])Scroll[0]-=Theme->c;else break;
sel[1]=sel[0];
}else
if(gm::keyboard_check_direct(39))
{
sel[0]=(int)min(max(sel[0],sel[1])+1,text.length());
while(sel[0]*Theme->c-Scroll[0]>this->w-Theme->c*2)Scroll[0]+=Theme->c;
gm::draw_text(10,24,sel[0]*Theme->c-Scroll[0]);
gm::draw_text(10,48,w-Theme->c);
sel[1]=sel[0];
}else
if(gm::keyboard_check_direct(gm::vk_lcontrol))
{
if(gm::keyboard_check_pressed(65))
{
sel[0]=0;sel[1]=text.length();
}else
if(gm::keyboard_check_pressed(67))
{
gm::execute_string("clipboard_set_text('"+text.substr(min(sel[0],sel[1]),max(sel[0],sel[1])-min(sel[0],sel[1]))+"')");
}else
if(gm::keyboard_check_pressed(86))
{
int vecsel[2]={min(sel[0],sel[1]),max(sel[0],sel[1])};
std::string Source=gm::execute_string("return clipboard_get_text()");
text.replace(min(vecsel[0],text.length()),vecsel[1]-vecsel[0],Source);
while((int)text.length()*Theme->c-Scroll[0]+Theme->c>w)Scroll[0]+=Theme->c;
while((int)text.length()*Theme->c-Scroll[0]+Theme->c<w && Scroll[0])Scroll[0]-=Theme->c;
sel[0]=vecsel[0]+Source.length();
sel[1]=sel[0];
}
}else
if(gm::keyboard_check_direct(gm::vk_backspace))
{
int vecsel[2]={max(min(sel[0],sel[1])-1,0),max(sel[0],sel[1])};
text.replace(vecsel[0],vecsel[1]-vecsel[0],keyboard_string);
while((int)text.length()*Theme->c-Scroll[0]+Theme->c>w)Scroll[0]+=Theme->c;
while((int)text.length()*Theme->c-Scroll[0]+Theme->c<w && Scroll[0])Scroll[0]-=Theme->c;
sel[0]=vecsel[0]+keyboard_string.length();
sel[1]=sel[0];
gm::execute_string("keyboard_string=''");
gm::io_clear();
}else
if(keyboard_string!="")
{
int vecsel[2]={min(sel[0],sel[1]),max(sel[0],sel[1])};
text.replace(min(vecsel[0],text.length()),vecsel[1]-vecsel[0],keyboard_string);
while((int)text.length()*Theme->c-Scroll[0]+Theme->c>w)Scroll[0]+=Theme->c;
while((int)text.length()*Theme->c-Scroll[0]+Theme->c<w && Scroll[0])Scroll[0]-=Theme->c;
sel[0]=vecsel[0]+keyboard_string.length();
sel[1]=sel[0];
gm::execute_string("keyboard_string=''");
}
gm::draw_set_color(gm::c_blue);
gm::draw_set_alpha(0.2);
gm::draw_rectangle(sel[0]*Theme->c-Scroll[0],2,sel[1]*Theme->c-Scroll[0],h-3,0);
gm::draw_set_alpha(1);
gm::draw_rectangle(sel[0]*Theme->c-Scroll[0],2,sel[1]*Theme->c-Scroll[0],h-3,1);
//gm::draw_rectangle_color(sel[0]*Theme->c-Scroll[0],2,sel[1]*Theme->c-Scroll[0],h-2,gm::c_red,gm::c_blue,gm::c_blue,gm::c_red,0);
gm::draw_set_color(0);
gm::draw_set_valign(gm::fa_middle);
if(PassWord)
{
std::string nstr;
while(nstr.length()<text.length())nstr+="*";
gm::draw_text(-Scroll[0],h/2,nstr);
}else
gm::draw_text(-Scroll[0],h/2,text);
gm::draw_set_color(gm::c_blue);
gm::draw_text(sel[0]*Theme->c-Theme->c/2-Scroll[0],h/2,"|");
gm::draw_set_valign(gm::fa_top);
gm::draw_rectangle(0,0,w-1,h-1,1);
break;
}
gm::surface_reset_target();
gm::draw_set_font(Theme->fonts[0]);
break;
case 3://radiobox
gm::surface_set_target(this->ctx);
DEFAULTSTYLES();
gm::surface_reset_target();
if(HOVER==this)
if(gm::mouse_check_button_pressed(gm::mb_left))
{
parent!=NULL?parent->ChildTarget=this:ChildTarget=this;
}
break;
default:
gm::surface_set_target(this->ctx);
DEFAULTSTYLES();
gm::surface_reset_target();
break;
}
}
void Refresh()
{
gm::surface_set_target(this->ctx);
DEFAULTSTYLES();
gm::surface_reset_target();
for(unsigned int i=0;i<Childs.size();i++)
Childs[i]->Draw();
}
void CSSFLAGS()
{
switch(flags)
{
case 0://window
if(parent!=NULL){gm::surface_set_target(this->parent->ctx);
if(!parent->Refreshed){
parent->DEFAULTSTYLES();parent->Refreshed=true;
}
}
gm::draw_surface(this->ctx,this->x,this->y);
if(FOCUS==this)gm::draw_set_color(gm::c_blue);else
if(HOVER==this)gm::draw_set_color(gm::c_green);else
gm::draw_set_color(gm::c_black);
gm::draw_rectangle(this->x,this->y,this->x+this->w,this->y+this->h,1);
if(this->parent!=NULL)gm::surface_reset_target();
break;
case 1://button
if(parent!=NULL){gm::surface_set_target(this->parent->ctx);if(!parent->Refreshed){if(parent->AutoUpdate)parent->DEFAULTSTYLES();parent->Refreshed=true;}}
gm::draw_surface(this->ctx,this->x,this->y);
if(this->parent!=NULL)gm::surface_reset_target();
break;
case 2://Textbox
if(FOCUS==this)
{
CSSTYLE(1);
}else CSSTYLE(0);
if(parent!=NULL){gm::surface_set_target(this->parent->ctx);if(!parent->Refreshed){if(parent->AutoUpdate)parent->DEFAULTSTYLES();parent->Refreshed=true;}}
gm::draw_surface(this->ctx,this->x,this->y);
if(this->parent!=NULL)gm::surface_reset_target();
break;
case 3:
if(parent!=NULL){gm::surface_set_target(this->parent->ctx);if(!parent->Refreshed){if(parent->AutoUpdate)parent->DEFAULTSTYLES();parent->Refreshed=true;}}
gm::draw_surface(this->ctx,this->x,this->y);
if(this->parent!=NULL)gm::surface_reset_target();
break;
default:
if(parent!=NULL){gm::surface_set_target(this->parent->ctx);if(!parent->Refreshed){if(parent->AutoUpdate)parent->DEFAULTSTYLES();parent->Refreshed=true;}}
gm::draw_surface(this->ctx,this->x,this->y);
if(this->parent!=NULL)gm::surface_reset_target();
break;
}
}
void Draw()
{
if(this->ctx==NULL)exit;
if(!this->Inside())exit;
Refreshed=false;
CSSFLAGS();
if(parent!=NULL){this->nx=this->parent->x+parent->nx;ny=parent->y+parent->ny;this->Overlap=this->parent->Over();}else this->Overlap=true;
if(M(x+nx,y+ny,w,h))
{
if(this->Overlap)
{
if(HOVER==this->parent){HOVER=this;commands=1;CSSTYLE(1);
}else
if(HOVER==NULL||this->depth>HOVER->depth){
HOVER=this;commands=1;CSSTYLE(1);
}else
if(HOVER==this)
if(MouseState[0]){
GW *tmp=this;CSSTYLE(2);
while(tmp->parent!=NULL)tmp=tmp->parent;
StayOnTop(tmp);
gm::mouse_clear(gm::mb_left);commands=2;
if(drag)
{
Vector2[0]=Mouse[0]-this->x;
Vector2[1]=Mouse[1]-this->y;
DRAG=this;
}
FOCUS=this;
}else
if(MouseState[1]){commands=4;gm::mouse_clear(gm::mb_left);CSSTYLE(3);Active=false;
}
}
}else if(HOVER==this){HOVER=NULL;commands=3;CSSTYLE(0);
}
}
};
void UpdateDepth()
{
for(unsigned int i=0;i<DepthBuffer.size();i++)
{
if(DepthBuffer[i]==NULL){DepthBuffer.erase(DepthBuffer.begin()+i);if(i)i--;}else DepthBuffer[i]->depth=i;
}
}
void StayOnTop(GW *Win)
{
DepthBuffer.erase(DepthBuffer.begin()+Win->depth);
DepthBuffer.push_back(Win);
UpdateDepth();
for(unsigned int i=0;i<Win->Childs.size();i++)
StayOnTop(Win->Childs[i]);
}
GML double newGW(double win,double x,double y,double w,double h,double flags)
{
GW *tmp=new GW();
if(win<9999)
{
tmp->parent=GList[(int)win];
tmp->parent->Childs.push_back(tmp);
}
tmp->x=(int)x;
tmp->y=(int)y;
tmp->flags=(int)flags;
if(flags==2)tmp->drag=false;
tmp->w=(int)w;
tmp->h=(int)h;
tmp->ctx=gm::surface_create((int)w,(int)h);
gm::surface_set_target(tmp->ctx);
/*gm::draw_clear_alpha(gm::c_white,0.5);
gm::draw_rectangle(0,0,w-1,h-1,1);*/
tmp->DEFAULTSTYLES();
gm::surface_reset_target();
tmp->CSSTYLE(0);
return(tmp->id);
};
GML double beginPaint(double Win)
{
if(GList[(int)Win]==NULL)return(0);
if(GList[(int)Win]->GHDC==NULL)GList[(int)Win]->GHDC=gm::surface_create(GList[(int)Win]->w,GList[(int)Win]->h);
gm::surface_set_target(GList[(int)Win]->GHDC);
return(0);
}
GML double endPaint(double Win)
{
gm::surface_reset_target();
if(GList[(int)Win]==NULL)return(0);
GList[(int)Win]->CSSTYLE(0);
return(0);
}
GML double SetText(double win,char *text)
{
if(GList[(int)win]==NULL)return(0);
GList[(int)win]->text=text;
GList[(int)win]->CSSTYLE(0);
return(1);
}
GML double GETMSG(double win)
{
if(GList[(int)win]==NULL)return(0);
double tmp=GList[(int)win]->commands;
GList[(int)win]->commands=0;
return(tmp);
}
GML double DestroyWin(double id)
{
//DepthBuffer.erase(DepthBuffer.begin()+GList[(int)id]->depth);
if(GList[(int)id]==NULL)return(0);
if(HOVER==GList[(int)id])HOVER=NULL;
if(FOCUS==GList[(int)id])FOCUS=NULL;
if(DRAG==GList[(int)id])DRAG=NULL;
if(GList[(int)id]->parent!=NULL)
{
for(unsigned int i=0;i<GList[(int)id]->parent->Childs.size();i++)
if(GList[(int)id]->parent->Childs[i]==GList[(int)id])
GList[(int)id]->parent->Childs.erase(GList[(int)id]->parent->Childs.begin()+i);
gm::surface_set_target(GList[(int)id]->parent->ctx);
GList[(int)id]->parent->DEFAULTSTYLES();
gm::surface_reset_target();
}
for(unsigned int i=0;i<GList[(int)id]->Childs.size();i++)
DestroyWin(GList[(int)id]->Childs[i]->id);
DepthBuffer[GList[(int)id]->depth]=NULL;
gm::surface_free(GList[(int)id]->ctx);
if(GList[(int)id]->GHDC!=NULL)gm::surface_free(GList[(int)id]->GHDC);
delete GList[(int)id];
GList[(int)id]=NULL;
UpdateDepth();
return(1);
}
GML double Render(char *KeyboardStr)
{
Mouse[0]=gm::window_mouse_get_x();
Mouse[1]=gm::window_mouse_get_y();
MouseState[0]=gm::mouse_check_button_pressed(gm::mb_left);
MouseState[1]=gm::mouse_check_button_released(gm::mb_left);
std::stringstream parser;
parser<<KeyboardStr;
keyboard_string=parser.str();
if(HOVER!=NULL)
{
//if(!HOVER->drag)
if(HOVER->flags==2)
gm::window_set_cursor(gm::cr_beam);else
if(HOVER->flags==1)
gm::window_set_cursor(gm::cr_handpoint);else gm::window_set_cursor(gm::cr_default);
}else gm::window_set_cursor(gm::cr_default);
if(DRAG!=NULL)
{
DRAG->x=Mouse[0]-Vector2[0];
DRAG->y=Mouse[1]-Vector2[1];
if(MouseState[1]){DRAG=NULL;}else
{
if(DRAG->parent!=NULL)
DRAG->parent->AutoUpdate=true;
}
}
for(unsigned int i=0;i<DepthBuffer.size();i++)
{
DepthBuffer[i]->Draw();
}
return(0);
}
BOOL WINAPI DllMain( HINSTANCE aModuleHandle, int aReason, int aReserved ) {
switch ( aReason ) {
case DLL_PROCESS_ATTACH: {
// Initialization
unsigned long result = 0;
gmapi = gm::CGMAPI::Create( &result );
Theme=new THEME();
// Check the result
if ( result != gm::GMAPI_INITIALIZATION_SUCCESS ) {
// MessageBoxA( 0, "Unable to initialize GMAPI.","", MB_SYSTEMMODAL | MB_ICONERROR );
return FALSE;
}
break;
}
case DLL_PROCESS_DETACH:
// Release from memory & deinitialize GMAPI
gmapi->Destroy();
break;
}
return TRUE;
}
Tópicos semelhantes
» Oi Galerinha, aqui um tutorial básico de um jogo de luta que eu fiz! [TUTORIAL]
» [Tutorial] 39dll Tutorial - Part II(Final)
» [Tutorial] 39dll Tutorial - Part I
» Como fazer com que a view siga 2 ou mais objeto?
» [Pergunta] Tutorial
» [Tutorial] 39dll Tutorial - Part II(Final)
» [Tutorial] 39dll Tutorial - Part I
» Como fazer com que a view siga 2 ou mais objeto?
» [Pergunta] Tutorial
Página 1 de 1
Permissões neste sub-fórum
Não podes responder a tópicos