Pád programu při použití SDL textu

Jenda

Pád programu při použití SDL textu
« kdy: 20. 10. 2010, 23:14:20 »
Ahoj
Zamotal jsem se do nasledujiciho problemu, mam program vyuzivajici knihovny SDL pri praci s grafikou vse funguje jak ma, pokud se vsak pokusim pridat zobrazeni textu dojte k ukonceni programu s"return 3 <0x3>. Pad vyvola ukazatel "font" na radku "text = TTF_RenderText_Solid(font,"ahoj svete",fg_col);"

predem dekuji za jakekoukoliv radu.

Kód: [Vybrat]
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <stdio.h>


#include <SDL/SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>

#include "grafickerozhrani.h"
#include "main.h"


//typedef struct {SDL_Surface *image;}Tobject;
//typedef struct {}Tobject;

//SDL_Surface *screen, *grafik[1];
char adresar[300];
//SDL_Surface *NactiObrazek(char *soubor,int pruhled);

TTF_Font *font;
SDL_Surface *screen;

SDL_Surface *grafik[30][30];
//int SirkaTextu,VyskaTextu;
//SDL_Rect pozicetextu;



//nahrají se obrázky do pole
int NactiObrazky()
{ grafik[0][0]=NactiObrazek("pozadi.bmp",0);
    grafik[0][1]=NactiObrazek("pozadi.bmp",0);
    grafik[0][2]=NactiObrazek("pozadi.bmp",0);
        X_PoziceObjektu[0]=0;
        Y_PoziceObjektu[0]=0;
grafik[1][0]=NactiObrazek("menu1na.bmp",1);
grafik[1][1]=NactiObrazek("menu1up.bmp",1);
grafik[1][2]=NactiObrazek("menu1dn.bmp",1);
        X_PoziceObjektu[1]=(screen->w-grafik[1][0]->w)/2-300;
        Y_PoziceObjektu[1]=(screen->h-grafik[1][0]->h)/2-200;
grafik[2][0]=NactiObrazek("menu2na.bmp",1);
grafik[2][1]=NactiObrazek("menu2up.bmp",1);
grafik[2][2]=NactiObrazek("menu2dn.bmp",1);
        X_PoziceObjektu[2]=(screen->w-grafik[2][0]->w)/2-100;
        Y_PoziceObjektu[2]=(screen->h-grafik[2][0]->h)/2-200;
grafik[3][0]=NactiObrazek("menu3na.bmp",1);
grafik[3][1]=NactiObrazek("menu3up.bmp",1);
grafik[3][2]=NactiObrazek("menu3dn.bmp",1);
        X_PoziceObjektu[3]=(screen->w-grafik[3][0]->w)/2+100;
        Y_PoziceObjektu[3]=(screen->h-grafik[3][0]->h)/2-200;
grafik[4][0]=NactiObrazek("menu4na.bmp",1);
grafik[4][1]=NactiObrazek("menu4up.bmp",1);
grafik[4][2]=NactiObrazek("menu4dn.bmp",1);
        X_PoziceObjektu[4]=(screen->w-grafik[4][0]->w)/2+300;
        Y_PoziceObjektu[4]=(screen->h-grafik[4][0]->h)/2-200;


}

// nacteni obrazku z disku
SDL_Surface *NactiObrazek(char *soubor,int pruhled)
{ SDL_Surface *image;
char cesta[300];
sprintf(cesta,"grafika\\%s",soubor);
if ((image=IMG_Load(cesta))==NULL)
        {fprintf(stderr,"Image %s wasn't found\n",cesta);
            exit(14);
        }
if (pruhled)
        {//urèí prùhlednou barvu obrázku podle prvního pixelu v levo nahoøe a barevné hloubky obrázku
//yatim nefunguje pruhlednost se nastavuje alfa kanalem bmp
if (image->format->BytesPerPixel==1) SDL_SetColorKey(image, (SDL_SRCCOLORKEY|SDL_RLEACCEL),*(Uint8 *)image->pixels);
if (image->format->BytesPerPixel==2) SDL_SetColorKey(image, (SDL_SRCCOLORKEY|SDL_RLEACCEL),*(Uint16 *)image->pixels);
        if (image->format->BytesPerPixel==3) SDL_SetColorKey(image, (SDL_SRCCOLORKEY|SDL_RLEACCEL),*(Uint32 *)image->pixels);
if (image->format->BytesPerPixel==4) SDL_SetColorKey(image, (SDL_SRCCOLORKEY|SDL_RLEACCEL),*(Uint32 *)image->pixels);
        }

return image;
}
//nacteni fontu
int NactiFont(char*soubor,int velikost)
{
    font = TTF_OpenFont(soubor, velikost);
if(!font)
{
printf("Unable to open font: %s\n", TTF_GetError());
return false;
}
  //  TTF_Font *font;
 /*   char cesta[300];
    sprintf(cesta,"grafika\\%s",soubor);

    font=(TTF_OpenFont("DejaVuSansCondensed.ttf", velikost));
    if (font==NULL)
        {fprintf(stderr,"Font %s wasn't found\n",cesta);
            exit(15);*/
        }


