[Tutorial]GMAPI

Ver o tópico anterior Ver o tópico seguinte Ir em baixo

[Tutorial]GMAPI

Mensagem por Jiraya em Dom 16 Set 2012, 00:29

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

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
C:\Users\NOME DO SEU COMPUTADOR\Documents\Visual Studio 2010\Projects\NOME DO SEU PROJETO\Release\NOME DO SEU PROJETO.dll
se encontrou sua dll tbm, copie ela para a area de trabalho

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 Happy!");

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)

Jiraya

Ranking : Nota A
Número de Mensagens : 1134
Data de inscrição : 20/03/2010
Notas recebidas : A+A
Reputação : 108
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 1
   : 0
   : 1

https://www.facebook.com/seito.washiro.7

Voltar ao Topo Ir em baixo

Re: [Tutorial]GMAPI

Mensagem por theguitarmester em Dom 16 Set 2012, 01:07

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).

theguitarmester

Ranking : Sem avaliações
Número de Mensagens : 1908
Idade : 21
Data de inscrição : 28/02/2012
Notas recebidas : B
Reputação : 80
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 1
Prêmios
   : 2
   : 2
   : 1

http://guitarmester.no.comunidades.net/index.php?pagina=19362978

Voltar ao Topo Ir em baixo

Re: [Tutorial]GMAPI

Mensagem por Jiraya em Dom 16 Set 2012, 02:20

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.

Jiraya

Ranking : Nota A
Número de Mensagens : 1134
Data de inscrição : 20/03/2010
Notas recebidas : A+A
Reputação : 108
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 1
   : 0
   : 1

https://www.facebook.com/seito.washiro.7

Voltar ao Topo Ir em baixo

Re: [Tutorial]GMAPI

Mensagem por vinians em Dom 16 Set 2012, 03:49

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!

vinians

Ranking : Nota B
Número de Mensagens : 2490
Idade : 27
Data de inscrição : 18/09/2008
Notas recebidas : B-C-A-C
Reputação : 52
Insignia 1 x 0 Insignia 2 x 1 Insignia 3 x 0
Prêmios
   : 0
   : 2
   : 1

http://xcreatorgames.weebly.com/

Voltar ao Topo Ir em baixo

Re: [Tutorial]GMAPI

Mensagem por PedroX em Dom 16 Set 2012, 09:34

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:
agora clique em Linker>Input>Additional Dependencys, substitua o que tem lá por
gmapi-mt-dll.lib
Se você substituir, vai dar erro de Unresolved Externals. Tem que adicionar ao já existente, separando por ponto-e-vírgula.

O outro erro:
GML double DRAW_TEXT(double x,double y, char **str)
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.

Até mais!

PedroX

Ranking : Nota C
Número de Mensagens : 6034
Idade : 21
Data de inscrição : 26/07/2008
Notas recebidas : C+B
Reputação : 286
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   :
   :
   :

Voltar ao Topo Ir em baixo

Re: [Tutorial]GMAPI

Mensagem por Jiraya em Dom 16 Set 2012, 13:59


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!
bom, a limitação da gmapi é que ela só funciona no game maker 8.0
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

Jiraya

Ranking : Nota A
Número de Mensagens : 1134
Data de inscrição : 20/03/2010
Notas recebidas : A+A
Reputação : 108
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 1
   : 0
   : 1

https://www.facebook.com/seito.washiro.7

Voltar ao Topo Ir em baixo

Re: [Tutorial]GMAPI

Mensagem por Mr.Brum em Dom 16 Set 2012, 14:59

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!!

Mr.Brum

Ranking : Nota C
Número de Mensagens : 913
Idade : 25
Data de inscrição : 28/04/2011
Notas recebidas : D + D + C + C + D + B
Reputação : 41
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 1
   : 0
   : 0

http://mrbrumgames.blogspot.com/

Voltar ao Topo Ir em baixo

Re: [Tutorial]GMAPI

Mensagem por Kapoty em Dom 16 Set 2012, 15:10

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

Ranking : Nota B
Número de Mensagens : 635
Data de inscrição : 05/11/2011
Notas recebidas : E + D + C + B + D +B + A
Reputação : 22
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 1
   : 0
   : 1

Voltar ao Topo Ir em baixo

Re: [Tutorial]GMAPI

Mensagem por Jiraya em Dom 16 Set 2012, 15:33


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!!
bom, n é bem assim ,a ideia é rodar o seu algoritimo dentro da dll
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.

Jiraya

Ranking : Nota A
Número de Mensagens : 1134
Data de inscrição : 20/03/2010
Notas recebidas : A+A
Reputação : 108
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 1
   : 0
   : 1

https://www.facebook.com/seito.washiro.7

Voltar ao Topo Ir em baixo

Re: [Tutorial]GMAPI

Mensagem por PedroX em Dom 16 Set 2012, 16:22

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!

PedroX

Ranking : Nota C
Número de Mensagens : 6034
Idade : 21
Data de inscrição : 26/07/2008
Notas recebidas : C+B
Reputação : 286
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   :
   :
   :

Voltar ao Topo Ir em baixo

Re: [Tutorial]GMAPI

Mensagem por Kapoty em Dom 23 Set 2012, 18:54

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 :

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

Ranking : Nota B
Número de Mensagens : 635
Data de inscrição : 05/11/2011
Notas recebidas : E + D + C + B + D +B + A
Reputação : 22
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 1
   : 0
   : 1

Voltar ao Topo Ir em baixo

Re: [Tutorial]GMAPI

Mensagem por Jiraya em Qui 27 Set 2012, 15:24

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

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;
}

Jiraya

Ranking : Nota A
Número de Mensagens : 1134
Data de inscrição : 20/03/2010
Notas recebidas : A+A
Reputação : 108
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 1
   : 0
   : 1

https://www.facebook.com/seito.washiro.7

Voltar ao Topo Ir em baixo

Re: [Tutorial]GMAPI

Mensagem por Conteúdo patrocinado Hoje à(s) 08:34


Conteúdo patrocinado


Voltar ao Topo Ir em baixo

Ver o tópico anterior Ver o tópico seguinte Voltar ao Topo

- Tópicos similares

 
Permissão deste fórum:
Você não pode responder aos tópicos neste fórum