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