int NastavFont()
{



}

int VykresliGrafickeRozhrani(int plocha)
    {
//inicializace grafiky
    if (SDL_Init(SDL_INIT_EVERYTHING) < 0 )
        {fprintf(stderr, "Problem: %s\n", SDL_GetError());
        exit(105);}
    if(SDL_Init(SDL_INIT_VIDEO) == -1)
{
fprintf(stderr, "Unable to initialize SDL: %s\n",
SDL_GetError());
return false;
}

    // Inicializace SDL_ttf
if(TTF_Init() == -1)
{
printf("Unable to initialize SDL_ttf: %s\n", TTF_GetError());
return false;
}


    //priukonceni ukonci SDL

  //  atexit(SDL_Quit);
    //nastaví rozlišení 800x600 s 32b barevné hloubky

    screen = SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE | SDL_DOUBLEBUF); //SDL_FULLSCREEN |

    //skryje se kurzor myši
    SDL_ShowCursor(1);

    //nacte obrazky do pole
    NactiObrazky();
    NactiFont("DejaVuSansCondensed.ttf", 16);
   // NastavFont();
}

//vakresleni uzivatelske plochy 1
void Plocha1()
{
    SDL_Rect drect,srect;
    int timer=0,i;

    srect.x=0;srect.y=0; //vystredeni obrazovky

    srect.w=grafik[0][0]->w;
    srect.h=grafik[0][0]->h;
    drect=srect;
    drect.x=X_PoziceObjektu[0];
    drect.y=Y_PoziceObjektu[0];
    SDL_BlitSurface(grafik[0][0],&srect,screen,&drect);

 //   srect.x=0;srect.y=0;
    srect.w=grafik[1][0]->w;
    srect.h=grafik[1][0]->h;
    drect=srect;
    drect.x=X_PoziceObjektu[1];
    drect.y=Y_PoziceObjektu[1];
    //     X_PoziceObjektu[1]=drect.x;
    //        Y_PoziceObjektu[1]=drect.x;
    SDL_BlitSurface(grafik[1][0],&srect,screen,&drect);

 //   srect.x=0;    srect.y=0;
    srect.w=grafik[2][0]->w;
    srect.h=grafik[2][0]->h;
    drect=srect;
    drect.x=X_PoziceObjektu[2];
    drect.y=Y_PoziceObjektu[2];
    SDL_BlitSurface(grafik[2][0],&srect,screen,&drect);
    //nastaví prùhlednost
   // SDL_SetAlpha(grafik[2][0],SDL_SRCALPHA | SDL_RLEACCEL | SDL_SRCCOLORKEY,abs(timer++%511-255));

 //   srect.x=0;    srect.y=0;
    srect.w=grafik[3][0]->w;
    srect.h=grafik[3][0]->h;
    drect=srect;
    drect.x=X_PoziceObjektu[3];
    drect.y=Y_PoziceObjektu[3];
    SDL_BlitSurface(grafik[3][0],&srect,screen,&drect);

 //   srect.x=0;srect.y=0;
    srect.w=grafik[4][0]->w;
    srect.h=grafik[4][0]->h;
    drect=srect;
    drect.x=X_PoziceObjektu[4];
    drect.y=Y_PoziceObjektu[4];
    SDL_BlitSurface(grafik[4][0],&srect,screen,&drect);


SDL_Color fg_col = { 255, 255, 255, 0 };
SDL_Surface *text;
//SDL_FreeSurface(text);

    font = TTF_OpenFont("c:\DejaVuSansCondensed.ttf", 16);

     
SDL_BlitSurface(text, NULL, screen, NULL);


  SDL_Flip(screen);





 //TTF_SetFontStyle((font, 16)), TTF_STYLE_NORMAL);
//SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 255));
  // TTF_SizeText(font, "Prilis zlutoucky kun upel dabelske ody" "- TTF_RenderText_Solid()",&SirkaTextu, NULL);
//pozicetextu.x = (screen->w >> 1) - (SirkaTextu >> 1);
//pozicetextu.y = (screen->h >> 1) - TTF_FontLineSkip(font)*2;

    //prehodí se prední a zadní buffer a tím se obrázek zjeví uživateli


 //   SDL_Delay(500); //zpomalení prozatím disablováno - zpomalení obstaráva alphablending ;-))
/* screen = TTF_RenderUTF8_Solid(font,// Text musi byt v utf8
"Příliš žluťoučký kůň úpěl ďábelské ódy"
" - TTF_RenderUTF8_Solid()",
{ 255, 255, 255, 0 });*/
}

