Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Managing SDL1.2/SDL2.0 on Win32 compiling by MSVC #281

Closed
wants to merge 8 commits into from

Conversation

drnovice
Copy link
Contributor

@drnovice drnovice commented Mar 1, 2017

This PR manages full SDL1.2/SDL2.0 support on Windows Systems and MSVC.
PR includes the making screen_magnification and scale_filter as global (extern) variables, to use them out of video driver module.
Press Plus (+) / Minus (-) keys to increase/decrease window size, F11 (or Alt+Enter) to toggle fullscreen. Original ratio resolution will be maintained.
Support to scale2x and hqx scalers are maintaned too.

To correctly compile on MSVC, just read SDL_Win32.txt

* sdl_config/sdl2_config with source.list
* graph_config with generate.vbs
… if not set default is /arch:SSE2, this patch need to specify explicitly WITH_SSE2 parameter into Preprocessor Definitions on MSVC.
@@ -39,7 +39,7 @@ Sub safety_check(sourcelist_file)

' Define regexp
Set regexp = New RegExp
regexp.Pattern = "#|audio/dsp_sdl.c"
regexp.Pattern = "#|audio/dsp_sdl.c|os/thread_sdl.c|video/video_sdl"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some voices to excluded files pattern to integrity check on source.list, since they are repeated by #if directive

#else
os/thread_win32.c
#endif
#endif
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added directives to create correctly MSVC Project files (.vcxproj), already activating SDL1.2/SDL2.0 files on project into solution

