2 RetroRay - integrated standalone vintage modeller/renderer
3 Copyright (C) 2023 John Tsiombikas <nuclear@mutantstargoat.com>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>.
26 static void display(void);
27 static void reshape(int x, int y);
28 static void keydown(unsigned char key, int x, int y);
29 static void keyup(unsigned char key, int x, int y);
30 static void skeydown(int key, int x, int y);
31 static void skeyup(int key, int x, int y);
32 static void mouse(int bn, int st, int x, int y);
33 static void motion(int x, int y);
34 static int translate_skey(int key);
36 #if defined(__unix__) || defined(unix)
41 static void (*glx_swap_interval_ext)();
42 static void (*glx_swap_interval_sgi)();
46 static PROC wgl_swap_interval_ext;
49 static rtk_rect rband;
52 int main(int argc, char **argv)
54 glutInit(&argc, argv);
55 glutInitWindowSize(640, 480);
56 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
57 glutCreateWindow("RetroRay");
59 glutDisplayFunc(display);
60 glutReshapeFunc(reshape);
61 glutKeyboardFunc(keydown);
62 glutKeyboardUpFunc(keyup);
63 glutSpecialFunc(skeydown);
64 glutSpecialUpFunc(skeyup);
66 glutMotionFunc(motion);
67 glutPassiveMotionFunc(motion);
68 glutSpaceballMotionFunc(app_sball_motion);
69 glutSpaceballRotateFunc(app_sball_rotate);
70 glutSpaceballButtonFunc(app_sball_button);
72 #if defined(__unix__) || defined(unix)
73 xdpy = glXGetCurrentDisplay();
74 xwin = glXGetCurrentDrawable();
76 if(!(glx_swap_interval_ext = glXGetProcAddress((unsigned char*)"glXSwapIntervalEXT"))) {
77 glx_swap_interval_sgi = glXGetProcAddress((unsigned char*)"glXSwapIntervalSGI");
81 wgl_swap_interval_ext = wglGetProcAddress("wglSwapIntervalEXT");
84 win_width = glutGet(GLUT_WINDOW_WIDTH);
85 win_height = glutGet(GLUT_WINDOW_HEIGHT);
86 win_aspect = (float)win_width / win_height;
89 add_log_stream(stdout);
91 if(app_init() == -1) {
99 unsigned long get_msec(void)
101 return (unsigned long)glutGet(GLUT_ELAPSED_TIME);
104 void app_redisplay(int x, int y, int w, int h)
106 /*dbgmsg("fakeupd: %d,%d (%dx%d)\n", x, y, w, h);*/
110 void app_swap_buffers(void)
112 glMatrixMode(GL_MODELVIEW);
114 glMatrixMode(GL_PROJECTION);
118 glRasterPos2i(-1, 1);
120 glEnable(GL_ALPHA_TEST);
121 glAlphaFunc(GL_GREATER, 0.5f);
122 glDrawPixels(win_width, win_height, GL_BGRA, GL_UNSIGNED_BYTE, framebuf);
123 glDisable(GL_ALPHA_TEST);
125 if(rband.width | rband.height) {
126 glOrtho(0, win_width, win_height, 0, -1, 1);
128 glPushAttrib(GL_ENABLE_BIT);
129 glDisable(GL_DEPTH_TEST);
130 glDisable(GL_LIGHTING);
132 glEnable(GL_COLOR_LOGIC_OP);
135 glBegin(GL_LINE_LOOP);
137 glVertex2f(rband.x, rband.y);
138 glVertex2f(rband.x + rband.width, rband.y);
139 glVertex2f(rband.x + rband.width, rband.y + rband.height);
140 glVertex2f(rband.x, rband.y + rband.height);
147 glMatrixMode(GL_MODELVIEW);
150 assert(glGetError() == GL_NO_ERROR);
158 void app_resize(int x, int y)
160 if(x == win_width && y == win_height) return;
162 glutReshapeWindow(x, y);
165 void app_fullscreen(int fs)
167 static int prev_w, prev_h;
173 if(fs == fullscr) return;
176 prev_w = glutGet(GLUT_WINDOW_WIDTH);
177 prev_h = glutGet(GLUT_WINDOW_HEIGHT);
180 glutReshapeWindow(prev_w, prev_h);
185 #if defined(__unix__) || defined(unix)
186 void app_vsync(int vsync)
188 vsync = vsync ? 1 : 0;
189 if(glx_swap_interval_ext) {
190 glx_swap_interval_ext(xdpy, xwin, vsync);
191 } else if(glx_swap_interval_sgi) {
192 glx_swap_interval_sgi(vsync);
197 void app_vsync(int vsync)
199 if(wgl_swap_interval_ext) {
200 wgl_swap_interval_ext(vsync ? 1 : 0);
205 void app_rband(int x, int y, int w, int h)
216 static void display(void)
222 static void reshape(int x, int y)
227 static void keydown(unsigned char key, int x, int y)
229 modkeys = glutGetModifiers();
230 app_keyboard(key, 1);
233 static void keyup(unsigned char key, int x, int y)
235 app_keyboard(key, 0);
238 static void skeydown(int key, int x, int y)
241 modkeys = glutGetModifiers();
242 if((k = translate_skey(key)) >= 0) {
247 static void skeyup(int key, int x, int y)
249 int k = translate_skey(key);
255 static void mouse(int bn, int st, int x, int y)
257 modkeys = glutGetModifiers();
258 app_mouse(bn - GLUT_LEFT_BUTTON, st == GLUT_DOWN, x, y);
261 static void motion(int x, int y)
266 static int translate_skey(int key)
277 case GLUT_KEY_PAGE_UP:
279 case GLUT_KEY_PAGE_DOWN:
285 case GLUT_KEY_INSERT:
288 if(key >= GLUT_KEY_F1 && key <= GLUT_KEY_F12) {
289 return key - GLUT_KEY_F1 + KEY_F1;