More work on SDL events. Also fixed an issue (very old?) where Grafx2 didn't accurately follow mouse movements when it's very busy, ie when using Continuous Freehand with a large brush or transparency. Now, as long as the setting Merge mouse is zero, all intermediate mouse positions are correctly buffered and played back. From my testing, up to 7 seconds will be memorized.

git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@1568 416bcca6-2ee7-4201-b75f-2eb2f807beb1
This commit is contained in:
Yves Rizoud 2010-08-11 00:07:55 +00:00
parent e4d6dcbcbe
commit 25796b9188
6 changed files with 113 additions and 39 deletions

View File

@ -3296,11 +3296,75 @@ void Delay_with_active_mouse(int speed)
Uint32 end; Uint32 end;
end = SDL_GetTicks()+speed*10; end = SDL_GetTicks()+speed*10;
Need_Timer_events=1; //Need_Timer_events=1;
//Activate_timer(10);
do do
{ {
Get_input(); Get_input();
now = SDL_GetTicks(); now = SDL_GetTicks();
} while (now<end); } while (now<end);
//Need_Timer_events=0;
//Disable_timer();
}
// ======== Timer stuff =========
// This system is installed whenever Grafx2 needs to wait
// for some input, but wants to be called back anyway
// if a specified amount of time has elapsed.
/// Pointer to the current timer, NULL if disabled at the moment.
static SDL_TimerID Current_timer=NULL;
///
/// This callback is meant to post SDL_USEREVENT in the event queue.
/// It is designed especially to "wake" grafx2 in some situations where
/// an animation or something is running, even if the mouse and keyboard
/// are untouched.
Uint32 Push_timer_event(Uint32 i, void* p)
{
//if (Need_Timer_events)
{
SDL_Event event;
SDL_UserEvent user_event;
user_event.type = SDL_USEREVENT;
user_event.code = 0;
user_event.data1 = NULL;
user_event.data2 = NULL;
event.type = SDL_USEREVENT;
event.user = user_event;
SDL_PushEvent(&event);
}
return i;
}
///
/// Activate the timer that runs Push_timer_event()
/// This function can safely be called while it's active.
void Activate_timer(int speed)
{
if (Current_timer)
{
if (SDL_RemoveTimer(Current_timer)==SDL_FALSE)
// Problem ?... keep running.
return;
}
Current_timer = SDL_AddTimer(speed, Push_timer_event, NULL);
}
///
/// Remove the running timer that runs Push_timer_event()
/// This function can safely be called while it's disabled.
void Disable_timer(void)
{
if (Current_timer)
{
if (SDL_RemoveTimer(Current_timer)==SDL_FALSE)
// Problem ?... can't really do anything.
return;
}
Current_timer=NULL;
} }

View File

@ -112,5 +112,17 @@ void Pixel_background(int x_pos, int y_pos, byte color);
/// Used when hovering the menu palette. /// Used when hovering the menu palette.
void Status_print_palette_color(byte color); void Status_print_palette_color(byte color);
/// Puts the user in wait mode for the specified time ( in 1/100s),
/// though the mouse still works.
void Delay_with_active_mouse(int delay); void Delay_with_active_mouse(int delay);
///
/// Activate the timer that runs Push_timer_event()
/// This function can safely be called while it's active.
void Activate_timer(int speed);
///
/// Remove the running timer that runs Push_timer_event()
/// This function can safely be called while it's disabled.
void Disable_timer(void);
#endif #endif

View File

