1 /**************************************************************
2 
3    grid.cpp - Simple test grid
4 
5    ---------------------------------------------------------
6 
7    Switchres   Modeline generation engine for emulation
8 
9    License     GPL-2.0+
10    Copyright   2010-2021 Chris Kennedy, Antonio Giner,
11                          Alexandre Wodarczyk, Gil Delescluse
12 
13  **************************************************************/
14 
15 #define SDL_MAIN_HANDLED
16 #define NUM_GRIDS 2
17 
18 #include <SDL2/SDL.h>
19 
20 typedef struct grid_display
21 {
22 	int index;
23 	int width;
24 	int height;
25 
26 	SDL_Window *window;
27 	SDL_Renderer *renderer;
28 } GRID_DISPLAY;
29 
30 //============================================================
31 //  draw_grid
32 //============================================================
33 
draw_grid(int num_grid,int width,int height,SDL_Renderer * renderer)34 void draw_grid(int num_grid, int width, int height, SDL_Renderer *renderer)
35 {
36 	// Clean the surface
37 	SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
38 	SDL_RenderClear(renderer);
39 
40 	SDL_Rect rect {0, 0, width, height};
41 
42 	switch (num_grid)
43 	{
44 		case 0:
45 			// 16 x 12 squares
46 			{
47 				// Fill the screen with red
48 				rect = {0, 0, width, height};
49 				SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
50 				SDL_RenderFillRect(renderer, &rect);
51 
52 				// Draw white rectangle
53 				rect = {width / 32, height / 24 , width - width / 16, height - height / 12};
54 				SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
55 				SDL_RenderFillRect(renderer, &rect);
56 
57 				// Draw grid using black rectangles
58 				SDL_Rect rects[16 * 12];
59 
60 				// Set the thickness of horizontal and vertical lines based on the screen resolution
61 				int line_w = round(float(width) / 320.0);
62 				int line_h = round(float(height) / 240.0);
63 				if ( line_w < 1 ) line_w = 1;
64 				if ( line_h < 1 ) line_h = 1;
65 
66 				float rect_w = (width - line_w * 17) / 16.0;
67 				float rect_h = (height - line_h * 13) / 12.0;
68 
69 				for (int i = 0; i < 16; i++)
70 				{
71 					int x_pos1 = ceil(i * rect_w);
72 					int x_pos2 = ceil((i+1) * rect_w);
73 					for (int j = 0; j < 12; j++)
74 					{
75 						int y_pos1 = ceil(j * rect_h);
76 						int y_pos2 = ceil((j+1) * rect_h);
77 						rects[i + j * 16] = {x_pos1 + (i+1) * line_w , y_pos1 + (j+1) * line_h, x_pos2 - x_pos1, y_pos2 - y_pos1};
78 					}
79 				}
80 
81 				SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
82 				SDL_RenderFillRects(renderer, rects, 16 * 12);
83 			}
84 			break;
85 
86 		case 1:
87 			// cps2 grid
88 
89 			// Draw outer rectangle
90 			SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
91 			SDL_RenderDrawRect(renderer, &rect);
92 
93 			for (int i = 0;  i < width / 16; i++)
94 			{
95 				for (int j = 0; j < height / 16; j++)
96 				{
97 					if (i == 0 || j == 0 || i == (width / 16) - 1 || j == (height / 16) - 1)
98 						SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
99 					else
100 						SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
101 
102 					rect = {i * 16, j * 16, 16, 16};
103 					SDL_RenderDrawRect(renderer, &rect);
104 
105 					rect = {i * 16 + 7, j * 16 + 7, 2, 2};
106 					SDL_RenderDrawRect(renderer, &rect);
107 				}
108 			}
109 			break;
110 	}
111 
112 	SDL_RenderPresent(renderer);
113 }
114 
115 //============================================================
116 //  main
117 //============================================================
118 
main(int argc,char ** argv)119 int main(int argc, char **argv)
120 {
121 	SDL_Window* win_array[10] = {};
122 	GRID_DISPLAY display_array[10] = {};
123 	int display_total = 0;
124 
125 	// Initialize SDL
126 	if (SDL_Init(SDL_INIT_VIDEO) != 0)
127 	{
128 		printf("error initializing SDL: %s\n", SDL_GetError());
129 		return 1;
130 	}
131 
132 	// Get target displays
133 	if (argc > 1)
134 	{
135 		// Parse command line for display indexes
136 		int display_index = 0;
137 		int num_displays = SDL_GetNumVideoDisplays();
138 
139 		for (int arg = 1; arg < argc; arg++)
140 		{
141 			sscanf(argv[arg], "%d", &display_index);
142 
143 			if (display_index < 0 || display_index > num_displays - 1)
144 			{
145 				printf("error, bad display_index: %d\n", display_index);
146 				return 1;
147 			}
148 
149 			display_array[display_total].index = display_index;
150 			display_total++;
151 		}
152 	}
153 	else
154 	{
155 		// No display specified, use default
156 		display_array[0].index = 0;
157 		display_total = 1;
158 	}
159 
160 	// Create windows
161 	for (int disp = 0; disp < display_total; disp++)
162 	{
163 		// Get target display size
164 		SDL_DisplayMode dm;
165 		SDL_GetCurrentDisplayMode(display_array[disp].index, &dm);
166 
167 		SDL_ShowCursor(SDL_DISABLE);
168 
169 		display_array[disp].width = dm.w;
170 		display_array[disp].height = dm.h;
171 
172 		// Create window
173 		display_array[disp].window = SDL_CreateWindow("Switchres test grid", SDL_WINDOWPOS_CENTERED_DISPLAY(display_array[disp].index), SDL_WINDOWPOS_CENTERED, dm.w, dm.h, SDL_WINDOW_FULLSCREEN_DESKTOP);
174 
175 		// Required by Window multi-monitor
176 		SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
177 
178 		// Create renderer
179 		display_array[disp].renderer = SDL_CreateRenderer(display_array[disp].window, -1, SDL_RENDERER_ACCELERATED);
180 
181 		// Draw grid
182 		draw_grid(0, display_array[disp].width, display_array[disp].height, display_array[disp].renderer);
183 	}
184 
185 	// Wait for escape key
186 	bool close = false;
187 	int  num_grid = 0;
188 
189 	while (!close)
190 	{
191 		SDL_Event event;
192 
193 		while (SDL_PollEvent(&event))
194 		{
195 			switch (event.type)
196 			{
197 				case SDL_QUIT:
198 					close = true;
199 					break;
200 
201 				case SDL_KEYDOWN:
202 					switch (event.key.keysym.scancode)
203 					{
204 						case SDL_SCANCODE_ESCAPE:
205 							close = true;
206 							break;
207 
208 						case SDL_SCANCODE_TAB:
209 							num_grid ++;
210 							for (int disp = 0; disp < display_total; disp++)
211 								draw_grid(num_grid % NUM_GRIDS, display_array[disp].width, display_array[disp].height, display_array[disp].renderer);
212 							break;
213 
214 						default:
215 							break;
216 					}
217 			}
218 		}
219 	}
220 
221 	// Destroy all windows
222 	for (int disp = 0; disp < display_total; disp++)
223 		SDL_DestroyWindow(display_array[disp].window);
224 
225 	SDL_Quit();
226 
227 	return 0;
228 }
229