~fluix/periodicus

periodicus/main.c -rw-r--r-- 3.2 KiB
9fa32d88Steven Guikal Improve Makefile 5 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#include <stdio.h>
#include "elements.h"
#include "log.h"

#define WIDTH 640
#define HEIGHT 480
#define SCALE 32
#define GROUPS 18
#define PERIODS 9

struct color {
	char* name;
	SDL_Color color;
};

static struct color theme[] = {
	{"black", {0, 0, 0}},
	{"primary", {139, 192, 208}},
	{"background", {46, 52, 64}},
	{"symbols", {236, 239, 244}},
};

SDL_Window *window;
SDL_Renderer *renderer;
TTF_Font *font;

SDL_Color* getColor(char* name) {
	for (int i = 0; i < sizeof(theme) / sizeof(theme[0]); i ++) {
		if (strcmp(name, theme[i].name) == 0) {
			return &theme[i].color;
		}
	}
	return NULL;
}

void setColor(char* name) {
	SDL_Color *c = getColor(name);
	SDL_SetRenderDrawColor(renderer, c->r, c->g, c->b, c->a);
}

void drawElement(struct element element, int x, int y) {
	SDL_Rect rect;
	rect.x = x;
	rect.y = y;
	rect.w = SCALE;
	rect.h = SCALE;
	SDL_RenderDrawRect(renderer, &rect);

	SDL_Color *color = getColor("symbols");
	SDL_Surface *surface = TTF_RenderText_Solid(font, element.symbol, *color);
	SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
	
	int tw, th;
	SDL_QueryTexture(texture, NULL, NULL, &tw, &th);
	SDL_Rect dstrect = {x+(SCALE-tw)/2, y+(SCALE-th)/2, tw, th};
	SDL_RenderCopy(renderer, texture, NULL, &dstrect);

	SDL_DestroyTexture(texture);
	SDL_FreeSurface(surface);
}

void draw() {
	setColor("background");
	SDL_RenderClear(renderer);
	setColor("primary");

	int windoww, windowh, offsetx, offsety;
	SDL_GetWindowSize(window, &windoww, &windowh);
	offsetx = (windoww-(SCALE+1)*GROUPS)/2;
	offsety = (windowh-(SCALE+1)*PERIODS-SCALE/3)/2;

	// XXX: Perhaps storing the position as part of the element is better?
	int atomic_num = 0;
	for (int y = 0; y < PERIODS; y ++) {
		for (int x = 0; x < GROUPS; x ++) {
			atomic_num += map[y][x];
			if (map[y][x] != 0) {
				int ex = x*(SCALE+1);
				int ey = y*(SCALE+1);
				if (y > 6) { // lanthanoids and actinoids
					ey += SCALE/3;
				}
				drawElement(elements[atomic_num-1], ex+offsetx, ey+offsety);
			}
		}
	}

	SDL_RenderPresent(renderer);
}

int main (int argc, char *argv[]) {
	if (SDL_Init(SDL_INIT_VIDEO) != 0) {
		ERROR("Failed SDL initialization: %s", SDL_GetError());
		goto quit_sdl;
	}
	if (TTF_Init() != 0) {
		ERROR("Failed TTF initialization: %s", SDL_GetError());
		goto quit_sdl;
	}
	font = TTF_OpenFont("cozette.ttf", 9);
	window = SDL_CreateWindow("Periodicus",
		SDL_WINDOWPOS_UNDEFINED,
		SDL_WINDOWPOS_UNDEFINED,
		WIDTH,
		HEIGHT,
		SDL_WINDOW_BORDERLESS|SDL_WINDOW_RESIZABLE);
	if (window == NULL) {
		ERROR("Failed window initialization: %s", SDL_GetError());
		goto quit_window;
	}
	renderer = SDL_CreateRenderer(window, -1, 0);
	if (renderer == NULL) {
		ERROR("Failed renderer initialization: %s", SDL_GetError());
		goto quit_all;
	}

	/* Event loop */
	while (1) {
		SDL_Event event;
		while (SDL_PollEvent(&event)) {
			switch(event.type) {
			case SDL_QUIT:
				goto quit_all;
				break;
			case SDL_WINDOWEVENT:
				if(event.window.event == SDL_WINDOWEVENT_EXPOSED)
					draw();
				break;
			}
		}
		SDL_Delay(1); // No kill CPU plz
	}

quit_all:
	SDL_DestroyRenderer(renderer);
	renderer = NULL;
quit_window:
	SDL_DestroyWindow(window);
	window = NULL;
quit_sdl:
	TTF_Quit();
	SDL_Quit();
	return 1;
}