SDL Tilemap multilayer

Hi to everyone in the SDL community,

I have created a simple tile map editor that can load in multiple sheets (tile set images), but so far only edits one map layer.

Here’s the pre game loop initializations from main.c:

engine e;
    SDL_Event evt;
    tileMap tb; /*tilemap top toolbar*/
    tileMap td;
    view top; /*viewport for toolbar*/
    view map;
    mouseSelect ms;
    SDL_Rect t;
    int loop = 1;
    int i, j;

    if(eng_init(&e, 1024, 768, 0) < 0){
        printf("\nError initializing engine: %s", SDL_GetError());
    }

    if(tm_loadMapSheet(&tb, "tiles/sheet1.txt", e.screen) < 0){
        printf("\nError loading sheet");
    }

    if(tm_loadMapSheet(&td, "tiles/sheet2.txt", e.screen) < 0){
        printf("\nError loading sheet 2");
    }
    tm_addSheet(&tb, &td);

    printf("\nTotal tiles: %d", tb.num_draw);

    if(tm_createMap(&tb, tb.t_w, tb.t_h, 100, 100) < 0){
        printf("\nError creating blank tile map");
    }

    view_new(&top, 0, 0, 800, 20);
    view_new(&map, 0, 0, 800, 400);

    map.off_x = 0;
    map.off_y = 40;

    t.w = tb.t_w;
    t.h = tb.t_h;

    ms.selected = -1;

    eng_setFPS(&e, 30);

And within loop (minus event handler):

if(SDL_GetMouseState(&ms.x, &ms.y) & SDL_BUTTON(SDL_BUTTON_LEFT)){
            if(ms.x > 0 && ms.x < top.box.w &&
               ms.y > 0 && ms.y < top.box.h){
                    ms.selected = ms.x / tb.t_w;

               }
            if(ms.x > map.off_x && ms.x < (map.off_x + map.box.w) &&
               ms.y > map.off_y && ms.y < (map.off_y + map.box.h)){
                    i = (ms.x - map.off_x) / tb.t_w;
                    j = (ms.y - map.off_y) / tb.t_h;

                    printf("\nTile clicked: %d", (j * tb.m_w + i));

                    tb.tiles[j * tb.m_w + i].type = ms.selected;


               }
        }


        SDL_FillRect(e.screen, NULL, 0xFFFFFFFF);


        tm_drawLoadedTiles(&tb, &top, e.screen);

        tm_drawTiles(&tb, &map, e.screen);



        /*****
        for(i = 0; i < 30; i++){
            t.x = (i * t.w);
            t.y = 0;
            SDL_BlitSurface(tb.draw_tiles[i], NULL, e.screen, &t);
        }

        ***/


        eng_flip(&e);
        eng_wait(&e);

This works perfectly and allows scrolling and saving by the event handler:

while(SDL_PollEvent(&evt)){
    if(evt.type == SDL_KEYDOWN){
        switch(evt.key.keysym.sym){
        case SDLK_ESCAPE:
            loop = 0;
            break;

        case SDLK_s:
            tm_saveMap(&tb, "savemap.txt");
            break;

        case SDLK_RIGHT:
            map.box.x += 3;
            break;

        case SDLK_LEFT:
            map.box.x -= 3;
        /*view movement*/

        }
    }
}

