LazyFoo Sdl2 Tutorial Error

My problem:
I followed the “Tiling Tutorial” of LazyFoo’s SDL2 Tutorial Series. I’m sure some of you know it.
So I followed the tutorial and everything worked out fine but after some time I tried to experiment with the Tiling
System and I stumbled across some Errors. In the Tutorial were defined some constants to describe the Tile like “const int TILE_WIDTH/HEIGHT” and my problems lies in “const int TOTAL_TILES”. It’s the number of the total existing Tiles but for some reason I get an error when this int is bigger than 192. I don’t know why, I get an “Unexpected end of map file” Error but you have to know the tutorial to understand what I mean. I hope there are some of you who still remember it or even read it because I just can’t figure out what the problem is and I really would be happy about some help.
Thanks.

The reason why you get an error message during the creation of the tilemap is that you’re having a map file (lazy.map) that consist of 16 columns- and 12 rows of tile information (so 192 tiles in total). The code for the application is based on this value, so if you were to raise the value, for example to 193, and then loop through the map file, you’ll end up in the end of the file earlier than expected. So when the for loop is at index 192, the end of the file is reached, an end-of-file character is returned (which is \n), map.fail() returns true and you get an error message saying “Unexpected end of map file”.

One solution to this problem: at the beginning of the map file, write out the level width and level height (so the number of horizontal and vertical tiles), read in those values at the start of the program and loop through the correct number of tiles in the map file.

Alright thanks for your answer but isn’t it possible to just add some colums and rows like: 40 colums and 40 rows for a 3200x3200 big level with Tiles that have the width and height of 80px. That’s what I tried and it didn’t work. I also don’t really understand your solution.
Can I just write the Level Height/Width at the beginning of the file and everything is done?

Yes, you can add tiles to the level file, increase the TOTAL_TILES variable in the code so it corresponds to the number of tiles in the level file and then it will load fine at the startup of the program.
For example, if you have 40 columns and 40 rows in the level file, TOTAL_TILES should be set to 1600.
You also need to increase LEVEL_WIDTH and LEVEL_HEIGHT to 3200 to be able to scroll through the whole level.

This solution is, as you can imagine, not very dynamic since it forces you to use levels that are all 40x40 in size. Also, the tile size is hardcoded aswell.
If you were to load a level file that has less than 40 horizontal and/or 40 vertical tiles, the application will shutdown because the level creation fails.
On the other hand, if you were to load a level file that has more than 40 horizontal and/or more than 40 vertical tiles, you won’t be able to scroll through the whole level, since the level size is hardcoded into the application code.
Also, if the tile size is different between levels, the scrolling will probably break because the application code expect a certain tile size (80x80).

To get around this limitation, you can write the level width, the level height, the tile width and the tile height in the level file. Example:

LevelWidth	10
LevelHeight	10
TileWidth	80
TileHeight	80

00 01 02 00 01 02 00 01 02 00 
01 02 00 01 02 00 01 02 00 01 
02 00 11 04 04 04 04 04 04 04 
00 01 10 03 03 03 03 03 03 03 
01 02 10 03 08 08 08 08 08 08 
02 00 10 06 00 01 02 00 01 02 
00 01 10 06 01 11 05 01 02 00 
01 02 10 06 02 09 07 02 00 01 
02 00 10 06 00 01 02 00 01 02 
00 01 10 03 04 04 04 05 02 00

Then, when the level is loaded in the application code, the header data (level width etc) can be read, saved and the number of tiles (and each tile’s size) that are created are based on that specific data. Example:

// A dynamic list containing the level tiles
std::list<Tile*> TileList;

bool setTiles()
{
	//Open the map
	std::ifstream MapFile("Data/Levels/lazy.map");

	//If the map couldn't be loaded
	if(!MapFile.is_open())
	{
		printf("Unable to load map file\n");
		return false;
	}

	else
	{
		std::string	TempString  =  "";
		unsigned int	LevelWidth  =  0;
		unsigned int	LevelHeight =  0;
		unsigned int	TileWidth   =  0;
		unsigned int	TileHeight  =  0;
		int		TileType    = -1;

		// Read out the header data from the level file
		MapFile >> TempString >> LevelWidth;
		MapFile >> TempString >> LevelHeight;
		MapFile >> TempString >> TileWidth;
		MapFile >> TempString >> TileHeight;

		for(unsigned int i = 0; i < LevelHeight; ++i)
		{
			for(unsigned int j = 0; j < LevelWidth; ++j)
			{
				MapFile >> TileType;

				Tile* pTile = new Tile(j * TileWidth, i * TileHeight, TileType);

				TileList.push_back(pTile);
			}
		}

		// Clip the sprite sheet etc
	}

	MapFile.close();

	return true;
}

