165 lines
4.2 KiB
C
165 lines
4.2 KiB
C
![]() |
#include <stdio.h>
|
||
|
#include <X11/X.h>
|
||
|
#include <X11/keysym.h>
|
||
|
#include <GL/gl.h>
|
||
|
#include <GL/glx.h>
|
||
|
#include <time.h>
|
||
|
#include <zoom/init.h>
|
||
|
#include <zoom/render.h>
|
||
|
#include <zoom/player.h>
|
||
|
|
||
|
Display *disp;
|
||
|
Window wnd;
|
||
|
Atom windele;
|
||
|
int running;
|
||
|
int fullscreen = 0;
|
||
|
static int attributeList[] = {GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 1, None};
|
||
|
GLXContext gc;
|
||
|
|
||
|
extern int input;
|
||
|
|
||
|
|
||
|
int main();
|
||
|
void GLXinit();
|
||
|
|
||
|
void GLXinit() {
|
||
|
char *str = "Zoom";
|
||
|
XTextProperty name;
|
||
|
XWMHints wmhints;
|
||
|
XSizeHints shints;
|
||
|
XClassHint chint;
|
||
|
XVisualInfo *vi;
|
||
|
Colormap cmap;
|
||
|
XSetWindowAttributes swa;
|
||
|
Pixmap pixmap;
|
||
|
Cursor cursor;
|
||
|
XColor color;
|
||
|
|
||
|
vi = glXChooseVisual(disp, DefaultScreen(disp), attributeList);
|
||
|
|
||
|
cmap = XCreateColormap(disp, RootWindow(disp, vi->screen), vi->visual, AllocNone);
|
||
|
swa.colormap = cmap;
|
||
|
swa.border_pixel = 0;
|
||
|
swa.event_mask = PointerMotionMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask;
|
||
|
|
||
|
wnd = XCreateWindow(disp, RootWindow(disp, vi->screen), 0, 0, 640, 480, 0, vi->depth, InputOutput,
|
||
|
vi->visual, CWBorderPixel|CWColormap|CWEventMask, &swa);
|
||
|
|
||
|
chint.res_name = "Zoom";
|
||
|
chint.res_class = "zoom";
|
||
|
XSetClassHint(disp, wnd, &chint);
|
||
|
|
||
|
shints.flags = PMaxSize | PMinSize;
|
||
|
shints.min_width = 640;
|
||
|
shints.min_height = 480;
|
||
|
shints.max_width = 640;
|
||
|
shints.max_height = 480;
|
||
|
XSetWMNormalHints(disp, wnd, &shints);
|
||
|
|
||
|
if (XStringListToTextProperty(&str, 1, &name) != 0)
|
||
|
{
|
||
|
XSetWMName(disp, wnd, &name);
|
||
|
XFree(name.value);
|
||
|
}
|
||
|
|
||
|
windele = XInternAtom(disp, "WM_DELETE_WINDOW", False);
|
||
|
XSetWMProtocols(disp, wnd, &windele, 1);
|
||
|
|
||
|
XMapWindow(disp, wnd);
|
||
|
|
||
|
color.pixel = WhitePixel(disp, vi->screen);
|
||
|
XQueryColor(disp, cmap, &color);
|
||
|
pixmap = XCreatePixmap(disp, wnd, 1, 1, 1);
|
||
|
cursor = XCreatePixmapCursor(disp, pixmap, pixmap, &color, &color, 0, 0);
|
||
|
XFreePixmap(disp, pixmap);
|
||
|
XDefineCursor(disp, wnd, cursor);
|
||
|
XGrabPointer(disp, wnd, False, PointerMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, wnd, None, CurrentTime);
|
||
|
XWarpPointer(disp, None, wnd, 0, 0, 0, 0, 320, 240);
|
||
|
|
||
|
gc = glXCreateContext(disp, vi, NULL, True);
|
||
|
|
||
|
glXMakeCurrent(disp, wnd, gc);
|
||
|
|
||
|
XFree(vi);
|
||
|
|
||
|
XSync(disp, 0);
|
||
|
}
|
||
|
|
||
|
int main() {
|
||
|
unsigned long ticks, delta = 0;
|
||
|
struct timeval tv;
|
||
|
XEvent event;
|
||
|
unsigned long frames = 0, tocks = 0;
|
||
|
|
||
|
|
||
|
disp = XOpenDisplay(0);
|
||
|
|
||
|
GLXinit();
|
||
|
|
||
|
running = InitGame();
|
||
|
|
||
|
gettimeofday(&tv, NULL);
|
||
|
ticks = tv.tv_usec;
|
||
|
while(running) {
|
||
|
while(XPending(disp)) {
|
||
|
XNextEvent(disp, &event);
|
||
|
switch(event.type) {
|
||
|
case ClientMessage:
|
||
|
if(event.xclient.data.l[0] == windele) running = 0;
|
||
|
break;
|
||
|
case ButtonPress:
|
||
|
input |= INPUT_OPEN;
|
||
|
break;
|
||
|
case ButtonRelease:
|
||
|
if(event.xbutton.button == Button2) input &= ~INPUT_OPEN;
|
||
|
break;
|
||
|
case MotionNotify:
|
||
|
if(event.xmotion.x == 320 && event.xmotion.y == 240) break;
|
||
|
MouseInput(event.xmotion.x - 320, event.xmotion.y - 240);
|
||
|
XWarpPointer(disp, None, wnd, 0, 0, 0, 0, 320, 240);
|
||
|
break;
|
||
|
case KeyPress:
|
||
|
switch(XKeycodeToKeysym(disp, event.xkey.keycode, 0)) {
|
||
|
case XK_Up: case XK_w: input |= INPUT_UP; break;
|
||
|
case XK_Down: case XK_s: input |= INPUT_DOWN; break;
|
||
|
case XK_Right: case XK_d: input |= INPUT_RIGHT; break;
|
||
|
case XK_Left: case XK_a: input |= INPUT_LEFT; break;
|
||
|
case XK_space: input |= INPUT_OPEN; break;
|
||
|
case XK_Escape: running = 0; break;
|
||
|
}
|
||
|
break;
|
||
|
case KeyRelease:
|
||
|
switch(XKeycodeToKeysym(disp, event.xkey.keycode, 0)) {
|
||
|
case XK_Up: case XK_w: input &= ~INPUT_UP; break;
|
||
|
case XK_Down: case XK_s: input &= ~INPUT_DOWN; break;
|
||
|
case XK_Right: case XK_d: input &= ~INPUT_RIGHT; break;
|
||
|
case XK_Left: case XK_a: input &= ~INPUT_LEFT; break;
|
||
|
case XK_space: input &= ~INPUT_OPEN; break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if(!running) break;
|
||
|
DoInput(delta);
|
||
|
Render();
|
||
|
glXSwapBuffers(disp, wnd);
|
||
|
XSync(disp, 0);
|
||
|
gettimeofday(&tv, NULL);
|
||
|
delta = ((tv.tv_usec + 1000000 - ticks)%1000000)/1000;
|
||
|
ticks = (ticks + delta*1000) % 1000000;
|
||
|
|
||
|
frames++;
|
||
|
tocks += delta*1000;
|
||
|
if(tocks > 1000000) {
|
||
|
fprintf(stderr, "%u\n", frames);
|
||
|
frames = 0;
|
||
|
tocks -= 1000000;
|
||
|
}
|
||
|
}
|
||
|
UninitGame();
|
||
|
XUngrabPointer(disp, CurrentTime);
|
||
|
XDestroyWindow(disp, wnd);
|
||
|
glXDestroyContext(disp, gc);
|
||
|
XCloseDisplay(disp);
|
||
|
return 0;
|
||
|
}
|