void uvolniGrafiku()

{
    if(screen != NULL)
        {
        SDL_FreeSurface(screen);
        screen =NULL;
        SDL_Quit();
        }

if(font != NULL)
{
TTF_CloseFont(font);
font = NULL;
TTF_Quit();
}

}
« Poslední změna: 21. 10. 2010, 07:14:13 od Petr Krčmář »


D.A. Tiger

  • ****
  • 486
  • Tygr, který žere tučňáka ;-)
    • Zobrazit profil
    • E-mail
Re: Pád programu při použití SDL textu
« Odpověď #1 kdy: 22. 10. 2010, 01:03:45 »
Citace
Pad vyvola ukazatel "font" na radku "text = TTF_RenderText_Solid(font,"ahoj svete",fg_col);"

1) A kde je ten radek? Ve funkci Plocha( )?
2) Proc funkce Plocha( ) a VykresliGrafickeRozhrani( ) nacitaji dvakrat tytez data do globalni promene ( tedy pokud retezce "DejaVuSansCondensed.ttf" a "c:\DejaVuSansCondensed.ttf" povazujes za stejny), navic retezec "c:\DejaVuSansCondensed.ttf" ve funkci Plocha( ) by mel asi byt "c:\\DejaVuSansCondensed.ttf" aby jsi zrusil zpecialni vyznam znaku zpetneho lomitka, a jeste k tomu zde ani nekontrolujes zda se ti font vube nacetl. Nakonec chyby nejake informace kdy a kde kterou funkci volas - s ohledem na to ze zde mas definovany dve operace, ktere by teoreticky mely (tedy alespon jsem to tak pochopil) nacist jeden soubor, avsak kazda to dela jinak (jedna uspech kontroluje, druha ne), je to docela dulezite.

Tvoji funkci NactiFont( ) bych resil asi nejak takto :

Kód: [Vybrat]
int load_font( char *file, int size )
{
  if( font != NULL ) {
    TTF_CloseFont( font );
    font = NULL; 
  }
 
  if( ( font = TTF_OpenFont( file, size ) ) == NULL ) {
    printf( "Not load font %s", file );
    return FALSE; 
  }
 
  return TRUE;
}

A pak ji dusledne pouzil vsude,kde je potreba nacist font.


3) Docela se divym, ze ti to pri stavu v jakem jsi to hodil sem nekolabuje na radku

Kód: [Vybrat]
SDL_BlitSurface(text, NULL, screen, NULL);
promena text neni nikde inicializovana. Zda se mi to cele takove docela chaoticke....

« Poslední změna: 22. 10. 2010, 08:55:22 od D.A. Tiger »

Jenda

Re: Pád programu při použití SDL textu
« Odpověď #2 kdy: 22. 10. 2010, 11:09:29 »
Mas pravdu chyba je na radku, debuger me to zastavoval o radek drive a tak jsem myslel ze mam chybu v nacitani fontu a proto ty zhuverilosti ve zdrojovem kodu.

SDL_BlitSurface(text, NULL, screen, NULL);

diky za pomoc ja jsem stim zapasil cely vecer a nenasel.

Tu kontrolu na nacteni souboru pouziju, nebude to lepsi udelat pomoci vyjimek try catch ?


D.A. Tiger

  • ****
  • 486
  • Tygr, který žere tučňáka ;-)
    • Zobrazit profil
    • E-mail
Re: Pád programu při použití SDL textu
« Odpověď #3 kdy: 22. 10. 2010, 13:22:50 »
Citace
Tu kontrolu na nacteni souboru pouziju, nebude to lepsi udelat pomoci vyjimek try catch ?

To záleží už na tobě, na tom jaký program píšeš, a jakou máš o něm představu. Funkce load_font( ), kterou jsem ti psal výše hlavně kontroluje zda už nějaký font načtený je - takže ti neunikají zdroje ( v tomto případě paměť) a zda načtení fontu proběhlo úspěšně.  Mužes si ji samozřejmě libovolně modifikovat.

Například kontrola zda je už font načtený (první if ) nemusí při pravdivostní hodnotě hned uvolńovat font z paměti, ale jen provede návrat z funkce s hodnotou TRUE. Jinak bude vše stejné. Takto bych postupoval v případě, že budu používat jen jeden font v celém zbytku aplikace, avšak není z nějakého důvodu jisté  kdy se font načte.

Vyjímku bych použil v případě, že chci na danou situaci nějak zareagovat. V našem případě např. bych dal uživateli možnost si soubor s fontem najít ručně (asi přes dialog) nebo zadat jiný vhodný font. Jinak je tu tež možnost rovnou ukončit celou aplikaci voláním exit( ).

To jsou varianty, které mě tak v rychlosti napadly. Můžeš samozřejmě postupovat úplně jinak - fakt to hodně zaleží na tom, co chceš Ty, aby to dělalo  :D