However, when I started with an array of layers in the next iteration of the project, I ran into issues regarding outputting the map tiles for any layer. Here’s the next iteration of main.c that simply doesn’t output any layers:

 engine e;
    SDL_Event evt;
    tileMap tb; /*tilemap top toolbar*/
    tileMap td;
    tileMap layers[5];
    view top; /*viewport for toolbar*/
    view map;
    mouseSelect ms;
    SDL_Rect t;
    int loop = 1;
    int i, j;
    int cur_layer;

    if(eng_init(&e, 1024, 768, 0) < 0){
        printf("\nError initializing engine: %s", SDL_GetError());
    }

    if(tm_loadMapSheet(&tb, "tiles/sheet1.txt", e.screen) < 0){
        printf("\nError loading sheet");
    }

    if(tm_loadMapSheet(&td, "tiles/sheet2.txt", e.screen) < 0){
        printf("\nError loading sheet 2");
    }
    tm_addSheet(&tb, &td);

    /*default map sheet*/
    if(tm_createMap(&tb, tb.t_w, tb.t_h, 100, 100) < 0){
        printf("\nError creating default tb sheet");
    }


    printf("\nTotal tiles: %d", tb.num_draw);

    for(i = 0; i < 5; i++){
        printf("Creating tile layer: %d", i);
        if(tm_createMap(&layers[i], tb.t_w, tb.t_h, 100, 100) < 0){
            printf("\nError creating blank tile map");
        }
    }

    view_new(&top, 0, 0, 1024, 20);
    view_new(&map, 0, 0, 600, 400);

    map.off_x = 0;
    map.off_y = 40;

    t.w = tb.t_w;
    t.h = tb.t_h;

    ms.selected = -1;

    eng_setFPS(&e, 30);

    cur_layer = 0;

    while(loop){
        while(SDL_PollEvent(&evt)){
            if(evt.type == SDL_KEYDOWN){
                switch(evt.key.keysym.sym){
                case SDLK_ESCAPE:
                    loop = 0;
                    break;

                case SDLK_s:
                    tm_saveMap(&tb, "savemap.txt");
                    break;

                case SDLK_RIGHT:
                    map.box.x += 3;
                    break;

                case SDLK_LEFT:
                    map.box.x -= 3;
                    break;
                /*for map layer management (layers[0-4]*/
                case SDLK_0:
                    printf("\nSwitching layers: 0");
                    cur_layer = 0;
                    break;
                case SDLK_1:
                    printf("\nSwitching layers: 1");
                    cur_layer = 1;
                    break;
                case SDLK_2:
                    printf("\nSwitching layers: 2");
                    cur_layer = 2;
                    break;
                case SDLK_3:
                    printf("\nSwitching layers: 3");
                    cur_layer = 3;
                    break;
                case SDLK_4:
                    printf("\nSwitching layers: 4");
                    cur_layer = 4;
                    break;

                default: break;
                }
            }
        }


        if(SDL_GetMouseState(&ms.x, &ms.y) & SDL_BUTTON(SDL_BUTTON_LEFT)){
            if(ms.x > 0 && ms.x < top.box.w &&
               ms.y > 0 && ms.y < top.box.h){
                    ms.selected = ms.x / tb.t_w;

               }
            if(ms.x > map.off_x && ms.x < (map.off_x + map.box.w) &&
               ms.y > map.off_y && ms.y < (map.off_y + map.box.h)){
                    i = (ms.x - map.off_x) / tb.t_w;
                    j = (ms.y - map.off_y) / tb.t_h;

                    printf("\nTile clicked: %d", (j * tb.m_w + i));

                    layers[cur_layer].tiles[j * tb.m_w + i].type = ms.selected;


               }
        }


        SDL_FillRect(e.screen, NULL, 0xFFFFFFFF);


        tm_drawLoadedTiles(&tb, &top, e.screen);

        printf("Drawing tile layer: %d", cur_layer);
        tm_drawTiles(&layers[cur_layer], &map, e.screen);



        /*****
        for(i = 0; i < 30; i++){
            t.x = (i * t.w);
            t.y = 0;
            SDL_BlitSurface(tb.draw_tiles[i], NULL, e.screen, &t);
        }

        ***/


        eng_flip(&e);
        eng_wait(&e);
    }

    printf("\nExiting SDL");

    for(i = 0; i < 5; i++){
        tm_delete(&layers[i]);
    }

    tm_delete(&tb);

    eng_close(&e);

    return 0;

Sorry, if I’m not being descriptive of the engine and tilemap functions. I will explain any questions regarding that if asked. Hope you can help.

Thank you

If I understand you correctly, you want to export the created tilemap to a file (‘savemap.txt’), correct?
If that’s the case, do you want to export all the layers to the same file or multiple files?

You need to show your tm_saveMap function, because my guess is that it might be something wrong in there.

Actually, it turns out I didn’t copy over the draw tiles from the sheet map (just copied the addresses, so no extra cleanup). I’ve gotten the save functionality to work, even saving multiple layers to different files. I’m now trying to work on having solid tiles and sprite placement.