1
1
Fork 0
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

279 lines
6.5 KiB

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <string.h>
#include <time.h>
#include "basic-lib.c"
const int screen_width = 800;
const int screen_height = 600;
/* logging definition */
typedef enum {
// high-low priority
// low-high verbosity
SILENT, ERROR, WARN, INFO, DEBUG
} logger_level;
logger_level LOGLEVEL = DEBUG;
logger_level STDOUTLEVEL = DEBUG;
void logwrite(logger_level level, char message[]) {
// write a string message
char time_str[100];
time_t current_time;
time(&current_time);
copy_str(time_str, asctime(localtime(&current_time)));
// delete the \n
time_str[24] = ' ';
char prepend[15];
copy_str(prepend, time_str);
switch (level) {
case DEBUG:
strcat(prepend, "DEBUG");
break;
case INFO:
strcat(prepend, "INFO ");
break;
case WARN:
strcat(prepend, "WARN ");
break;
case ERROR:
strcat(prepend, "ERROR");
break;
}
strcat(prepend, ": ");
if (level <= LOGLEVEL) {
FILE * logfile = fopen("debug.log", "a");
fprintf(logfile, "%s", prepend);
fprintf(logfile, message);
fclose(logfile);
}
if (level <= STDOUTLEVEL) {
printf("%s", prepend);
printf(message);
}
}
/* Type definition for object cleanups */
typedef enum {
NO, SURFACE, TEXTURE, RENDERER, WINDOW
} sdl_types;
typedef union {
SDL_Window * window;
SDL_Renderer * renderer;
SDL_Surface * surface;
SDL_Texture * texture;
void * generic;
} thing_for_cleanup ;
typedef struct {
sdl_types kind;
thing_for_cleanup thing;
} sdl_abstract;
static sdl_abstract cleanup_queue[100];
static int cleanup_queue_length = 0;
void queue_for_cleanup(void * SDL_thing, sdl_types kind) {
sdl_abstract obj;
obj.kind = kind;
switch (kind) {
case TEXTURE:
obj.thing.texture = SDL_thing;
break;
case WINDOW:
obj.thing.window = SDL_thing;
break;
case RENDERER:
obj.thing.renderer = SDL_thing;
break;
case SURFACE:
obj.thing.surface = SDL_thing;
break;
}
cleanup_queue_length++;
cleanup_queue[cleanup_queue_length] = obj;
}
void cleanup(void * thing, sdl_types thing_type) {
if (!thing) {
logwrite(DEBUG, "Null passed to cleanup\n");
return;
}
switch(thing_type) {
case SURFACE:
SDL_FreeSurface(thing);
logwrite(DEBUG, "Freed surface\n");
break;
case TEXTURE:
SDL_DestroyTexture(thing);
logwrite(DEBUG, "Destroyed texture\n");
break;
case RENDERER:
SDL_DestroyRenderer(thing);
logwrite(DEBUG, "Destroyed renderer\n");
break;
case WINDOW:
SDL_DestroyWindow(thing);
logwrite(DEBUG, "Destroyed window\n");
break;
case NO:
return;
}
}
void empty_cleanup_queue(void) {
for (; cleanup_queue_length > 0; cleanup_queue_length--) {
sdl_abstract thing = cleanup_queue[cleanup_queue_length];
cleanup(thing.thing.generic, thing.kind);
}
}
struct SDL_Window* make_window(void) {
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
printf("error initializing SDL: %s\n", SDL_GetError());
}
return SDL_CreateWindow("sdl_tester",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
screen_width, screen_height, 0);
}
void step(void) {
// game
//
// draw
return;
}
void render_texture_at(struct SDL_Renderer * ren, struct SDL_Texture * texture,int x, int y) {
SDL_Rect destination;
destination.x = x;
destination.y = y;
SDL_QueryTexture(texture, NULL, NULL, &destination.w, &destination.h);
SDL_RenderCopy(ren, texture, NULL, &destination);
// queue for cleanup
}
void queue_object_for_cleanup(void * thing, sdl_types thing_type) {
}
void refresh(struct SDL_Renderer * ren) {
}
SDL_Texture * load_image(SDL_Renderer * ren, char fname[]) {
SDL_Surface * surface = IMG_Load(fname) ;
if(!surface) {
printf("IMG_Load: %s\n", IMG_GetError());
// handle error
}
SDL_Texture * png_image = SDL_CreateTextureFromSurface(ren, surface);
cleanup(surface, SURFACE);
return (png_image);
}
void draw_pictures(struct SDL_Renderer * ren) {
// display an initial splash screen
const char file[] = "image.bmp";
SDL_Surface* surface = SDL_LoadBMP(file);
SDL_Texture * texture = SDL_CreateTextureFromSurface(ren,surface);
const char png_file[] = "trans.PNG";
SDL_Surface * png_surface = IMG_Load(png_file) ;
if(!png_surface) {
printf("IMG_Load: %s\n", IMG_GetError());
// handle error
}
SDL_Texture * png_image = SDL_CreateTextureFromSurface(ren, png_surface);
// remove the surface from memory as no longer needed
cleanup(png_surface, SURFACE);
cleanup(surface, SURFACE);
// check this actually does stuff
SDL_RenderClear(ren);
//render_texture_at(ren, texture, 100, 100);
//render_texture_at(ren, png_image, 100, 100);
SDL_RenderCopy(ren, png_image, NULL, NULL);
// update the actual screen
SDL_RenderPresent(ren);
}
int main() {
logwrite(INFO, "Starting\n");
SDL_Window * win = make_window();
SDL_Renderer * ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED);
queue_for_cleanup(win, WINDOW);
queue_for_cleanup(ren, RENDERER);
IMG_Init(IMG_INIT_PNG | IMG_INIT_JPG);
if (ren == NULL) {
SDL_DestroyWindow(win);
SDL_Quit();
}
int close = 0;
int first = 1;
while (!close) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
close = 1;
break;
default:
if (!first) {
step();
} else {
draw_pictures(ren);
first = 1;
}
}
}
}
printf("Cleanup queue length: %d\n", cleanup_queue_length);
empty_cleanup_queue();
printf("Cleanup queue length: %d\n", cleanup_queue_length);
logwrite(DEBUG, "Emptied cleanup queue\n");
return 0;
}