vrshoot

annotate src/main_glut.cc @ 0:b2f14e535253

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 01 Feb 2014 19:58:19 +0200
parents
children
rev   line source
nuclear@0 1 #include <stdlib.h>
nuclear@0 2 #include <ctype.h>
nuclear@0 3 #include <assert.h>
nuclear@0 4 #include "opengl.h"
nuclear@0 5
nuclear@0 6 #include "game.h"
nuclear@0 7 #include "input.h"
nuclear@0 8 #include "screen.h"
nuclear@0 9 #include "logger.h"
nuclear@0 10
nuclear@0 11 /* called by any other part of the game when a redisplay is needed
nuclear@0 12 * (mostly useful for tools which do not redisplay continuously)
nuclear@0 13 */
nuclear@0 14 void request_redisplay();
nuclear@0 15
nuclear@0 16 void swap_buffers();
nuclear@0 17
nuclear@0 18 static void display(void);
nuclear@0 19 static void reshape(int x, int y);
nuclear@0 20 static void keydown(unsigned char key, int x, int y);
nuclear@0 21 static void keyup(unsigned char key, int x, int y);
nuclear@0 22 static void skeydown(int key, int x, int y);
nuclear@0 23 static void skeyup(int key, int x, int y);
nuclear@0 24 static void mouse(int bn, int state, int x, int y);
nuclear@0 25 static void motion(int x, int y);
nuclear@0 26 static void passive_motion(int x, int y);
nuclear@0 27
nuclear@0 28 static long redisp_interval;
nuclear@0 29
nuclear@0 30 int main(int argc, char **argv)
nuclear@0 31 {
nuclear@0 32 glutInit(&argc, argv);
nuclear@0 33 glutInitWindowSize(800, 600);
nuclear@0 34 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE | GLUT_MULTISAMPLE);
nuclear@0 35 glutCreateWindow("Xmass inferno");
nuclear@0 36
nuclear@0 37 glutDisplayFunc(display);
nuclear@0 38 glutReshapeFunc(reshape);
nuclear@0 39 glutKeyboardFunc(keydown);
nuclear@0 40 glutKeyboardUpFunc(keyup);
nuclear@0 41 glutSpecialFunc(skeydown);
nuclear@0 42 glutSpecialUpFunc(skeyup);
nuclear@0 43 glutMouseFunc(mouse);
nuclear@0 44 glutMotionFunc(motion);
nuclear@0 45 glutPassiveMotionFunc(passive_motion);
nuclear@0 46
nuclear@0 47 game_set_args(argc, argv);
nuclear@0 48 if(!game_init()) {
nuclear@0 49 return 1;
nuclear@0 50 }
nuclear@0 51 atexit(game_cleanup);
nuclear@0 52
nuclear@0 53 glutMainLoop();
nuclear@0 54 return 0;
nuclear@0 55 }
nuclear@0 56
nuclear@0 57 void request_redisplay()
nuclear@0 58 {
nuclear@0 59 glutPostRedisplay();
nuclear@0 60 }
nuclear@0 61
nuclear@0 62 void swap_buffers()
nuclear@0 63 {
nuclear@0 64 glUseProgram(0);
nuclear@0 65 glutSwapBuffers();
nuclear@0 66 }
nuclear@0 67
nuclear@0 68 static void display()
nuclear@0 69 {
nuclear@0 70 long ival = current_screen()->redisplay_interval();
nuclear@0 71 if(ival && !redisp_interval) {
nuclear@0 72 debug_log("switching to auto-redisplay (interval: %ld)\n", redisp_interval);
nuclear@0 73 glutIdleFunc(request_redisplay);
nuclear@0 74 }
nuclear@0 75 if(!ival && redisp_interval) {
nuclear@0 76 debug_log("switching to manual redisplay\n");
nuclear@0 77 glutIdleFunc(0);
nuclear@0 78 }
nuclear@0 79 redisp_interval = ival;
nuclear@0 80
nuclear@0 81 game_display();
nuclear@0 82 // TODO implement framerate limiter
nuclear@0 83 }
nuclear@0 84
nuclear@0 85
nuclear@0 86 static void reshape(int x, int y)
nuclear@0 87 {
nuclear@0 88 game_reshape(x, y);
nuclear@0 89 }
nuclear@0 90
nuclear@0 91 /* GLUT doesn't have any callbacks for modifier keys, so we fake it by calling
nuclear@0 92 * this function all over the place, to generate fake events whenever a modifier
nuclear@0 93 * key is detected to have changed state.
nuclear@0 94 * The limitation is that this will only detect modkey changes whenever a regular
nuclear@0 95 * key is pressed or released, or when a mouse button is pressed or released.
nuclear@0 96 */
nuclear@0 97 static void handle_modkeys()
nuclear@0 98 {
nuclear@0 99 static int modstate;
nuclear@0 100
nuclear@0 101 int mod = glutGetModifiers();
nuclear@0 102 if(mod != modstate) {
nuclear@0 103 int diff = mod ^ modstate;
nuclear@0 104
nuclear@0 105 if(diff & GLUT_ACTIVE_SHIFT) {
nuclear@0 106 bool pressed = mod & GLUT_ACTIVE_SHIFT;
nuclear@0 107 game_key(KEY_LSHIFT, pressed);
nuclear@0 108 }
nuclear@0 109 if(diff & GLUT_ACTIVE_CTRL) {
nuclear@0 110 bool pressed = mod & GLUT_ACTIVE_CTRL;
nuclear@0 111 game_key(KEY_LCTRL, pressed);
nuclear@0 112 }
nuclear@0 113 if(diff & GLUT_ACTIVE_ALT) {
nuclear@0 114 bool pressed = mod & GLUT_ACTIVE_ALT;
nuclear@0 115 game_key(KEY_LALT, pressed);
nuclear@0 116 }
nuclear@0 117 }
nuclear@0 118 modstate = mod;
nuclear@0 119 }
nuclear@0 120
nuclear@0 121 static int translate_special_key(int key)
nuclear@0 122 {
nuclear@0 123 if(key >= GLUT_KEY_F1 && key <= GLUT_KEY_F12) {
nuclear@0 124 return (key - GLUT_KEY_F1) + KEY_F1;
nuclear@0 125 }
nuclear@0 126 if(key >= GLUT_KEY_LEFT && key <= GLUT_KEY_PAGE_DOWN) {
nuclear@0 127 return (key - GLUT_KEY_LEFT) + KEY_LEFT;
nuclear@0 128 }
nuclear@0 129
nuclear@0 130 switch(key) {
nuclear@0 131 case GLUT_KEY_HOME:
nuclear@0 132 return KEY_HOME;
nuclear@0 133 case GLUT_KEY_END:
nuclear@0 134 return KEY_END;
nuclear@0 135 case GLUT_KEY_INSERT:
nuclear@0 136 return KEY_INSERT;
nuclear@0 137
nuclear@0 138 default:
nuclear@0 139 break;
nuclear@0 140 }
nuclear@0 141 return 0;
nuclear@0 142 }
nuclear@0 143
nuclear@0 144 static void keydown(unsigned char c, int x, int y)
nuclear@0 145 {
nuclear@0 146 int key = c;
nuclear@0 147 if(key == 127) {
nuclear@0 148 key = KEY_DELETE;
nuclear@0 149 }
nuclear@0 150
nuclear@0 151 handle_modkeys();
nuclear@0 152 game_key(key, true);
nuclear@0 153 }
nuclear@0 154
nuclear@0 155 static void keyup(unsigned char c, int x, int y)
nuclear@0 156 {
nuclear@0 157 int key = c;
nuclear@0 158 if(key == 127) {
nuclear@0 159 key = KEY_DELETE;
nuclear@0 160 }
nuclear@0 161
nuclear@0 162 handle_modkeys();
nuclear@0 163 game_key(key, false);
nuclear@0 164 }
nuclear@0 165
nuclear@0 166 static void skeydown(int key, int x, int y)
nuclear@0 167 {
nuclear@0 168 handle_modkeys();
nuclear@0 169
nuclear@0 170 if((key = translate_special_key(key)) > 0) {
nuclear@0 171 game_key(key, true);
nuclear@0 172 }
nuclear@0 173 }
nuclear@0 174
nuclear@0 175 static void skeyup(int key, int x, int y)
nuclear@0 176 {
nuclear@0 177 handle_modkeys();
nuclear@0 178
nuclear@0 179 if((key = translate_special_key(key)) > 0) {
nuclear@0 180 game_key(key, false);
nuclear@0 181 }
nuclear@0 182 }
nuclear@0 183
nuclear@0 184 static void mouse(int bn, int state, int x, int y)
nuclear@0 185 {
nuclear@0 186 handle_modkeys();
nuclear@0 187
nuclear@0 188 int bnidx = bn - GLUT_LEFT_BUTTON;
nuclear@0 189 bool bnstate = state == GLUT_DOWN;
nuclear@0 190
nuclear@0 191 current_screen()->button(bnidx, bnstate, x, y);
nuclear@0 192 set_mouse_state(x, y, bnidx, bnstate); // this MUST be after the event dispatch
nuclear@0 193 }
nuclear@0 194
nuclear@0 195 static void motion(int x, int y)
nuclear@0 196 {
nuclear@0 197 set_mouse_state(x, y);
nuclear@0 198 current_screen()->motion(x, y, false);
nuclear@0 199 }
nuclear@0 200
nuclear@0 201 static void passive_motion(int x, int y)
nuclear@0 202 {
nuclear@0 203 set_mouse_state(x, y);
nuclear@0 204 current_screen()->motion(x, y, true);
nuclear@0 205 }