1
0
mirror of https://github.com/rzzzwilson/pymlac.git synced 2025-06-10 09:32:41 +00:00
rzzzwilson.pymlac/vimlac/display_sdl.c
2018-08-04 22:40:31 +07:00

231 lines
6.8 KiB
C

/******************************************************************************\
* display_sdl.c *
* ------------- *
* *
* This file is used to display the vimlac screen using the SDL2 library. *
* *
* TODO: make display size dynamic depending on screen size, ie, choose one *
* (51, 512), (1024, 1024) or (2048, 2048). *
* *
\******************************************************************************/
#include <SDL.h>
#include "display.h"
/******
* Constants, etc.
******/
// screen/display stuff
#define MAX_X 512 // max X coord for display
#define MAX_Y 512 // max Y coord for display
#define SCALE_MAX_X 512 // max vimlac X coord
#define SCALE_MAX_Y 512 // max vimlac Y coord
//#define SCALE_MAX_X 2048 // max vimlac X coord
//#define SCALE_MAX_Y 2048 // max vimlac Y coord
// initial and increment size for dynamic DisplayList
#define DL_INIT_SIZE 2048 // initial size of the DisplayList array
#define DL_INC_SIZE 1024 // how much we increase DisplayList size
// struct to hold info for one line drawn from (x1,y1) to (x2,y2)
typedef struct DrawLine
{
int x1;
int y1;
int x2;
int y2;
} DrawLine;
// display state variables
static SDL_Window *window = NULL; // the SDL window reference
static SDL_Renderer *renderer = NULL; // reference to SDL renderer
static DrawLine *DisplayList; // the DrawLine array (dynamic)
static int DisplayListSize = 0; // current size of the dynamic DisplayList
static int NumLines = 0; // number of lines in DisplayList
static bool DisplayDirty = false; // true if the DisplayList has changed
/******************************************************************************
Description : Draw one line on the vimlac screen.
Parameters : x1, y1 - start point coordinates
: x2, y2 - stop point coordinates
Returns :
Comments : Must check if DisplayList full and reallocate it bigger.
******************************************************************************/
void display_draw(int x1, int y1, int x2, int y2)
{
// check if DisplayList full
if (NumLines >= DisplayListSize)
{
int newsize = DisplayListSize + DL_INC_SIZE;
DisplayList = realloc(DisplayList, sizeof(DrawLine) * newsize);
if (!DisplayList)
{
printf("Out of memory in 'display_draw()' reallocing to %d bytes.\n",
newsize);
printf("Possibly runaway display processor!?\n");
display_close();
exit(1);
}
DisplayListSize = newsize;
}
// invert the Y coords
y1 = SCALE_MAX_Y - y1;
y2 = SCALE_MAX_Y - y2;
// scale line coords
x1 = x1 / (SCALE_MAX_X / MAX_X);
y1 = y1 / (SCALE_MAX_Y / MAX_Y);
x2 = x2 / (SCALE_MAX_X / MAX_X);
y2 = y2 / (SCALE_MAX_Y / MAX_Y);
// add new line to DisplayList
DrawLine *p = &DisplayList[NumLines++];
p->x1 = x1;
p->y1 = y1;
p->x2 = x2;
p->y2 = y2;
DisplayDirty = true;
}
/******************************************************************************
Description : Draw the DisplayList to the SDL screen.
Parameters :
Returns :
Comments :
******************************************************************************/
void display_write(void)
{
DrawLine *p = DisplayList; // get pointer to first struct in DisplayList
SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE);
for (int i = 0; i < NumLines; ++i)
{
SDL_RenderDrawLine(renderer, p->x1, p->y1, p->x2, p->y2);
++p;
}
SDL_RenderPresent(renderer);
DisplayDirty = false;
}
/******************************************************************************
Description : Set the state back to "nothing on the screen".
Parameters :
Returns :
Comments :
******************************************************************************/
void display_reset(void)
{
NumLines = 0;
DisplayDirty = true;
}
/******************************************************************************
Description : Initialize the SDL system.
Parameters :
Returns : 'true' if all went well, else 'false'.
Comments :
******************************************************************************/
bool display_init()
{
// if NOT initialized, do the initialization
if (!window)
{
if (SDL_Init(SDL_INIT_VIDEO) != 0)
return false;
// SDL_DisplayMode dm;
//
// if (SDL_GetDesktopDisplayMode(0, &dm) != 0)
// {
// printf("SDL_GetDesktopDisplayMode failed: %s\n", SDL_GetError());
// return false;
// }
// printf("Screen wxh = %d x %d\n", dm.w, dm.h);
window = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, MAX_X,
MAX_Y, SDL_WINDOW_SHOWN);
if (!window)
return false;
renderer = SDL_CreateRenderer(window, -1, 0);
if (!renderer)
{
if (window)
SDL_DestroyWindow(window);
return false;
}
// set window title
SDL_SetWindowTitle(window, "vimlac 0.1");
// allocate the initial DisplayList array
DisplayList = malloc(sizeof(DrawLine) * DL_INIT_SIZE);
if (!DisplayList)
{
display_close();
return false;
}
// error allocating DisplayList if we get here
// free up DSL resources
DisplayListSize = DL_INIT_SIZE;
display_reset();
}
return true;
}
/******************************************************************************
Description : Get the display "dirty" flag.
Parameters :
Returns : 'true' if the DisplayList has changed, else 'false'.
Comments :
******************************************************************************/
bool display_dirty(void)
{
return DisplayDirty;
}
/******************************************************************************
Description : Close down the SDL system.
Parameters :
Returns :
Comments :
******************************************************************************/
void display_close(void)
{
if (renderer)
SDL_DestroyRenderer(renderer);
if (window)
SDL_DestroyWindow(window);
SDL_Quit();
}