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