]> Shamusworld >> Repos - virtualjaguar/blob - src/video.cpp
1df9fca1e15627bfd619bfb8fb77dbf810729130
[virtualjaguar] / src / video.cpp
1 //
2 // VIDEO.CPP: SDL/local hardware specific video routines
3 //
4 // by James L. Hammons
5 //
6
7 #include "types.h"
8 #include "tom.h"
9 #include "sdlemu_opengl.h"
10 #include "settings.h"
11 #include "video.h"
12
13 // External global variables
14
15 //shouldn't these exist here??? Prolly.
16 extern SDL_Surface * surface, * mainSurface;
17 extern Uint32 mainSurfaceFlags;
18 extern int16 * backbuffer;
19 extern SDL_Joystick * joystick;
20
21 //
22 // Prime SDL and create surfaces
23 //
24 bool InitVideo(void)
25 {
26         // Set up SDL library
27         if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO | SDL_INIT_TIMER | SDL_INIT_NOPARACHUTE) < 0)
28         {
29                 WriteLog("VJ: Could not initialize the SDL library: %s", SDL_GetError());
30                 return false;
31         }
32
33         // Get proper info about the platform we're running on...
34         const SDL_VideoInfo * info = SDL_GetVideoInfo();
35
36         if (!info)
37         {
38                 WriteLog("VJ: SDL is unable to get the video info: %s\n", SDL_GetError());
39                 return false;
40         }
41
42         if (vjs.useOpenGL)
43         {
44                 mainSurfaceFlags = SDL_HWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF | SDL_OPENGL;
45                 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
46         }
47         else
48         {
49                 if (info->hw_available)
50                         mainSurfaceFlags = SDL_HWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF;
51
52                 if (info->blit_hw)
53                         mainSurfaceFlags |= SDL_HWACCEL;
54         }
55
56         if (vjs.fullscreen)
57                 mainSurfaceFlags |= SDL_FULLSCREEN;
58
59         if (!vjs.useOpenGL)
60                 mainSurface = SDL_SetVideoMode(VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT, 16, mainSurfaceFlags);
61         else
62                 mainSurface = SDL_SetVideoMode(VIRTUAL_SCREEN_WIDTH * 2, VIRTUAL_SCREEN_HEIGHT * 2, 16, mainSurfaceFlags);
63
64         if (mainSurface == NULL)
65         {
66                 WriteLog("VJ: SDL is unable to set the video mode: %s\n", SDL_GetError());
67                 return false;
68         }
69
70         SDL_WM_SetCaption("Virtual Jaguar", "Virtual Jaguar");
71
72         // Create the primary SDL display (16 BPP, 5/5/5 RGB format)
73         surface = SDL_CreateRGBSurface(SDL_SWSURFACE, VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT,
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                 sdlemu_init_opengl(surface, 1/*method*/, 2/*size*/, 0/*texture type (linear, nearest)*/);
84
85         // Initialize Joystick support under SDL
86         if (vjs.useJoystick)
87         {
88                 if (SDL_NumJoysticks() <= 0)
89                 {
90                         vjs.useJoystick = false;
91                         printf("VJ: No joystick(s) or joypad(s) detected on your system. Using keyboard...\n");
92                 }
93                 else
94                 {
95                         if ((joystick = SDL_JoystickOpen(vjs.joyport)) == 0)
96                         {
97                                 vjs.useJoystick = false;
98                                 printf("VJ: Unable to open a Joystick on port: %d\n", (int)vjs.joyport);
99                         }
100                         else
101                                 printf("VJ: Using: %s\n", SDL_JoystickName(vjs.joyport));
102                 }
103         }
104
105         return true;
106 }
107
108 //
109 // Free various SDL components
110 //
111 void VideoDone(void)
112 {
113         if (vjs.useOpenGL)
114                 sdlemu_close_opengl();
115
116         SDL_JoystickClose(joystick);
117         SDL_FreeSurface(surface);
118         SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO | SDL_INIT_TIMER);
119         SDL_Quit();
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         sprintf(window_title, "Virtual Jaguar (%i x %i)", (int)width, (int)height);
164
165         if (!vjs.useOpenGL)
166         {
167                 mainSurface = SDL_SetVideoMode(width, height, 16, mainSurfaceFlags);
168
169                 if (mainSurface == NULL)
170                 {
171                         WriteLog("Video: SDL is unable to set the video mode: %s\n", SDL_GetError());
172                         exit(1);
173                 }
174         }
175
176         SDL_WM_SetCaption(window_title, window_title);
177
178         // This seems to work well for resizing (i.e., changes in the pixel width)...
179         if (vjs.useOpenGL)
180                 sdlemu_resize_texture(surface, mainSurface);
181 }
182
183 //
184 // Return the screen's pitch
185 //
186 uint32 GetSDLScreenPitch(void)
187 {
188         return surface->pitch;
189 }
190
191 //
192 // Fullscreen <-> window switching
193 //
194 //NOTE: This does *NOT* work with OpenGL rendering! !!! FIX !!!
195 void ToggleFullscreen(void)
196 {
197         vjs.fullscreen = !vjs.fullscreen;
198         mainSurfaceFlags &= ~SDL_FULLSCREEN;
199
200         if (vjs.fullscreen)
201                 mainSurfaceFlags |= SDL_FULLSCREEN;
202
203         mainSurface = SDL_SetVideoMode(tom_width, tom_height, 16, mainSurfaceFlags);
204
205         if (mainSurface == NULL)
206         {
207                 WriteLog("Video: SDL is unable to set the video mode: %s\n", SDL_GetError());
208                 exit(1);
209         }
210
211         SDL_WM_SetCaption("Virtual Jaguar", "Virtual Jaguar");
212 }