1 /*  DreamChess
2 **
3 **  DreamChess is the legal property of its developers, whose names are too
4 **  numerous to list here. Please refer to the AUTHORS.txt file distributed
5 **  with this source distribution.
6 **
7 **  This program is free software: you can redistribute it and/or modify
8 **  it under the terms of the GNU General Public License as published by
9 **  the Free Software Foundation, either version 3 of the License, or
10 **  (at your option) any later version.
11 **
12 **  This program is distributed in the hope that it will be useful,
13 **  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 **  GNU General Public License for more details.
16 **
17 **  You should have received a copy of the GNU General Public License
18 **  along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 #include "ui_sdlgl.h"
22 
utf8_to_utf32(const char * utf8)23 static unsigned int utf8_to_utf32(const char *utf8) {
24 	unsigned int char_utf32 = 0;
25 	char *utf32 = SDL_iconv_string("UTF-32LE", "UTF-8", utf8, strlen(utf8) + 1);
26 
27 	if (utf32) {
28 		char_utf32 = ((unsigned char)utf32[3] << 24) | ((unsigned char)utf32[2] << 16) |
29 					 ((unsigned char)utf32[1] << 8) | ((unsigned char)utf32[0]);
30 		SDL_free(utf32);
31 	}
32 
33 	return char_utf32;
34 }
35 
36 extern SDL_Window *sdl_window;
37 
convert_event(SDL_Event * event)38 gg_event_t convert_event(SDL_Event *event) {
39 	gg_event_t gg_event = {GG_EVENT_NONE};
40 
41 	switch (event->type) {
42 	case SDL_KEYDOWN:
43 		gg_event.type = GG_EVENT_KEY;
44 		switch (event->key.keysym.sym) {
45 		case SDLK_RIGHT:
46 			gg_event.key = GG_KEY_RIGHT;
47 			break;
48 		case SDLK_LEFT:
49 			gg_event.key = GG_KEY_LEFT;
50 			break;
51 		case SDLK_UP:
52 			gg_event.key = GG_KEY_UP;
53 			break;
54 		case SDLK_DOWN:
55 			gg_event.key = GG_KEY_DOWN;
56 			break;
57 		case SDLK_HOME:
58 			gg_event.key = GG_KEY_HOME;
59 			break;
60 		case SDLK_END:
61 			gg_event.key = GG_KEY_END;
62 			break;
63 		case SDLK_RETURN:
64 			gg_event.key = GG_KEY_ACTION;
65 			break;
66 		case SDLK_BACKSPACE:
67 			gg_event.key = GG_KEY_BACKSPACE;
68 			break;
69 		case SDLK_DELETE:
70 			gg_event.key = GG_KEY_DELETE;
71 			break;
72 		case SDLK_ESCAPE:
73 			gg_event.key = GG_KEY_ESCAPE;
74 			break;
75 		default:
76 			if (event->key.keysym.sym >= 32 || event->key.keysym.sym < 255)
77 				gg_event.key = event->key.keysym.sym;
78 			else
79 				gg_event.type = GG_EVENT_NONE;
80 			return gg_event;
81 		}
82 		break;
83 
84 	case SDL_TEXTINPUT: {
85 		unsigned int utf32 = utf8_to_utf32(event->text.text);
86 
87 		if (utf32 > 0 && utf32 <= 0xff) {
88 			gg_event.type = GG_EVENT_CHAR;
89 			gg_event.key = utf32 & 0xff;
90 			return gg_event;
91 		}
92 	} break;
93 
94 	case SDL_MOUSEBUTTONDOWN:
95 	case SDL_MOUSEBUTTONUP: {
96 		int width, height;
97 		int mouse_x, mouse_y;
98 		SDL_GetWindowSize(sdl_window, &width, &height);
99 		mouse_x = event->motion.x * get_screen_width() / width;
100 		mouse_y = event->motion.y * get_screen_height() / height;
101 		set_mouse_pos(mouse_x, mouse_y);
102 		gg_event.type = GG_EVENT_MOUSE;
103 		gg_event.mouse.type = (event->type == SDL_MOUSEBUTTONDOWN ? GG_MOUSE_BUTTON_DOWN : GG_MOUSE_BUTTON_UP);
104 		gg_event.mouse.button = event->button.button - 1;
105 		gg_event.mouse.x = ((float)mouse_x / (float)get_screen_width()) * get_gl_width();
106 		gg_event.mouse.y = SCREEN_HEIGHT - 1 - ((float)mouse_y / (float)get_screen_height()) * 480;
107 	} break;
108 
109 	case SDL_MOUSEMOTION: {
110 		int width, height;
111 		int mouse_x, mouse_y;
112 		SDL_GetWindowSize(sdl_window, &width, &height);
113 		mouse_x = event->motion.x * get_screen_width() / width;
114 		mouse_y = event->motion.y * get_screen_height() / height;
115 		set_mouse_pos(mouse_x, mouse_y);
116 		gg_event.type = GG_EVENT_MOUSE;
117 		gg_event.mouse.type = GG_MOUSE_MOVE;
118 		gg_event.mouse.x = ((float)mouse_x / (float)get_screen_width()) * get_gl_width();
119 		gg_event.mouse.y = SCREEN_HEIGHT - 1 - ((float)mouse_y / (float)get_screen_height()) * 480;
120 	}
121 	}
122 
123 	return gg_event;
124 }
125 
draw_image(void * image,gg_rect_t source,gg_rect_t dest,int mode_h,int mode_v,gg_colour_t * colour)126 static void draw_image(void *image, gg_rect_t source, gg_rect_t dest, int mode_h, int mode_v, gg_colour_t *colour) {
127 	texture_t *texture = image;
128 	float hsize = texture->u2 - texture->u1;
129 	float vsize = texture->v2 - texture->v1;
130 	float tex_h = texture->width / hsize;
131 	float tex_v = texture->height / vsize;
132 	float xsrc = texture->u1 + source.x / tex_h;
133 	float ysrc = texture->v1 + source.y / tex_v;
134 	float width, height;
135 	GLenum en_h, en_v;
136 
137 	if (mode_h == GG_MODE_TILE) {
138 		en_h = GL_REPEAT;
139 		width = dest.width / tex_h;
140 	} else {
141 		en_h = GL_CLAMP_TO_EDGE;
142 		width = source.width / tex_h;
143 	}
144 
145 	if (mode_v == GG_MODE_TILE) {
146 		en_v = GL_REPEAT;
147 		height = dest.height / tex_v;
148 	} else {
149 		en_v = GL_CLAMP_TO_EDGE;
150 		height = source.height / tex_v;
151 	}
152 
153 	draw_texture_uv(texture, dest.x, dest.y, dest.width, dest.height, 1.0f, colour, xsrc, ysrc, xsrc + width,
154 					ysrc + height, en_h, en_v);
155 }
156 
get_char_image(int c)157 static void *get_char_image(int c) {
158 	if (c < 0)
159 		c += 256;
160 
161 	return get_text_character(c);
162 	/*    return &text_characters[c];*/
163 }
164 
draw_char(int c,int x,int y,gg_colour_t * colour)165 static void draw_char(int c, int x, int y, gg_colour_t *colour) {
166 	text_draw_char(x, y, 1.0f, c, colour);
167 }
168 
get_image_size(void * image,int * width,int * height)169 static void get_image_size(void *image, int *width, int *height) {
170 	texture_t *texture = image;
171 
172 	if (width)
173 		*width = texture->width;
174 
175 	if (height)
176 		*height = texture->height;
177 }
178 
get_char_size(int c,int * width,int * height)179 static void get_char_size(int c, int *width, int *height) {
180 	if (c < 0)
181 		c += 256;
182 
183 	if (width)
184 		*width = get_text_character(c)->width;
185 
186 	if (height)
187 		*height = get_text_character(c)->height;
188 }
189 
get_ticks(void)190 static unsigned int get_ticks(void) {
191 	return SDL_GetTicks();
192 }
193 
get_gl_screen_width(void)194 static float get_gl_screen_width(void) {
195 	return get_gl_width();
196 }
197 
198 gg_driver_t gg_driver_sdlgl = {draw_rect, draw_rect_fill, draw_rect_fill_gradient, draw_image, get_char_image,
199 							   draw_char, get_image_size, get_char_size,		   get_ticks,  get_gl_screen_width};
200 
get_gg_driver_sdlgl(void)201 gg_driver_t *get_gg_driver_sdlgl(void) {
202 	return &gg_driver_sdlgl;
203 }
204