@@ -50,7 +50,7 @@
static inline void stage_scale2x(void* dst0, void* dst1, const void* src0, const void* src1, const void* src2, unsigned pixel, unsigned pixel_per_row)
{
switch (pixel) {
#if defined(__x86_64__) || defined(_M_X64) || defined(__SSE2__) || (defined(_M_IX86_FP) && (_M_IX86_FP == 2))
#if defined(__x86_64__) || defined(_M_X64) || defined(__SSE2__) || (defined(_M_IX86_FP) && (_M_IX86_FP == 2) && defined(WITH_SSE2))
Copy link
Contributor Author

@drnovice drnovice Mar 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is strange for my Intel Pentium 2020M processor: on Debug build solution, it can manage SSE2 instructions, but NOT on Release build solution. Of course it's a x64 dual core processor.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pentium 2020M does of course support SSE2.
http://ark.intel.com/products/71142
You may have issues with your compiler.
_M_IX86_FP == 2 means that MSVC options are set to compile with SSE2.
Just set properly MSVC options to compile without SSE2 it you want to

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know it, but remember that if "/arch:" isn't set, default for x64 is SSE2.
I would let this option to make it more explicit.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe you are mixing x64 and x86: x64 CPUs are all SSE2 compatible.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://msdn.microsoft.com/en-us/library/7t5yh4fd.aspx
"/arch:SSE2
Enables the use of SSE2 instructions. This is the default instruction on x86 platforms if no /arch option is specified."
If compiling x86 default is SSE2 on Visual Studio (even on x64 Systems).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I said first if you want to compile without SSE2 code, just use the proper MSVC option :
Because the x86 compiler generates code that uses SSE2 instructions by default, you must specify /arch:IA32 to disable generation of SSE and SSE2 instructions for x86 processors.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SSE2 can't be default if nothing is set, if could be problem with Visual Studio compiler.
Again, since x64 processors support SSE2, if you compile x86, default is _M_IX86_FP == 2, therefore /arch:SSE2
arch_sse2

Trying to use Not Set:
arch_not_set
and see what _M_IX86_FP is valued (equal to 2)...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, I found a really interesting topic:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/e9ee12d7-6d6e-4f80-90a4-35b08f383c3f/illegal-code-generated-by-vc2013-compiler-x64-or-x86-with-sse-instructions?forum=vcgeneral
If you surround scale2x_8_sse2_border(...) with #pragma optimize("", off) / #pragma optimize("", on) problem is fixed.
It seems a real serious bug of MSVC 12 optimizer in Release compiling mode.
If you don't like WITH_SSE2 option, we could do so:

#if defined(_MSC_VER) && _MSC_VER == 1800
#pragma optimize("", off)
#endif
static inline void scale2x_8_sse2_border(scale2x_uint8* dst, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count)
{
[...]
}
#if defined(_MSC_VER) && _MSC_VER == 1800
#pragma optimize("", on)
#endif

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is scale2x_8_sse2_border() the only function affected by the MSVC 2012 bug ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently it seems it was only this function (I've got VS2013 Community, v12 release: I cannot assess if it happens even on VS2012). Anyway I tested all filters (nearest, scale2x & hqx) both debug/release compilations, and no other compiler/optimizer bugs detected.
Now it's good for FreeBSD compiling? Can we accept this PR?

#if defined(_WIN32) && defined(WITH_SDL2)
if (g_scale_filter == FILTER_NEAREST_NEIGHBOR) {
g_mouseX = mouseX / g_screen_magnification;
g_mouseY = mouseY / g_screen_magnification;
Copy link
Contributor Author

@drnovice drnovice Mar 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's necessary since SDL_RenderSetLogicalSize is no more used: it seems can't manage very well cursor pointer x/y limits. Alternatively SDL_RenderCopy is managed by Dst Rect.

if (!Video_Init(screen_magnification, filter)) return false;
#if !(defined(_WIN32) && (defined(WITH_SDL) || defined(WITH_SDL2)))
if (!Video_Init()) return false;
#endif
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since SDL_Init under Windows must be used in same thread of Video_Tick, where inputs are recognized, I added SDL_Init call inside Video_Tick with Win32.

Video_Uninit();
#endif
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for SDL_Quit into Video_Uninit (see comment above)

@@ -1155,9 +1155,14 @@ static bool OpenDune_Init(int screen_magnification, VideoScaleFilter filter, int
return false;
}

g_screen_magnification = screen_magnification;
g_scale_filter = filter;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turned "screen_magnification" and "scale_filter" parameters into global extern variables, to can use them freely inside Video_Tick and Video_Init calls, since we added internal SDL_Init call into Video_Tick thread (see comments about Video_Init).

@miniupnp
Copy link
Contributor

miniupnp commented Mar 3, 2017

well it doesn't even compile... :(
on my FreeBSD machine with sdl2. with SDL1 it's fine

@miniupnp
Copy link
Contributor

miniupnp commented Mar 3, 2017

also, please note that SSE2 is part of the AMD64 / x64 specification

@drnovice
Copy link
Contributor Author

drnovice commented Mar 4, 2017

What is the problem about your compiler on FreeBSD?

@miniupnp
Copy link
Contributor

miniupnp commented Mar 6, 2017

[SRC] Compiling video/video_sdl2.c
/home/nanard/code/git/OpenDUNE/src/video/video_sdl2.c: In function 'Video_DrawScreen_Scale2x':
/home/nanard/code/git/OpenDUNE/src/video/video_sdl2.c:388:2: warning: ISO C90 forbids mixed declarations and code [-Wpedantic]
  int render_width = SCREEN_WIDTH * g_screen_magnification;
  ^
/home/nanard/code/git/OpenDUNE/src/video/video_sdl2.c: In function 'Video_DrawScreen_Hqx':
/home/nanard/code/git/OpenDUNE/src/video/video_sdl2.c:440:2: warning: ISO C90 forbids mixed declarations and code [-Wpedantic]
  int render_width = SCREEN_WIDTH * g_screen_magnification;
  ^
/home/nanard/code/git/OpenDUNE/src/video/video_sdl2.c: In function 'Video_DrawScreen':
/home/nanard/code/git/OpenDUNE/src/video/video_sdl2.c:498:2: warning: ISO C90 forbids mixed declarations and code [-Wpedantic]
  SDL_Rect Src, Dest;
  ^
/home/nanard/code/git/OpenDUNE/src/video/video_sdl2.c: In function 'Video_ToggleFullscreen':
/home/nanard/code/git/OpenDUNE/src/video/video_sdl2.c:545:3: error: expected expression before '/' token
   //SDL_SetWindowFullscreen(s_window, 0);
   ^

@miniupnp
Copy link
Contributor

miniupnp commented Mar 6, 2017

I just had a quick look at video_sdl2.c, I don't understand why you changed the fullscreen part.
The original worked better (tested on FreeBSD 10)

@drnovice
Copy link
Contributor Author

drnovice commented Mar 6, 2017

Errors are due to some // comments (c++ style), warnings are because I declared some int vars after some operations in those functions...
Even if I can't understand why those comments:
[..]\OpenDUNE\src\video\hqx.c(64): // Load image
[..]\OpenDUNE\src\video\hqx.c(73): // Allocate memory for image data
[..]\OpenDUNE\src\video\hqx.c(79): // Init srcData from loaded image
[..]\OpenDUNE\src\video\hqx.c(80): // We want the pixels in BGRA format so that when converting to uint32_t
[..]\OpenDUNE\src\video\hqx.c(81): // we get a RGB value due to little-endianness.
[..]\OpenDUNE\src\video\hqx.c(87): // If big endian we have to swap the byte order to get RGB values
[..]\OpenDUNE\src\video\hqx.c(109): // If big endian we have to swap byte order of destData to get BGRA format
[..]\OpenDUNE\src\video\hqx.c(117): // Copy destData into image
[..]\OpenDUNE\src\video\hqx.c(120): // Free image data
[..]\OpenDUNE\src\video\hqx.c(124): // Save image
[..]\OpenDUNE\src\video\hqx.c(125): ilConvertImage(IL_BGRA, IL_UNSIGNED_BYTE); // No alpha channel
don't cause errors, I'll fix all of them (by /* */ c style of course) with a new commit.

@drnovice
Copy link
Contributor Author

drnovice commented Mar 6, 2017

I changed fullscreen part to let to use Zoom In/Out features (+/- keys), with integer scaler so as to maintain original aspect ratio. What would you clarify? I left some comments into review changes to explain some of logics. You could reply to one of them if something isn't clear or disagree.

} else if (g_scale_filter != FILTER_HQX) {
//SDL_SetPalette(s_gfx_surface, SDL_LOGPAL | SDL_PHYSPAL, colors, 0, 256);
if (!SDL_SetPalette(s_gfx_surface, SDL_LOGPAL | SDL_PHYSPAL, colors, 0, 256)) Warning("SDL_SetPalette() failed while resizing\n");
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Video_Resize function: reset again surface with new dimensions (width & height for their integer scaler multiplier), recalculating palette if filter isn't HQX, otherwise bad side effect about ingame strange colours.

if (!s_fullscreen) {
s_prev_magnification = g_screen_magnification;
g_screen_magnification = 2;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we fix magnification to 2 because of HQX filter breaks surface pixels filling, and using a real fullscreen mode it can get better aspect ratio dimensions from 2x instead of from 3x.

g_screen_magnification = s_prev_magnification;
Video_Resize();
}
#endif
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Workaround: this because of SDL1.2 under Windows, when you Quit the game in fullscreen mode, it freezes. So we first return on windowed mode, then can dispose and close all.

@@ -1,5 +1,8 @@
/** @file src/video/video_sdl2.c SDL 2 video driver. */

#if defined(_WIN32)
#include <stdio.h>
#endif
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Win32 needs stdio.h library.

@@ -154,6 +159,9 @@ static void Video_Mouse_Move(uint16 x, uint16 y)
if (s_mouseMinY != 0 && ry < s_mouseMinY) ry = s_mouseMinY;
if (s_mouseMaxY != 0 && ry > s_mouseMaxY) ry = s_mouseMaxY;

if (ry > SCREEN_HEIGHT * g_screen_magnification - 1) ry = SCREEN_HEIGHT * g_screen_magnification - 1;
if (rx > SCREEN_WIDTH * g_screen_magnification - 1) rx = SCREEN_WIDTH * g_screen_magnification - 1;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This checks mouse x/y limits to bottom and right, for fake Fullscreeen_Desktop mode.


if (err != 0) {
Error("Could not set logical size: %s\n", SDL_GetError());
return false;
}
}*/
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No more necessary RenderSetLogicalSize, since we're using Src/Dst rectangles to RenderCopy, who better manages original aspect ratio.

@drnovice
Copy link
Contributor Author

drnovice commented Mar 9, 2017

First to change PR with the fix, I just wish to know why on Ubuntu 16.04 TLS I can't compile opendune:
#283

@drnovice
Copy link
Contributor Author

drnovice commented Mar 17, 2017

Tried under Ubuntu 14.04 TLS 32bit (to compile SDL1.2, it needs to add -msse option on configure.lib), and Ubuntu 16.04 TLS 64bit (to compile just remove -ansi and -pedantic option, as suggest by @miniupnp: #283)

@miniupnp
Copy link
Contributor

I'm trying to build with SDL under Win32 with MS Visual C++ 2010 but it still includes video_win32.c
how are we supposed to tell to generate.vbs that we are building with SDL or SDL2 ?

@drnovice
Copy link
Contributor Author

Just set:
graph_config = "SDL" or graph_config = "SDL2"
and launch vbs to create correct including from build.

Warning: For SDL2 there is a bug on script creation vbs, line 166, because of double definition in source.list of os/thread_sdl.c (first time it exclude it if not SDL, second time it has to include it if SDL2:

[...]
#if WIN32
	os/error_win32.c
	#if SDL
		os/thread_sdl.c
	#else
		#if SDL2
			os/thread_sdl.c
		#else
			os/thread_win32.c
		#endif
	#endif
	os/readdir_win32.c
#else
[...]

Change:

source_list.Add line, "included"

to:

If source_list.Exists(line) Then
	source_list.Item(line) = "included"
Else
	source_list.Add line, "included"
End If

I'll add vbs fix into this PR.

@drnovice
Copy link
Contributor Author

Ok, tested on VS2010, VS2013, VS2015... no other Linux impacts: Let's accept this PR!

@@ -21,6 +21,9 @@
#include <time.h>
#if defined(WITH_SDL) || defined(WITH_SDL2)
#include <SDL.h>
#ifdef _WIN32
#undef main
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will avoid to have to set /SUBSYSTEM:CONSOLE or /SUBSYSTEM:WINDOW on VS Linker System options...

@miniupnp
Copy link
Contributor

miniupnp commented May 5, 2017

Just set:
graph_config = "SDL" or graph_config = "SDL2"
and launch vbs to create correct including from build.

You mean "edit generate.vbs at line XX, then launch it"
That should be explained in SDL_Win32.txt

@miniupnp
Copy link
Contributor

miniupnp commented May 5, 2017

OK, I have tested with both SDL 1.2.5 and 2.0.5 under Win32 (32bits) with VC++ 2010 Express.

@drnovice
Copy link
Contributor Author

drnovice commented May 8, 2017

Ok I updated SDL_Win32.txt
Tests are ok? Can we accept this PR?

@miniupnp
Copy link
Contributor

miniupnp commented May 9, 2017

I still have issues with Full screen SDL2 FreeBSD.

@drnovice
Copy link
Contributor Author

drnovice commented May 9, 2017

What are exactly fullscreen issues?

@drnovice
Copy link
Contributor Author

Does anyone follow this project yet?!?

@miniupnp miniupnp closed this in a30a8cc Nov 3, 2017
@miniupnp
Copy link
Contributor

miniupnp commented Nov 3, 2017

I picked up changes that broke nothing for other OS.
ie only support for SDL / SDL2 under windows.

@drnovice
Copy link
Contributor Author

drnovice commented Nov 5, 2017

No zoom changes?
I can't understand: what code broke others os?
I tested on Ubuntu 14 32bit (ok), Ubuntu 16 64bit (ok), what is problem on FreeBSD?
Can you show me some screenshot or more info about it?

@miniupnp
Copy link
Contributor

miniupnp commented Nov 5, 2017

I will add zoom change later.

@drnovice
Copy link
Contributor Author

drnovice commented Nov 6, 2017

I'll try to install FreeBSD on vm. What version did you use?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants