]> Shamusworld >> Repos - virtualjaguar/blob - src/video.cpp
1.0.7 update
[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, 16, mainSurfaceFlags);
62         else
63                 mainSurface = SDL_SetVideoMode(VIRTUAL_SCREEN_WIDTH * 2, VIRTUAL_SCREEN_HEIGHT * 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,
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                 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 * sizeof(int16));
112
113         return true;
114 }
115
116 //
117 // Free various SDL components
118 //
119 void VideoDone(void)
120 {
121         if (vjs.useOpenGL)
122                 sdlemu_close_opengl();
123
124         SDL_JoystickClose(joystick);
125         SDL_FreeSurface(surface);
126         SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO | SDL_INIT_TIMER);
127         SDL_Quit();
128
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                 exit(1);
171         }
172
173         if (vjs.useOpenGL)
174                 // This seems to work well for resizing (i.e., changes in the pixel width)...
175                 sdlemu_resize_texture(surface, mainSurface, vjs.glFilter);
176         else
177         {
178                 mainSurface = SDL_SetVideoMode(width, height, 16, mainSurfaceFlags);
179
180                 if (mainSurface == NULL)
181                 {
182                         WriteLog("Video: SDL is unable to set the video mode: %s\n", SDL_GetError());
183                         exit(1);
184                 }
185         }
186
187         sprintf(window_title, "Virtual Jaguar (%i x %i)", (int)width, (int)height);
188         SDL_WM_SetCaption(window_title, window_title);
189
190         // This seems to work well for resizing (i.e., changes in the pixel width)...
191 //      if (vjs.useOpenGL)
192 //              sdlemu_resize_texture(surface, mainSurface);
193 }
194
195 //
196 // Return the screen's pitch
197 //
198 uint32 GetSDLScreenPitch(void)
199 {
200         return surface->pitch;
201 }
202
203 //
204 // Fullscreen <-> window switching
205 //
206 //NOTE: This does *NOT* work with OpenGL rendering! !!! FIX !!!
207 void ToggleFullscreen(void)
208 {
209         vjs.fullscreen = !vjs.fullscreen;
210         mainSurfaceFlags &= ~SDL_FULLSCREEN;
211
212         if (vjs.fullscreen)
213                 mainSurfaceFlags |= SDL_FULLSCREEN;
214
215         mainSurface = SDL_SetVideoMode(tom_width, tom_height, 16, mainSurfaceFlags);
216
217         if (mainSurface == NULL)
218         {
219                 WriteLog("Video: SDL is unable to set the video mode: %s\n", SDL_GetError());
220                 exit(1);
221         }
222
223         SDL_WM_SetCaption("Virtual Jaguar", "Virtual Jaguar");
224 }