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