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
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(¤t_time); |
|
|
|
copy_str(time_str, asctime(localtime(¤t_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; |
|
} |
|
|
|
|