1 #include "Screen.h"
2 
3 #include "FileSystemUtils.h"
4 #include "GraphicsUtil.h"
5 
6 #include <stdlib.h>
7 
8 // Used to create the window icon
9 extern "C"
10 {
11 	extern unsigned lodepng_decode24(
12 		unsigned char** out,
13 		unsigned* w,
14 		unsigned* h,
15 		const unsigned char* in,
16 		size_t insize
17 	);
18 }
19 
Screen()20 Screen::Screen()
21 {
22     m_window = NULL;
23     m_renderer = NULL;
24     m_screenTexture = NULL;
25     m_screen = NULL;
26     isWindowed = true;
27     stretchMode = 0;
28     isFiltered = false;
29     filterSubrect.x = 1;
30     filterSubrect.y = 1;
31     filterSubrect.w = 318;
32     filterSubrect.h = 238;
33     SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest");
34 
35 	// Uncomment this next line when you need to debug -flibit
36 	// SDL_SetHintWithPriority(SDL_HINT_RENDER_DRIVER, "software", SDL_HINT_OVERRIDE);
37 	SDL_CreateWindowAndRenderer(
38 		640,
39 		480,
40 		SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE,
41 		&m_window,
42 		&m_renderer
43 	);
44 	SDL_SetWindowTitle(m_window, "VVVVVV");
45 
46 	unsigned char *fileIn = NULL;
47 	size_t length = 0;
48 	unsigned char *data;
49 	unsigned int width, height;
50 	FILESYSTEM_loadFileToMemory("VVVVVV.png", &fileIn, &length);
51 	lodepng_decode24(&data, &width, &height, fileIn, length);
52 	FILESYSTEM_freeMemory(&fileIn);
53 	SDL_Surface *icon = SDL_CreateRGBSurfaceFrom(
54 		data,
55 		width,
56 		height,
57 		24,
58 		width * 3,
59 		0x000000FF,
60 		0x0000FF00,
61 		0x00FF0000,
62 		0x00000000
63 	);
64 	SDL_SetWindowIcon(m_window, icon);
65 	SDL_FreeSurface(icon);
66 	free(data);
67 
68 	// FIXME: This surface should be the actual backbuffer! -flibit
69 	m_screen = SDL_CreateRGBSurface(
70 		0,
71 		320,
72 		240,
73 		32,
74 		0x00FF0000,
75 		0x0000FF00,
76 		0x000000FF,
77 		0xFF000000
78 	);
79 	m_screenTexture = SDL_CreateTexture(
80 		m_renderer,
81 		SDL_PIXELFORMAT_ARGB8888,
82 		SDL_TEXTUREACCESS_STREAMING,
83 		320,
84 		240
85 	);
86 
87     badSignalEffect = false;
88 
89     glScreen = true;
90 }
91 
ResizeScreen(int x,int y)92 void Screen::ResizeScreen(int x , int y)
93 {
94 	static int resX = 320;
95 	static int resY = 240;
96 	if (x != -1 && y != -1)
97 	{
98 		// This is a user resize!
99 		resX = x;
100 		resY = y;
101 	}
102 
103 	if(!isWindowed)
104 	{
105 		SDL_SetWindowFullscreen(m_window, SDL_WINDOW_FULLSCREEN_DESKTOP);
106 	}
107 	else
108 	{
109 		SDL_SetWindowFullscreen(m_window, 0);
110 		if (x != -1 && y != -1)
111 		{
112 			SDL_SetWindowSize(m_window, resX, resY);
113 			SDL_SetWindowPosition(m_window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
114 		}
115 	}
116 	if (stretchMode == 1)
117 	{
118 		int winX, winY;
119 		SDL_GetWindowSize(m_window, &winX, &winY);
120 		SDL_RenderSetLogicalSize(m_renderer, winX, winY);
121 		SDL_RenderSetIntegerScale(m_renderer, SDL_FALSE);
122 	}
123 	else
124 	{
125 		SDL_RenderSetLogicalSize(m_renderer, 320, 240);
126 		SDL_RenderSetIntegerScale(m_renderer, (SDL_bool) (stretchMode == 2));
127 	}
128 	SDL_ShowWindow(m_window);
129 }
130 
GetWindowSize(int * x,int * y)131 void Screen::GetWindowSize(int* x, int* y)
132 {
133 	SDL_GetWindowSize(m_window, x, y);
134 }
135 
UpdateScreen(SDL_Surface * buffer,SDL_Rect * rect)136 void Screen::UpdateScreen(SDL_Surface* buffer, SDL_Rect* rect )
137 {
138     if((buffer == NULL) && (m_screen == NULL) )
139     {
140         return;
141     }
142 
143     if(badSignalEffect)
144     {
145         buffer = ApplyFilter(buffer);
146     }
147 
148 
149     FillRect(m_screen, 0x000);
150     BlitSurfaceStandard(buffer,NULL,m_screen,rect);
151 
152     if(badSignalEffect)
153     {
154         SDL_FreeSurface(buffer);
155     }
156 
157 }
158 
GetFormat()159 const SDL_PixelFormat* Screen::GetFormat()
160 {
161     return m_screen->format;
162 }
163 
FlipScreen()164 void Screen::FlipScreen()
165 {
166 	SDL_UpdateTexture(
167 		m_screenTexture,
168 		NULL,
169 		m_screen->pixels,
170 		m_screen->pitch
171 	);
172 	SDL_RenderCopy(
173 		m_renderer,
174 		m_screenTexture,
175 		isFiltered ? &filterSubrect : NULL,
176 		NULL
177 	);
178 	SDL_RenderPresent(m_renderer);
179 	SDL_RenderClear(m_renderer);
180 	SDL_FillRect(m_screen, NULL, 0x00000000);
181 }
182 
toggleFullScreen()183 void Screen::toggleFullScreen()
184 {
185 	isWindowed = !isWindowed;
186 	ResizeScreen(-1, -1);
187 }
188 
toggleStretchMode()189 void Screen::toggleStretchMode()
190 {
191 	stretchMode = (stretchMode + 1) % 3;
192 	ResizeScreen(-1, -1);
193 }
194 
toggleLinearFilter()195 void Screen::toggleLinearFilter()
196 {
197 	isFiltered = !isFiltered;
198 	SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, isFiltered ? "linear" : "nearest");
199 	SDL_DestroyTexture(m_screenTexture);
200 	m_screenTexture = SDL_CreateTexture(
201 		m_renderer,
202 		SDL_PIXELFORMAT_ARGB8888,
203 		SDL_TEXTUREACCESS_STREAMING,
204 		320,
205 		240
206 	);
207 }
208 
ClearScreen(int colour)209 void Screen::ClearScreen( int colour )
210 {
211     //FillRect(m_screen, colour) ;
212 }
213