deepstone

annotate src/main.c @ 33:03a0b307706a

added proper keyboard handling
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 23 Sep 2013 04:34:43 +0300
parents 11d14f688485
children c6406e4aa0fb
rev   line source
nuclear@27 1 #include <stdio.h>
nuclear@27 2 #include <stdlib.h>
nuclear@27 3 #include <math.h>
nuclear@27 4 #include <signal.h>
nuclear@27 5 #include <conio.h>
nuclear@27 6 #include "wvga.h"
nuclear@27 7 #include "mingl.h"
nuclear@27 8 #include "timer.h"
nuclear@33 9 #include "keyb.h"
nuclear@27 10 #include "mouse.h"
nuclear@27 11 #include "texture.h"
nuclear@27 12 #include "palman.h"
nuclear@27 13 #include "scene.h"
nuclear@27 14
nuclear@27 15 #define DEG2RAD(x) (M_PI * (x) / 180.0)
nuclear@27 16
nuclear@27 17 static int init(void);
nuclear@27 18 static void shutdown(void);
nuclear@27 19 static void redraw(void);
nuclear@27 20 static int proc_events(void);
nuclear@33 21 static int proc_keyb_input(void);
nuclear@27 22 static void mouse_button(int bn, int x, int y);
nuclear@27 23 static void mouse_motion(int x, int y);
nuclear@27 24 static void sighandler(int s);
nuclear@27 25
nuclear@27 26
nuclear@27 27 static float cam_x, cam_y, cam_z;
nuclear@27 28 static float cam_theta, cam_phi;
nuclear@27 29
nuclear@27 30 static float walk_speed = 0.5;
nuclear@27 31 static float look_speed = 1.0;
nuclear@33 32
nuclear@33 33 #ifdef __DOS__
nuclear@33 34 static int mouse_look = 1;
nuclear@33 35 #else
nuclear@27 36 static int mouse_look = 0;
nuclear@33 37 #endif
nuclear@27 38
nuclear@27 39 static void *fbuf;
nuclear@27 40 static struct scene scn;
nuclear@27 41
nuclear@27 42
nuclear@27 43 int main(void)
nuclear@27 44 {
nuclear@27 45 if(init() == -1) {
nuclear@27 46 return 1;
nuclear@27 47 }
nuclear@27 48
nuclear@27 49 while(proc_events()) {
nuclear@27 50 redraw();
nuclear@27 51 }
nuclear@27 52
nuclear@27 53 shutdown();
nuclear@27 54 return 0;
nuclear@27 55 }
nuclear@27 56
nuclear@27 57
nuclear@27 58 static int init(void)
nuclear@27 59 {
nuclear@28 60 float vfov, hfov, aspect;
nuclear@28 61
nuclear@28 62 aspect = 320.0 / 200.0;
nuclear@28 63 vfov = 60.0;
nuclear@28 64 hfov = vfov * aspect;
nuclear@28 65
nuclear@27 66 init_timer(100);
nuclear@33 67 kb_init(16); /* 16 characters input buffer */
nuclear@27 68
nuclear@27 69 set_video_mode(0x13);
nuclear@27 70
nuclear@27 71 signal(SIGINT, sighandler);
nuclear@27 72 signal(SIGSEGV, sighandler);
nuclear@27 73 signal(SIGFPE, sighandler);
nuclear@27 74 signal(SIGILL, sighandler);
nuclear@27 75 signal(SIGABRT, sighandler);
nuclear@27 76
nuclear@27 77 if(mgl_init(320, 200) == -1) {
nuclear@27 78 fprintf(stderr, "mgl init failed\n");
nuclear@27 79 return -1;
nuclear@27 80 }
nuclear@27 81 fbuf = mgl_framebuffer();
nuclear@27 82
nuclear@27 83 mgl_enable(MGL_CULL_FACE);
nuclear@27 84 mgl_enable(MGL_SMOOTH);
nuclear@27 85 mgl_enable(MGL_LIGHTING);
nuclear@27 86 mgl_enable(MGL_DEPTH_TEST);
nuclear@27 87
nuclear@27 88 mgl_matrix_mode(MGL_PROJECTION);
nuclear@27 89 mgl_load_identity();
nuclear@28 90 mgl_perspective(vfov, aspect, 0.5, 200.0);
nuclear@28 91
nuclear@28 92 #if 0
nuclear@28 93 mgl_enable(MGL_CLIP_PLANE0);
nuclear@28 94 mgl_enable(MGL_CLIP_PLANE1);
nuclear@28 95 mgl_enable(MGL_CLIP_PLANE2);
nuclear@28 96 mgl_enable(MGL_CLIP_PLANE3);
nuclear@28 97 mgl_clip_plane(MGL_CLIP_PLANE0, -1, 0, -1, 0); /* positive X */
nuclear@28 98 mgl_clip_plane(MGL_CLIP_PLANE1, 1, 0, -1, 0); /* negative X */
nuclear@28 99 mgl_clip_plane(MGL_CLIP_PLANE2, 0, -1, -0.5, 0); /* positive Y */
nuclear@28 100 mgl_clip_plane(MGL_CLIP_PLANE3, 0, 1, -0.5, 0); /* negative Y */
nuclear@28 101 #endif
nuclear@27 102
nuclear@27 103 /* setup palette */
nuclear@27 104 palm_add_color(255, 255, 255);
nuclear@27 105
nuclear@27 106 scn_init(&scn);
nuclear@27 107 if(scn_load(&scn, "data/hall.obj") == -1) {
nuclear@27 108 return -1;
nuclear@27 109 }
nuclear@27 110
nuclear@27 111 palm_build();
nuclear@27 112 {
nuclear@27 113 int i, palsz = palm_palette_size();
nuclear@27 114 struct palm_color *pal = palm_palette();
nuclear@27 115
nuclear@27 116 for(i=0; i<palsz; i++) {
nuclear@27 117 set_pal_entry(i, pal[i].r, pal[i].g, pal[i].b);
nuclear@27 118 }
nuclear@27 119 }
nuclear@27 120
nuclear@27 121 mgl_color_range(palm_color_range() - 1);
nuclear@27 122 return 0;
nuclear@27 123 }
nuclear@27 124
nuclear@27 125 static void shutdown(void)
nuclear@27 126 {
nuclear@27 127 mgl_free();
nuclear@27 128 set_video_mode(3);
nuclear@33 129 kb_shutdown();
nuclear@27 130 }
nuclear@27 131
nuclear@27 132 static void redraw(void)
nuclear@27 133 {
nuclear@27 134 mgl_clear(0);
nuclear@27 135 mgl_clear_depth();
nuclear@27 136
nuclear@27 137 mgl_matrix_mode(MGL_MODELVIEW);
nuclear@27 138 mgl_load_identity();
nuclear@27 139 mgl_rotate(cam_phi, 1, 0, 0);
nuclear@27 140 mgl_rotate(cam_theta, 0, 1, 0);
nuclear@27 141 mgl_translate(-cam_x, -cam_y, -cam_z);
nuclear@27 142 mgl_translate(0, -2.0, 0);
nuclear@27 143
nuclear@27 144 mgl_light_intensity(0, 1.0);
nuclear@27 145 mgl_light_position(0, 0, 5, 0, 1);
nuclear@27 146
nuclear@27 147 /*mgl_torus(0.75, 0.25, 16, 8);*/
nuclear@27 148 scn_render(&scn);
nuclear@27 149
nuclear@27 150 copy_frame(fbuf);
nuclear@27 151 }
nuclear@27 152
nuclear@27 153 #define DEG_TO_RAD(x) (M_PI * (x) / 180.0)
nuclear@27 154 void cam_move(float dx, float dy)
nuclear@27 155 {
nuclear@27 156 float angle = DEG_TO_RAD(cam_theta);
nuclear@27 157 cam_x += cos(angle) * dx + sin(angle) * dy;
nuclear@27 158 cam_z -= -sin(angle) * dx + cos(angle) * dy;
nuclear@27 159 }
nuclear@27 160
nuclear@27 161 static int proc_events(void)
nuclear@27 162 {
nuclear@27 163 static int prev_mx, prev_my, prev_bnmask;
nuclear@33 164 int mx, my, bnmask, key;
nuclear@27 165
nuclear@33 166 if(!proc_keyb_input()) {
nuclear@33 167 return 0;
nuclear@27 168 }
nuclear@27 169
nuclear@27 170 bnmask = read_mouse(&mx, &my);
nuclear@27 171 if(bnmask != prev_bnmask) {
nuclear@27 172 mouse_button(bnmask, mx, my);
nuclear@27 173 prev_bnmask = bnmask;
nuclear@27 174 }
nuclear@27 175 if(mx != prev_mx || my != prev_my) {
nuclear@27 176 mouse_motion(mx, my);
nuclear@27 177 prev_mx = mx;
nuclear@27 178 prev_my = my;
nuclear@27 179 }
nuclear@27 180 return 1;
nuclear@27 181 }
nuclear@27 182
nuclear@33 183 static int proc_keyb_input(void)
nuclear@27 184 {
nuclear@33 185 /* first examine all keypresses and handle non-movement keys */
nuclear@33 186 int key;
nuclear@33 187 while((key = kb_getkey()) != -1) {
nuclear@33 188 switch(key) {
nuclear@33 189 case 27:
nuclear@33 190 return 0;
nuclear@27 191
nuclear@33 192 case '`':
nuclear@33 193 mouse_look = !mouse_look;
nuclear@33 194 break;
nuclear@33 195
nuclear@33 196 default:
nuclear@33 197 break;
nuclear@33 198 }
nuclear@33 199 }
nuclear@33 200
nuclear@33 201 /* for the movement keys we just care if they are pressed at the moment */
nuclear@33 202 if(kb_isdown('w') || kb_isdown('W'))
nuclear@27 203 cam_move(0, walk_speed);
nuclear@27 204
nuclear@33 205 if(kb_isdown('s') || kb_isdown('S'))
nuclear@27 206 cam_move(0, -walk_speed);
nuclear@27 207
nuclear@33 208 if(kb_isdown('a') || kb_isdown('A'))
nuclear@27 209 cam_move(-walk_speed, 0);
nuclear@27 210
nuclear@33 211 if(kb_isdown('d') || kb_isdown('D'))
nuclear@27 212 cam_move(walk_speed, 0);
nuclear@27 213
nuclear@27 214 return 1;
nuclear@27 215 }
nuclear@27 216
nuclear@27 217 static int bnstate;
nuclear@27 218 static void mouse_button(int bn, int x, int y)
nuclear@27 219 {
nuclear@27 220 bnstate = bn;
nuclear@27 221 }
nuclear@27 222
nuclear@27 223 static void mouse_motion(int x, int y)
nuclear@27 224 {
nuclear@33 225 static int prev_x = -1, prev_y;
nuclear@27 226 int dx = x - prev_x;
nuclear@27 227 int dy = y - prev_y;
nuclear@33 228
nuclear@33 229 if(mouse_look) {
nuclear@33 230 if(prev_x == -1) {
nuclear@33 231 dx = dy = 0;
nuclear@33 232 }
nuclear@33 233
nuclear@33 234 set_mouse(160, 100);
nuclear@33 235 prev_x = 160;
nuclear@33 236 prev_y = 100;
nuclear@33 237 } else {
nuclear@33 238 prev_x = x;
nuclear@33 239 prev_y = y;
nuclear@33 240 }
nuclear@27 241
nuclear@27 242 if(mouse_look || bnstate) {
nuclear@27 243 cam_theta += dx * look_speed;
nuclear@27 244 cam_phi += dy * look_speed;
nuclear@27 245
nuclear@27 246 if(cam_phi < -90) {
nuclear@27 247 cam_phi = -90;
nuclear@27 248 }
nuclear@27 249 if(cam_phi > 90) {
nuclear@27 250 cam_phi = 90;
nuclear@27 251 }
nuclear@27 252 }
nuclear@27 253 }
nuclear@27 254
nuclear@27 255 static void sighandler(int s)
nuclear@27 256 {
nuclear@27 257 set_video_mode(3);
nuclear@27 258
nuclear@27 259 switch(s) {
nuclear@27 260 case SIGABRT:
nuclear@27 261 fprintf(stderr, "abort\n");
nuclear@27 262 break;
nuclear@27 263
nuclear@27 264 case SIGILL:
nuclear@27 265 fprintf(stderr, "illegal operation\n");
nuclear@27 266 break;
nuclear@27 267
nuclear@27 268 case SIGSEGV:
nuclear@27 269 fprintf(stderr, "segmentation fault\n");
nuclear@27 270 break;
nuclear@27 271
nuclear@27 272 case SIGINT:
nuclear@27 273 fprintf(stderr, "interrupted\n");
nuclear@27 274 break;
nuclear@27 275
nuclear@27 276 case SIGFPE:
nuclear@27 277 fprintf(stderr, "floating point exception\n");
nuclear@27 278 break;
nuclear@27 279
nuclear@27 280 default:
nuclear@27 281 fprintf(stderr, "unexpected signal\n");
nuclear@27 282 }
nuclear@27 283
nuclear@27 284 exit(1);
nuclear@27 285 }