]> Shamusworld >> Repos - virtualjaguar/blob - src/video.cpp
Expended OpenGL rendering with 16, 24 and 32 bit texture types.
[virtualjaguar] / src / video.cpp
1 //
2 // VIDEO.CPP: SDL/local hardware specific video routines
3 //
4 // by James L. Hammons
5 //
6
7 #include "tom.h"
8 #include "sdlemu_opengl.h"
9 #include "settings.h"
10 #include "video.h"
11
12 // External global variables
13
14 //shouldn't these exist here??? Prolly.
15 //And now, they do! :-)
16 SDL_Surface * surface, * mainSurface;
17 Uint32 mainSurfaceFlags;
18 int16 * backbuffer;
19 SDL_Joystick * joystick;
20
21 //
22 // Create SDL/OpenGL surfaces
23 //
24 bool InitVideo(void)
25 {
26         // Get proper info about the platform we're running on...
27         const SDL_VideoInfo * info = SDL_GetVideoInfo();
28
29         if (!info)
30         {
31                 WriteLog("VJ: SDL is unable to get the video info: %s\n", SDL_GetError());
32                 return false;
33         }
34
35         if (vjs.useOpenGL)
36         {
37             SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
38         SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
39
40 //              mainSurfaceFlags = SDL_HWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF | SDL_OPENGL;
41                 mainSurfaceFlags = SDL_OPENGL;
42                 
43         }
44         else
45         {
46                 if (info->hw_available)
47                         mainSurfaceFlags = SDL_HWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF;
48
49                 if (info->blit_hw)
50                         mainSurfaceFlags |= SDL_HWACCEL;
51         }
52
53         if (vjs.fullscreen)
54                 mainSurfaceFlags |= SDL_FULLSCREEN;
55
56         if (!vjs.useOpenGL)
57 //              mainSurface = SDL_SetVideoMode(VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT_NTSC, 16, mainSurfaceFlags);
58                 mainSurface = SDL_SetVideoMode(VIRTUAL_SCREEN_WIDTH,
59                         (vjs.hardwareTypeNTSC ? VIRTUAL_SCREEN_HEIGHT_NTSC : VIRTUAL_SCREEN_HEIGHT_PAL),
60                         16, mainSurfaceFlags);
61         else
62 //              mainSurface = SDL_SetVideoMode(VIRTUAL_SCREEN_WIDTH * 2, VIRTUAL_SCREEN_HEIGHT_NTSC * 2, 16, mainSurfaceFlags);
63                 mainSurface = SDL_SetVideoMode(VIRTUAL_SCREEN_WIDTH * 2,
64                         (vjs.hardwareTypeNTSC ? VIRTUAL_SCREEN_HEIGHT_NTSC : VIRTUAL_SCREEN_HEIGHT_PAL) * 2,
65                         16, mainSurfaceFlags);
66
67         if (mainSurface == NULL)
68         {
69                 WriteLog("VJ: SDL is unable to set the video mode: %s\n", SDL_GetError());
70                 return false;
71         }
72
73         SDL_WM_SetCaption("Virtual Jaguar", "Virtual Jaguar");
74
75         // Create the primary SDL display (16 BPP, 5/5/5 RGB format)
76         surface = SDL_CreateRGBSurface(SDL_SWSURFACE, VIRTUAL_SCREEN_WIDTH,
77                 (vjs.hardwareTypeNTSC ? VIRTUAL_SCREEN_HEIGHT_NTSC : VIRTUAL_SCREEN_HEIGHT_PAL),
78 //              16, 63488, 2016, 31, 0);
79                 16, 0x7C00, 0x03E0, 0x001F, 0);
80
81         if (surface == NULL)
82         {
83                 WriteLog("VJ: Could not create primary SDL surface: %s\n", SDL_GetError());
84                 return false;
85         }
86
87         if (vjs.useOpenGL)
88 //Should make another setting here, for either linear or nearest (instead of just picking one)
89 //And we have! ;-)
90                 sdlemu_init_opengl(surface, 1/*method*/, 2/*size*/, vjs.glFilter/*texture type (linear, nearest)*/, NULL);
91
92         // Initialize Joystick support under SDL
93         if (vjs.useJoystick)
94         {
95                 if (SDL_NumJoysticks() <= 0)
96                 {
97                         vjs.useJoystick = false;
98                         printf("VJ: No joystick(s) or joypad(s) detected on your system. Using keyboard...\n");
99                 }
100                 else
101                 {
102                         if ((joystick = SDL_JoystickOpen(vjs.joyport)) == 0)
103                         {
104                                 vjs.useJoystick = false;
105                                 printf("VJ: Unable to open a Joystick on port: %d\n", (int)vjs.joyport);
106                         }
107                         else
108                                 printf("VJ: Using: %s\n", SDL_JoystickName(vjs.joyport));
109                 }
110         }
111
112         // Set up the backbuffer
113 //To be safe, this should be 1280 * 625 * 2...
114 //      backbuffer = (int16 *)malloc(845 * 525 * sizeof(int16));
115         backbuffer = (int16 *)malloc(1280 * 625 * sizeof(int16));
116 //      memset(backbuffer, 0x44, VIRTUAL_SCREEN_WIDTH * VIRTUAL_SCREEN_HEIGHT_NTSC * sizeof(int16));
117         memset(backbuffer, 0x44, VIRTUAL_SCREEN_WIDTH *
118                 (vjs.hardwareTypeNTSC ? VIRTUAL_SCREEN_HEIGHT_NTSC : VIRTUAL_SCREEN_HEIGHT_PAL)
119                 * sizeof(int16));
120
121         return true;
122 }
123
124 //
125 // Free various SDL components
126 //
127 void VideoDone(void)
128 {
129         if (vjs.useOpenGL)
130                 sdlemu_close_opengl();
131
132         SDL_JoystickClose(joystick);
133         SDL_FreeSurface(surface);
134         free(backbuffer);
135 }
136
137 //
138 // Render the backbuffer to the primary screen surface
139 //
140 void RenderBackbuffer(void)
141 {
142         if (SDL_MUSTLOCK(surface))
143                 while (SDL_LockSurface(surface) < 0)
144                         SDL_Delay(10);
145
146         memcpy(surface->pixels, backbuffer, tom_getVideoModeWidth() * tom_getVideoModeHeight() * 2);
147
148         if (SDL_MUSTLOCK(surface))
149                 SDL_UnlockSurface(surface);
150
151         if (vjs.useOpenGL)
152                 sdlemu_draw_texture(mainSurface, surface, 1/*1=GL_QUADS*/);
153         else
154         {
155                 SDL_Rect rect = { 0, 0, surface->w, surface->h };
156                 SDL_BlitSurface(surface, &rect, mainSurface, &rect);
157                 SDL_Flip(mainSurface);
158     }
159 }
160
161 //
162 // Resize the main SDL screen & backbuffer
163 //
164 void ResizeScreen(uint32 width, uint32 height)
165 {
166         char window_title[256];
167
168         SDL_FreeSurface(surface);
169         surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 
170 //              16, 63488, 2016, 31, 0);
171         16, 0x7C00, 0x03E0, 0x001F, 0);
172
173         if (surface == NULL)
174         {
175                 WriteLog("Video: Could not create primary SDL surface: %s", SDL_GetError());
176 //This is just crappy. We shouldn't exit this way--it leaves all kinds of memory leaks
177 //as well as screwing up SDL... !!! FIX !!!
178                 exit(1);
179         }
180
181         if (vjs.useOpenGL)
182         {
183 //Need to really resize the window height--no pixel height shenanigans!
184 //Err, we should only do this *if* we changed from PAL to NTSC or vice versa... !!! FIX !!!
185                 mainSurface = SDL_SetVideoMode(VIRTUAL_SCREEN_WIDTH * 2, height * 2, 16, mainSurfaceFlags);
186                 // This seems to work well for resizing (i.e., changes in the pixel width)...
187                 sdlemu_resize_texture(surface, mainSurface, vjs.glFilter, NULL);
188         }
189         else
190         {
191                 mainSurface = SDL_SetVideoMode(width, height, 16, mainSurfaceFlags);
192
193                 if (mainSurface == NULL)
194                 {
195                         WriteLog("Video: SDL is unable to set the video mode: %s\n", SDL_GetError());
196                         exit(1);
197                 }
198         }
199
200         sprintf(window_title, "Virtual Jaguar (%i x %i)", (int)width, (int)height);
201         SDL_WM_SetCaption(window_title, window_title);
202 }
203
204 //
205 // Return the screen's pitch
206 //
207 uint32 GetSDLScreenPitch(void)
208 {
209         return surface->pitch;
210 }
211
212 //
213 // Fullscreen <-> window switching
214 //
215 void ToggleFullscreen(void)
216 {
217 //NOTE: This does *NOT* work with OpenGL rendering! !!! FIX !!!
218 //      if (vjs.useOpenGL)
219 //              return;                                                                         // Until we can fix it...
220
221         vjs.fullscreen = !vjs.fullscreen;
222         mainSurfaceFlags &= ~SDL_FULLSCREEN;
223
224         if (vjs.fullscreen)
225                 mainSurfaceFlags |= SDL_FULLSCREEN;
226
227         mainSurface = SDL_SetVideoMode(tom_width, tom_height, 16, mainSurfaceFlags);
228
229         if (mainSurface == NULL)
230         {
231                 WriteLog("Video: SDL is unable to set the video mode: %s\n", SDL_GetError());
232                 exit(1);
233         }
234
235         SDL_WM_SetCaption("Virtual Jaguar", "Virtual Jaguar");
236 }