PsySc0rpi0n Posted December 16, 2016 at 11:43 PM Report Share #601317 Posted December 16, 2016 at 11:43 PM Boas... Andava aqui a ler uns tutoriais sobre SDL e estava a tentar criar uma janela com uma imagem! Estou apenas no início! Mas a janela não está a carregar a imagem. Fica como que bloqueada e quando arrasto a janela ela fica com uma imagem do desktop como se fosse a imagem que eu carreguei! Não sei se tem a ver com o facto de eu ter pegado numa imagem .jpg e a ter "Gravado Como" .bmp, estando a usar a função SDL_LoadBMP()... Também já tentei mesmo abrir uma imagem .jpg no Gimp e exportar como .bmp em vez de fazer "Gravar Como" mas o resultado é o mesmo. O código é este: #include <stdio.h> #include "SDL2/SDL.h" #include <stdbool.h> const int screenWidth = 1024; const int screenHeight = 768; bool sdl_Init(SDL_Window* pWindow, SDL_Surface* pSurface); bool sdl_LoadMedia(SDL_Surface* pSurface, char* pfilepath); void sdl_Close(SDL_Window* pWindow, SDL_Surface* pSurface); int main(int argc, char** argv){ SDL_Window* gWindow = NULL; SDL_Surface* gScreenSurface = NULL; SDL_Surface* gXOut = NULL; SDL_Event evt; bool quit = false; if( !sdl_Init(gWindow, gScreenSurface) ){ printf("Failed to initialise!\n"); }else{ if( !sdl_LoadMedia(gXOut, "Devil_May_Cry_III.bmp") ){ printf("Failed to load media!\n"); }else{ while(!quit){ while(SDL_PollEvent (&evt) != 0){ if(evt.type == SDL_QUIT) quit = true; } SDL_BlitSurface(gXOut, NULL, gScreenSurface, NULL); SDL_UpdateWindowSurface(gWindow); } } } sdl_Close(gWindow, gXOut); return 0; } /*********************** **Function definitions** ************************/ bool sdl_Init(SDL_Window* pWindow, SDL_Surface* pSurface){ bool success = true; if(SDL_Init(SDL_INIT_VIDEO) < 0){ printf("SDL could not initialize! SDL_Error: %s!\n", SDL_GetError()); success = false; }else{ pWindow = SDL_CreateWindow( "WindowZed fun", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, screenWidth, screenHeight, SDL_WINDOW_SHOWN ); if(pWindow == NULL){ printf("Window Could not be created! SDL Error: %s!\n", SDL_GetError()); success = false; }else{ pSurface = SDL_GetWindowSurface(pWindow); } } return success; } bool sdl_LoadMedia(SDL_Surface* pSurface, char* pfilepath){ bool success = true; pSurface = SDL_LoadBMP(pfilepath); if(pSurface == NULL){ printf("Unable to load %s. SDL Error: %s!\n", pfilepath, SDL_GetError()); success = false; } return success; } void sdl_Close(SDL_Window* pWindow, SDL_Surface* pSurface){ SDL_FreeSurface(pSurface); pSurface = NULL; SDL_DestroyWindow(pWindow); pWindow = NULL; SDL_Quit(); } Kurt Cobain - Grunge misses you Nissan GT-R - beast killer Link to comment Share on other sites More sharing options...
HappyHippyHippo Posted December 17, 2016 at 07:58 AM Report Share #601320 Posted December 17, 2016 at 07:58 AM eu desconfio que o problema não e carregar o bmp. E assambarcares o processador todo para ti e não o dares ao sistema operativo para ele fazer o que tem a fazer. Adiciona a instrucao SDL_Delay(30) no fim do teu ciclo run ( dentro do ciclo) IRC : sim, é algo que ainda existe >> #p@p Portugol Plus Link to comment Share on other sites More sharing options...
PsySc0rpi0n Posted December 17, 2016 at 10:47 AM Author Report Share #601322 Posted December 17, 2016 at 10:47 AM (edited) Eu ainda só estou a copiar (e a adicionar uns pósitos) código de uns tutorias da net e por isso ainda estou a tentar perceber como funciona o SDL por isso não sei o que é isso do meu "ciclo run" nem onde é que estou a "assambarcar o cpu todo para mim". Troca lá isso por miúdos. O "ciclo run" deve ser um dos whiles que eu lá tenho mas a outra expressão não faço ideia! Edited December 17, 2016 at 10:50 AM by PsySc0rpi0n Kurt Cobain - Grunge misses you Nissan GT-R - beast killer Link to comment Share on other sites More sharing options...
HappyHippyHippo Posted December 17, 2016 at 11:28 AM Report Share #601323 Posted December 17, 2016 at 11:28 AM ciclo run: While(!quit) IRC : sim, é algo que ainda existe >> #p@p Portugol Plus Link to comment Share on other sites More sharing options...
PsySc0rpi0n Posted December 17, 2016 at 11:33 AM Author Report Share #601325 Posted December 17, 2016 at 11:33 AM (edited) 4 minutes ago, HappyHippyHippo said: ciclo run: While(!quit) Tentei assim mas o resultado é o mesmo: #include <stdio.h> #include "SDL2/SDL.h" #include <stdbool.h> const int screenWidth = 1024; const int screenHeight = 768; bool sdl_Init(SDL_Window* pWindow, SDL_Surface* pSurface); bool sdl_LoadMedia(SDL_Surface* pSurface, char* pfilepath); void sdl_Close(SDL_Window* pWindow, SDL_Surface* pSurface); int main(int argc, char** argv){ SDL_Window* gWindow = NULL; SDL_Surface* gScreenSurface = NULL; SDL_Surface* gXOut = NULL; SDL_Event evt; bool quit = false; if( !sdl_Init(gWindow, gScreenSurface) ){ printf("Failed to initialise!\n"); }else{ if( !sdl_LoadMedia(gXOut, "Devil_May_Cry_III.bmp") ){ printf("Failed to load media!\n"); }else{ while(!quit){ while(SDL_PollEvent (&evt) != 0){ if(evt.type == SDL_QUIT) quit = true; } SDL_BlitSurface(gXOut, NULL, gScreenSurface, NULL); SDL_UpdateWindowSurface(gWindow); SDL_Delay(30);// <---aqui } } } sdl_Close(gWindow, gXOut); return 0; } /*********************** **Function definitions** ************************/ bool sdl_Init(SDL_Window* pWindow, SDL_Surface* pSurface){ bool success = true; if(SDL_Init(SDL_INIT_VIDEO) < 0){ printf("SDL could not initialize! SDL_Error: %s!\n", SDL_GetError()); success = false; }else{ pWindow = SDL_CreateWindow( "WindowZed fun", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, screenWidth, screenHeight, SDL_WINDOW_SHOWN ); if(pWindow == NULL){ printf("Window Could not be created! SDL Error: %s!\n", SDL_GetError()); success = false; }else{ pSurface = SDL_GetWindowSurface(pWindow); } } return success; } bool sdl_LoadMedia(SDL_Surface* pSurface, char* pfilepath){ bool success = true; pSurface = SDL_LoadBMP(pfilepath); if(pSurface == NULL){ printf("Unable to load %s. SDL Error: %s!\n", pfilepath, SDL_GetError()); success = false; } return success; } void sdl_Close(SDL_Window* pWindow, SDL_Surface* pSurface){ SDL_FreeSurface(pSurface); pSurface = NULL; SDL_DestroyWindow(pWindow); pWindow = NULL; SDL_Quit(); } Edited December 17, 2016 at 11:33 AM by PsySc0rpi0n Kurt Cobain - Grunge misses you Nissan GT-R - beast killer Link to comment Share on other sites More sharing options...
PsySc0rpi0n Posted December 17, 2016 at 01:13 PM Author Report Share #601328 Posted December 17, 2016 at 01:13 PM Ok, para já está resolvido! No entanto vou aproveitar a thread para futuras dúvidas minhas sobre o tema. Vou alterar o título da thread (se conseguir)! Kurt Cobain - Grunge misses you Nissan GT-R - beast killer Link to comment Share on other sites More sharing options...
PsySc0rpi0n Posted December 19, 2016 at 12:29 PM Author Report Share #601358 Posted December 19, 2016 at 12:29 PM Afinal não percebi porque é que tinha o código mal @HappyHippyHippo. Estou no work e não me recordo ao certo das alterações que se fizeram no code porque não o tenho aqui comigo. Mas sei que tinha ali uma confusão qualquer com os ponteiros porque acho que tinha que passar as variáveis [tt]gWindow[/tt], [tt]gScreenShot[/tt] e [tt]gXout[/tt] como ponteiro para ponteiro ou algo parecido! Mas não percebi porquê! Kurt Cobain - Grunge misses you Nissan GT-R - beast killer Link to comment Share on other sites More sharing options...
HappyHippyHippo Posted December 19, 2016 at 12:53 PM Report Share #601360 Posted December 19, 2016 at 12:53 PM ok ... eu poderia te redireccionar para o tópico onde andas a reclamar da existência de uma variavel global, algo completamente ao lado do inteuito do código ... mas vou ficar por aqui a regra é simples : - quando queres que uma função retorne um valor por parâmetro, isto é, o retorno não é feito por resultado da função, mas sim por alteração de um valor dado como argumento da função, então passas um ponteiro para a região da memória a ser alterada. tendo isso, como todas as tuas funções auxiliares fazem exactamente isso, deverás dar ponteiros para as variáveis. Como o tipo das tuas variáveis são "SDL_Surface *", então um ponteiro para isso é "SDL_Surface **" IRC : sim, é algo que ainda existe >> #p@p Portugol Plus Link to comment Share on other sites More sharing options...
PsySc0rpi0n Posted December 19, 2016 at 01:46 PM Author Report Share #601361 Posted December 19, 2016 at 01:46 PM (edited) 57 minutes ago, HappyHippyHippo said: ok ... eu poderia te redireccionar para o tópico onde andas a reclamar da existência de uma variavel global, algo completamente ao lado do inteuito do código ... mas vou ficar por aqui a regra é simples : - quando queres que uma função retorne um valor por parâmetro, isto é, o retorno não é feito por resultado da função, mas sim por alteração de um valor dado como argumento da função, então passas um ponteiro para a região da memória a ser alterada. tendo isso, como todas as tuas funções auxiliares fazem exactamente isso, deverás dar ponteiros para as variáveis. Como o tipo das tuas variáveis são "SDL_Surface *", então um ponteiro para isso é "SDL_Surface **" A outra thread, acho eu, não tem muito a ver com esta questão, mas ok! Adiante, senão já sei onde isto vai acabar! Eu não percebo bem esse conceito. "SDL_Surface* gSurface" é um endereço de memória. Se eu passo para uma função a variável "gSurface", já estou a passar um endereço de memória, que por sinal é o endereço de memória usado pela variável gSurface dentro da função main! Então dentro da nova função eu teria acesso ao conteúdo da variável "gSurface" dentro da função main, mas parece que não é assim que funciona! E depois, acho que em termos gerais a malta não entende bem (eu incluído) o uso dos operadores * e &. Nomeadamente quando o nível referenciamento/desreferencimaento (ou lá como se chama) aumenta. Se eu declaro: int i; i é uma variável tipo inteiro &i é o endereço de memória desta variável. *i, não sei se existe ou se tem algum significado. Se eu declaro: int* i; i, é um endereço de memória &i é um endereço de memória diferente do anterior (tenho dúvidas aqui sobre que endereço é este) *i, é o valor apontado por i. E depois começa a aumentar o nível de referenciação/desreferenciação int** i; i é um endereço de memória de um endereço de memória. &i é um endereço de memória de um endereço de memória de um endereço de memória *i é um valor que é um endereço de memória **i é o valor apontado por i... Quer se queira quer não isto´começa a ser confuso a partir de um determinado nível! "Ah e tal, complicam o que é simples!"... Cada um no seu galho! E depois ainda posso divagar mais: int i; E isto: &&i; tem algum significado? Edited December 19, 2016 at 02:04 PM by PsySc0rpi0n Kurt Cobain - Grunge misses you Nissan GT-R - beast killer Link to comment Share on other sites More sharing options...
PsySc0rpi0n Posted December 19, 2016 at 02:44 PM Author Report Share #601363 Posted December 19, 2016 at 02:44 PM Bom, acho que era assim que ficava a funcionar bem... Quando chegar a casa já vejo. Spoiler #include <stdio.h> #include "SDL2/SDL.h" #include <stdbool.h> const int screenWidth = 1024; const int screenHeight = 768; bool sdl_Init(SDL_Window** pWindow, SDL_Surface** pSurface); bool sdl_LoadMedia(SDL_Surface** pSurface, char* pfilepath); void sdl_Close(SDL_Window** pWindow, SDL_Surface** pSurface); int main(int argc, char** argv){ SDL_Window* gWindow = NULL; SDL_Surface* gScreenSurface = NULL; SDL_Surface* gXOut = NULL; SDL_Event evt; bool quit = false; enum KeyPressSurfaces{ KEY_PRESS_SURFACE_DEFAULT, KEY_PRESS_SURFACE_UP, KEY_PRESS_SURFACE_DOWN, KEY_PRESS_SURFACE_LEFT, KEY_PRESS_SURFACE_RIHT, KEY_PRESS_SURFACE_TOTAL }; if( !sdl_Init(& gWindow, & gScreenSurface) ){ printf("Failed to initialise!\n"); exit(-1); } if( !sdl_LoadMedia(& gXOut, "Devil_May_Cry_III.bmp") ){ printf("Failed to load media!\n"); exit(-1); } while(!quit){ while(SDL_PollEvent (&evt) != 0){ if(evt.type == SDL_QUIT) quit = true; } SDL_BlitSurface(gXOut, NULL, gScreenSurface, NULL); SDL_UpdateWindowSurface(gWindow); } sdl_Close(& gWindow, & gXOut); return 0; } /*********************** **Function definitions** ************************/ bool sdl_Init(SDL_Window** pWindow, SDL_Surface** pSurface){ bool success = true; if(SDL_Init(SDL_INIT_VIDEO) < 0){ printf("SDL could not initialize! SDL_Error: %s!\n", SDL_GetError()); success = false; }else{ *pWindow = SDL_CreateWindow( "WindowZed fun", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, screenWidth, screenHeight, SDL_WINDOW_SHOWN ); if(*pWindow == NULL){ printf("Window Could not be created! SDL Error: %s!\n", SDL_GetError()); success = false; }else{ *pSurface = SDL_GetWindowSurface(*pWindow); } } return success; } bool sdl_LoadMedia(SDL_Surface** pSurface, char* pfilepath){ bool success = true; * pSurface = SDL_LoadBMP(pfilepath); if(pSurface == NULL){ printf("Unable to load %s. SDL Error: %s!\n", pfilepath, SDL_GetError()); success = false; } return success; } void sdl_Close(SDL_Window** pWindow, SDL_Surface** pSurface){ SDL_FreeSurface(* pSurface); * pSurface = NULL; SDL_DestroyWindow(* pWindow); * pWindow = NULL; SDL_Quit(); } Kurt Cobain - Grunge misses you Nissan GT-R - beast killer Link to comment Share on other sites More sharing options...
Flinger Posted December 19, 2016 at 03:09 PM Report Share #601364 Posted December 19, 2016 at 03:09 PM Tenta o seguinte exercício. Faz uma função que te aloque dinamicamente (malloc) uma qualquer estrutura e retorna o apontador por referência para a main. É a melhor forma de entenderes o porquê do **. De uma forma mais simples **i é o apontado para uma variável onde guardas o apontador para outra variável. Link to comment Share on other sites More sharing options...
PsySc0rpi0n Posted December 19, 2016 at 03:15 PM Author Report Share #601365 Posted December 19, 2016 at 03:15 PM 4 minutes ago, Flinger said: Tenta o seguinte exercício. Faz uma função que te aloque dinamicamente (malloc) uma qualquer estrutura e retorna o apontador por referência para a main. É a melhor forma de entenderes o porquê do **. De uma forma mais simples **i é o apontado para uma variável onde guardas o apontador para outra variável. Eu percebo isso, mas não no context do código que estava a fazer! Se eu envio um endereço de uma variável com scope na função main para dentro dessa função e depois atribuo algum valor a esse endereço de memória, devia estar automaticamente a alterar o valor na função main porque foi o endereço da variável na função main que eu passei para dentro da função em questão! Kurt Cobain - Grunge misses you Nissan GT-R - beast killer Link to comment Share on other sites More sharing options...
HappyHippyHippo Posted December 19, 2016 at 03:19 PM Report Share #601366 Posted December 19, 2016 at 03:19 PM duas questões void foo(int i) { i = 10; } int main (void) { int i = 0; foo (i); printf ("%d", i); // qual o valor apresentado ? return 0; } void foo(int * i) { * i = malloc(19); } int main (void) { int * i = 0; foo (i); printf ("%p", i); // qual o valor apresentado ? return 0; } novamente ... isto é matéria do outro post IRC : sim, é algo que ainda existe >> #p@p Portugol Plus Link to comment Share on other sites More sharing options...
Flinger Posted December 19, 2016 at 03:24 PM Report Share #601367 Posted December 19, 2016 at 03:24 PM Não...Tu estás a enviar um valor para dentro da função. Esse valor vai ser exactamente o mesmo quando a função termina. No caso de um apontador, tu estás a enviar o endereço de uma variável. O endereço nunca muda, o que está escrito nesse endereço é que muda.Por isso é que se tu tiveres a função: void incrementa(int x) { x++; } Isto não funciona, certo? Porquê? Agora pensa lá. Tu estás a inicializar a variável como SDL_Surface* gScreenSurface = NULL. Se o endereço é 0, como vais obter o valor(endereço) certo no fim da função? Link to comment Share on other sites More sharing options...
PsySc0rpi0n Posted December 19, 2016 at 03:31 PM Author Report Share #601368 Posted December 19, 2016 at 03:31 PM O "x++; funciona, não é é actualizado na função que chamou a função "incrementa". A questão é que se tentar imprimir a variável "gScreenSurface" sem * nem nada com %p vai mostrar o endereço da variável gScreenSurface e é isso que é enviado para dentro da função e supostamente esse endereço tem scope na função main e seria aí que o valor apontado por esse endereço ia ser alterado! Por isso é que não percebo bem a necessidade de enviar o & de uma variável do tipo int* ou whatever! Kurt Cobain - Grunge misses you Nissan GT-R - beast killer Link to comment Share on other sites More sharing options...
PsySc0rpi0n Posted December 19, 2016 at 03:42 PM Author Report Share #601369 Posted December 19, 2016 at 03:42 PM (edited) @HappyHippyHippo, o Segundo exemplo dá segfault. (gdb) bt #0 0x00000000004006f9 in foo (i=0x0) at teste.c:5 #1 0x0000000000400719 in main () at teste.c:10 E isto tem só para aí 10% de matéria do outro post! Não vejo variáveis globais aqui, nem variáveis globais a serem devolvidas em funções, etc etc... Mas não quero ir por aqui, porque já sei o resultado! Edited December 19, 2016 at 03:43 PM by PsySc0rpi0n Kurt Cobain - Grunge misses you Nissan GT-R - beast killer Link to comment Share on other sites More sharing options...
HappyHippyHippo Posted December 19, 2016 at 03:43 PM Report Share #601370 Posted December 19, 2016 at 03:43 PM 1 minute ago, PsySc0rpi0n said: @HappyHippyHippo, o Segundo exemplo dá segfault. (gdb) bt #0 0x00000000004006f9 in foo (i=0x0) at teste.c:5 #1 0x0000000000400719 in main () at teste.c:10 tira o * antes do i na atribuição do malloc ... desculpa ... mas mesmo assim a resposta deveria ser de cabeça IRC : sim, é algo que ainda existe >> #p@p Portugol Plus Link to comment Share on other sites More sharing options...
PsySc0rpi0n Posted December 19, 2016 at 03:48 PM Author Report Share #601371 Posted December 19, 2016 at 03:48 PM (edited) Sim, eu acho que o que devia imprimir zero. No entanto se compilar e executar isso dá (nil). Quando se faz: int* i = 0; não estamos a tentar forçar a que os valores que vão ser guardados em "i" fiquem no endereço de memória '0' (zero)? Edited December 19, 2016 at 03:56 PM by PsySc0rpi0n Kurt Cobain - Grunge misses you Nissan GT-R - beast killer Link to comment Share on other sites More sharing options...
HappyHippyHippo Posted December 19, 2016 at 04:08 PM Report Share #601372 Posted December 19, 2016 at 04:08 PM 18 minutes ago, PsySc0rpi0n said: Sim, eu acho que o que devia imprimir zero. No entanto se compilar e executar isso dá (nil). Quando se faz: int* i = 0; não estamos a tentar forçar a que os valores que vão ser guardados em "i" fiquem no endereço de memória '0' (zero)? sim ... mas isso é antes da chamada da função ... o printf é depois da função agora diz, porque razão, apesar de enviar um ponteiro, e ser feito um malloc, o printf continua nil ? IRC : sim, é algo que ainda existe >> #p@p Portugol Plus Link to comment Share on other sites More sharing options...
PsySc0rpi0n Posted December 19, 2016 at 05:44 PM Author Report Share #601378 Posted December 19, 2016 at 05:44 PM Não sei ao certo ao que respondeste "sim", mas a questão nesse exemplo que me causa dúvidas é o int* i = 0; No meu entender, quando se faz: int* i = 0; já estamos a reservar o endereço de memória '0' para guardar um valor. Depois dentro da outra função estamos de novo a alocar um bloco de memória para a variável i. O que acontece é que está-se a tentar alterar o valor '0' para outro valor qualquer atribuído pelo malloc! (isto deve ser o que queres ouvir/ver/ler). Mas posso dizer algo diferente que não sei também se é válido ou não que é esse código ao ser compilado, o compilador se queixar de estarmos a tentar reservar dois blocos de memória diferente para o mesmo nome 'i'. Kurt Cobain - Grunge misses you Nissan GT-R - beast killer Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now