Skip to content
Snippets Groups Projects
Select Git revision
  • 6f23a2ddc9c308a57b320a775e7e1f62c865882f
  • master default protected
2 results

gfx.c

Blame
  • fardin.hossain's avatar
    fardin.hossain authored
    6f23a2dd
    History
    gfx.c 2.98 KiB
    /// @file gfx.c
    /// @author Florent Gluck
    /// @date November 6, 2016
    /// Helper routines to render pixels in fullscreen graphic mode.
    /// Uses the SDL2 library.
    
    #include "gfx.h"
    
    /// Create a fullscreen graphic window.
    /// @param title Title of the window.
    /// @param width Width of the window in pixels.
    /// @param height Height of the window in pixels.
    /// @return a pointer to the graphic context or NULL if it failed.
    struct gfx_context_t* gfx_create(char *title, uint width, uint height) {
    	if (SDL_Init(SDL_INIT_VIDEO) != 0) goto error;
    	SDL_Window *window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED,
    			SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_RESIZABLE);
    	SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
    	SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888,
    			SDL_TEXTUREACCESS_STREAMING, width, height);
    	uint32_t *pixels = malloc(width*height*sizeof(uint32_t));
    	struct gfx_context_t *ctxt = malloc(sizeof(struct gfx_context_t));
    
    	if (!window || !renderer || !texture || !pixels || !ctxt) goto error;
    
    	ctxt->renderer = renderer;
    	ctxt->texture = texture;
    	ctxt->window = window;
    	ctxt->width = width;
    	ctxt->height = height;
    	ctxt->pixels = pixels;
    
    	SDL_ShowCursor(SDL_DISABLE);
    	gfx_clear(ctxt, COLOR_BLACK);
    	return ctxt;
    
    error:
    	return NULL;
    }
    
    /// Draw a pixel in the specified graphic context.
    /// @param ctxt Graphic context where the pixel is to be drawn.
    /// @param x X coordinate of the pixel.
    /// @param y Y coordinate of the pixel.
    /// @param color Color of the pixel.
    void gfx_putpixel(struct gfx_context_t *ctxt, int x, int y, uint32_t color) {
    	if (x < ctxt->width && y < ctxt->height)
    		ctxt->pixels[ctxt->width*y+x] = color;
    }
    
    /// Clear the specified graphic context.
    /// @param ctxt Graphic context to clear.
    /// @param color Color to use.
    void gfx_clear(struct gfx_context_t *ctxt, uint32_t color) {
    	int n = ctxt->width*ctxt->height;
    	while (n)
    		ctxt->pixels[--n] = color;
    }
    
    /// Display the graphic context.
    /// @param ctxt Graphic context to clear.
    void gfx_present(struct gfx_context_t *ctxt) {
    	SDL_UpdateTexture(ctxt->texture, NULL, ctxt->pixels, ctxt->width*sizeof(uint32_t));
    	SDL_RenderCopy(ctxt->renderer, ctxt->texture, NULL, NULL);
    	SDL_RenderPresent(ctxt->renderer);
    }
    
    /// Destroy a graphic window.
    /// @param ctxt Graphic context of the window to close.
    void gfx_destroy(struct gfx_context_t *ctxt) {
    	SDL_ShowCursor(SDL_ENABLE);
    	SDL_DestroyTexture(ctxt->texture);
    	SDL_DestroyRenderer(ctxt->renderer);
    	SDL_DestroyWindow(ctxt->window);
    	free(ctxt->pixels);
    	ctxt->texture = NULL;
    	ctxt->renderer = NULL;
    	ctxt->window = NULL;
    	ctxt->pixels = NULL;
    	SDL_Quit();
    	free(ctxt);
    }
    
    /// If a key was pressed, returns its key code (non blocking call).
    /// List of key codes: https://wiki.libsdl.org/SDL_Keycode
    /// SDL_PumpEvents() must be called before.
    /// @return 0 if escape was not pressed.
    SDL_Keycode gfx_keypressed() {
    	const Uint8 *state = SDL_GetKeyboardState(NULL);
    	if (state && state[SDL_SCANCODE_ESCAPE]) {
    		return SDLK_ESCAPE;
    	}
    	return 0;
    }