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:
		
							parent
							
								
									e4d6dcbcbe
								
							
						
					
					
						commit
						25796b9188
					
				
							
								
								
									
										70
									
								
								src/engine.c
									
									
									
									
									
								
							
							
						
						
									
										70
									
								
								src/engine.c
									
									
									
									
									
								
							@ -3296,11 +3296,75 @@ void Delay_with_active_mouse(int speed)
 | 
			
		||||
  Uint32 end;
 | 
			
		||||
  end = SDL_GetTicks()+speed*10;
 | 
			
		||||
  
 | 
			
		||||
  Need_Timer_events=1;
 | 
			
		||||
  
 | 
			
		||||
  //Need_Timer_events=1;
 | 
			
		||||
  //Activate_timer(10);
 | 
			
		||||
  do
 | 
			
		||||
  {
 | 
			
		||||
    Get_input();
 | 
			
		||||
    now = SDL_GetTicks();
 | 
			
		||||
  } 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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										12
									
								
								src/engine.h
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								src/engine.h
									
									
									
									
									
								
							@ -112,5 +112,17 @@ void Pixel_background(int x_pos, int y_pos, byte color);
 | 
			
		||||
/// Used when hovering the menu palette.
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
/// 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
 | 
			
		||||
 | 
			
		||||
@ -1082,6 +1082,7 @@ void Fill_general(byte fill_color)
 | 
			
		||||
    if (! (Permanent_draw_count&7))
 | 
			
		||||
    {
 | 
			
		||||
      Uint32 now = SDL_GetTicks();
 | 
			
		||||
      SDL_PumpEvents();
 | 
			
		||||
      if (now>= Permanent_draw_next_refresh)
 | 
			
		||||
      {
 | 
			
		||||
        Permanent_draw_next_refresh = now+100;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										24
									
								
								src/input.c
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								src/input.c
									
									
									
									
									
								
							@ -234,11 +234,11 @@ int Move_cursor_with_constraints()
 | 
			
		||||
    // Hide cursor, because even just a click change needs it
 | 
			
		||||
    if (!Mouse_moved)
 | 
			
		||||
    {
 | 
			
		||||
      Mouse_moved++;
 | 
			
		||||
      // Hide cursor (erasing icon and brush on screen
 | 
			
		||||
      // before changing the coordinates.
 | 
			
		||||
      Hide_cursor();
 | 
			
		||||
    }
 | 
			
		||||
    Mouse_moved++;
 | 
			
		||||
    if (Input_new_mouse_X != Mouse_X || Input_new_mouse_Y != Mouse_Y)
 | 
			
		||||
    {
 | 
			
		||||
      Mouse_X=Input_new_mouse_X;
 | 
			
		||||
@ -246,10 +246,9 @@ int Move_cursor_with_constraints()
 | 
			
		||||
    }
 | 
			
		||||
    Mouse_K=Input_new_mouse_K;
 | 
			
		||||
    
 | 
			
		||||
    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.
 | 
			
		||||
      // if (! Operation[Current_operation][Mouse_K_unique]
 | 
			
		||||
      //    [Operation_stack_size].Fast_mouse)
 | 
			
		||||
    if (Mouse_moved > Config.Mouse_merge_movement
 | 
			
		||||
      && !Operation[Current_operation][Mouse_K_unique]
 | 
			
		||||
          [Operation_stack_size].Fast_mouse)
 | 
			
		||||
        feedback=1;
 | 
			
		||||
  }
 | 
			
		||||
  if (mouse_blocked)
 | 
			
		||||
@ -687,11 +686,14 @@ int Get_input(void)
 | 
			
		||||
    Mouse_moved=0;
 | 
			
		||||
    Input_new_mouse_X = Mouse_X;
 | 
			
		||||
    Input_new_mouse_Y = Mouse_Y;
 | 
			
		||||
 | 
			
		||||
    if (!SDL_PollEvent(&event))
 | 
			
		||||
    {
 | 
			
		||||
      SDL_WaitEvent(&event);
 | 
			
		||||
    }
 | 
			
		||||
    // Process as much events as possible without redrawing the screen.
 | 
			
		||||
    // This mostly allows us to merge mouse events for people with an high
 | 
			
		||||
    // 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)
 | 
			
		||||
        {
 | 
			
		||||
@ -783,6 +785,12 @@ int Get_input(void)
 | 
			
		||||
                //DEBUG("Unhandled SDL event number : ",event.type);
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
        if (user_feedback_required)
 | 
			
		||||
          break;
 | 
			
		||||
        // Fetch another event from the queue,
 | 
			
		||||
        // stopping when it's empty.
 | 
			
		||||
        if (!SDL_PollEvent(&event))
 | 
			
		||||
          break;
 | 
			
		||||
    }
 | 
			
		||||
    // Directional controller
 | 
			
		||||
    if (!(Directional_up||Directional_up_right||Directional_right||
 | 
			
		||||
@ -848,7 +856,7 @@ int Get_input(void)
 | 
			
		||||
      Display_cursor();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return 1;//(Mouse_moved!=0) || user_feedback_required;
 | 
			
		||||
    return (Mouse_moved!=0) || user_feedback_required;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Adjust_mouse_sensitivity(word fullscreen)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										27
									
								
								src/main.c
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								src/main.c
									
									
									
									
									
								
							@ -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 -------------------------
 | 
			
		||||
// Returns 0 on fail
 | 
			
		||||
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];
 | 
			
		||||
  T_Gui_skin *gfx;
 | 
			
		||||
  int file_in_command_line;
 | 
			
		||||
  SDL_TimerID tid;
 | 
			
		||||
  static char main_filename [MAX_PATH_CHARACTERS];
 | 
			
		||||
  static char main_directory[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");
 | 
			
		||||
    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);
 | 
			
		||||
  SDL_EnableKeyRepeat(250, 32);
 | 
			
		||||
 | 
			
		||||
@ -1909,7 +1909,8 @@ void Airbrush_1_0(void)
 | 
			
		||||
  Shade_table=Shade_table_left;
 | 
			
		||||
 | 
			
		||||
  Airbrush_next_time = SDL_GetTicks()+Airbrush_delay*10;
 | 
			
		||||
  Need_Timer_events=1;
 | 
			
		||||
  //Need_Timer_events=1;
 | 
			
		||||
  //Activate_timer(10);
 | 
			
		||||
  Airbrush(LEFT_SIDE);
 | 
			
		||||
 | 
			
		||||
  Operation_push(Paintbrush_X);
 | 
			
		||||
@ -1932,7 +1933,8 @@ void Airbrush_2_0(void)
 | 
			
		||||
  Backup();
 | 
			
		||||
  Shade_table=Shade_table_right;
 | 
			
		||||
  Airbrush_next_time = SDL_GetTicks()+Airbrush_delay*10;
 | 
			
		||||
  Need_Timer_events=1;
 | 
			
		||||
  //Need_Timer_events=1;
 | 
			
		||||
  //Activate_timer(10);
 | 
			
		||||
  Airbrush(RIGHT_SIDE);
 | 
			
		||||
 | 
			
		||||
  Operation_push(Paintbrush_X);
 | 
			
		||||
@ -1949,6 +1951,7 @@ void Airbrush_12_2(void)
 | 
			
		||||
//
 | 
			
		||||
{
 | 
			
		||||
  short old_x,old_y;
 | 
			
		||||
  Uint32 now;
 | 
			
		||||
 | 
			
		||||
  Operation_pop(&old_y);
 | 
			
		||||
  Operation_pop(&old_x);
 | 
			
		||||
@ -1960,9 +1963,13 @@ void Airbrush_12_2(void)
 | 
			
		||||
    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);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -1980,7 +1987,8 @@ void Airbrush_0_2(void)
 | 
			
		||||
//
 | 
			
		||||
{
 | 
			
		||||
  Operation_stack_size-=2;
 | 
			
		||||
  Need_Timer_events=0;
 | 
			
		||||
  //Need_Timer_events=0;
 | 
			
		||||
  //Disable_timer();  
 | 
			
		||||
  End_of_modification();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user