PDA

Ver la versión completa : Tratamiento de ficheros en GP32



canseco
16/06/2004, 12:12
Tengo una duda acerca del uso de las funciones de la gp32. Quiero abrir un fichero de texto, que se dirija a una linea en concreto y que pase la linea entera a una variable, para poder cargar la imagen con IMG_Load en SDL. El formato del texto seria:

gp:\\game\\imagenes\\menu\\portada.bmp
gp:\\game\\imagenes\\cartas\\dreed.bmp
gp:\\game\\imagenes\\cartas\\cibmerc.bmp

¿Como podria hacerlo?

BeaR
16/06/2004, 12:19
Mmmm, en C creo ke es asisgnando un puntero al fichero, y moviendo el puntero ese hasta ke encuentre la linea ke buskas(con un "for" o hasta ke encuentre el final de fichero), una vez que la encuentres con un "for" metes la linea esa en un array de caracteres.

Talvez te he dicho algo ke no te "interesa/ayuda" para nada, pero weno, según tengo entendido el C es con lo ke se programa en la gp32 (más o menos x'D)

A ver si alguien te ayuda mejor ke yo :S , x lo menos te subo el post :D:D:D

Salu2

oankali
16/06/2004, 14:27
A ver si te vale esto. No lo he testeado osea que puede contener errores. Además no está muy optimizado ya que eso de leer carácter a carácter no es lo más rápido.





...

// Lee la siguiente linea de texto dentro de pLine
// Devuelve 0 si ok, -1 si final de archivo
int GetNextLine(F_HANDLE handle, char *pLine)
{
  unsigned long bytesRead;
  int i;

  // Leemos el archivo hasta el pròximo \n
  i = 0;
  do
  {
    // Leemos el octeto siguiente
    GpFileRead(handle, &pLine[i], 1, &bytesRead);

    // Si hemos llegado al final del archivo
    if (bytesRead != 1)
      if (i == 0)
        return -1; // Si no habiamos leido nada, EOF
      else
      {
        i++;
        break; // Sino, salir del bucle
      }

    // No tenemos en cuenta los \r
    if (pLine[i] != '\r')
      i++;

  } while (pLine[i] != '\n');

  // Marcamos el final de la linea
  pLine[i] = '\0';

  return 0;
}

// Lee el texto de la linea numLine del archivo pFilename dentro de pLine
// Devuelve 0 si ok, -1 si no ha encontrado la linea
// La primera linea = 1
int GetFileLine(char *pFilename, int numLine, char *pLine)
{
  F_HANDLE handle;
  int eof, i;
  
  // Abrimos el archivo
  if (GpFileOpen(pFilename, OPEN_R, &handle) != SM_OK)
    return -1;

  // Vamos leyendo lineas hasta encontrar la que buscamos
  eof = FALSE;
&nbsp;&nbsp;for (i=1; i <= numLine && !eof; i++)
&nbsp;&nbsp;&nbsp;&nbsp;if (GetNextLine(handle, pLine) == -1)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eof = TRUE;

&nbsp;&nbsp;// Cerramos el archivo
&nbsp;&nbsp;GpFileClose(handle);

&nbsp;&nbsp;// Si hemos encontrado la linea
&nbsp;&nbsp;if (!eof)
&nbsp;&nbsp;&nbsp;&nbsp;return 0;
&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;pLine[0] = '\0';

&nbsp;&nbsp;return -1;
}


void GpMain (void * arg)
{
&nbsp;&nbsp;char texto[63+1]; // limitado a lineas de 63 de longitud
&nbsp;&nbsp;
&nbsp;&nbsp;...
&nbsp;&nbsp;GpFatInit();
&nbsp;&nbsp;
&nbsp;&nbsp;// recupera la tercera linea del archivo
&nbsp;&nbsp;if (GetFileLine("gp://gpmm//file.txt", 3, texto) != -1)
&nbsp;&nbsp;&nbsp;&nbsp;// tratar la linea 3
&nbsp;&nbsp;
&nbsp;&nbsp;...
}

canseco
16/06/2004, 16:29
¿Cual se supone que es la variable que guarda la linea? char texto?

oankali
16/06/2004, 16:55
Exacto, si las lineas de tu archivo pueden contener más de 63 carácteres tendrás que canviar la declaración.
Como he dicho antes, no lo he testado pero al menos tienes una idea de lo que podría ser una solución.

canseco
16/06/2004, 23:50
Gracias por la ayuda.

canseco
28/06/2004, 16:54
He intentado hacer los siguiente:

if (GetFileLine("gp:\\gpmm\\imagenes\\cartas\\set.txt", 1, texto) != -1)
{
portada = IMG_Load(texto);
SDL_BlitSurface(portada, NULL, TFT, &rectportada);
SDL_Flip(TFT);
}

Pero la pantalla al ejecutarlo se queda en negro y no carga ninguna imagen. ¿Cual es el problema?

oankali
29/06/2004, 07:06
No conozco la función IMG_Load(), así que no te puedo responder.
Pero una cosa que te puedo aconsejar, es que hagas un print en pantalla de la variable text1, para ver si realmente contiene el camino completo de la imágen y de si funciona correctamente GetTextLine().

Un pequeño ejemplo que he encontrado en internet, por si te puede servir.

// load sample.png into image
SDL_Surface *image;
image=IMG_Load("sample.png");
if(!image) {
printf("IMG_Load: %s\n", IMG_GetError());
// handle error
}


Por lo visto no tienes que olvidarte liberar el objecto imágen con SDL_FreeSurface.

canseco
29/06/2004, 16:44
He echo lo siguiente:

int nflip=1;

#define LCD_FRONT (&gpDraw[(nflip + 1) & 0x01])

void GpMain(void *argv)
{
GpClockSpeedChange(132000000, 0x3a011, 3);

GPDRAWSURFACE gpDraw[2];

GpGraphicModeSet(8, NULL);
GpLcdSurfaceGet(&gpDraw,0);
GpSurfaceSet(&gpDraw);
GpLcdEnable();

GpRectFill(NULL, &gpDraw, 0, 0, 320, 240, 0);

char texto[63+1]; // limitado a lineas de 63 de longitud

do
{


if (GetFileLine("gp://gpmm//imagenes//cartas//set.txt", 2, texto) != -1)
{
GpTextOut(NULL,LCD_FRONT,20,20,(char*)"Funciona",0xFF);
}


}
while(GpKeyGet() != GPC_VK_START);
}

Pero no muestra la palabra "Funciona" por pantalla. Quizas es la funcion que no devuelve la linea correctamente.

oankali
30/06/2004, 10:11
Bueno, efectivamente había un pequeño error en GetNextLine().
Aquí tienes una solución que funciona perfectamente, la he testado yo mismo.
No he puesto lo que falta en el lugar de los ... ya que es lo mismo que ya había posteado.

Por tu parte, tu código tiene varios errores. No has inicializado la SMC com GpFatIni() como te indiqué, además declaras dos superfícies con GPDRAWSURFACE gpDraw[2];, pero solo creas una con GpLcdSurfaceGet(&gpDraw,0);.
Por cierto hay que declarar las superficies de forma global o no tendrás acceso a ellas en otras funciones que no sea GpMain().
En tu ejemplo es posible que funcione ya que parece que solo utilices la superficie primária, pero hay incoherencias y crea confusión.
Y otro pequeño detalle: es de buena costumbre declarar las variables al principio de un módulo y no en medio de otras instrucciones, vease la declaración de
texto.

Ah y me olvidaba, ¿porqué pasas el procesador a 132Mhz?
La GP32 es suficientemente potente para no tener que subir tan alto. Mis dos juegos Puzzle Mix y Animings rulan perfectamente a 40Mhz.

Espero que con esto ya lo consigas.




#include "gpdef.h"
#include "gpstdlib.h"
#include "gpstdio.h"
#include "gpgraphic.h"
#include "gpfont.h"


// Declaración de variables globales a toda la aplicación
GPDRAWSURFACE gtSurface[2];
int giSurface;


int GetNextLine(F_HANDLE handle, char *pLine)
{
&nbsp;&nbsp;...

&nbsp;&nbsp;&nbsp;&nbsp;// No tenemos en cuenta los \r ni los \n
&nbsp;&nbsp;&nbsp;&nbsp;if ((pLine[i] != '\r') && (pLine[i] != '\n'))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i++;

&nbsp;&nbsp;...
}

int GetFileLine(char *pFilename, int numLine, char *pLine)
{
&nbsp;&nbsp;...
}


void GpMain(void *arg)
{
&nbsp;&nbsp;// Declaración de variables privadas de la función
&nbsp;&nbsp;char texto[63+1]; // limitado a lineas de 63 de longitud

&nbsp;&nbsp;// Crea las 2 superfícies
&nbsp;&nbsp;GpLcdSurfaceGet(&gtSurface[0], 0);
&nbsp;&nbsp;GpLcdSurfaceGet(&gtSurface[1], 1);

&nbsp;&nbsp;// Activa la superfície primária
&nbsp;&nbsp;GpSurfaceSet(&gtSurface[0]);
&nbsp;&nbsp;giSurface = 1;

&nbsp;&nbsp;// Inicializa la tarjeta SMC
&nbsp;&nbsp;GpFatInit();
&nbsp;&nbsp;
&nbsp;&nbsp;// Recupera la segunda línea del archivo
&nbsp;&nbsp;if (GetFileLine("gp:\\gpmm\\imagenes\\cartas\\set.txt", 6, texto) == -1)
&nbsp;&nbsp;&nbsp;&nbsp;gm_strcpy(texto, "Problema al recuperar la linea.");

&nbsp;&nbsp;// Bucle principal
&nbsp;&nbsp;while(TRUE)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;// Prepara la pantalla en la superfície secundária (la que no se ve)
&nbsp;&nbsp;&nbsp;&nbsp;GpRectFill(NULL, &gtSurface[giSurface], 0, 0, GPC_LCD_WIDTH, GPC_LCD_HEIGHT, 0); // Borra la pantalla
&nbsp;&nbsp;&nbsp;&nbsp;GpTextOut(NULL, &gtSurface[giSurface], 10, 10, texto, 0xFF);

&nbsp;&nbsp;&nbsp;&nbsp;// Activa la superfície secundária para hacerla primária (aparece en pantalla)
&nbsp;&nbsp;&nbsp;&nbsp;GpSurfaceFlip(&gtSurface[giSurface]);
&nbsp;&nbsp;&nbsp;&nbsp;giSurface ^= 0x01;

&nbsp;&nbsp;&nbsp;&nbsp;// Si apreta START, sale del bucle
&nbsp;&nbsp;&nbsp;&nbsp;if (GpKeyGet() & GPC_VK_START)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;}

&nbsp;&nbsp;// Resetea la GP32
&nbsp;&nbsp;GpAppExit();
}

canseco
30/06/2004, 12:09
Ahora si que me furula, muchas gracias por la ayuda.