Instead of using a fixed-size array of tiles, I’m using a dynamic array/list, which I can add non-fixed number of tiles into.
Since I’m using new to create my tiles, the tiles need to be properly destroyed at application shutdown, by calling delete on all the tiles, to avoid memory leak.

TOTAL_TILES = (LEVEL_WIDTH/TILE_WIDTH)*(LEVEL_HEIGHT/TILE_HEIGHT);

So simple is that.

But…

First of all:

/* This source code copyrighted by Lazy Foo' Productions (2004-2015)
and may not be redistributed without written permission. */

secondly:
from:
http://lazyfoo.net/faq.php

Q: I don’t get tutorial/article X.
A: Well contact me and I’ll try to explain it better and maybe make adjustments to the tutorial.

It is in my interest that people learn from my tutorials. If people can’t learn from my tutorials, honestly what good are they?

That person wrote that tutorial for a reason, he wanted get the Idea how a tile map editor works.
That is the simplest form one can have, it is loosely knit mixed C/C++ code.
It was good enough for him/her to get it rudimentary working and thought it would be a good idea to share the code, what I appreciate.

Personally I wouldn’t use C++ code for those short tutorials at all, cause all those classes are just distracting from the topic and the compiler output if you run in errors is massive. The compilation time even without cmake is horrible but negligible. So in the end it is a matter of taste and I guess if you code in C++ you need tutorials in that languages. I think for those things Pseudocode works best and at the end, some implementations could be provided.

“If you want to pick a strawberry, you don’t need a master plan… just pick it.”

Why would you struggle to work with a prototype instead of a mature, well supported piece of software?

Software development is expensive, thousands of hours going to development unsure if the project will be successful. Most projects aren’t useful unless they are 5 years developed and maintained.

Just watch this:
https://www.openhub.net/p/sdl

took an estimated 80 years of effort (COCOMO model)
starting with its first commit in April, 2001

I wonder where all this “Game-Engines” and “MapEditors” starting here will go ?!?!

What projection of the tiles do you need?
Orthogonal Projection, Oblique Projection, Isometric Projection, Isometric Stagger, Isometric Terrain?

And how about

Cheers,
–Cass

Update:
Pitfall!,
working name jungle runner

designed by David Crane for the Atari 2600 and released by Activision in 1982 was written by him in 64 weeks ~ 1,000 h. And I don’t think he was uneducated or lazy - probably he was smarter than me at that age and software development for that hardware was easier IMO cause of all those constraints. He didn’t waste his time on picking one out of 16,8 mil. colors and did not need a master degree in Media-Design to make the choice.

What I mean by this, even if you are a hobbyist you need something like project management and a goal or in the end you will achieve nothing.

Thanks to your answer it. I did what you said. I made a map file, 40 rows/40 columns. TOTAL_TILES set to 1600 or (LEVEL_WIDTH / TILE_WIDTH)*(LEVEL_HEIGHT / TILE_HEIGHT) and the Level was 3200x3200 big. But, that’s simply not working. It won’t let me use more than 192 tiles. I don’t get why. Although I appreciate your solution with the dynamic method I wanted to try it like this, because as you said, it should work.

No problem, I haven’t looked further in the code. It compiled on Linux after fixing headers and one error. So, lazy didn’t want to make it adjustable by the look. Maybe I find it quick.

It works fine on my computer. Do you get the error message saying ‘unexpected end of file’?

Works here also.
You need 40 lines of something like this
00 01 02 00 01 02 00 01 02 00 01 02 00 01 02 00 01 02 00 01 02 00 01 02 00 01 02 00 01 02 00 01 02 00 11 04 04 04 04 04
and don’t forget to change the filename in code :-/
but again, why bother? You really wanna edit 1600 tiles like that? Haha, coding assembler is easier and less tedious :smile:

Yes I got it. But he doesn’t explain how this error message works and what it means.

Yeah I have those 40 lines.
And yes, I want to edit 1600 tiles and I don’t want to use any other programs for this. I want to learn and understand how this works and I don’t like programs that do work for me that I could do by myself. Anyways, what do you mean with “change the filename in code”?

Well, I hope you are on your own operating system with your own browser and prepared to rewrite SDL. Good luck buddy!

BTW this section is for SDL development.

I think you misunderstood my message. If I would use your program I wouldn’t understand how tiling works. I just would use a program without knowing the tech behind it. Of course I can’t program my own os or browser nor I can rewrite SDL. I just wanted to make clear that I want to learn it the oldschool way and not with the help of such a program.

Do you mind uploading your code and your level file somewhere so I can check it out?
Might be something you’re missing or that might be incorrect in the code.

If you are saying that questions related to using SDL should not be posted here, where should they be posted? The description of this forum says that it is for “all discussion of SDL” and the only others I see are ‘Announcements’ and ‘Game Development’ (“non-SDL discussion about making games”).

Alright meanwhile it works but I don’t know why and I still don’t know what I did wrong. Anyways I thank you all for your answers.