Dumb-ways-to-memorize
2D game
graphics.c
Go to the documentation of this file.
1 #include "globals.h"
2 #include "graphics.h"
3 #include <SDL.h>
4 #include <SDL_image.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include <stdlib.h>
8 
9 SDL_Window *gWindow = NULL;
10 SDL_Renderer *gRenderer = NULL;
11 SDL_Surface *gRedSurface = NULL;
12 SDL_Texture *gRedTexture = NULL;
13 SDL_Renderer *gRedRenderer = NULL;
14 sprite_t *gSprites = NULL;
15 int gLastSprite = 0;
16 int gScreenWidth = 0;
17 int gScreenHeight = 0;
18 
20 {
21  Uint32 flags = 0;
22  SDL_DisplayMode current;
23  if(SDL_Init(SDL_INIT_EVERYTHING))
24  {
25  printf("SDL can't initialize : %s", SDL_GetError());
26  exit(-1);
27  }
28  if(SDL_GetDisplayMode(0,0,&current))
29  {
30  printf("No video mode: %s", SDL_GetError());
31  exit(-1);
32  }
33 
34  //Create Window based on either default or set screenWidth / Height
36  {
37  if( (gWindow = SDL_CreateWindow(GAME_NAME, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, gScreenWidth, gScreenHeight, flags )) == NULL )
38  {
39  printf("Can't create window %s", SDL_GetError());
40  exit(-1);
41  }
42  } else {
43  if( (gWindow = SDL_CreateWindow(GAME_NAME, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_RES_W, SCREEN_RES_H, flags )) == NULL )
44  {
45  printf("Can't create window %s", SDL_GetError());
46  exit(-1);
47  }
50  }
51 
52  //Main Rendering Context
53  SDL_SetWindowTitle(gWindow, "Dumb Ways to Memorize");
54 
55  if( (gRenderer = SDL_CreateRenderer(gWindow, -1, flags)) == NULL)
56  {
57  printf("Can't create renderer %s ", SDL_GetError());
58  exit(-1);
59  }
60 
61  //Red Renderer
62  if ( (gRedSurface = SDL_CreateRGBSurface(0,gScreenWidth,gScreenHeight,32,0,0,0,0)) == NULL)
63  {
64  printf("Can't create red surface : %s \n", SDL_GetError());
65  }
66  if( (gRedRenderer = SDL_CreateSoftwareRenderer(gRedSurface)) == NULL)
67  {
68  printf("Can't create red renderer : %s \n", SDL_GetError());
69  }
70  if( SDL_SetRenderDrawColor(gRedRenderer, 0xFF, 0, 0, 0xFF) )
71  {
72  printf("Can't set red renderer : %s \n", SDL_GetError());
73  }
74  SDL_RenderClear(gRedRenderer);
75  if( (gRedTexture = SDL_CreateTextureFromSurface(gRenderer, gRedSurface)) == NULL)
76  {
77  printf("Can't create red texture : %s \n", SDL_GetError());
78  }
79  gSprites = (sprite_t*) malloc(sizeof(sprite_t)*MAX_SPRITES);
80  if(!gSprites)
81  {
82  printf("Could not allocate sprites");
83  return -1;
84  }
85  memset(gSprites, 0, sizeof(sprite_t)*MAX_SPRITES);
86  gLastSprite = 0;
87  atexit(SDL_Quit);
88  atexit(ShutdownGraphics);
89  return 0;
90 }
91 
93 {
94  int i;
95  for(i = 0; i < MAX_SPRITES; i++)
96  {
97  if(!gSprites[i].refCount)
98  {
99  continue;
100  }
101  FreeSprite(&gSprites[i]);
102 
103  }
104  free(gSprites);
105 }
106 
107 sprite_t *LoadSprite(const char *name, int flags)
108 {
109  SDL_Surface *temp;
110  sprite_t *check;
111  int position;
112  if(!gSprites)
113  {
114  return NULL;
115  }
116  if(abs(gLastSprite) > MAX_SPRITES)
117  {
118  gLastSprite = 0;
119  }
120  if(!name)
121  {
122  printf("No name given to load sprite");
123  return NULL;
124  }
125  if( (check = FindSprite(name, NULL)) != NULL)
126  {
127  check->refCount++;
128  return check;
129  }
130  if( (check = FindFreeSprite(&position)) == NULL)
131  {
132  printf("No free sprites");
133  return NULL;
134  }
135  temp = IMG_Load(name);
136  if(!temp)
137  {
138  printf("Could not load image : %s \n", name);
139  return NULL;
140  }
141  check->mSize.x = temp->w;
142  check->mSize.y = temp->h;
143  check->mTexture = SDL_CreateTextureFromSurface(gRenderer, temp);
144  check->name = strdup(name);
145  check->refCount = 1;
146  check->mFrames = 0;
147  SDL_FreeSurface(temp);
148  gLastSprite = position;
149  return check;
150 }
151 
152 int DrawSprite(sprite_t *sprite, int* frame, vec2_t * position, SDL_Renderer * renderer)
153 {
154  SDL_Rect src, dst;
155  int zero = 0;
156  if(!sprite)
157  {
158  printf("Null sprite given \n");
159  return -1;
160  }
161  if(!frame)
162  {
163  frame = &zero;
164  }
165  if( *frame >= sprite->mFrames )
166  {
167  *frame = 0;
168  }
169 
170  SDL_SetRect(&src, sprite->mAnimations[*frame].Position.x, sprite->mAnimations[*frame].Position.y, sprite->mSize.x, sprite->mSize.y);
171 
172  *frame = *frame+1;
173 
174  if(!position)
175  {
176  SDL_SetRect(&dst, 0, 0, 0, 0);
177  SDL_GetRendererOutputSize(renderer, &dst.w, &dst.h);
178  } else {
179  SDL_SetRect(&dst, position->x, position->y, sprite->mSize.x, sprite->mSize.y);
180  }
181 
182 
183  if( SDL_RenderCopy(renderer, sprite->mTexture, &src, &dst) )
184  {
185  printf("Could not draw sprite %s : %s", sprite->name, SDL_GetError());
186  }
187  return 0;
188 }
189 
190 Frame *LoadAnimation(int frame_width, int frame_height, int width, int height)
191 {
192  Frame *retVal;
193  int i,j, rows, cols;
194  cols = frame_width ? width/frame_width : 1;
195  rows = frame_height ? height/frame_height : 1;
196  retVal = (Frame*) malloc(sizeof(Frame)*(rows*cols+1));
197  for(i = 0; i < rows; i++)
198  {
199  for(j = 0; j < cols; j++)
200  {
201  retVal[i*rows + j].Position.x = j*frame_width;
202  retVal[i*rows + j].Position.y = i*frame_height;
203  }
204  }
205  memset(&retVal[rows*cols+1], 0, sizeof(Frame));
206  return retVal;
207 }
208 
209 sprite_t* FindSprite(const char* name, int* position)
210 {
211  int i;
212  for(i = 0; i < MAX_SPRITES; i++)
213  {
214  if(gSprites[i].refCount == 0)
215  continue;
216  if(!strcmp(gSprites[i].name, name))
217  {
218  if(position)
219  *position = i;
220  return &gSprites[i];
221  }
222  }
223  return NULL;
224 }
225 
226 sprite_t* FindFreeSprite(int *position)
227 {
228  int i;
229  for(i = gLastSprite; i < MAX_SPRITES; i++)
230  {
231  if(gSprites[i].refCount == 0)
232  {
233  return &gSprites[i];
234  }
235  }
236  for(i = 0; i < gLastSprite; i++)
237  {
238  if(gSprites[i].refCount == 0)
239  {
240  return &gSprites[i];
241  }
242  }
243  return NULL;
244 }
245 
246 void FreeSprite(sprite_t *sprite)
247 {
248  int position;
249  if(sprite == FindSprite(sprite->name, &position))
250  {
251  sprite->refCount--;
252  if(sprite->refCount > 0)
253  return;
254  }
255  SDL_DestroyTexture(sprite->mTexture);
256  free(sprite->name);
257  memset(&gSprites[position], 0, sizeof(sprite_t) );
258 
259 }
260 
261 //Unused for now
262 void IncrementFrame(sprite_t* sprite)
263 {
264  int frames;
265  if(!sprite)
266  {
267  return;
268  }
269  frames = CountMem(&sprite->mAnimations[0], sizeof(Frame));
270  if(!frames)
271  {
272  return;
273  }
274 }
275 
276 void SDL_SetRect(SDL_Rect* rect, int x, int y, int w, int h)
277 {
278  rect->x = x;
279  rect->y = y;
280  rect->w = w;
281  rect->h = h;
282 }
int CountMem(void *src, int size_type)
Definition: mymath.c:51
void ShutdownGraphics()
Definition: graphics.c:92
void IncrementFrame(sprite_t *sprite)
Definition: graphics.c:262
int y
Definition: globals.h:22
Definition: graphics.h:15
void FreeSprite(sprite_t *sprite)
Definition: graphics.c:246
Frame * LoadAnimation(int frame_width, int frame_height, int width, int height)
Definition: graphics.c:190
int gLastSprite
Definition: graphics.c:15
SDL_Renderer * gRenderer
Definition: graphics.c:10
SDL_Window * gWindow
Definition: graphics.c:9
vec2_t Position
Definition: graphics.h:17
#define GAME_NAME
Definition: graphics.h:7
int gScreenWidth
Definition: graphics.c:16
#define MAX_SPRITES
Definition: graphics.h:11
SDL_Texture * gRedTexture
Definition: graphics.c:12
int gScreenHeight
Definition: graphics.c:17
int InitGraphics()
Definition: graphics.c:19
SDL_Surface * gRedSurface
Definition: graphics.c:11
sprite_t * FindFreeSprite(int *position)
Definition: graphics.c:226
void SDL_SetRect(SDL_Rect *rect, int x, int y, int w, int h)
Definition: graphics.c:276
SDL_Renderer * gRedRenderer
Definition: graphics.c:13
char * name
Definition: parseobject.h:24
sprite_t * LoadSprite(const char *name, int flags)
Definition: graphics.c:107
int x
Definition: globals.h:21
#define SCREEN_RES_W
Definition: graphics.h:9
sprite_t * FindSprite(const char *name, int *position)
Definition: graphics.c:209
int DrawSprite(sprite_t *sprite, int *frame, vec2_t *position, SDL_Renderer *renderer)
Definition: graphics.c:152
#define SCREEN_RES_H
Definition: graphics.h:10
sprite_t * gSprites
Definition: graphics.c:14
Definition: globals.h:19