core: Fix libdwarf and Qt build failure
[clinton/Virtual-Jaguar-Rx.git] / src / gui / glwidget.cpp
CommitLineData
cf76e892
JPM
1// OpenGL implementation in Qt
2// Parts of this are blantantly ripped off from BSNES (thanks Byuu!)
3//
4// by James Hammons
5// (C) 2010 Underground Software
6//
7// JLH = James Hammons <jlhamm@acm.org>
8// JPM = Jean-Paul Mari <djipi.mari@gmail.com>
9//
10// Who When What
11// --- ---------- -------------------------------------------------------------
12// JLH 01/14/2010 Created this file
13// JLH 02/03/2013 Added "centered" fullscreen mode with correct aspect ratio
14// JPM 06/06/2016 Visual Studio support
15//
16
17#include "glwidget.h"
18
19#include "jaguar.h"
20#include "settings.h"
21#include "tom.h"
22
23#if defined(__GCCWIN32__) || defined(_MSC_VER)
24#if defined(_MSC_VER)
25#include <GL/gl.h>
26#endif
27// Apparently on win32, various OpenGL constants aren't pulled in.
28#include <GL/glext.h>
29#endif
30
31
32GLWidget::GLWidget(QWidget * parent/*= 0*/): QGLWidget(parent), texture(0),
33 textureWidth(0), textureHeight(0), buffer(0), rasterWidth(326), rasterHeight(240),
34 offset(0), hideMouseTimeout(60)
35{
36 // Screen pitch has to be the texture width (in 32-bit pixels)...
37 JaguarSetScreenPitch(1024);
38 setMouseTracking(true);
39}
40
41
42GLWidget::~GLWidget()
43{
44 if (buffer)
45 delete[] buffer;
46}
47
48
49void GLWidget::initializeGL()
50{
51 format().setDoubleBuffer(true);
52 resizeGL(rasterWidth, rasterHeight);
53
54 glDisable(GL_ALPHA_TEST);
55 glDisable(GL_BLEND);
56 glDisable(GL_DEPTH_TEST);
57 glDisable(GL_POLYGON_SMOOTH);
58 glDisable(GL_STENCIL_TEST);
59 glEnable(GL_DITHER);
60 glEnable(GL_TEXTURE_2D);
61 glClearColor(0.0, 0.0, 0.0, 0.0);
62
63 CreateTextures();
64}
65
66
67void GLWidget::paintGL()
68{
69 // If we're in fullscreen mode, we take the value of the screen width as
70 // set by MainWin, since it may be wider than what our aspect ratio allows.
71 // In that case, we adjust the viewport over so that it's centered on the
72 // screen. Otherwise, we simply take the width from our width() funtion
73 // which will always be correct in windowed mode.
74
75 if (!fullscreen)
76 outputWidth = width();
77
78 // Bit 0 in VP is interlace flag. 0 = interlace, 1 = non-interlaced
79 double multiplier = (TOMGetVP() & 0x0001 ? 1.0 : 2.0);
80 unsigned outputHeight = height();
81
82 glMatrixMode(GL_PROJECTION);
83 glLoadIdentity();
84 glOrtho(0, outputWidth, 0, outputHeight, -1.0, 1.0);
85 glViewport(0 + offset, 0, outputWidth, outputHeight);
86
87 glMatrixMode(GL_MODELVIEW);
88 glLoadIdentity();
89
90 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (vjs.glFilter ? GL_LINEAR : GL_NEAREST));
91 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (vjs.glFilter ? GL_LINEAR : GL_NEAREST));
92 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, TOMGetVideoModeWidth(), rasterHeight * multiplier, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, buffer);
93
94 double w = (double)TOMGetVideoModeWidth() / (double)textureWidth;
95 double h = ((double)rasterHeight * multiplier) / (double)textureHeight;
96 unsigned u = outputWidth;
97 unsigned v = outputHeight;
98
99 glBegin(GL_TRIANGLE_STRIP);
100 glTexCoord2f(0, 0); glVertex3i(0, v, 0);
101 glTexCoord2f(w, 0); glVertex3i(u, v, 0);
102 glTexCoord2f(0, h); glVertex3i(0, 0, 0);
103 glTexCoord2f(w, h); glVertex3i(u, 0, 0);
104 glEnd();
105}
106
107
108void GLWidget::resizeGL(int /*width*/, int /*height*/)
109{
110//kludge [No, this is where it belongs!]
111 rasterHeight = (vjs.hardwareTypeNTSC ? VIRTUAL_SCREEN_HEIGHT_NTSC : VIRTUAL_SCREEN_HEIGHT_PAL);
112
113 return;
114}
115
116
117// At some point, we'll have to create more than one texture to handle
118// cases like Doom. Or have another go at TV type rendering; it will
119// require a 2048x512 texture though. (Note that 512 is the correct height for
120// interlaced screens; we won't have to change much here to support it.)
121void GLWidget::CreateTextures(void)
122{
123 // Seems that power of 2 sizes are still mandatory...
124 textureWidth = 1024;
125 textureHeight = 512;
126 buffer = new uint32_t[textureWidth * textureHeight];
127 JaguarSetScreenBuffer(buffer);
128
129 glGenTextures(1, &texture);
130 glBindTexture(GL_TEXTURE_2D, texture);
131 glPixelStorei(GL_UNPACK_ROW_LENGTH, textureWidth);
132 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
133 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
134 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, NULL);
135}
136
137
138void GLWidget::HandleMouseHiding(void)
139{
140 // Mouse watchdog timer handling. Basically, if the timeout value is
141 // greater than zero, decrement it. Otherwise, check for zero, if so, then
142 // hide the mouse and set the hideMouseTimeout value to -1 to signal that
143 // the mouse has been hidden.
144 if (hideMouseTimeout > 0)
145 hideMouseTimeout--;
146 else if (hideMouseTimeout == 0)
147 {
148 hideMouseTimeout--;
149 setCursor(Qt::BlankCursor);
150 }
151}
152
153
154// We use this as part of a watchdog system for hiding/unhiding the mouse. This
155// part shows the mouse (if hidden) and resets the watchdog timer.
156void GLWidget::CheckAndRestoreMouseCursor(void)
157{
158 // Has the mouse been hidden? (-1 means mouse was hidden)
159 if (hideMouseTimeout == -1)
160 setCursor(Qt::ArrowCursor);
161
162 hideMouseTimeout = 60;
163}
164
165
166// We check here for mouse movement; if there is any, show the mouse and reset
167// the watchdog timer.
168void GLWidget::mouseMoveEvent(QMouseEvent * /*event*/)
169{
170 CheckAndRestoreMouseCursor();
171}
172
173
174#if 0
175class RubyGLWidget: public QGLWidget
176{
177 public:
178 GLuint texture;
179 unsigned textureWidth, textureHeight;
180
181 uint32_t * buffer;
182 unsigned rasterWidth, rasterHeight;
183
184 bool synchronize;
185 unsigned filter;
186
187 void updateSynchronization() {
188 #ifdef __APPLE__
189 makeCurrent();
190 CGLContextObj context = CGLGetCurrentContext();
191 GLint value = synchronize; //0 = draw immediately (no vsync), 1 = draw once per frame (vsync)
192 CGLSetParameter(context, kCGLCPSwapInterval, &value);
193 #endif
194 }
195} * widget;
196#endif