Working win32 API implementation with mouse
(no keyboard yet)
This commit is contained in:
		
							parent
							
								
									aa73e76e67
								
							
						
					
					
						commit
						9ac4267468
					
				@ -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)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										39
									
								
								src/input.c
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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 
 | 
			
		||||
 | 
			
		||||
@ -807,4 +807,8 @@ word Key_for_scancode(word scancode)
 | 
			
		||||
{
 | 
			
		||||
  return scancode;
 | 
			
		||||
}
 | 
			
		||||
word Get_Key_modifiers(void)
 | 
			
		||||
{
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										21
									
								
								src/main.c
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								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();
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
 | 
			
		||||
@ -20,28 +20,235 @@
 | 
			
		||||
    You should have received a copy of the GNU General Public License
 | 
			
		||||
    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 "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)
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user