Working win32 API implementation with mouse

(no keyboard yet)
This commit is contained in:
Thomas Bernard 2018-06-20 16:34:53 +02:00
parent aa73e76e67
commit 9ac4267468
8 changed files with 304 additions and 3 deletions

View File

@ -171,6 +171,7 @@ enum ERROR_CODES
ERROR_MISSING_DIRECTORY, ///< Unable to return to the original "current directory" on program exit 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_INI_CORRUPTED, ///< File gfx2.ini couldn't be parsed
ERROR_SAVING_INI, ///< Error while writing gfx2.ini 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) ERROR_SORRY_SORRY_SORRY ///< (Page allocation error that shouldn't ever happen, now)
}; };

View File

@ -402,6 +402,8 @@ try_again:
{ {
#if defined(USE_SDL) || defined(USE_SDL2) #if defined(USE_SDL) || defined(USE_SDL2)
Set_mode_SDL(&width, &height,fullscreen); Set_mode_SDL(&width, &height,fullscreen);
#else
GFX2_Set_mode(&width, &height, fullscreen);
#endif #endif
} }

View File

@ -393,6 +393,7 @@ int Handle_mouse_release(SDL_MouseButtonEvent event)
// Keyboard management // Keyboard management
#if defined(USE_SDL) || defined(USE_SDL2)
int Handle_key_press(SDL_KeyboardEvent event) int Handle_key_press(SDL_KeyboardEvent event)
{ {
//Appui sur une touche du clavier //Appui sur une touche du clavier
@ -612,6 +613,7 @@ int Handle_key_release(SDL_KeyboardEvent event)
} }
return Release_control(released_key, modifier); return Release_control(released_key, modifier);
} }
#endif
// Joystick management // 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; 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 // Main input handling function
int Get_input(int sleep_time) int Get_input(int sleep_time)
@ -1125,6 +1131,39 @@ int Get_input(int sleep_time)
// Nothing significant happened // Nothing significant happened
if (sleep_time) if (sleep_time)
SDL_Delay(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 #endif
return 0; return 0;
} }

View File

@ -51,6 +51,8 @@ void Adjust_mouse_sensitivity(word fullscreen);
void Set_mouse_position(void); void Set_mouse_position(void);
int Move_cursor_with_constraints(void);
/// ///
/// This holds the ID of the GUI control that the mouse /// This holds the ID of the GUI control that the mouse
/// is manipulating. The input system will reset it to zero /// is manipulating. The input system will reset it to zero

View File

@ -807,4 +807,8 @@ word Key_for_scancode(word scancode)
{ {
return scancode; return scancode;
} }
word Get_Key_modifiers(void)
{
return 0;
}
#endif #endif

View File

@ -1153,9 +1153,30 @@ void Program_shutdown(void)
// -------------------------- Procédure principale --------------------------- // -------------------------- 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[]) 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)) if(!Init_program(argc,argv))
{ {
Program_shutdown(); Program_shutdown();

View File

@ -32,6 +32,12 @@
#include "struct.h" #include "struct.h"
#include "global.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); byte Get_Screen_pixel(int x, int y);
void Set_Screen_pixel(int x, int y, byte value); void Set_Screen_pixel(int x, int y, byte value);

View File

@ -20,28 +20,235 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with Grafx2; if not, see <http://www.gnu.org/licenses/> along with Grafx2; if not, see <http://www.gnu.org/licenses/>
*/ */
#include <Windows.h>
#include <malloc.h>
#include <stdio.h>
#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf _snprintf
#endif
#include "screen.h" #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) 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) 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) 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) 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) 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) 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) 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) void Clear_border(byte color)