Search code examples
c++arrayscoordinatessdl

Is there a way to map a 2D array's x and y to a screen's resolution?


I have this SDL & C++ code to render the 24 x 24 array to the screen.

int main(int argc, char *argv[])
{
    // Init
    SDL_Window *mainwindow = SDL_CreateWindow("window", SDL_WINDOWPOS_UNDEFINED,
    SDL_WINDOWPOS_UNDEFINED, SCREEN_W, SCREEN_H, SDL_WINDOW_SHOWN);
    SDL_Renderer *mainrenderer = SDL_CreateRenderer(mainwindow, -1,
            SDL_RENDERER_PRESENTVSYNC);
    SDL_Texture *maintexture = SDL_CreateTexture(mainrenderer, SDL_PIXELFORMAT_RGBA8888,
            SDL_TEXTUREACCESS_STATIC, SCREEN_W, SCREEN_H);
    Uint32 *buffer = new Uint32[SCREEN_W * SCREEN_H];
    memset(buffer, 0, SCREEN_H * SCREEN_W * sizeof(Uint32));



    //Loop

    while(true){
        if(quit_event() == false){break;}

        for(int y = 0; y < MAP_H; y++){
            for(int x = 0; x < MAP_W; x++){
                if(worldMap[y][x] == 0){
                    Uint32 colour = 0;

                    colour += 0xFF;
                    colour <<= 8;
                    colour += 0xFF;
                    colour <<= 8;
                    colour += 0xFF;
                    colour <<= 8;
                    colour += 0;

                    buffer[(y * SCREEN_W) + x] = colour;
                }
            }
        }
        SDL_UpdateTexture(maintexture, NULL, buffer,
                SCREEN_W * sizeof(Uint32));
        SDL_RenderClear(mainrenderer);
        SDL_RenderCopy(mainrenderer, maintexture, NULL, NULL);
        SDL_RenderPresent(mainrenderer);
    }
    delete[] buffer;
    SDL_DestroyRenderer(mainrenderer);
    SDL_DestroyTexture(maintexture);
    SDL_DestroyWindow(mainwindow);
    SDL_Quit();

}

When running the program this is displayed. enter image description here

How could I map the X and Y values of worldMap to one's of those on a screen without making the worldMap array the size of the screen?

EDIT: I have changed the program and it sort of works now.

enter image description here

#include <iostream>
#include "SDL.h"

#define MAP_W 8
#define MAP_H 8
#define MAP_A 64
#define GRID_S 64
#define SCREEN_W 640
#define SCREEN_H 480
using namespace std;
int worldMap[]=
{
 1,1,1,1,1,1,1,1,
 1,0,1,0,0,0,0,1,
 1,0,1,0,0,0,0,1,
 1,0,1,0,0,0,0,1,
 1,0,0,0,0,0,0,1,
 1,0,0,0,0,1,0,1,
 1,0,0,0,0,0,0,1,
 1,1,1,1,1,1,1,1,
};

bool quit_event(){
    SDL_Event event;

    while (SDL_PollEvent(&event)) {
        if (event.type == SDL_QUIT) {

            return false;
        }
    }
    return true;
}



int main(int argc, char *argv[])
{
    SDL_Init(SDL_INIT_EVERYTHING);
    // Init
    SDL_Window *mainwindow = SDL_CreateWindow("window", SDL_WINDOWPOS_UNDEFINED,
    SDL_WINDOWPOS_UNDEFINED, SCREEN_W, SCREEN_H, SDL_WINDOW_RESIZABLE);
    SDL_Renderer *mainrenderer = SDL_CreateRenderer(mainwindow, -1,
            SDL_RENDERER_PRESENTVSYNC);



    //Loop

    while(true){
        SDL_SetRenderDrawColor(mainrenderer,0,0,255,255);

        SDL_RenderClear(mainrenderer);

         SDL_SetRenderDrawColor(mainrenderer,0,255,255,255);
        if(quit_event() == false){break;}
        SDL_Rect rect;
        rect.w = GRID_S;
        rect.h = GRID_S;
        for(int y = 0; y < MAP_H; y++){
            rect.y = 0 + (y * GRID_S);
            for(int x = 0; x < MAP_W; x++){
                rect.x = 0 + (x * GRID_S);
                if(worldMap[y*MAP_W+x] == 1){
                    SDL_RenderDrawRect(mainrenderer,&rect);
                    SDL_RenderFillRect(mainrenderer,&rect);
                }
            }
        }




        SDL_RenderPresent(mainrenderer);
    }

    SDL_DestroyRenderer(mainrenderer);

    SDL_DestroyWindow(mainwindow);
    SDL_Quit();

}

Now I'm just confused on how the rectangles are rendered wonky...


Solution

  • This seems to be a recent open issue. https://github.com/libsdl-org/SDL/issues/4001

    In your case the issue is apparently with the top side, instead of the bottom one, but it's the same issue overall.

    Try leaving out SDL_RenderDrawRect and use just SDL_RenderFillRect.