Kris Asick
Member #1,424
July 2001
|
I know I'm doing something wrong, but I'm not entirely sure what. Basically, before reading the lengthy amount of code below, here's what I'm trying to do: I'm writing an input wrapper for the Keyboard, Mouse and Joystick.
I'm trying to use my own window instead of Allegro's built-in window.
I still want access to Allegro's graphics handling.
This is what I've accomplished: Keyboard input works fine.
Mouse input works fine but is still incomplete.
Graphics work fine both windowed or fullscreen.
And here's the problem: What am I doing wrong? 1 | // Gemini's DirectInput Testing Program | 2 | | 3 | #define ALLEGRO_NO_MAGIC_MAIN | 4 | | 5 | #define APPLICATION_NAME "Gemini's DirectInput Testing Program" | 6 | #define GEMINI_WND_CLASS "GWNDCLASS1" | 7 | | 8 | #include <allegro.h> | 9 | #include <winalleg.h> | 10 | #include <stdio.h> | 11 | #include <stdlib.h> | 12 | | 13 | #include "g-dinput.h" | 14 | | 15 | HINSTANCE app_hInst; | 16 | HWND app_hWnd; | 17 | | 18 | BITMAP *buffer, *cursor; | 19 | | 20 | | 21 | | 22 | LRESULT CALLBACK G_WindowProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) | 23 | { | 24 | switch (msg) | 25 | { | 26 | case WM_CREATE: return 0; | 27 | case WM_DESTROY: PostQuitMessage(0); return 0; | 28 | case WM_KEYDOWN: case WM_KEYUP: case WM_SYSKEYDOWN: case WM_SYSKEYUP: return 0; | 29 | case WM_PAINT: return 0; | 30 | } | 31 | | 32 | return DefWindowProc(hWnd, msg, wParam, lParam); | 33 | } | 34 | | 35 | void G_HandleWindowsMessages (void) | 36 | { | 37 | MSG msg; | 38 | | 39 | while (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) | 40 | { | 41 | TranslateMessage(&msg); | 42 | DispatchMessage(&msg); | 43 | } | 44 | } | 45 | | 46 | | 47 | | 48 | void Switch_In_Callback (void) | 49 | { | 50 | GDINPUT_ResetThread(); | 51 | } | 52 | | 53 | void g_main (void) | 54 | { | 55 | char s[512]; | 56 | int z, zz, c; | 57 | | 58 | set_color_depth(32); | 59 | set_gfx_mode(GFX_AUTODETECT_WINDOWED,640,480,0,0); | 60 | set_display_switch_callback(SWITCH_IN,Switch_In_Callback); | 61 | | 62 | if (GDINPUT_Initialize(app_hInst,app_hWnd)) | 63 | { | 64 | allegro_message("Unable to start DirectInput driver."); | 65 | exit(1); | 66 | } | 67 | if (GDINPUT_Init_Keyboard()) | 68 | { | 69 | allegro_message("Unable to start DirectInput Keyboard device."); | 70 | GDINPUT_Shutdown(); | 71 | exit(1); | 72 | } | 73 | if (GDINPUT_Init_Mouse(0,0,screen->w-1,screen->h-1,is_windowed_mode())) | 74 | { | 75 | allegro_message("Unable to start DirectInput Mouse device."); | 76 | GDINPUT_Shutdown(); | 77 | exit(1); | 78 | } | 79 | GDINPUT_SetMousePos(screen->w/2,screen->h/2); | 80 | | 81 | buffer = create_bitmap(640,480); | 82 | cursor = create_bitmap(25,25); | 83 | | 84 | clear_to_color(cursor,bitmap_mask_color(cursor)); | 85 | putpixel(cursor,12,12,makecol(255,255,255)); | 86 | line(cursor,1,12,9,12,makecol(255,255,255)); | 87 | line(cursor,15,12,23,12,makecol(255,255,255)); | 88 | line(cursor,12,1,12,9,makecol(255,255,255)); | 89 | line(cursor,12,15,12,23,makecol(255,255,255)); | 90 | for (z = 0; z < 25; z++) for (zz = 0; zz < 25; zz++) | 91 | { | 92 | if (getpixel(cursor,z,zz) == bitmap_mask_color(cursor)) | 93 | { | 94 | if ((getpixel(cursor,z-1,zz) | getpixel(cursor,z+1,zz) | getpixel(cursor,z,zz-1) | 95 | | getpixel(cursor,z,zz+1)) != bitmap_mask_color(cursor)) | 96 | putpixel(cursor,z,zz,0); | 97 | } | 98 | } | 99 | | 100 | do { | 101 | memset(s,0,sizeof(s)); | 102 | clear_bitmap(buffer); | 103 | GDINPUT_Poll_Keyboard(); | 104 | GDINPUT_Poll_Mouse(); | 105 | textprintf_ex(buffer,font,8,8,makecol(255,255,0),-1,"Gemini's DirectInput Wrapper Testing Program"); | 106 | textprintf_ex(buffer,font,16,24,makecol(255,255,255),-1,"Key States"); | 107 | for (z = 0; z < 16; z++) textprintf_ex(buffer,font,40+z*24,40,makecol(255,255,255),-1,"0%x",z); | 108 | for (z = 0; z < 16; z++) textprintf_ex(buffer,font,16,56+z*16,makecol(255,255,255),-1,"%x0",z); | 109 | for (z = 0; z < 256; z++) | 110 | { | 111 | if (gkey[z]) | 112 | { | 113 | c = makecol(255,64,64); | 114 | if (!s[0]) | 115 | sprintf(s,"%s",gkey_name_16[z]); | 116 | else | 117 | sprintf(s,"%s, %s",s,gkey_name_16[z]); | 118 | } | 119 | else | 120 | c = makecol(96,96,96); | 121 | textprintf_ex(buffer,font,40+(z%16)*24,56+(z/16)*16,c,-1,"%2x",gkey[z]); | 122 | } | 123 | if (s[0]) textprintf_ex(buffer,font,8,440,makecol(0,255,255),-1,"Keys: %s",s); | 124 | textprintf_right_ex(buffer,font,640,0,makecol(255,192,0),-1,"%d",gdinput_thread_loop); | 125 | textprintf_right_ex(buffer,font,640,8,makecol(255,0,0),-1,"%d",gdinput_reset_count); | 126 | draw_sprite(buffer,cursor,gmouse.x-12,gmouse.y-12); | 127 | vsync(); | 128 | blit(buffer,screen,0,0,0,0,640,480); | 129 | G_HandleWindowsMessages(); | 130 | Sleep(0); | 131 | } while (!gkey[GKEY_ESCAPE]); | 132 | | 133 | GDINPUT_Shutdown(); | 134 | } | 135 | | 136 | int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) | 137 | { | 138 | WNDCLASSEX g_winClass; | 139 | HWND g_hWnd; | 140 | | 141 | app_hInst = hInstance; | 142 | | 143 | g_winClass.cbSize = sizeof(WNDCLASSEX); | 144 | g_winClass.style = CS_HREDRAW | CS_VREDRAW; | 145 | g_winClass.lpfnWndProc = G_WindowProc; | 146 | g_winClass.cbClsExtra = 0; | 147 | g_winClass.cbWndExtra = 0; | 148 | g_winClass.hInstance = hInstance; | 149 | g_winClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); | 150 | g_winClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); | 151 | g_winClass.hCursor = LoadCursor(NULL, IDC_ARROW); | 152 | g_winClass.hbrBackground = NULL; | 153 | g_winClass.lpszMenuName = NULL; | 154 | g_winClass.lpszClassName = GEMINI_WND_CLASS; | 155 | | 156 | if (!RegisterClassEx(&g_winClass)) return 0; | 157 | | 158 | if (!(g_hWnd = CreateWindowEx(NULL,GEMINI_WND_CLASS,APPLICATION_NAME, | 159 | WS_OVERLAPPEDWINDOW | WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX, | 160 | 100,100,800,600,NULL,NULL,hInstance,NULL))) return 0; | 161 | | 162 | app_hWnd = g_hWnd; | 163 | | 164 | ShowWindow(g_hWnd,SW_SHOWNORMAL); | 165 | SetForegroundWindow(g_hWnd); | 166 | UpdateWindow(g_hWnd); | 167 | | 168 | win_set_window(g_hWnd); | 169 | allegro_init(); | 170 | | 171 | g_main(); | 172 | | 173 | return 0; | 174 | } |
(NOTE: Unrecognized commands probably come from my DirectInput wrapper. Since the problem is likely messaging related I've excluded it, but will post it if no one can find anything wrong with the above code.) Also, just a quick note, many of the messages I'm normally supposed to handle are being handled by Allegro. When you set up a custom window, Allegro still processes its message handler before calling your own, and half of the messages in it still function properly (such as WM_PAINT) even if you're using your own window. (Granted, WM_PAINT for example, only functions if you've called set_gfx_mode().) EDIT: Another quick note: I know the window is bigger than what set_gfx_mode() is being set to. This was to test some stuff and I haven't changed them back yet. EDIT: Yet another quick note: I tried removing all references to my input wrapper and the hang problem persisted, so the problem's definitely not related to that. -------------------------------------------------------------------------------- EDIT (6:52 AM, Several Hours Later): Solved! ...wish I could take the credit. Apparently, as I suspected, I wasn't the first person to try to attempt this. In the "allegro\tests\win" folder is a program called "dxwindow", which features a fully functional, user-created window, working perfectly, using Allegro's graphics system. After comparing the differences between my code and it, the solution was all of one line: set_display_switch_mode(SWITCH_BACKGROUND); My code works flawlessly now, and I have the amount of control I wanted. (Such as being able to manipulate the mouse cursor without loading the Allegro mouse drivers.) In the several hour long process of trying to solve this issue I learned some more about the Windows messaging system and how much Allegro handles on its own, so at least those hours weren't completely lost to frustration. --- Kris Asick (Gemini) --- http://www.pixelships.com
|