Page 1 of 3 1 2 3 LastLast
Results 1 to 10 of 30

Thread: [C/C++] Stuck On a Create-A-Level

  
  1. #1
    HadesMinion's Avatar
    HadesMinion is offline -Hacks Smarty
    Join Date
    Oct 2010
    Location
    Wisconsin
    Posts
    176
    Rep Power
    10914

    Default [C/C++] Stuck On a Create-A-Level

    Well, I'm diving into a fairly complicated (For me) feature for my game. This feature will enable the user to create levels for my game inside of the game, then save them to files for loading any time they want. I have been non-stop working on this since Saturday at about 2 AM, all of my time has went into this except for eating, sleeping, and going to school (Actually I've been eating at my computer so...). I thought I had it all figured out, but I didn't. Here is the function I use to save a level created by the user:
    Code:
    void saveLevel()
    {
    	oskRunning = true;
    	enterLevelName();
    	char levelSavePath[50] = "file/levels/";
    	strcat(levelSavePath, levelName);
    	w_levelSave = fopen(levelSavePath, "w");
    	fclose(w_levelSave);
    	w_levelSave = NULL;
    	w_levelSave = fopen(levelSavePath, "a");
    	bgOne->scrollX = 0;
    	bgOne->scrollY = 0;
    	for (int s = 0; s < 50; s ++)
    		fprintf(w_levelSave, "%i: %i, %i\n", s, moveX[s], moveY[s]);
    	for (int m = 50; m < 100; m ++)
    		fprintf(w_levelSave, "%i: %i, %i\n", m, moveX[m], moveY[m]);
    	iVar = 0;
    	fclose(w_levelSave);
    	w_levelSave = NULL;
    }
    And here is the loading function:

    Code:
    void loadLevel()
    {
    	c_loaded = true;
    	char *r_levelBuffer = new char[5000];
    	//int useless[100];
    	oskRunning = true;
    	enterLevelName();
    	char levelSavePath[50] = "file/levels/";
    	strcat(levelSavePath, levelName);
    	r_levelSave = fopen(levelSavePath, "r");
    	if (!r_levelSave) fclose(r_levelSave), oslDebug("Error loading level!");
    	else
    	{
    		smVar = 0, mdVar = 0;
    		bgOne->scrollX = 0;
    		bgOne->scrollY = 0;
    		fseek(r_levelSave, 0, SEEK_END);
    		r_levelSize = ftell(r_levelSave);
    		rewind(r_levelSave);
    		r_levelBuffer = (char *) malloc(r_levelSize + 1);
    		fread(r_levelBuffer, 1, r_levelSize, r_levelSave);
    		r_levelBuffer[r_levelSize] = '\0';
    		string c_search;
    		string c_finish = "%i, %i\n";
    		for (int s = 0; s < 50; s ++)
    		{
    			sprintf(const_cast<char *>(c_search.c_str()), "%i: %s", s, c_finish.c_str());
    			sscanf(r_levelBuffer, c_search.c_str(), &moveX[s], &moveY[s]);
    		}
    		for (int m = 50; m < 100; m ++)
    		{
    			sprintf(const_cast<char *>(c_search.c_str()), "%i: %s", m, c_finish.c_str());
    			sscanf(r_levelBuffer, c_search.c_str(), &moveX[m], &moveY[m]);
    		}
    		iVar = 0;
    	}
    	fclose(r_levelSave);
    	r_levelSave = NULL;
    	delete(r_levelBuffer);
    	r_levelBuffer = NULL;
    }
    Now, the saving function works. It produces results like this:
    Code:
    1: 150, 200
    2: 200, 200
    3: 93, 125
    And so on... The reason there are two separate for loops for each is because I have two types of blocks (So far): Small and Medium. The user drags around each with the cursor and then saves the level. Okay, working so far. Then I try to load it. After I load it up, either nothing happens or it resets depending on how much I've fucked with my code since the last time I've tested it out. I honestly don't know what I'm doing wrong. Can someone help me out?


  2. #2
    Stinkee2's Avatar
    Stinkee2 is offline Programmer -Hacks Hacker
    Join Date
    Jul 2009
    Location
    ಠ_ಠ
    Posts
    888
    Rep Power
    280

    Default

    This isn't your problem since you said it saves fine, but what's this about?
    Code:
        w_levelSave = fopen(levelSavePath, "w");
        fclose(w_levelSave);
        w_levelSave = NULL;
        w_levelSave = fopen(levelSavePath, "a");
    You open it for writing and then appending? Tehehe.

    Okay, I can't really see what's going wrong there either. Tell me what exactly you want to load from this file. Does the entire file look like that?
    "PM Oyabun a bunch of gay pr0n and you're in." - ...BeAkEr... (BeAkErOo)

  3. #3
    HadesMinion's Avatar
    HadesMinion is offline -Hacks Smarty
    Join Date
    Oct 2010
    Location
    Wisconsin
    Posts
    176
    Rep Power
    10914

    Default

    Quote Originally Posted by Stinkee2
    This isn't your problem since you said it saves fine, but what's this about?
    That's the only way I could think of to delete/clear any existing file in three lines, that way I don't even need a check: If it exists, it wipes it clean, if it doesn't it creates an empty one.

    Quote Originally Posted by Stinkee2
    Okay, I can't really see what's going wrong there either. Tell me what exactly you want to load from this file. Does the entire file look like that?
    Alright, this is what I'm doing, I'll copy a saved file exactly then post it and describe what I'm loading.

    Code:
    0: 154, 70
    1: 188, 70
    2: 222, 70
    3: 266, 42
    4: 326, 66
    5: 388, 88
    6: 502, 92
    7: 0, 0
    8: 448, 156
    9: 412, 176
    10: 376, 184
    11: 338, 188
    12: 254, 188
    13: 134, 186
    14: 0, 0
    15: 0, 0
    16: 0, 0
    17: 0, 0
    18: 0, 0
    19: 0, 0
    20: 0, 0
    21: 0, 0
    22: 0, 0
    23: 0, 0
    24: 0, 0
    25: 0, 0
    26: 0, 0
    27: 0, 0
    28: 0, 0
    29: 0, 0
    30: 0, 0
    31: 0, 0
    32: 0, 0
    33: 0, 0
    34: 0, 0
    35: 0, 0
    36: 0, 0
    37: 0, 0
    38: 0, 0
    39: 0, 0
    40: 0, 0
    41: 0, 0
    42: 0, 0
    43: 0, 0
    44: 0, 0
    45: 0, 0
    46: 0, 0
    47: 0, 0
    48: 0, 0
    49: 0, 0
    50: 192, 158
    51: 60, 158
    52: 0, 0
    53: 0, 0
    54: 0, 0
    55: 0, 0
    56: 0, 0
    57: 0, 0
    58: 0, 0
    59: 0, 0
    60: 0, 0
    61: 0, 0
    62: 0, 0
    63: 0, 0
    64: 0, 0
    65: 0, 0
    66: 0, 0
    67: 0, 0
    68: 0, 0
    69: 0, 0
    70: 0, 0
    71: 0, 0
    72: 0, 0
    73: 0, 0
    74: 0, 0
    75: 0, 0
    76: 0, 0
    77: 0, 0
    78: 0, 0
    79: 0, 0
    80: 0, 0
    81: 0, 0
    82: 0, 0
    83: 0, 0
    84: 0, 0
    85: 0, 0
    86: 0, 0
    87: 0, 0
    88: 0, 0
    89: 0, 0
    90: 0, 0
    91: 0, 0
    92: 0, 0
    93: 0, 0
    94: 0, 0
    95: 0, 0
    96: 0, 0
    97: 0, 0
    98: 0, 0
    99: 0, 0
    That's the exact file that was just saved after I just created a quick scrap level. I've only implemented two types of blocks so there's only 100 variables.

    What this does is use a string to hold the changing variable "s" and then adds on "%i, %i\n" so it is essentially searching for "0: %i, %i\n", "1: %i, %i\n", and so on. Then it stores the first %i into moveX[VARIABLE] and moveY[VARIABLE]. In other words I want to use the numbers before the colon as a reference for blocks and something to search for, then the numbers after the colon as two X and Y variables.

    After it's done saving to the X and Y variables, I have an environment class, and from there I create a platform using:
    Code:
    moveX[VARIABLE] - bgOne->scrollX, moveY[VARIABLE] - bgOne->scrollY
    for the coordinates.

  4. #4
    hardhat is offline Programmer -Hacks Enthusiast
    Join Date
    May 2007
    Posts
    544
    Rep Power
    66

    Default

    Hi,

    Well this code is a problem for sure:
    Code:
    		for (int s = 0; s < 50; s ++)
    		{
    			sprintf(const_cast<char *>(c_search.c_str()), "%i: %s", s, c_finish.c_str());
    			sscanf(r_levelBuffer, c_search.c_str(), &moveX[s], &moveY[s]);
    		}
    You can't be sprintf-ing into a std::string. It just is extremely unwise. It'll corrupt memory. Myself, I'd read in one line at a time with fgets, and then do the sscanf:
    Code:
           char line[256];
           while( fgets( line, 255, file)) {
               int id,x,y;
               int items=sscanf("%d: %d, %d", &id, &x, &y);
               if( items==3) { // we read all 3
                   if( id>=0 && id<100 ) {
                         moveX[id]=x;
                         moveY[id]=y;
                   }
               }
           }
    But that's how I like to do things.

    Assuming you want to continue to load the whole file in one shot, and then search through it for the line you want, I suppose a minimal correction would be more like:
    Code:
    		string c_search;
    		string c_finish = "%i, %i\n";
    		char key[256];
    		const char *line;
    		for (int s = 0; s < 50; s ++)
    		{
    			sprintf(key, "%i: ", s);
    			line=strstr( r_levelBuffer, key);
    			if( line) { 
    				sscanf(line+strlen(key), "%i, %i", &id, &moveX[s], &moveY[s]);
     			} else {
    				moveX[s]=0;
    				moveY[s]=0;
    			}
    		}
    		for (int m = 50; m < 100; m ++)
    		{
    			sprintf(key, "%i: ", s);
    			line=strstr( r_levelBuffer, key);
    			if( line) { 
    				sscanf(line+strlen(key), "%i, %i", &id, &moveX[s], &moveY[s]);
     			} else {
    				moveX[s]=0;
    				moveY[s]=0;
    			}
    		}
    Also fopen( filename, "w"); will delete a file if it exists. If you want to keep the file you have to use "a" or one of the + modes ("r+", "a+", "w+") I suppose.

    My 2D homebrew | My 3D homebrew with Team Sushi. | My YouTube channel. | My Twitter
    Spoiler:

    hardhat: F1 == help on Windows
    J697: oh I have never used the help, so I wouldnt know
    hardhat: so that's why you're always lost. :-P

  5. #5
    HadesMinion's Avatar
    HadesMinion is offline -Hacks Smarty
    Join Date
    Oct 2010
    Location
    Wisconsin
    Posts
    176
    Rep Power
    10914

    Default

    Holy titties, thank you soooo much Hardhat. I've been working on this forever and hopefully this will work, I'll try it soon and get back to you on it.

    I know that opening it with write permissions will delete the file, that's what I'm trying to do (So it doesn't append one level onto another if the user chooses the same name as a previous level).
    I don't know if I'll be able to do it line by line because it's somewhat confusing to me, but I'll read up on it and maybe I'll convert it once I get it working.

    I know you're not supposed to manipulate std::strings when they're in the form of c strings, I just didn't know it could result in memory corruption o.o.

    I'm sure I'll be able to work through it without knowing, but what exactly do strstr and strlen do? Once I write the function I'll look it up, but just in case you reply before I'm done I figured I'd ask.
    Thanks, and I was gonna +Rep you later, but I'll just do it now.

    EDIT:
    ... ... ...
    ... ... ...
    HOLY FUCK, IT WORKED!!!!
    USUALLY I DON'T USE CAPS OR RUN-ON SENTENCES BUT I'M SO HAPPY I CAN'T HELP IT I HAVE BEEN WORKING ON THIS FOR YOU DON'T KNOW HOW LONG AND NOW I AM HAPPY AND EXITED AND I DON'T EVEN KNOW WHAT ELSE TO SAY THANK YOU VERY MUCH OH MY GOD I JUST SHIT OUT OF MY MAN BOOBS I'M THAT HAPPY, YEAH, THAT HAPPY!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    Alright that's about the most obnoxious I'll ever be on this forum, but now you get the idea of how much trouble that God damn function was giving me. Thanks!!!

  6. #6
    hardhat is offline Programmer -Hacks Enthusiast
    Join Date
    May 2007
    Posts
    544
    Rep Power
    66

    Default

    I suspect that you have other errors in that code.

    It seems to me like you use new to construct your loading buffer, then malloc it (causing a memory leak), then delete the pointer instead of the array:

    Code:
    char *buffer=new char[5000];
    // ...
    delete buffer;
    is incorrect, instead you should do:
    Code:
    delete [] buffer;
    And if you malloc() you should use free() instead of delete of course.

    My 2D homebrew | My 3D homebrew with Team Sushi. | My YouTube channel. | My Twitter
    Spoiler:

    hardhat: F1 == help on Windows
    J697: oh I have never used the help, so I wouldnt know
    hardhat: so that's why you're always lost. :-P

  7. #7
    HadesMinion's Avatar
    HadesMinion is offline -Hacks Smarty
    Join Date
    Oct 2010
    Location
    Wisconsin
    Posts
    176
    Rep Power
    10914

    Default

    Thanks, I don't really know a lot about malloc other than it allocates memory. I also didn't know the difference between delete and free until now lol. I wouldn't have to free it as an array though, right? (EG: It would be free(buffer), not free [] buffer, right?)

  8. #8
    hardhat is offline Programmer -Hacks Enthusiast
    Join Date
    May 2007
    Posts
    544
    Rep Power
    66

    Default

    That is correct. You say:
    Code:
    char *buffer=(char *)malloc(size);
    // ...
    free(buffer);
    or you say:
    Code:
    int *list=new list[size];
    // ...
    delete [] list;

    My 2D homebrew | My 3D homebrew with Team Sushi. | My YouTube channel. | My Twitter
    Spoiler:

    hardhat: F1 == help on Windows
    J697: oh I have never used the help, so I wouldnt know
    hardhat: so that's why you're always lost. :-P

  9. #9
    HadesMinion's Avatar
    HadesMinion is offline -Hacks Smarty
    Join Date
    Oct 2010
    Location
    Wisconsin
    Posts
    176
    Rep Power
    10914

    Default

    Thanks for clearing that up, you've been a huge help. Out of curiosity, why use malloc in the first place if you could just create a new variable on the free store? In other words, what is the difference?

  10. #10
    hardhat is offline Programmer -Hacks Enthusiast
    Join Date
    May 2007
    Posts
    544
    Rep Power
    66

    Default

    Well, new and delete are only available in C++, so if you happen to be using C you can't use them. The nice thing about new is that it creates the correct type automatically, and calls any class constructor if it is defined.

    On the other hand, C++ doesn't have a parallel to realloc() which can be used to make a buffer larger: malloc, then as the buffer grows call realloc() to expand the buffer. Then free() it when it is done.

    So basically some code expects new/delete and other code expects malloc/calloc/realloc/free.

    My 2D homebrew | My 3D homebrew with Team Sushi. | My YouTube channel. | My Twitter
    Spoiler:

    hardhat: F1 == help on Windows
    J697: oh I have never used the help, so I wouldnt know
    hardhat: so that's why you're always lost. :-P

Page 1 of 3 1 2 3 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •