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