Thread: Loading Text File Resources

  1. #1
    Registered User
    Join Date
    Sep 2010
    Posts
    11

    Loading Text File Resources

    I am working on converting my hand-coded int arrays for levels to putting them in a .txt file and loading them by resource. So this function will also handle looping through the file and then setting the ints in the global level array.

    Everythings working so far, but I have a few questions.

    On the char array, how can I use a variable size? or should I just set it to the maximum?

    Then, what function would I use to loop through the char array and extract ints?

    The text file will be setup, and formatted with some extra spacing such as:
    Code:
    0,  0,  1,  2, 10,  0,  5
    1,  0,  0, 11,  0,  0,  0
    0,  0,  0,  0,  0,  0,  0
    I have checked the char array, and it is loading the text file correctly.

    Code:
    void loadResourceLevel(int resid) {   
        // variables
        DWORD dwFileSize;
        LPVOID lpTxtData;
        LPVOID pvData;
        LPSTREAM pstm;
        HRSRC hrlp;
        HGLOBAL hGlobal;
        HINSTANCE hInst = (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE);
        char data[100];
        
        // find resource
        hrlp = FindResource(hInst, MAKEINTRESOURCE(resid), RT_RCDATA);
        
        // make sure it found something
        if (hrlp != NULL) {
            dwFileSize = SizeofResource(hInst, hrlp);
            hGlobal = LoadResource(hInst, hrlp);
            
            // something was loaded
            if (hGlobal != 0) {
                lpTxtData = LockResource(hGlobal);
                pvData = NULL;
                hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwFileSize);
                pvData = GlobalLock(hGlobal);
                CopyMemory(pvData, lpTxtData, dwFileSize);
                GlobalUnlock(hGlobal);
                memcpy(data, lpTxtData, dwFileSize);
    
                return;
            }
        }
    
        MessageBox(hwnd, "Failed", NULL, MB_OK);
    }
    I was thinking of something like sscanf() to read the ints. That won't work though because each line will contain 100's of ints, so I need a function to iterate through each int.

  2. #2
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Is there a good reason to use text files?


    I usually define a structure, and save the data as a binary stream (binary file, not text file).

    Then it is easier (and quicker) to copy the struct out of the memory (from the resource file) and into an array of the structs.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  3. #3
    Registered User
    Join Date
    Sep 2010
    Posts
    11
    I want this to all be easily editable, so all I have to do to add levels is create the text file and add it to the resource file. It is working for backgrounds of levels, but now I just need to do it for level information.

    Right now all the file consists of is an array of tile ID's, and I got it working. It just loads the text from resource and places all the ints in the global iMap array.

    But I need to add more to it, such as enemy info, and a few other level variables. I don't see any way to do that with the way its currently setup... I guess I could break it up and loop through the different parts of the file separately, and still read int by int. It seems kind of sloppy, but would work...

    Code:
                char data[dwFileSize];
                memcpy(data, lpTxtData, dwFileSize);
                
                // fill default map
                for (int i = 0; i < MAP_HEIGHT; i++) {
                    for (int j = 0; j < MAP_WIDTH_MAX; j++) {
                        iMap[i][j] = 0;
                    }
                }
                
                // read file
                // FILE FORMAT
                // line 0-11: map ints split by spaces and commas
                int line = 0;
                int col = 0;
                int currentInt = -1;
                int currentIntPos = 0;
                int scannedInt;
                int colMax = 0;
                
                for (int i = 0; i < dwFileSize; i++) { 
                    
                    // get int at position
                    scannedInt = charToInt(data[i]);
                    
                    // check if number or not
                    if (scannedInt != -1) {
                        if (currentInt == -1) currentInt = 0;
                        currentInt = (currentInt*10)+scannedInt;
                        currentIntPos++;
                    }
                    // not int
                    else {
                        // check to save current int
                        if (currentInt != -1) {
                            iMap[line][col] = currentInt;
                            currentInt = -1;
                            currentIntPos = 0;
                            col++;
                            if (col >= MAP_WIDTH_MAX) col = 0;
                        }
                    }
                    
                    // next line
                    if (data[i] == '\n') { 
                        if (col > colMax) colMax = col; // check for max col
                        line++; col = 0; // add line and reset col
                        if (line >= MAP_HEIGHT) break; // too many lines
                    }
                }
    Code:
    int charToInt(char conv) {
        int ret, ret2;
        ret = (int)conv;
        ret2 = ret-48; // ascii for 0 (48) 
        if (ret2 < 0 || ret2 > 9) ret2 = -1;
        return ret2;
    }

  4. #4
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    I have found text files sometimes cause issues, are larger and slower to process.

    I also do not want the user to be able to easily edit them (by opening the exe in a hex editor and viewing/modifing the text).

    BTW

    What happens in 'charToInt' if you have an int with more than one digit?

    Have you looked at 'atoi'? (['ascii to int'] which reads a char array until the first non digit character, then converts to an int)

    or isdigit()
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  5. #5
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Is all the data just int's?

    Quote Originally Posted by Brokenhope View Post
    But I need to add more to it, such as enemy info, and a few other level variables. I don't see any way to do that with the way its currently setup...
    This is where using a struct helps.

    You can have different structs grouping all the data for an enemy, other level variables, etc.
    Then one big struct holding all the smaller ones (or multiples of them).
    The size will be much smaller.

    You can then read the file (memory block) right into the main struct (or read a sequence of structs as required).


    Quote Originally Posted by Brokenhope View Post
    I guess I could break it up and loop through the different parts of the file separately, and still read int by int. It seems kind of sloppy, but would work...
    For a few pieces of data this is a fine approach, but as the data becomes more complex other ways are easier.

    Use a charater to define where data items start and another to define the end of the line
    Code:
    // ',' is data separator
    // '.' is end of line
    //data file
    1,2,3,4,5.
    6,7,8,9,10.
    //end of data file
    
    #define MAP_HEIGHT 2
    #define MAP_WIDTH 5
    
    //allocate memory the size of the file +1 for the terminator
    char *data = NULL;
    int index =0;
    
    data = (char*)calloc( (dwFileSize + 1) * sizeof(char));//init all chars to terminators (0)
    if(data == null) 
        //handle memory alloc error
    //fill  the data buffer
    memcpy(data, lpTxtData, dwFileSize);
    //find first digit
    while(!isdigit(data[index] && index <dwFileSize)
        index++;
    // fill default map
    int i=0;//the height
    int j=0;//the width
    while (index < dwFileSize && i<MAP_HEIGHT && j<MAP_WIDTH)//make sure we stay in the array sizes
    {
         iMap[i][j] = atoi(data[index]);
         //now fin the next 'special' character in the buffer
         while(data[index]!=',' && data[index]!= '.' && index <dwFileSize)
              index++;
         //now process what that character means
         if(data[index]==',') //move on one width
         {
              j++;//move across one
              if(j==MAP_WIDTH)
                   //error as we have filled all the data but not found a '.'
         }
         else if(data[index]=='.')//end of line, start new one
         {
              j=0;//reset the width
              i++;
              if(i==MAP_HEIGHT)//end of data
                  break;
           }
           //move to next digit (past any EOL characters we will find after a '.' ie '/r/n' )
           while(!isdigit(data[index] )
           {
               index++;
               if( index >=dwFileSize)
                   break;
            }
    }
    //clean up
    free(data);
    
    
    [NOTE: Off the top of my head not compiled! or even well thought through....]
    Last edited by novacain; 10-11-2010 at 04:38 AM.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Basic text file encoder
    By Abda92 in forum C Programming
    Replies: 15
    Last Post: 05-22-2007, 01:19 PM
  2. Batch file programming
    By year2038bug in forum Tech Board
    Replies: 10
    Last Post: 09-05-2005, 03:30 PM
  3. Unknown Memory Leak in Init() Function
    By CodeHacker in forum Windows Programming
    Replies: 3
    Last Post: 07-09-2004, 09:54 AM
  4. Outputting String arrays in windows
    By Xterria in forum Game Programming
    Replies: 11
    Last Post: 11-13-2001, 07:35 PM