@ -1082,6 +1082,7 @@ void Fill_general(byte fill_color)
if (! (Permanent_draw_count&7)) if (! (Permanent_draw_count&7))
{ {
Uint32 now = SDL_GetTicks(); Uint32 now = SDL_GetTicks();
SDL_PumpEvents();
if (now>= Permanent_draw_next_refresh) if (now>= Permanent_draw_next_refresh)
{ {
Permanent_draw_next_refresh = now+100; Permanent_draw_next_refresh = now+100;

View File

@ -234,11 +234,11 @@ int Move_cursor_with_constraints()
// Hide cursor, because even just a click change needs it // Hide cursor, because even just a click change needs it
if (!Mouse_moved) if (!Mouse_moved)
{ {
Mouse_moved++;
// Hide cursor (erasing icon and brush on screen // Hide cursor (erasing icon and brush on screen
// before changing the coordinates. // before changing the coordinates.
Hide_cursor(); Hide_cursor();
} }
Mouse_moved++;
if (Input_new_mouse_X != Mouse_X || Input_new_mouse_Y != Mouse_Y) if (Input_new_mouse_X != Mouse_X || Input_new_mouse_Y != Mouse_Y)
{ {
Mouse_X=Input_new_mouse_X; Mouse_X=Input_new_mouse_X;
@ -246,10 +246,9 @@ int Move_cursor_with_constraints()
} }
Mouse_K=Input_new_mouse_K; Mouse_K=Input_new_mouse_K;
if (Mouse_moved > Config.Mouse_merge_movement) if (Mouse_moved > Config.Mouse_merge_movement
// TODO : not sure what that was meant to do, but it prevents moving the default cursor when there is no operation. && !Operation[Current_operation][Mouse_K_unique]
// if (! Operation[Current_operation][Mouse_K_unique] [Operation_stack_size].Fast_mouse)
// [Operation_stack_size].Fast_mouse)
feedback=1; feedback=1;
} }
if (mouse_blocked) if (mouse_blocked)
@ -687,11 +686,14 @@ int Get_input(void)
Mouse_moved=0; Mouse_moved=0;
Input_new_mouse_X = Mouse_X; Input_new_mouse_X = Mouse_X;
Input_new_mouse_Y = Mouse_Y; Input_new_mouse_Y = Mouse_Y;
if (!SDL_PollEvent(&event))
{
SDL_WaitEvent(&event);
}
// Process as much events as possible without redrawing the screen. // Process as much events as possible without redrawing the screen.
// This mostly allows us to merge mouse events for people with an high // This mostly allows us to merge mouse events for people with an high
// resolution mouse // resolution mouse
while( (!user_feedback_required) && SDL_WaitEvent(&event)) // Try to cumulate for a full VBL except if there is a required feedback while(1)
{ {
switch(event.type) switch(event.type)
{ {
@ -783,6 +785,12 @@ int Get_input(void)
//DEBUG("Unhandled SDL event number : ",event.type); //DEBUG("Unhandled SDL event number : ",event.type);
break; break;
} }
if (user_feedback_required)
break;
// Fetch another event from the queue,
// stopping when it's empty.
if (!SDL_PollEvent(&event))
break;
} }
// Directional controller // Directional controller
if (!(Directional_up||Directional_up_right||Directional_right|| if (!(Directional_up||Directional_up_right||Directional_right||
@ -848,7 +856,7 @@ int Get_input(void)
Display_cursor(); Display_cursor();
} }
return 1;//(Mouse_moved!=0) || user_feedback_required; return (Mouse_moved!=0) || user_feedback_required;
} }
void Adjust_mouse_sensitivity(word fullscreen) void Adjust_mouse_sensitivity(word fullscreen)

View File

@ -411,27 +411,6 @@ int Analyze_command_line(int argc, char * argv[], char *main_filename, char *mai
} }
Uint32 Push_timer_event(Uint32 i, void* p)
{
if (Need_Timer_events)
{
SDL_Event event;
SDL_UserEvent user_event;
user_event.type = SDL_USEREVENT;
user_event.code = 0;
user_event.data1 = NULL;
user_event.data2 = NULL;
event.type = SDL_USEREVENT;
event.user = user_event;
SDL_PushEvent(&event);
}
return i;
}
// ------------------------ Initialiser le programme ------------------------- // ------------------------ Initialiser le programme -------------------------
// Returns 0 on fail // Returns 0 on fail
int Init_program(int argc,char * argv[]) int Init_program(int argc,char * argv[])
@ -441,7 +420,6 @@ int Init_program(int argc,char * argv[])
static char program_directory[MAX_PATH_CHARACTERS]; static char program_directory[MAX_PATH_CHARACTERS];
T_Gui_skin *gfx; T_Gui_skin *gfx;
int file_in_command_line; int file_in_command_line;
SDL_TimerID tid;
static char main_filename [MAX_PATH_CHARACTERS]; static char main_filename [MAX_PATH_CHARACTERS];
static char main_directory[MAX_PATH_CHARACTERS]; static char main_directory[MAX_PATH_CHARACTERS];
static char spare_filename [MAX_PATH_CHARACTERS]; static char spare_filename [MAX_PATH_CHARACTERS];
@ -545,7 +523,10 @@ int Init_program(int argc,char * argv[])
printf("Couldn't initialize SDL.\n"); printf("Couldn't initialize SDL.\n");
return(0); return(0);
} }
tid = SDL_AddTimer(10, Push_timer_event, NULL);
// Start the timer that will push about 60 "wake up" events
// per second in the event queue.
Activate_timer(16);
Joystick = SDL_JoystickOpen(0); Joystick = SDL_JoystickOpen(0);
SDL_EnableKeyRepeat(250, 32); SDL_EnableKeyRepeat(250, 32);

View File

@ -1909,7 +1909,8 @@ void Airbrush_1_0(void)
Shade_table=Shade_table_left; Shade_table=Shade_table_left;
Airbrush_next_time = SDL_GetTicks()+Airbrush_delay*10; Airbrush_next_time = SDL_GetTicks()+Airbrush_delay*10;
Need_Timer_events=1; //Need_Timer_events=1;
//Activate_timer(10);
Airbrush(LEFT_SIDE); Airbrush(LEFT_SIDE);
Operation_push(Paintbrush_X); Operation_push(Paintbrush_X);
@ -1932,7 +1933,8 @@ void Airbrush_2_0(void)
Backup(); Backup();
Shade_table=Shade_table_right; Shade_table=Shade_table_right;
Airbrush_next_time = SDL_GetTicks()+Airbrush_delay*10; Airbrush_next_time = SDL_GetTicks()+Airbrush_delay*10;
Need_Timer_events=1; //Need_Timer_events=1;
//Activate_timer(10);
Airbrush(RIGHT_SIDE); Airbrush(RIGHT_SIDE);
Operation_push(Paintbrush_X); Operation_push(Paintbrush_X);
@ -1949,6 +1951,7 @@ void Airbrush_12_2(void)
// //
{ {
short old_x,old_y; short old_x,old_y;
Uint32 now;
Operation_pop(&old_y); Operation_pop(&old_y);
Operation_pop(&old_x); Operation_pop(&old_x);
@ -1960,9 +1963,13 @@ void Airbrush_12_2(void)
Display_cursor(); Display_cursor();
} }
if (SDL_GetTicks()>Airbrush_next_time) now=SDL_GetTicks();
if (now>Airbrush_next_time)
{ {
Airbrush_next_time+=Airbrush_delay*10; //Airbrush_next_time+=Airbrush_delay*10;
// Time is now reset, because the += was death spiral
// if drawing took more time than the frequency.
Airbrush_next_time=now+Airbrush_delay*10;
Airbrush(Mouse_K_unique); Airbrush(Mouse_K_unique);
} }
@ -1980,7 +1987,8 @@ void Airbrush_0_2(void)
// //
{ {
Operation_stack_size-=2; Operation_stack_size-=2;
Need_Timer_events=0; //Need_Timer_events=0;
//Disable_timer();
End_of_modification(); End_of_modification();
} }