diff --git a/src/const.h b/src/const.h
index 7e35f243..a7936ac8 100644
--- a/src/const.h
+++ b/src/const.h
@@ -171,6 +171,7 @@ enum ERROR_CODES
ERROR_MISSING_DIRECTORY, ///< Unable to return to the original "current directory" on program exit
ERROR_INI_CORRUPTED, ///< File gfx2.ini couldn't be parsed
ERROR_SAVING_INI, ///< Error while writing gfx2.ini
+ ERROR_INIT, ///< Program initialization error
ERROR_SORRY_SORRY_SORRY ///< (Page allocation error that shouldn't ever happen, now)
};
diff --git a/src/graph.c b/src/graph.c
index 4639fa05..2f07d496 100644
--- a/src/graph.c
+++ b/src/graph.c
@@ -402,6 +402,8 @@ try_again:
{
#if defined(USE_SDL) || defined(USE_SDL2)
Set_mode_SDL(&width, &height,fullscreen);
+#else
+ GFX2_Set_mode(&width, &height, fullscreen);
#endif
}
diff --git a/src/input.c b/src/input.c
index b3bbf8af..7794df16 100644
--- a/src/input.c
+++ b/src/input.c
@@ -393,6 +393,7 @@ int Handle_mouse_release(SDL_MouseButtonEvent event)
// Keyboard management
+#if defined(USE_SDL) || defined(USE_SDL2)
int Handle_key_press(SDL_KeyboardEvent event)
{
//Appui sur une touche du clavier
@@ -612,6 +613,7 @@ int Handle_key_release(SDL_KeyboardEvent event)
}
return Release_control(released_key, modifier);
}
+#endif
// Joystick management
@@ -876,6 +878,10 @@ int Directional_acceleration(int msec)
return 1+(msec-initial_delay+linear_factor)/linear_factor+(msec-initial_delay)*(msec-initial_delay)/accel_factor;
}
+#if defined(WIN32) && !defined(USE_SDL) && !defined(USE_SDL2)
+int user_feedback_required = 0; // Flag qui indique si on doit arrêter de traiter les évènements ou si on peut enchainer
+#endif
+
// Main input handling function
int Get_input(int sleep_time)
@@ -1125,6 +1131,39 @@ int Get_input(int sleep_time)
// Nothing significant happened
if (sleep_time)
SDL_Delay(sleep_time);
+#elif defined(WIN32)
+ MSG msg;
+
+ user_feedback_required = 0;
+ Key_ANSI = 0;
+ Key_UNICODE = 0;
+ Key = 0;
+ Mouse_moved=0;
+ Input_new_mouse_X = Mouse_X;
+ Input_new_mouse_Y = Mouse_Y;
+ Input_new_mouse_K = Mouse_K;
+
+ Color_cycling();
+ // Commit any pending screen update.
+ // This is done in this function because it's called after reading
+ // some user input.
+ Flush_update();
+
+ while (!user_feedback_required && PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ // If the cursor was moved since last update,
+ // it was erased, so we need to redraw it (with the preview brush)
+ if (Mouse_moved)
+ {
+ Compute_paintbrush_coordinates();
+ Display_cursor();
+ return 1;
+ }
+ if (user_feedback_required)
+ return 1;
#endif
return 0;
}
diff --git a/src/input.h b/src/input.h
index bc47758d..e8b754f8 100644
--- a/src/input.h
+++ b/src/input.h
@@ -51,6 +51,8 @@ void Adjust_mouse_sensitivity(word fullscreen);
void Set_mouse_position(void);
+int Move_cursor_with_constraints(void);
+
///
/// This holds the ID of the GUI control that the mouse
/// is manipulating. The input system will reset it to zero
diff --git a/src/keyboard.c b/src/keyboard.c
index 516e2712..c0781138 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -807,4 +807,8 @@ word Key_for_scancode(word scancode)
{
return scancode;
}
+word Get_Key_modifiers(void)
+{
+ return 0;
+}
#endif
diff --git a/src/main.c b/src/main.c
index 52c403ac..e1a645d1 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1153,9 +1153,30 @@ void Program_shutdown(void)
// -------------------------- Procédure principale ---------------------------
+#if defined(WIN32) && !defined(USE_SDL) && !defined(USE_SDL2)
+int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
+#else
int main(int argc,char * argv[])
+#endif
{
+#if defined(WIN32) && !defined(USE_SDL) && !defined(USE_SDL2)
+ TCHAR ModuleFileName[MAX_PATH];
+ TCHAR ModuleShortFileName[MAX_PATH];
+ int i;
+ int argc = 0;
+ char arg_buffer[4096];
+ char * argv[16] = {NULL};
+ Init_Win32(hInstance, hPrevInstance);
+ GetModuleFileName(NULL, ModuleFileName, MAX_PATH);
+ GetShortPathName(ModuleFileName, ModuleShortFileName, MAX_PATH);
+ argv[argc++] = arg_buffer;
+ for (i = 0; i < sizeof(arg_buffer); i++) {
+ arg_buffer[i] = (char)ModuleShortFileName[i];
+ if (arg_buffer[i] == 0) break;
+ }
+ // TODO : parse command line
+#endif
if(!Init_program(argc,argv))
{
Program_shutdown();
diff --git a/src/screen.h b/src/screen.h
index 6a04fbbf..1242e445 100644
--- a/src/screen.h
+++ b/src/screen.h
@@ -32,6 +32,12 @@
#include "struct.h"
#include "global.h"
+#if defined(WIN32) && !defined(USE_SDL) && !defined(USE_SDL2)
+int Init_Win32(HINSTANCE hInstance, HINSTANCE hPrevInstance);
+#endif
+
+void GFX2_Set_mode(int *width, int *height, int fullscreen);
+
byte Get_Screen_pixel(int x, int y);
void Set_Screen_pixel(int x, int y, byte value);
diff --git a/src/win32screen.c b/src/win32screen.c
index 342ad9a2..cb59457f 100644
--- a/src/win32screen.c
+++ b/src/win32screen.c
@@ -20,28 +20,235 @@
You should have received a copy of the GNU General Public License
along with Grafx2; if not, see
*/
+#include
+#include
+#include
+#if defined(_MSC_VER) && _MSC_VER < 1900
+ #define snprintf _snprintf
+#endif
#include "screen.h"
+#include "errors.h"
+#include "windows.h"
+#include "input.h"
+
+extern int user_feedback_required;
+extern word Input_new_mouse_X;
+extern word Input_new_mouse_Y;
+extern byte Input_new_mouse_K;
+
+static HBITMAP Windows_DIB = NULL;
+static void *Windows_Screen = NULL;
+static int Windows_DIB_width = 0;
+static int Windows_DIB_height = 0;
+static HWND Win32_hwnd = NULL;
+
+static void Win32_Repaint(HWND hwnd)
+{
+ PAINTSTRUCT ps;
+ HDC dc;
+ HDC dc2;
+ HBITMAP old_bmp;
+ RECT rect;
+
+ if (!GetUpdateRect(hwnd, &rect, FALSE)) return;
+ dc = BeginPaint(hwnd, &ps);
+ dc2 = CreateCompatibleDC(dc);
+ old_bmp = (HBITMAP)SelectObject(dc2, Windows_DIB);
+ BitBlt(dc, 0, 0, Windows_DIB_width, Windows_DIB_height,
+ dc2, 0, 0,
+ SRCCOPY);
+ SelectObject(dc2, old_bmp);
+ DeleteDC(dc2);
+ EndPaint(hwnd, &ps);
+}
+
+static LRESULT CALLBACK Win32_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch(uMsg)
+ {
+ case WM_CREATE:
+ break;
+ case WM_CLOSE:
+ Quit_is_required = 1;
+ break;
+ case WM_PAINT:
+ Win32_Repaint(hwnd);
+ return 0;
+ case WM_SETCURSOR:
+ if (LOWORD(lParam) == HTCLIENT)
+ {
+ SetCursor(NULL);
+ return TRUE;
+ }
+ break;
+ case WM_MOUSELEAVE:
+ //ShowCursor(TRUE);
+ return 0;
+ //case WM_MOUSEENTER:
+ //ShowCursor(FALSE);
+ //return 0;
+ case WM_MOUSEMOVE:
+ //Hide_cursor();
+ Input_new_mouse_X = (LOWORD(lParam))/Pixel_width;
+ Input_new_mouse_Y = (HIWORD(lParam))/Pixel_height;
+ //Display_cursor();
+ Move_cursor_with_constraints();
+ user_feedback_required = 1;
+ return 0;
+ case WM_LBUTTONDOWN:
+ Input_new_mouse_K |= 1;
+ Move_cursor_with_constraints();
+ user_feedback_required = 1;
+ return 0;
+ case WM_LBUTTONUP:
+ Input_new_mouse_K &= ~1;
+ Move_cursor_with_constraints();
+ user_feedback_required = 1;
+ return 0;
+// WM_LBUTTONDBLCLK
+ case WM_RBUTTONDOWN:
+ Input_new_mouse_K |= 2;
+ Move_cursor_with_constraints();
+ user_feedback_required = 1;
+ return 0;
+ case WM_RBUTTONUP:
+ Input_new_mouse_K &= ~2;
+ Move_cursor_with_constraints();
+ user_feedback_required = 1;
+ return 0;
+// WM_RBUTTONDBLCLK
+ case WM_MBUTTONDOWN:
+ //case WM_MBUTTONUP:
+ Key = KEY_MOUSEMIDDLE|Get_Key_modifiers();
+ return 0;
+// WM_MBUTTONDBLCLK
+ default:
+ {
+ char msg[256];
+ snprintf(msg, sizeof(msg), "unknown Message : 0x%x", uMsg);
+ Warning(msg);
+ }
+ }
+ return DefWindowProc(hwnd, uMsg, wParam, lParam);
+}
+
+int Init_Win32(HINSTANCE hInstance, HINSTANCE hPrevInstance)
+{
+ WNDCLASS wc;
+ //HINSTANCE hInstance;
+
+ //hInstance = GetModuleHandle(NULL);
+
+ wc.style = 0;
+ wc.lpfnWndProc = Win32_WindowProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = hInstance;
+ wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(100));
+ wc.hCursor = NULL;
+ wc.hbrBackground = 0;
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = TEXT("grafx2");
+ if (!RegisterClass(&wc)) {
+ Warning("RegisterClass failed\n");
+ Error(ERROR_INIT);
+ return 0;
+ }
+ return 1; // OK
+}
+
+static int Video_AllocateDib(int width, int height)
+{
+ BITMAPINFO *bi;
+ HDC dc;
+
+ if (Windows_DIB != NULL) {
+ DeleteObject(Windows_DIB);
+ Windows_DIB = NULL;
+ Windows_Screen = NULL;
+ }
+ bi = (BITMAPINFO*)_alloca(sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256);
+ memset(bi, 0, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256);
+ bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bi->bmiHeader.biWidth = width;
+ bi->bmiHeader.biHeight = -height;
+ bi->bmiHeader.biPlanes = 1;
+ bi->bmiHeader.biBitCount = 8;
+ bi->bmiHeader.biCompression = BI_RGB;
+
+ dc = GetDC(NULL);
+ Windows_DIB = CreateDIBSection(dc, bi, DIB_RGB_COLORS, &Windows_Screen, NULL, 0);
+ if (Windows_DIB == NULL) {
+ Warning("CreateDIBSection failed");
+ return -1;
+ }
+ ReleaseDC(NULL, dc);
+ Windows_DIB_width = width;
+ Windows_DIB_height = height;
+ return 0;
+}
+
+static void Win32_CreateWindow(int width, int height, int fullscreen)
+{
+ DWORD style;
+
+ style = WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU;
+ /* allow window to be resized */
+ style |= WS_THICKFRAME;
+
+ Win32_hwnd = CreateWindow(TEXT("grafx2"), TEXT("grafx2"), style, CW_USEDEFAULT, CW_USEDEFAULT,
+ width, height, NULL, NULL,
+ GetModuleHandle(NULL), NULL);
+ if (Win32_hwnd == NULL) {
+ Error(ERROR_INIT);
+ return;
+ }
+ ShowWindow(Win32_hwnd, SW_SHOWNORMAL);
+}
+
+void GFX2_Set_mode(int *width, int *height, int fullscreen)
+{
+ Video_AllocateDib(*width, *height);
+ Win32_CreateWindow(*width, *height, fullscreen);
+}
byte Get_Screen_pixel(int x, int y)
{
- return 0;
+ if (Windows_Screen == NULL) return 0;
+ return *((byte *)Windows_Screen + x + y * Windows_DIB_width);
}
void Set_Screen_pixel(int x, int y, byte value)
{
+ if (Windows_Screen == NULL) return;
+ *((byte *)Windows_Screen + x + y * Windows_DIB_width) = value;
}
byte* Get_Screen_pixel_ptr(int x, int y)
{
- return NULL;
+ if (Windows_Screen == NULL) return NULL;
+ return (byte *)Windows_Screen + x + y * Windows_DIB_width;
}
void Screen_FillRect(int x, int y, int w, int h, byte color)
{
+ int i;
+ byte * ptr;
+
+ for (i = 0; i < h; i++) {
+ ptr = Get_Screen_pixel_ptr(x, y + i);
+ memset(ptr, color, w);
+ }
}
void Update_rect(short x, short y, unsigned short width, unsigned short height)
{
+ RECT rect;
+ rect.left = x;
+ rect.top = y;
+ rect.right = x + width;
+ rect.bottom = y + height;
+ InvalidateRect(Win32_hwnd, &rect, TRUE);
}
void Flush_update(void)
@@ -54,7 +261,26 @@ void Update_status_line(short char_pos, short width)
int SetPalette(const T_Components * colors, int firstcolor, int ncolors)
{
- return 0;
+ int i;
+ RGBQUAD rgb[256];
+ HDC dc;
+ HDC dc2;
+ HBITMAP old_bmp;
+
+ for (i = 0; i < ncolors; i++) {
+ rgb[i].rgbRed = colors[i].R;
+ rgb[i].rgbGreen = colors[i].G;
+ rgb[i].rgbBlue = colors[i].B;
+ }
+
+ dc = GetDC(Win32_hwnd);
+ dc2 = CreateCompatibleDC(dc);
+ old_bmp = SelectObject(dc2, Windows_DIB);
+ SetDIBColorTable(dc2, firstcolor, ncolors, rgb);
+ SelectObject(dc2, old_bmp);
+ DeleteDC(dc2);
+ ReleaseDC(Win32_hwnd, dc);
+ return 1;
}
void Clear_border(byte color)