diff options
| -rw-r--r-- | src/all.c | 132 | 
1 files changed, 126 insertions, 6 deletions
| @@ -8,11 +8,27 @@  #define xmemcpy __builtin_memcpy  #endif -  typedef struct {  	unsigned char r, g, b, a;  } Color; +typedef enum { +	BUTTON_STATE_IDLE, +	BUTTON_STATE_HOVERED, +	BUTTON_STATE_PRESSED +} ButtonState; + +typedef struct { +	int idle_colour; +	int hover_colour; +	int pressed_colour; +} ButtonStyle; + +typedef struct { +	int x, y, w, h; +	ButtonState state; +} Button; +  typedef struct {  	int x, y, w, h;  	Color fill; @@ -20,14 +36,20 @@ typedef struct {  } DrawElement;  typedef struct { +	DrawElement bg; +} SidePanel; + +typedef struct {  	int len;  	DrawElement els[512]; +	SidePanel panel;  } DrawList;  #define MEM_SIZE (1<<16)  #define GRIDWIDTH 16  #define GRIDHEIGHT 16  #define TICK_LENGTH 1000 +#define GRID_OFFSET_X 256  typedef struct {  	char *start; @@ -88,18 +110,35 @@ static const Color colors[N_COLORS] = {  	{255, 255, 0, 255}  }; +static const ButtonStyle button_style = { +	.idle_colour = BLACK, +	.hover_colour = RED, +	.pressed_colour = YELLOW +}; + +enum { +	BUTTON_RETRY, +	BUTTON_BACK, +	N_BUTTONS, +}; + +static Button buttons[N_BUTTONS] = { +	{.x = 64, .y = 64, .w = 128, .h = 32, .state = BUTTON_STATE_IDLE}, +	{.x = 64, .y = 114, .w = 128, .h = 32, .state = BUTTON_STATE_IDLE}, +}; +  static DrawList *render(State *state, UI *ui, Arena *a) {  	(void) ui;  	DrawList *drawList = new(a, 1, DrawList); -	int cellWidth = ui->width / GRIDWIDTH; +	int cellWidth = (ui->width - GRID_OFFSET_X) / GRIDWIDTH;  	int cellHeight = ui->height / GRIDHEIGHT;  	for (int x = 0; x < GRIDWIDTH; x++) {  		for (int y = 0; y < GRIDHEIGHT; y++) {  			drawList->els[drawList->len++] = (DrawElement) { -				.x = cellWidth * x, +				.x = cellWidth * x + GRID_OFFSET_X,  				.y = cellHeight * y,  				.w = cellWidth,  				.h = cellHeight, @@ -109,14 +148,45 @@ static DrawList *render(State *state, UI *ui, Arena *a) {  		}  	} +	drawList->panel = (SidePanel) { +		.bg = (DrawElement) { +			.x = 0, +			.y = 0, +			.w = GRID_OFFSET_X, +			.h = ui->height, +			.fill = colors[YELLOW], +			.border = {0, 0, 0, 255} +		} +	}; +  	return drawList;  } +static void update_buttons(const int mx, const int my, const int mstate) { +	for (int i = 0; i < N_BUTTONS; i++) { +		if ( +			mx > buttons[i].x && mx < buttons[i].x + buttons[i].w && +			my > buttons[i].y && my < buttons[i].y + buttons[i].h +			) { +			if (mstate == 1) { +				buttons[i].state = BUTTON_STATE_PRESSED; +			} +			else +				buttons[i].state = BUTTON_STATE_HOVERED; +		} +		else { +			buttons[i].state = BUTTON_STATE_IDLE; +		} +	} +} +  static void update(Game *game, uint64_t now, Arena a) { +	const int offset_width = game->ui.width - GRID_OFFSET_X; +	  	switch (game->input) {  		int x, y;  		case INPUT_CLICK: -			x = game->mousex * GRIDWIDTH / game->ui.width; +			x = game->mousex * GRIDWIDTH / offset_width;  			y = game->mousey * GRIDHEIGHT / game->ui.height;  			game->state.grid[x + y * GRIDWIDTH] = (game->state.grid[x + y * GRIDWIDTH] + 1) % (sizeof(colors) / sizeof(colors[0]));  			break; @@ -161,6 +231,45 @@ static void update(Game *game, uint64_t now, Arena a) {  #include <SDL3/SDL.h> +void render_button(SDL_Renderer* r, const Button* b) { +	Color colour = colors[BLACK]; +	switch (b->state) { +		case BUTTON_STATE_IDLE: +			colour = colors[button_style.idle_colour]; +			break; +		case BUTTON_STATE_HOVERED: +			colour = colors[button_style.hover_colour]; +			break; +		case BUTTON_STATE_PRESSED: +			colour = colors[button_style.pressed_colour]; +			break; +	} +	SDL_SetRenderDrawColor(r, colour.r, colour.g, colour.b, colour.a); +	SDL_FRect rect = { +		.x = (float) b->x, +		.y = (float) b->y, +		.w = (float) b->w, +		.h = (float) b->h +	}; +	SDL_RenderFillRect(r, &rect); +} + +void render_side_panel(SDL_Renderer* r, SidePanel* panel) { +	Color* bg_colour = &panel->bg.fill; +	SDL_FRect rect = { +		.x = (float) panel->bg.x, +		.y = (float) panel->bg.y, +		.w = (float) panel->bg.w, +		.h = (float) panel->bg.h, +	}; +	SDL_SetRenderDrawColor(r, bg_colour->r, bg_colour->g, bg_colour->b, bg_colour->a); +	SDL_RenderFillRect(r, &rect); + +	for (int i = 0; i < N_BUTTONS; i++) { +		render_button(r, &buttons[i]); +	} +} +  int main(int argc, char **argv) {  	(void) argc;  	(void) argv; @@ -191,7 +300,8 @@ int main(int argc, char **argv) {  	SDL_SetNumberProperty(renderProps, SDL_PROP_RENDERER_CREATE_PRESENT_VSYNC_NUMBER, 1);  	SDL_Renderer *r = SDL_CreateRendererWithProperties(renderProps);  	SDL_DestroyProperties(renderProps); -	 + +	int mousex = 0, mousey = 0, mousestate = 0;  	for (;;) {  		uint64_t now = SDL_GetTicks();  		game->input = INPUT_NONE; @@ -202,8 +312,16 @@ int main(int argc, char **argv) {  					return 0;  				case SDL_EVENT_MOUSE_BUTTON_DOWN:  					game->input = INPUT_CLICK; -					game->mousex = (int) e.button.x; +					game->mousex = (int) e.button.x - GRID_OFFSET_X;  					game->mousey = (int) e.button.y; +					mousestate = SDL_BUTTON_MASK(e.motion.state); +					break; +				case SDL_EVENT_MOUSE_BUTTON_UP: +					mousestate = 0; +					break; +				case SDL_EVENT_MOUSE_MOTION: +					mousex = (int) e.motion.x; +					mousey = (int) e.motion.y;  					break;  				case SDL_EVENT_KEY_DOWN:  					switch (e.key.key) { @@ -216,6 +334,7 @@ int main(int argc, char **argv) {  					SDL_GetWindowSize(w, &game->ui.width, &game->ui.height);  					break;  			} +			update_buttons(mousex, mousey, mousestate);  		}  		Arena scratch = a; @@ -248,6 +367,7 @@ int main(int argc, char **argv) {  			);  			SDL_RenderRect(r, &rect);  		} +		render_side_panel(r, &drawList->panel);  		update(game, now, a); | 
