aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/extantz/fangWin.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/extantz/fangWin.c')
-rw-r--r--src/extantz/fangWin.c330
1 files changed, 330 insertions, 0 deletions
diff --git a/src/extantz/fangWin.c b/src/extantz/fangWin.c
new file mode 100644
index 0000000..7503fe0
--- /dev/null
+++ b/src/extantz/fangWin.c
@@ -0,0 +1,330 @@
1#include "extantz.h"
2
3
4static void _on_camera_input_down(void *data, Evas *evas, Evas_Object *obj, void *event_info)
5{
6 GLData *gld = data;
7 Evas_Event_Key_Down *ev = event_info;
8
9 if (gld->move)
10 {
11 // TODO - Careful, gld->move MIGHT be read at the other end by another thread. MIGHT, coz I really don't know at what point the camera animate routine is actually called.
12
13 // Yes, we are dealing with the horrid Evas keyboard handling FUCKING STRING COMPARES! Soooo ...
14 // TODO - make this a hash lookup dammit.
15 if (0 == strcmp(ev->key, "Escape"))
16 {
17 }
18 else if (0 == strcmp(ev->key, "Left"))
19 gld->move->r = 2.0;
20 else if (0 == strcmp(ev->key, "Right"))
21 gld->move->r = -2.0;
22 else if (0 == strcmp(ev->key, "Up"))
23 gld->move->x = 2.0;
24 else if (0 == strcmp(ev->key, "Down"))
25 gld->move->x = -2.0;
26// else if (0 == strcmp(ev->key, "Prior"))
27// ;
28// else if (0 == strcmp(ev->key, "Next"))
29// ;
30// else if (0 == strcmp(ev->key, "Home"))
31// ;
32// else if (0 == strcmp(ev->key, "End"))
33// ;
34 else if (0 == strcmp(ev->key, "space"))
35 gld->move->jump = 1.0;
36 else
37 printf("Unexpected down keystroke - %s\n", ev->key);
38 }
39 else
40 printf("Camera input not ready\n");
41}
42
43/* SL / OS camera controls
44 up / down / w / s moves avatar forward / backward
45 shifted version does the same
46 double tap triggers run mode / or fast fly mode
47 Running backwards turns your avatar to suit, walking does not.
48 left / right / a / d rotates avatar left / right, strafes in mouselook
49 shifted version turns the avatar to walk sideways, so not really a strafe.
50 So not sure if the "strafe" in mouse look turns the avatar as well?
51 PgDn / c crouch while it is held down move up in flight mode
52 PgUp jump move down in flight mode
53 Home toggle flying
54 End Nothing?
55 Esc return to third person view
56 m toggle mouse look
57 mouse wheel move view closer / further away from current focused object or avatar
58 Alt left click focus on some other object
59 Ins ???
60 Del ???
61 BS ???
62 Tab ???
63
64 Mouse look is just first person view, moving mouse looks left / right / up / down.
65 Not sure if the avatar rotates with left / right, but that's likely.
66
67 mouse moves With the left mouse button held down -
68 left / right up / down
69 ---------------------------------
70 for avatar swings avatar around zoom in and out of avatar
71 for object nothing
72 alt orbit left / right zoom in and out
73 alt ctrl orbit left / right orbit up / down
74 alt shift orbit left / right zoom in and out
75 alt ctrl shift shift view left / right / up / down
76 ctrl Nothing?
77 shift Nothing?
78 ctrl shift Nothing?
79
80 Need to also consider when looking at a moving object / avatar.
81
82 I think there are other letter keys that duplicate arrow keys and such. I'll look for them later, but I don't use them.
83 No idea what the function keys are mapped to, but think it's various non camera stuff.
84 I'm damn well leaving the Win/Command and Menu keys for the OS / window manager. lol
85 Keypad keys? Not interested, I don't have them.
86 Print Screen / SysRq, Pause / Break, other oddball keys, also not interested.
87 NOTE - gonna have an easily programmable "bind key to command" thingy, like E17s, so that can deal with other keys.
88 Should even let them be saveable so people can swap them with other people easily.
89
90 TODO - implement things like space mouse, sixaxis, phone as controller, joysticks, data gloves, etc.
91*/
92
93/* A moveRotate array of floats.
94 * X, Y, Z, and whatever the usual letters are for rotations. lol
95 * Each one means "move or rotate this much in this direction".
96 * Where 1.0 means "what ever the standard move is if that key is held down".
97 * So a keyboard move would just change it's part to 1.0 or -1.0 on key down,
98 * and back to 0.0 on key up. Or 2.0 / -2.0 if in run mode.
99 * Which would even work in fly mode.
100 * A joystick could be set to range over -2.0 to 2.0, and just set it's part directly.
101 * A mouse look rotate, well will come to that when we need to. B-)
102 * Setting the x or y to be the DIFFERENCE in window position of the mouse (-1.0 to 1.0) since the last frame.
103 *
104 * TODO - In the Elm_glview version, 2.0 seems to be correct speed for walking, but I thought 1.0 was in Evas_GL.
105 */
106
107static void _on_camera_input_up(void *data, Evas *evas, Evas_Object *obj, void *event_info)
108{
109 GLData *gld = data;
110 Evas_Event_Key_Up *ev = event_info;
111
112 if (gld->move)
113 {
114 // TODO - Careful, gld->move MIGHT be read at the other end by another thread. MIGHT, coz I really don't know at what point the camera animate routine is actually called.
115
116 // Yes, we are dealing with the horrid Evas keyboard handling FUCKING STRING COMPARES! Soooo ...
117 // TODO - make this a hash lookup dammit.
118 if (0 == strcmp(ev->key, "Escape"))
119 {
120 }
121 else if (0 == strcmp(ev->key, "Left"))
122 gld->move->r = 0.0;
123 else if (0 == strcmp(ev->key, "Right"))
124 gld->move->r = 0.0;
125 else if (0 == strcmp(ev->key, "Up"))
126 gld->move->x = 0.0;
127 else if (0 == strcmp(ev->key, "Down"))
128 gld->move->x = 0.0;
129// else if (0 == strcmp(ev->key, "Prior"))
130// ;
131// else if (0 == strcmp(ev->key, "Next"))
132// ;
133// else if (0 == strcmp(ev->key, "Home"))
134// ;
135// else if (0 == strcmp(ev->key, "End"))
136// ;
137 else if (0 == strcmp(ev->key, "space"))
138 gld->move->jump = 0.0;
139 else
140 printf("Unexpected up keystroke - %s\n", ev->key);
141 }
142 else
143 printf("Camera input not ready\n");
144}
145
146// Elm style event callback.
147static Eina_Bool _cb_event_GL(void *data, Evas_Object *obj, Evas_Object *src, Evas_Callback_Type type, void *event_info)
148{
149 GLData *gld = data;
150 Eina_Bool processed = EINA_FALSE;
151
152 switch (type)
153 {
154 case EVAS_CALLBACK_KEY_DOWN :
155 {
156 _on_camera_input_down(gld, evas_object_evas_get(obj), obj, event_info);
157 processed = EINA_TRUE;
158 break;
159 }
160
161 case EVAS_CALLBACK_KEY_UP :
162 {
163 _on_camera_input_up(gld, evas_object_evas_get(obj), obj, event_info);
164 processed = EINA_TRUE;
165 break;
166 }
167
168 default :
169 printf("Unknown GL input event.\n");
170 }
171
172 return processed;
173}
174
175// Elm inlined image windows needs this to change focus on mouse click.
176// Evas style event callback.
177static void _cb_mouse_down_elm(void *data, Evas *evas, Evas_Object *obj, void *event_info)
178{
179// GLData *gld = data;
180 Evas_Event_Mouse_Down *ev = event_info;
181
182 if (1 == ev->button)
183 elm_object_focus_set(obj, EINA_TRUE);
184}
185
186static void cb_mouse_move(void *data, Evas *evas, Evas_Object *obj, void *event_info)
187{
188 Evas_Event_Mouse_Move *ev = event_info;
189 Evas_Object *orig = data;
190 Evas_Coord x, y;
191 Evas_Map *p;
192 int i, w, h;
193
194 if (!ev->buttons) return;
195 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
196 evas_object_move(obj,
197 x + (ev->cur.canvas.x - ev->prev.output.x),
198 y + (ev->cur.canvas.y - ev->prev.output.y));
199 evas_object_image_size_get(orig, &w, &h);
200 p = evas_map_new(4);
201 evas_object_map_enable_set(orig, EINA_TRUE);
202// evas_object_raise(orig);
203 for (i = 0; i < 4; i++)
204 {
205 Evas_Object *hand;
206 char key[32];
207
208 snprintf(key, sizeof(key), "h-%i\n", i);
209 hand = evas_object_data_get(orig, key);
210 evas_object_raise(hand);
211 evas_object_geometry_get(hand, &x, &y, NULL, NULL);
212 x += 15;
213 y += 15;
214 evas_map_point_coord_set(p, i, x, y, 0);
215 if (i == 0) evas_map_point_image_uv_set(p, i, 0, 0);
216 else if (i == 1) evas_map_point_image_uv_set(p, i, w, 0);
217 else if (i == 2) evas_map_point_image_uv_set(p, i, w, h);
218 else if (i == 3) evas_map_point_image_uv_set(p, i, 0, h);
219 }
220 evas_object_map_set(orig, p);
221 evas_map_free(p);
222}
223
224static void create_handles(Evas_Object *obj)
225{
226 int i;
227 Evas_Coord x, y, w, h;
228
229 evas_object_geometry_get(obj, &x, &y, &w, &h);
230 for (i = 0; i < 4; i++)
231 {
232 Evas_Object *hand;
233 char buf[PATH_MAX];
234 char key[32];
235
236 hand = evas_object_image_filled_add(evas_object_evas_get(obj));
237 evas_object_resize(hand, 31, 31);
238 snprintf(buf, sizeof(buf), "%s/pt.png", elm_app_data_dir_get());
239 evas_object_image_file_set(hand, buf, NULL);
240 if (i == 0) evas_object_move(hand, x - 15, y - 15);
241 else if (i == 1) evas_object_move(hand, x + w - 15, y - 15);
242 else if (i == 2) evas_object_move(hand, x + w - 15, y + h - 15);
243 else if (i == 3) evas_object_move(hand, x - 15, y + h - 15);
244 evas_object_event_callback_add(hand, EVAS_CALLBACK_MOUSE_MOVE, cb_mouse_move, obj);
245 evas_object_show(hand);
246 snprintf(key, sizeof(key), "h-%i\n", i);
247 evas_object_data_set(obj, key, hand);
248 }
249}
250
251Evas_Object *fang_win_add(GLData *gld)
252{
253 Evas_Object *win, *bg;
254
255 // In theory this should create an EWS window, in practice, I'm not seeing any difference.
256 // Guess I'll have to implement my own internal window manager. I don't think a basic one will be that hard. Famous last words.
257// elm_config_engine_set("ews");
258 win = elm_win_add(gld->win, "inlined", ELM_WIN_INLINED_IMAGE);
259 // On mouse down we try to shift focus to the backing image, this seems to be the correct thing to force focus onto it's widgets.
260 // According to the Elm inlined image window example, this is what's needed to.
261 evas_object_event_callback_add(elm_win_inlined_image_object_get(win), EVAS_CALLBACK_MOUSE_DOWN, _cb_mouse_down_elm, gld);
262 elm_win_alpha_set(win, EINA_TRUE);
263
264 // Apparently transparent is not good enough for ELM backgrounds, so make it a rectangle.
265 // Apparently coz ELM prefers stuff to have edjes. A bit over the top if all I want is a transparent rectangle.
266 bg = evas_object_rectangle_add(evas_object_evas_get(win));
267 evas_object_color_set(bg, 50, 0, 100, 100);
268 evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
269 elm_win_resize_object_add(win, bg);
270 evas_object_show(bg);
271
272 return win;
273}
274
275void fang_win_complete(GLData *gld, Evas_Object *win, int x, int y, int w, int h)
276{
277 // image object for win is unlinked to its pos/size - so manual control
278 // this allows also for using map and other things with it.
279 evas_object_move(elm_win_inlined_image_object_get(win), x, y);
280 // Odd, it needs to be resized twice. WTF?
281 evas_object_resize(win, w, h);
282 evas_object_resize(elm_win_inlined_image_object_get(win), w, h);
283 evas_object_show(win);
284 create_handles(elm_win_inlined_image_object_get(win));
285}
286
287void overlay_add(GLData *gld)
288{
289 Evas_Object *bg;
290//, *bx, *tb, *menu;
291// Elm_Object_Item *tb_it, *menu_it;
292
293 // There many are reasons for this window.
294 // The first is to cover the GL and provide something to click on to change focus.
295 // The second is to provide something to click on for all the GL type clicking stuff that needs to be done. In other words, no click through,we catch the clicks here.
296 // So we can probably avoid the following issue -
297 // How to do click through? evas_object_pass_events_set(rectangle, EINA_TRUE), and maybe need to do that to the underlaying window to?
298 // Though if the rectangle is entirely transparent, or even hidden, events might pass through anyway.
299 // Gotta have click through on the parts where there's no other window.
300 // The third is to have the other windows live here.
301 // This idea doesn't work, as it breaks the damn focus again.
302 // Don't think it's needed anyway.
303 // While on the subject of layers, need a HUD layer of some sort, but Irrlicht might support that itself.
304
305 gld->winwin = elm_win_add(gld->win, "inlined", ELM_WIN_INLINED_IMAGE);
306 // On mouse down we try to shift focus to the backing image, this seems to be the correct thing to force focus onto it's widgets.
307 // According to the Elm inlined image window example, this is what's needed to.
308 evas_object_event_callback_add(elm_win_inlined_image_object_get(gld->winwin), EVAS_CALLBACK_MOUSE_DOWN, _cb_mouse_down_elm, gld);
309 // In this code, we are making our own camera, so grab it's input when we are focused.
310 evas_object_event_callback_add(gld->winwin, EVAS_CALLBACK_KEY_DOWN, _on_camera_input_down, gld);
311 evas_object_event_callback_add(gld->winwin, EVAS_CALLBACK_KEY_UP, _on_camera_input_up, gld);
312 elm_object_event_callback_add(gld->winwin, _cb_event_GL, gld);
313
314 elm_win_alpha_set(gld->winwin, EINA_TRUE);
315 // Apparently transparent is not good enough for ELM backgrounds, so make it a rectangle.
316 // Apparently coz ELM prefers stuff to have edjes. A bit over the top if all I want is a transparent rectangle.
317 bg = evas_object_rectangle_add(evas_object_evas_get(gld->winwin));
318 evas_object_color_set(bg, 0, 0, 0, 0);
319 evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
320 elm_win_resize_object_add(gld->winwin, bg);
321 evas_object_show(bg);
322
323 // image object for win is unlinked to its pos/size - so manual control
324 // this allows also for using map and other things with it.
325 evas_object_move(elm_win_inlined_image_object_get(gld->winwin), 0, 0);
326 // Odd, it needs to be resized twice. WTF?
327 evas_object_resize(gld->winwin, gld->win_w, gld->win_h);
328 evas_object_resize(elm_win_inlined_image_object_get(gld->winwin), gld->win_w, gld->win_h);
329 evas_object_show(gld->winwin);
330}