Last active
August 29, 2015 13:56
-
-
Save asarium/9327053 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Index: code/cmdline/cmdline.cpp | |
=================================================================== | |
--- code/cmdline/cmdline.cpp (revision 10476) | |
+++ code/cmdline/cmdline.cpp (working copy) | |
@@ -190,7 +190,6 @@ | |
{ "-save_render_target", "Save render targets to file", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-save_render_target", }, | |
{ "-debug_window", "Display debug window", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-debug_window", }, | |
{ "-verify_vps", "Spew VP CRCs to vp_crcs.txt", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-verify_vps", }, | |
- { "-nograb", "Don't grab mouse/keyboard in a window", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nograb", }, | |
{ "-reparse_mainhall", "Reparse mainhall.tbl when loading halls", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-reparse_mainhall", }, | |
{ "-profile_frame_time","Profile engine subsystems", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-profile_frame_timings", }, | |
{ "-profile_write_file", "Write profiling information to file", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-profile_write_file", }, | |
@@ -413,7 +412,6 @@ | |
cmdline_parm res_arg("-res", NULL); // Cmdline_lores | |
cmdline_parm verify_vps_arg("-verify_vps", NULL); // Cmdline_verify_vps -- spew VP crcs to vp_crcs.txt | |
cmdline_parm parse_cmdline_only(PARSE_COMMAND_LINE_STRING, NULL); | |
-cmdline_parm no_grab("-nograb", NULL); // Cmdline_no_grab | |
cmdline_parm reparse_mainhall_arg("-reparse_mainhall", NULL); //Cmdline_reparse_mainhall | |
cmdline_parm frame_profile_arg("-profile_frame_time", NULL); //Cmdline_frame_profile | |
cmdline_parm frame_profile_write_file("-profile_write_file", NULL); // Cmdline_profile_write_file | |
@@ -1390,11 +1388,6 @@ | |
Cmdline_no_vsync = 1; | |
} | |
- // no key/mouse grab | |
- if(no_grab.found()){ | |
- Cmdline_no_grab = 1; | |
- } | |
- | |
if ( normal_arg.found() ) { | |
Cmdline_normal = 0; | |
} | |
Index: code/cmdline/cmdline.h | |
=================================================================== | |
--- code/cmdline/cmdline.h (revision 10476) | |
+++ code/cmdline/cmdline.h (working copy) | |
@@ -144,7 +144,6 @@ | |
extern int Cmdline_save_render_targets; | |
extern int Cmdline_debug_window; | |
extern int Cmdline_verify_vps; | |
-extern int Cmdline_no_grab; | |
extern int Cmdline_reparse_mainhall; | |
extern bool Cmdline_frame_profile; | |
extern bool Cmdline_profile_write_file; | |
Index: code/cutscene/movie.cpp | |
=================================================================== | |
--- code/cutscene/movie.cpp (revision 10476) | |
+++ code/cutscene/movie.cpp (working copy) | |
@@ -77,7 +77,6 @@ | |
cutscene_mark_viewable(name); | |
} | |
- extern int Mouse_hidden; | |
extern int Is_standalone; | |
if (Cmdline_nomovies || Is_standalone) | |
@@ -101,7 +100,7 @@ | |
} | |
// clear the screen and hide the mouse cursor | |
- Mouse_hidden++; | |
+ io::mouse::CursorManager::get()->showCursor(false); | |
gr_reset_clip(); | |
gr_set_color(255, 255, 255); | |
gr_set_clear_color(0, 0, 0); | |
@@ -127,7 +126,7 @@ | |
} else { | |
// uh-oh, movie is invalid... Abory, Retry, Fail? | |
mprintf(("MOVIE ERROR: Found invalid movie! (%s)\n", name)); | |
- Mouse_hidden--; // show the mouse cursor! | |
+ io::mouse::CursorManager::get()->showCursor(true); // show the mouse cursor! | |
return false; | |
} | |
} else if (rc == MOVIE_MVE) { | |
@@ -144,13 +143,13 @@ | |
} else { | |
// uh-oh, movie is invalid... Abory, Retry, Fail? | |
mprintf(("MOVIE ERROR: Found invalid movie! (%s)\n", name)); | |
- Mouse_hidden--; // show the mouse cursor! | |
+ io::mouse::CursorManager::get()->showCursor(true); // show the mouse cursor! | |
return false; | |
} | |
} | |
// show the mouse cursor again | |
- Mouse_hidden--; | |
+ io::mouse::CursorManager::get()->showCursor(true); | |
return true; | |
} | |
Index: code/cutscene/oggplayer.cpp | |
=================================================================== | |
--- code/cutscene/oggplayer.cpp (revision 10476) | |
+++ code/cutscene/oggplayer.cpp (working copy) | |
@@ -694,7 +694,6 @@ | |
} | |
} | |
-extern int Mouse_hidden; | |
static void OGG_video_draw(theora_state *tstate) | |
{ | |
yuv_buffer yuv; | |
@@ -716,7 +715,7 @@ | |
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | |
} | |
- Mouse_hidden = 1; | |
+ io::mouse::CursorManager::get()->showCursor(false); | |
gr_flip(); | |
os_poll(); | |
Index: code/fred2/management.cpp | |
=================================================================== | |
--- code/fred2/management.cpp (revision 10476) | |
+++ code/fred2/management.cpp (working copy) | |
@@ -355,7 +355,7 @@ | |
gr_init(GR_OPENGL, 640, 480, 32); | |
- Mouse_hidden = 1; | |
+ io::mouse::CursorManager::get()->showCursor(false); | |
gr_font_init(); // loads up all fonts | |
Index: code/freespace2/freespace.cpp | |
=================================================================== | |
--- code/freespace2/freespace.cpp (revision 10476) | |
+++ code/freespace2/freespace.cpp (working copy) | |
@@ -62,6 +62,7 @@ | |
#include "io/joy_ff.h" | |
#include "io/key.h" | |
#include "io/mouse.h" | |
+#include "io/cursor.h" | |
#include "io/timer.h" | |
#include "jumpnode/jumpnode.h" | |
#include "lab/lab.h" | |
@@ -457,10 +458,6 @@ | |
// Internal function prototypes | |
-void game_maybe_draw_mouse(float frametime); | |
-void init_animating_pointer(); | |
-void load_animating_pointer(char *filename, int dx, int dy); | |
-void unload_animating_pointer(); | |
void game_do_training_checks(); | |
void game_shutdown(void); | |
void game_show_event_debug(float frametime); | |
@@ -1243,7 +1240,7 @@ | |
Assertion( Game_loading_ani.num_frames > 0, "Load Screen animation %s not found, or corrupted. Needs to be an animation with at least 1 frame.", Game_loading_ani.filename ); | |
Game_loading_callback_inited = 1; | |
- Mouse_hidden = 1; | |
+ io::mouse::CursorManager::get()->showCursor(false); | |
framenum = 0; | |
game_busy_callback( game_loading_callback, (COUNT_ESTIMATE/Game_loading_ani.num_frames)+1 ); | |
@@ -1257,8 +1254,8 @@ | |
// Make sure bar shows all the way over. | |
game_loading_callback(COUNT_ESTIMATE); | |
- int real_count = game_busy_callback( NULL ); | |
- Mouse_hidden = 0; | |
+ int real_count = game_busy_callback(NULL); | |
+ io::mouse::CursorManager::get()->showCursor(true); | |
Game_loading_callback_inited = 0; | |
@@ -1990,7 +1987,6 @@ | |
// initialize psnet | |
psnet_init( Multi_options_g.protocol, Multi_options_g.port ); // initialize the networking code | |
- init_animating_pointer(); | |
asteroid_init(); | |
mission_brief_common_init(); // Mark all the briefing structures as empty. | |
@@ -2005,8 +2001,6 @@ | |
pilot_load_pic_list(); | |
pilot_load_squad_pic_list(); | |
- load_animating_pointer(NOX("cursor"), 0, 0); | |
- | |
if(!Cmdline_reparse_mainhall) | |
{ | |
main_hall_table_init(); | |
@@ -2036,6 +2030,10 @@ | |
mprintf(("cfile_init() took %d\n", e1 - s1)); | |
Script_system.RunBytecode(Script_gameinithook); | |
+ // if we are done initializing, start showing the cursor | |
+ io::mouse::CursorManager::get()->showCursor(true); | |
+ | |
+ mouse_set_pos(gr_screen.max_w / 2, gr_screen.max_h / 2); | |
} | |
char transfer_text[128]; | |
@@ -4821,12 +4819,8 @@ | |
last_single_step = game_single_step; | |
- if ((gameseq_get_state() == GS_STATE_GAME_PLAY) && Use_mouse_to_fly){ | |
- Keep_mouse_centered = 1; // force mouse to center of our window (so we don't hit movement limits) | |
- } | |
game_frame(); | |
- Keep_mouse_centered = 0; | |
monitor_update(); // Update monitor variables | |
} | |
@@ -4902,7 +4896,7 @@ | |
k = key_inkey(); | |
// Move the mouse cursor with the joystick. | |
- if (os_foreground() && (!Mouse_hidden) && (Use_joy_mouse) ) { | |
+ if (os_foreground() && !io::mouse::CursorManager::get()->isCursorShown() && (Use_joy_mouse)) { | |
// Move the mouse cursor with the joystick | |
int mx, my, dx, dy; | |
int jx, jy, jz, jr; | |
@@ -6410,7 +6404,7 @@ | |
// do stuff that may need to be done regardless of state | |
void game_do_state_common(int state,int no_networking) | |
{ | |
- game_maybe_draw_mouse(flFrametime); // determine if to draw the mouse this frame | |
+ io::mouse::CursorManager::doFrame(); // determine if to draw the mouse this frame | |
snd_do_frame(); // update sound system | |
event_music_do_frame(); // music needs to play across many states | |
@@ -7115,7 +7109,9 @@ | |
weapon_close(); // free any memory that was allocated for the weapons | |
ship_close(); // free any memory that was allocated for the ships | |
hud_free_scrollback_list();// free space allocated to store hud messages in hud scrollback | |
- unload_animating_pointer();// frees the frames used for the animating mouse pointer | |
+ | |
+ io::mouse::CursorManager::shutdown(); | |
+ | |
mission_campaign_clear(); // clear out the campaign stuff | |
message_mission_close(); // clear loaded table data from message.tbl | |
mission_parse_close(); // clear out any extra memory that may be in use by mission parsing | |
@@ -7194,151 +7190,6 @@ | |
Target_static_looping = -1; | |
} | |
-////////////////////////////////////////////////////////////////////////// | |
-// | |
-// Code for supporting an animating mouse pointer | |
-// | |
-// | |
-////////////////////////////////////////////////////////////////////////// | |
- | |
-typedef struct animating_obj | |
-{ | |
- int first_frame; | |
- int num_frames; | |
- int current_frame; | |
- float time; | |
- float elapsed_time; | |
-} animating_obj; | |
- | |
-static animating_obj Animating_mouse; | |
- | |
-// ---------------------------------------------------------------------------- | |
-// init_animating_pointer() | |
-// | |
-// Called by load_animating_pointer() to ensure the Animating_mouse struct | |
-// gets properly initialized | |
-// | |
-void init_animating_pointer() | |
-{ | |
- Animating_mouse.first_frame = -1; | |
- Animating_mouse.num_frames = 0; | |
- Animating_mouse.current_frame = -1; | |
- Animating_mouse.time = 0.0f; | |
- Animating_mouse.elapsed_time = 0.0f; | |
-} | |
- | |
-// ---------------------------------------------------------------------------- | |
-// load_animating_pointer() | |
-// | |
-// Called at game init to load in the frames for the animating mouse pointer | |
-// | |
-// input: filename => filename of animation file that holds the animation | |
-// | |
-void load_animating_pointer(char *filename, int dx, int dy) | |
-{ | |
- int fps; | |
- animating_obj *am; | |
- | |
- init_animating_pointer(); | |
- | |
-//TEMP | |
- mprintf(("loading animated cursor \"%s\"\n", filename)); | |
- | |
- | |
- am = &Animating_mouse; | |
- am->first_frame = bm_load_animation(filename, &am->num_frames, &fps); | |
- if ( am->first_frame == -1 ) | |
- Error(LOCATION, "Could not load animation %s for the mouse pointer\n", filename); | |
- am->current_frame = 0; | |
- am->time = am->num_frames / i2fl(fps); | |
-} | |
- | |
-// ---------------------------------------------------------------------------- | |
-// unload_animating_pointer() | |
-// | |
-// Called at game shutdown to free the memory used to store the animation frames | |
-// | |
-void unload_animating_pointer() | |
-{ | |
- int i; | |
- animating_obj *am; | |
- | |
- am = &Animating_mouse; | |
- for ( i = 0; i < am->num_frames; i++ ) { | |
- Assert( (am->first_frame+i) >= 0 ); | |
- | |
- // if we are the current cursor then reset to avoid gr_close() issues - taylor | |
- gr_unset_cursor_bitmap(am->first_frame + i); | |
- } | |
- | |
- // this will release all of the frames at once | |
- if (am->first_frame >= 0) | |
- bm_release(am->first_frame); | |
- | |
- am->first_frame = -1; | |
- am->num_frames = 0; | |
- am->current_frame = -1; | |
-} | |
- | |
-// draw the correct frame of the game mouse... called from game_maybe_draw_mouse() | |
-void game_render_mouse(float frametime) | |
-{ | |
- int mx, my; | |
- animating_obj *am; | |
- | |
- // if animating cursor exists, play the next frame | |
- am = &Animating_mouse; | |
- if ( am->first_frame != -1 ) { | |
- mouse_get_pos(&mx, &my); | |
- am->elapsed_time += frametime; | |
- am->current_frame = fl2i( ( am->elapsed_time / am->time ) * (am->num_frames-1) ); | |
- if ( am->current_frame >= am->num_frames ) { | |
- am->current_frame = 0; | |
- am->elapsed_time = 0.0f; | |
- } | |
- gr_set_cursor_bitmap(am->first_frame + am->current_frame); | |
- } | |
-} | |
- | |
-// ---------------------------------------------------------------------------- | |
-// game_maybe_draw_mouse() | |
-// | |
-// determines whether to draw the mouse pointer at all, and what frame of | |
-// animation to use if the mouse is animating | |
-// | |
-// Sets mouse.cpp globals Mouse_hidden and Mouse_moved based on the state of the game. | |
-// | |
-// input: frametime => elapsed frame time in seconds since last call | |
-// | |
-void game_maybe_draw_mouse(float frametime) | |
-{ | |
- int game_state; | |
- | |
- game_state = gameseq_get_state(); | |
- | |
- switch ( game_state ) { | |
- case GS_STATE_GAME_PAUSED: | |
- // case GS_STATE_MULTI_PAUSED: | |
- case GS_STATE_GAME_PLAY: | |
- case GS_STATE_DEATH_DIED: | |
- case GS_STATE_DEATH_BLEW_UP: | |
- if ( popup_active() || popupdead_is_active() ) { | |
- Mouse_hidden = 0; | |
- } else { | |
- Mouse_hidden = 1; | |
- } | |
- break; | |
- | |
- default: | |
- Mouse_hidden = 0; | |
- break; | |
- } // end switch | |
- | |
- if ( !Mouse_hidden ) | |
- game_render_mouse(frametime); | |
- | |
-} | |
- | |
void game_do_training_checks() | |
{ | |
int i, s; | |
Index: code/graphics/2d.cpp | |
=================================================================== | |
--- code/graphics/2d.cpp (revision 10476) | |
+++ code/graphics/2d.cpp (working copy) | |
@@ -31,6 +31,7 @@ | |
#include "parse/scripting.h" | |
#include "gamesequence/gamesequence.h" //WMC - for scripting hooks in gr_flip() | |
#include "io/keycontrol.h" // m!m | |
+#include "io/cursor.h" | |
#if ( SDL_VERSION_ATLEAST(1, 2, 7) ) | |
@@ -37,6 +38,8 @@ | |
#include "SDL_cpuinfo.h" | |
#endif | |
+#include "SDL_surface.h" | |
+ | |
// Includes for different rendering systems | |
#include "graphics/gropengl.h" | |
@@ -55,9 +58,7 @@ | |
char Gr_current_palette_name[128] = NOX("none"); | |
// cursor stuff | |
-int Gr_cursor = -1; | |
-int Web_cursor_bitmap = -1; | |
-int Gr_cursor_size = 32; // default w/h | |
+io::mouse::Cursor* Web_cursor = NULL; | |
int Gr_inited = 0; | |
@@ -573,29 +574,12 @@ | |
gr_set_palette_internal(Gr_current_palette_name, NULL, 0); | |
bm_init(); | |
+ io::mouse::CursorManager::init(); | |
- if (Gr_cursor < 0) { | |
- int w, h; | |
- | |
- Gr_cursor = bm_load( "cursor" ); | |
- | |
- if (Gr_cursor >= 0) { | |
- // get cursor size, so that we can be sure to account for the full thing | |
- // in later cursor hiding code | |
- bm_get_info(Gr_cursor, &w, &h); | |
- Gr_cursor_size = MAX(w, h); | |
- | |
- if (Gr_cursor_size <= 0) { | |
- Int3(); | |
- Gr_cursor_size = 32; | |
- } | |
- } | |
- } | |
- | |
// load the web pointer cursor bitmap | |
- if (Web_cursor_bitmap < 0) { | |
+ if (Web_cursor == NULL) { | |
//if it still hasn't loaded then this usually means that the executable isn't in the same directory as the main fs2 install | |
- if ( (Web_cursor_bitmap = bm_load_animation("cursorweb")) < 0 ) { | |
+ if ( (Web_cursor = io::mouse::CursorManager::get()->loadCursor("cursorweb", true)) == NULL ) { | |
Error(LOCATION, "\nWeb cursor bitmap not found. This is most likely due to one of three reasons:\n" | |
"\t1) You're running FreeSpace Open from somewhere other than your FreeSpace 2 folder;\n" | |
"\t2) You've somehow corrupted your FreeSpace 2 installation, e.g. by modifying or removing the retail VP files;\n" | |
@@ -749,76 +733,6 @@ | |
} | |
} | |
-/** | |
- * Set the bitmap for the mouse pointer. This is called by the animating mouse | |
- * pointer code. | |
- * | |
- * The lock parameter just locks basically disables the next call of this function that doesn't | |
- * have an unlock feature. If adding in more cursor-changing situations, be aware of | |
- * unexpected results. You have been warned. | |
- * | |
- * @todo investigate memory leak of original Gr_cursor bitmap when this is called | |
- */ | |
-void gr_set_cursor_bitmap(int n, int lock) | |
-{ | |
- int w, h; | |
- static int locked = 0; | |
- | |
- if ( !locked || (lock == GR_CURSOR_UNLOCK) ) { | |
- // if we are changing the cursor to something different | |
- // then unload the previous cursor's data - taylor | |
- if ( (Gr_cursor >= 0) && (Gr_cursor != n) ) { | |
- // be sure to avoid changing a cursor which is simply another frame | |
- if ( (GL_cursor_nframes < 2) || ((n - Gr_cursor) >= GL_cursor_nframes) ) { | |
- gr_unset_cursor_bitmap(Gr_cursor); | |
- } | |
- } | |
- | |
- if (n != Gr_cursor) { | |
- // get cursor size, so that we can be sure to account for the full thing | |
- // in later cursor hiding code | |
- bm_get_info(n, &w, &h, NULL, &GL_cursor_nframes); | |
- Assert( GL_cursor_nframes > 0 ); | |
- | |
- Gr_cursor_size = MAX(w, h); | |
- | |
- if (Gr_cursor_size <= 0) { | |
- Int3(); | |
- Gr_cursor_size = 32; | |
- } | |
- } | |
- | |
- Gr_cursor = n; | |
- } else { | |
- locked = 0; | |
- } | |
- | |
- if (lock == GR_CURSOR_LOCK) { | |
- locked = 1; | |
- } | |
-} | |
- | |
-void gr_unset_cursor_bitmap(int n) | |
-{ | |
- if (n < 0) { | |
- return; | |
- } | |
- | |
- if (Gr_cursor == n) { | |
- bm_unload(Gr_cursor); | |
- Gr_cursor = -1; | |
- } | |
-} | |
- | |
-/** | |
- * Retrieves the current bitmap | |
- * Used in UI_GADGET to save/restore current cursor state | |
- */ | |
-int gr_get_cursor_bitmap() | |
-{ | |
- return Gr_cursor; | |
-} | |
- | |
// new bitmap functions | |
void gr_bitmap(int _x, int _y, bool allow_scaling) | |
{ | |
Index: code/graphics/2d.h | |
=================================================================== | |
--- code/graphics/2d.h (revision 10476) | |
+++ code/graphics/2d.h (working copy) | |
@@ -16,6 +16,7 @@ | |
#include "graphics/tmapper.h" | |
#include "cfile/cfile.h" | |
#include "bmpman/bmpman.h" | |
+#include "io/cursor.h" | |
extern const float Default_min_draw_distance; | |
extern const float Default_max_draw_distance; | |
@@ -598,13 +599,7 @@ | |
void gr_get_string_size_win(int *w, int *h, const char *text); | |
void gr_string_win(int x, int y, const char *s ); | |
-// set the mouse pointer to a specific bitmap, used for animating cursors | |
-#define GR_CURSOR_LOCK 1 | |
-#define GR_CURSOR_UNLOCK 2 | |
-void gr_set_cursor_bitmap(int n, int lock = 0); | |
-void gr_unset_cursor_bitmap(int n); | |
-int gr_get_cursor_bitmap(); | |
-extern int Web_cursor_bitmap; | |
+extern io::mouse::Cursor* Web_cursor; | |
// Called by OS when application gets/looses focus | |
extern void gr_activate(int active); | |
Index: code/graphics/grinternal.h | |
=================================================================== | |
--- code/graphics/grinternal.h (revision 10476) | |
+++ code/graphics/grinternal.h (working copy) | |
@@ -16,9 +16,6 @@ | |
#include "globalincs/pstypes.h" // IAM_64BIT | |
#include "globalincs/globals.h" // just in case pstypes.h messed up | |
-extern int Gr_cursor; | |
-extern int Gr_cursor_size; | |
- | |
extern ubyte Gr_original_palette[768]; // The palette | |
extern ubyte Gr_current_palette[768]; | |
Index: code/graphics/gropengl.cpp | |
=================================================================== | |
--- code/graphics/gropengl.cpp (revision 10476) | |
+++ code/graphics/gropengl.cpp (working copy) | |
@@ -78,19 +78,9 @@ | |
static int GL_dump_frame_size = 0; | |
static ubyte *GL_saved_screen = NULL; | |
-static ubyte *GL_saved_mouse_data = NULL; | |
static int GL_saved_screen_id = -1; | |
-static GLuint GL_cursor_pbo = 0; | |
static GLuint GL_screen_pbo = 0; | |
-static int GL_mouse_saved = 0; | |
-static int GL_mouse_saved_x1 = 0; | |
-static int GL_mouse_saved_y1 = 0; | |
-static int GL_mouse_saved_x2 = 0; | |
-static int GL_mouse_saved_y2 = 0; | |
- | |
-void opengl_save_mouse_area(int x, int y, int w, int h); | |
- | |
extern const char *Osreg_title; | |
extern GLfloat GL_anisotropy; | |
@@ -107,7 +97,6 @@ | |
static GLenum GL_read_format = GL_BGRA; | |
-SDL_Renderer *GL_renderer = NULL; | |
SDL_GLContext GL_context = NULL; | |
void opengl_go_fullscreen() | |
@@ -203,17 +192,8 @@ | |
opengl_go_windowed(); | |
else | |
opengl_go_fullscreen(); | |
- | |
- // Check again and if we didn't go fullscreen turn on grabbing if possible | |
- if(!Cmdline_no_grab && !(SDL_GetWindowFlags(os_get_window()) & SDL_WINDOW_FULLSCREEN)) { | |
- SDL_SetRelativeMouseMode(SDL_TRUE); | |
- } | |
} else { | |
opengl_minimize(); | |
- | |
- // let go of mouse/keyboard | |
- if (SDL_GetRelativeMouseMode() == SDL_TRUE) | |
- SDL_SetRelativeMouseMode(SDL_FALSE); | |
} | |
} | |
@@ -234,23 +214,7 @@ | |
gr_reset_clip(); | |
mouse_reset_deltas(); | |
- | |
- GL_mouse_saved = 0; | |
- | |
- if ( mouse_is_visible() ) { | |
- int mx, my; | |
- gr_reset_clip(); | |
- mouse_get_pos( &mx, &my ); | |
- | |
- // opengl_save_mouse_area(mx, my, Gr_cursor_size, Gr_cursor_size); | |
- | |
- if (Gr_cursor != -1 && bm_is_valid(Gr_cursor)) { | |
- gr_set_bitmap(Gr_cursor); | |
- gr_bitmap( mx, my, false); | |
- } | |
- } | |
- | |
SDL_GL_SwapWindow(os_get_window()); | |
opengl_tcache_frame(); | |
@@ -799,70 +763,12 @@ | |
} | |
-void opengl_save_mouse_area(int x, int y, int w, int h) | |
-{ | |
- int cursor_size; | |
- | |
- GL_CHECK_FOR_ERRORS("start of save_mouse_area()"); | |
- | |
- // lazy - taylor | |
- cursor_size = (Gr_cursor_size * Gr_cursor_size); | |
- | |
- // no reason to be bigger than the cursor, should never be smaller | |
- if (w != Gr_cursor_size) | |
- w = Gr_cursor_size; | |
- if (h != Gr_cursor_size) | |
- h = Gr_cursor_size; | |
- | |
- GL_mouse_saved_x1 = x; | |
- GL_mouse_saved_y1 = y; | |
- GL_mouse_saved_x2 = x+w-1; | |
- GL_mouse_saved_y2 = y+h-1; | |
- | |
- CLAMP(GL_mouse_saved_x1, gr_screen.clip_left, gr_screen.clip_right ); | |
- CLAMP(GL_mouse_saved_x2, gr_screen.clip_left, gr_screen.clip_right ); | |
- CLAMP(GL_mouse_saved_y1, gr_screen.clip_top, gr_screen.clip_bottom ); | |
- CLAMP(GL_mouse_saved_y2, gr_screen.clip_top, gr_screen.clip_bottom ); | |
- | |
- GL_state.SetTextureSource(TEXTURE_SOURCE_NO_FILTERING); | |
- GL_state.SetAlphaBlendMode(ALPHA_BLEND_NONE); | |
- GL_state.SetZbufferType(ZBUFFER_TYPE_NONE); | |
- | |
- if ( Use_PBOs ) { | |
- // since this is used a lot, and is pretty small in size, we just create it once and leave it until exit | |
- if (!GL_cursor_pbo) { | |
- vglGenBuffersARB(1, &GL_cursor_pbo); | |
- vglBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_cursor_pbo); | |
- vglBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, cursor_size * 4, NULL, GL_STATIC_READ); | |
- } | |
- | |
- vglBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_cursor_pbo); | |
- glReadBuffer(GL_BACK); | |
- glReadPixels(x, gr_screen.max_h-y-1-h, w, h, GL_read_format, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); | |
- vglBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0); | |
- } else { | |
- // this should really only have to be malloc'd once | |
- if (GL_saved_mouse_data == NULL) | |
- GL_saved_mouse_data = (ubyte*)vm_malloc_q(cursor_size * 4); | |
- | |
- if (GL_saved_mouse_data == NULL) | |
- return; | |
- | |
- glReadBuffer(GL_BACK); | |
- glReadPixels(x, gr_screen.max_h-y-1-h, w, h, GL_read_format, GL_UNSIGNED_INT_8_8_8_8_REV, GL_saved_mouse_data); | |
- } | |
- | |
- GL_CHECK_FOR_ERRORS("end of save_mouse_area()"); | |
- | |
- GL_mouse_saved = 1; | |
-} | |
- | |
int gr_opengl_save_screen() | |
{ | |
int i; | |
ubyte *sptr = NULL, *dptr = NULL; | |
ubyte *opengl_screen_tmp = NULL; | |
- int width_times_pixel, mouse_times_pixel; | |
+ int width_times_pixel; | |
gr_opengl_reset_clip(); | |
@@ -903,7 +809,6 @@ | |
pixels = (GLubyte*)vglMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY); | |
width_times_pixel = (gr_screen.max_w * 4); | |
- mouse_times_pixel = (Gr_cursor_size * 4); | |
sptr = (ubyte *)pixels; | |
dptr = (ubyte *)&GL_saved_screen[gr_screen.max_w * gr_screen.max_h * 4]; | |
@@ -917,24 +822,6 @@ | |
vglUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB); | |
vglBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0); | |
- if (GL_mouse_saved && GL_cursor_pbo) { | |
- vglBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_cursor_pbo); | |
- | |
- pixels = (GLubyte*)vglMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY); | |
- | |
- sptr = (ubyte *)pixels; | |
- dptr = (ubyte *)&GL_saved_screen[(GL_mouse_saved_x1 + GL_mouse_saved_y2 * gr_screen.max_w) * 4]; | |
- | |
- for (i = 0; i < Gr_cursor_size; i++) { | |
- memcpy(dptr, sptr, mouse_times_pixel); | |
- sptr += mouse_times_pixel; | |
- dptr -= width_times_pixel; | |
- } | |
- | |
- vglUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB); | |
- vglBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0); | |
- } | |
- | |
vglDeleteBuffersARB(1, &GL_screen_pbo); | |
GL_screen_pbo = 0; | |
@@ -959,7 +846,6 @@ | |
dptr = (ubyte *)GL_saved_screen; | |
width_times_pixel = (gr_screen.max_w * 4); | |
- mouse_times_pixel = (Gr_cursor_size * 4); | |
for (i = 0; i < gr_screen.max_h; i++) { | |
sptr -= width_times_pixel; | |
@@ -969,17 +855,6 @@ | |
vm_free(opengl_screen_tmp); | |
- if (GL_mouse_saved && GL_saved_mouse_data) { | |
- sptr = (ubyte *)GL_saved_mouse_data; | |
- dptr = (ubyte *)&GL_saved_screen[(GL_mouse_saved_x1 + GL_mouse_saved_y2 * gr_screen.max_w) * 4]; | |
- | |
- for (i = 0; i < Gr_cursor_size; i++) { | |
- memcpy(dptr, sptr, mouse_times_pixel); | |
- sptr += mouse_times_pixel; | |
- dptr -= width_times_pixel; | |
- } | |
- } | |
- | |
GL_saved_screen_id = bm_create(32, gr_screen.max_w, gr_screen.max_h, GL_saved_screen, 0); | |
} | |
@@ -1274,16 +1149,6 @@ | |
// NOTE: This should only ever be called through os_cleanup(), or when switching video APIs | |
void gr_opengl_shutdown() | |
{ | |
- if (GL_cursor_pbo) { | |
- vglDeleteBuffersARB(1, &GL_cursor_pbo); | |
- GL_cursor_pbo = 0; | |
- } | |
- | |
- if (GL_saved_mouse_data != NULL) { | |
- vm_free(GL_saved_mouse_data); | |
- GL_saved_mouse_data = NULL; | |
- } | |
- | |
opengl_tcache_shutdown(); | |
opengl_light_shutdown(); | |
opengl_tnl_shutdown(); | |
@@ -1302,9 +1167,6 @@ | |
GL_original_gamma_ramp = NULL; | |
} | |
- SDL_DestroyRenderer(GL_renderer); | |
- GL_renderer = NULL; | |
- | |
SDL_GL_DeleteContext(GL_context); | |
GL_context = NULL; | |
} | |
@@ -1430,7 +1292,6 @@ | |
} | |
} | |
- int flags = SDL_RENDERER_ACCELERATED; | |
int r = 0, g = 0, b = 0, depth = 0, stencil = 1, db = 1; | |
mprintf((" Initializing SDL video...\n")); | |
@@ -1440,11 +1301,6 @@ | |
return 1; | |
} | |
- // grab mouse/key unless told otherwise, ignore when we are going fullscreen | |
- if ((Cmdline_fullscreen_window || Cmdline_window || os_config_read_uint(NULL, "Fullscreen", 1) == 0) && !Cmdline_no_grab) { | |
- SDL_SetRelativeMouseMode(SDL_TRUE); | |
- } | |
- | |
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, Gr_red.bits); | |
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, Gr_green.bits); | |
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, Gr_blue.bits); | |
@@ -1482,11 +1338,6 @@ | |
os_set_window(window); | |
} | |
- if ((GL_renderer = SDL_CreateRenderer(os_get_window(), -1, flags)) == NULL) { | |
- fprintf(stderr, "Couldn't set up renderer: %s", SDL_GetError()); | |
- return 1; | |
- } | |
- | |
GL_context = SDL_GL_CreateContext(os_get_window()); | |
SDL_GL_MakeCurrent(os_get_window(), GL_context); | |
@@ -1502,11 +1353,6 @@ | |
mprintf((" Actual SDL Video values = R: %d, G: %d, B: %d, depth: %d, stencil: %d, double-buffer: %d, FSAA: %d\n", r, g, b, depth, stencil, db, fsaa_samples)); | |
- SDL_ShowCursor(0); | |
- | |
- /* might as well put this here */ | |
-// SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); | |
- | |
if (GL_original_gamma_ramp != NULL) { | |
SDL_GetWindowGammaRamp( os_get_window(), GL_original_gamma_ramp, (GL_original_gamma_ramp+256), (GL_original_gamma_ramp+512) ); | |
} | |
@@ -1794,7 +1640,6 @@ | |
Gr_current_green = &Gr_green; | |
Gr_current_alpha = &Gr_alpha; | |
- Mouse_hidden++; | |
gr_opengl_reset_clip(); | |
gr_opengl_clear(); | |
gr_opengl_flip(); | |
@@ -1801,7 +1646,6 @@ | |
gr_opengl_clear(); | |
gr_opengl_flip(); | |
gr_opengl_clear(); | |
- Mouse_hidden--; | |
glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &GL_max_elements_vertices); | |
Index: code/io/cursor.cpp | |
=================================================================== | |
--- code/io/cursor.cpp (revision 0) | |
+++ code/io/cursor.cpp (working copy) | |
@@ -0,0 +1,284 @@ | |
+ | |
+#include <cmath> | |
+#include <algorithm> | |
+ | |
+#include "cmdline/cmdline.h" | |
+#include "bmpman/bmpman.h" | |
+#include "io/cursor.h" | |
+#include "io/timer.h" | |
+#include "gamesequence/gamesequence.h" | |
+#include "popup/popup.h" | |
+#include "popup/popupdead.h" | |
+ | |
+namespace | |
+{ | |
+ SDL_Cursor* bitmapToCursor(int bitmapNum) | |
+ { | |
+ Assertion(bm_is_valid(bitmapNum), "%d is no valid bitmap handle!", bitmapNum); | |
+ | |
+ int w; | |
+ int h; | |
+ | |
+ bm_get_info(bitmapNum, &w, &h, NULL, NULL); | |
+ Uint32 rmask, gmask, bmask, amask; | |
+ | |
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN | |
+ rmask = 0x0000ff00; | |
+ gmask = 0x00ff0000; | |
+ bmask = 0xff000000; | |
+ amask = 0x000000ff; | |
+#else | |
+ rmask = 0x00ff0000; | |
+ gmask = 0x0000ff00; | |
+ bmask = 0x000000ff; | |
+ amask = 0xff000000; | |
+#endif | |
+ | |
+ SDL_Surface* bitmapSurface = SDL_CreateRGBSurface(0, w, h, 32, rmask, gmask, bmask, amask); | |
+ SDL_LockSurface(bitmapSurface); | |
+ bitmap* bmp = bm_lock(bitmapNum, 32, BMP_TEX_XPARENT); | |
+ | |
+ memcpy(bitmapSurface->pixels, reinterpret_cast<void*>(bmp->data), w * h * 4); | |
+ | |
+ bm_unlock(bitmapNum); | |
+ SDL_UnlockSurface(bitmapSurface); | |
+ | |
+ // For now set the hot coordinates to the upper left corner | |
+ SDL_Cursor* cursorHandle = SDL_CreateColorCursor(bitmapSurface, 0, 0); | |
+ | |
+ SDL_FreeSurface(bitmapSurface); | |
+ | |
+ return cursorHandle; | |
+ } | |
+} | |
+ | |
+namespace io | |
+{ | |
+ namespace mouse | |
+ { | |
+ void Cursor::addFrame(SDL_Cursor* frame) | |
+ { | |
+ mAnimationFrames.push_back(frame); | |
+ } | |
+ | |
+ void Cursor::setFPS(float fps) | |
+ { | |
+ this->mFps = fps; | |
+ } | |
+ | |
+ void Cursor::enable() | |
+ { | |
+ if (mAnimationFrames.size() > 1) | |
+ { | |
+ // Animated, set the begin and do everything else in setCurrentFrame() | |
+ mBeginTimeStamp = timestamp(); | |
+ mAnimationLength = static_cast<float>(mAnimationFrames.size()) / mFps; | |
+ mLastFrame = static_cast<size_t>(-1); | |
+ } | |
+ else | |
+ { | |
+ // Not animated, just set the first frame | |
+ SDL_SetCursor(mAnimationFrames.front()); | |
+ } | |
+ } | |
+ | |
+ void Cursor::setCurrentFrame() | |
+ { | |
+ if (mAnimationFrames.size() > 1) | |
+ { | |
+ // We are animated, compute the current frame | |
+ float diffSeconds = i2fl(timestamp() - mBeginTimeStamp) / TIMESTAMP_FREQUENCY; | |
+ | |
+ float progress = std::fmod(diffSeconds, mAnimationLength) / mAnimationLength; | |
+ | |
+ // This should round towards zero | |
+ size_t frameIndex = static_cast<size_t>(mAnimationFrames.size() * progress); | |
+ | |
+ Assert(frameIndex < mAnimationFrames.size()); | |
+ | |
+ if (mLastFrame != frameIndex) | |
+ { | |
+ SDL_SetCursor(mAnimationFrames[frameIndex]); | |
+ mLastFrame = frameIndex; | |
+ } | |
+ } | |
+ } | |
+ | |
+ void Cursor::releaseResources() | |
+ { | |
+ SCP_vector<SDL_Cursor*>::iterator iter; | |
+ | |
+ for (iter = mAnimationFrames.begin(); iter != mAnimationFrames.end(); ++iter) | |
+ { | |
+ SDL_FreeCursor(*iter); | |
+ } | |
+ | |
+ mAnimationFrames.clear(); | |
+ } | |
+ | |
+ CursorManager* CursorManager::mSingleton = NULL; | |
+ | |
+ CursorManager::CursorManager() : mCursorShown(true), mCurrentCursor(NULL), mLoadedCursors(SCP_vector<Cursor*>()) | |
+ { | |
+ } | |
+ | |
+ CursorManager::~CursorManager() | |
+ { | |
+ SCP_vector<Cursor*>::iterator iter; | |
+ | |
+ for (iter = mLoadedCursors.begin(); iter != mLoadedCursors.end(); ++iter) | |
+ { | |
+ (*iter)->releaseResources(); | |
+ delete *iter; | |
+ } | |
+ | |
+ mLoadedCursors.clear(); | |
+ } | |
+ | |
+ Cursor* CursorManager::loadCursor(const char* fileName, bool animated) | |
+ { | |
+ int handle; | |
+ int frameNum = 1; | |
+ int fps = 0; | |
+ | |
+ if (animated) | |
+ { | |
+ handle = bm_load_animation(fileName, &frameNum, &fps); | |
+ } | |
+ else | |
+ { | |
+ handle = bm_load(fileName); | |
+ } | |
+ | |
+ if (handle < 0) | |
+ { | |
+ mprintf(("Failed to load cursor bitmap %s!", fileName)); | |
+ return NULL; | |
+ } | |
+ | |
+ Cursor* cursor = this->loadFromBitmap(handle); | |
+ | |
+ bm_release(handle); | |
+ | |
+ return cursor; | |
+ } | |
+ | |
+ Cursor* CursorManager::loadFromBitmap(int bitmapHandle) | |
+ { | |
+ Assertion(bm_is_valid(bitmapHandle), "%d is no valid bitmap handle!", bitmapHandle); | |
+ | |
+ int nframes; | |
+ int fps; | |
+ | |
+ bm_get_info(bitmapHandle, NULL, NULL, NULL, &nframes, &fps); | |
+ | |
+ Cursor* cursor = new Cursor(); | |
+ cursor->setFPS(i2fl(fps)); | |
+ | |
+ for (int i = 0; i < nframes; ++i) | |
+ { | |
+ cursor->addFrame(bitmapToCursor(bitmapHandle + i)); | |
+ } | |
+ | |
+ mLoadedCursors.push_back(cursor); | |
+ | |
+ return cursor; | |
+ } | |
+ | |
+ void CursorManager::setCurrentCursor(Cursor* cursor) | |
+ { | |
+ Assertion(cursor != NULL, "Invalud cursor pointer passed!"); | |
+ Assertion(std::find(mLoadedCursors.begin(), mLoadedCursors.end(), cursor) != mLoadedCursors.end(), | |
+ "Cursor pointer is not in the loaded cursors vector!"); | |
+ | |
+ mCurrentCursor = cursor; | |
+ mCurrentCursor->enable(); | |
+ } | |
+ | |
+ void CursorManager::showCursor(bool show, bool grab) | |
+ { | |
+ if (show == mCursorShown && grab == mMouseGrabbed) | |
+ { | |
+ // Don't bother calling anithing if it's not going to change anything | |
+ return; | |
+ } | |
+ | |
+ if (show) | |
+ { | |
+ // If shown don't grab the mouse | |
+ SDL_SetRelativeMouseMode(SDL_FALSE); | |
+ SDL_ShowCursor(1); | |
+ } | |
+ else | |
+ { | |
+ if (grab) | |
+ { | |
+ SDL_SetRelativeMouseMode(SDL_TRUE); | |
+ } | |
+ else | |
+ { | |
+ SDL_SetRelativeMouseMode(SDL_FALSE); | |
+ } | |
+ | |
+ SDL_ShowCursor(0); | |
+ } | |
+ | |
+ mCursorShown = show; | |
+ mMouseGrabbed = grab; | |
+ } | |
+ | |
+ void CursorManager::init() | |
+ { | |
+ mSingleton = new CursorManager(); | |
+ | |
+ // Load the default cursor and enable it | |
+ Cursor* cursor = mSingleton->loadCursor("cursor", true); | |
+ mSingleton->setCurrentCursor(cursor); | |
+ | |
+ // Hide the cursor initially | |
+ mSingleton->showCursor(false); | |
+ } | |
+ | |
+ void CursorManager::doFrame() | |
+ { | |
+ CursorManager* manager = get(); | |
+ | |
+ int game_state = gameseq_get_state(); | |
+ | |
+ switch (game_state) { | |
+ case GS_STATE_GAME_PAUSED: | |
+ // case GS_STATE_MULTI_PAUSED: | |
+ // Don't grab the mouse when we are pausing, helps with debugging | |
+ manager->showCursor(false); | |
+ break; | |
+ case GS_STATE_GAME_PLAY: | |
+ case GS_STATE_DEATH_DIED: | |
+ case GS_STATE_DEATH_BLEW_UP: | |
+ if (popup_active() || popupdead_is_active()) | |
+ { | |
+ manager->showCursor(true); | |
+ } | |
+ else | |
+ { | |
+ // Always grab the mouse when in gameplay | |
+ manager->showCursor(false, true); | |
+ } | |
+ break; | |
+ | |
+ default: | |
+ manager->showCursor(true); | |
+ break; | |
+ } // end switch | |
+ | |
+ if (manager->mCurrentCursor != NULL && manager->mCursorShown) | |
+ { | |
+ manager->mCurrentCursor->setCurrentFrame(); | |
+ } | |
+ } | |
+ | |
+ void CursorManager::shutdown() | |
+ { | |
+ delete mSingleton; | |
+ } | |
+ } | |
+} | |
Index: code/io/cursor.h | |
=================================================================== | |
--- code/io/cursor.h (revision 0) | |
+++ code/io/cursor.h (working copy) | |
@@ -0,0 +1,169 @@ | |
+ | |
+#ifndef CURSOR_H | |
+#define CURSOR_H | |
+#pragma once | |
+ | |
+#include <SDL_mouse.h> | |
+ | |
+#include "globalincs/pstypes.h" | |
+#include "cmdline/cmdline.h" | |
+ | |
+namespace io | |
+{ | |
+ namespace mouse | |
+ { | |
+ /** | |
+ * @brief A mouse cursor | |
+ * | |
+ * This class holds the SDL_Cursor objects which represent the individual animation frames | |
+ */ | |
+ class Cursor | |
+ { | |
+ private: | |
+ SCP_vector<SDL_Cursor*> mAnimationFrames; //! The individual frames | |
+ | |
+ float mFps; //! The FPS of the animation, unused if only one frame | |
+ | |
+ int mBeginTimeStamp; //! The timestamp when the animation was started, unused when not animated | |
+ float mAnimationLength; //! The length (in seconds) of the animation | |
+ size_t mLastFrame; //! The last frame which was set | |
+ public: | |
+ /** | |
+ * @brief Default constructor | |
+ */ | |
+ Cursor() : mFps(-1.0f), mBeginTimeStamp(-1), mLastFrame(static_cast<size_t>(-1)) {} | |
+ | |
+ /** | |
+ * @brief Adds an animation frame | |
+ * | |
+ * @param frame The cursor frame to add | |
+ */ | |
+ void addFrame(SDL_Cursor* frame); | |
+ | |
+ /** | |
+ * @brief Sets the FPS of the animation | |
+ * Make sure you set this before enabling the cursor so the values are correctly initialized | |
+ * | |
+ * @param fps The frames per second | |
+ */ | |
+ void setFPS(float fps); | |
+ | |
+ /** | |
+ * @brief Called to enable the cursor | |
+ * Either this function sets the cursor directly, or initializes values to #setCurrentFrame() works correctly | |
+ */ | |
+ void enable(); | |
+ | |
+ /** | |
+ * @brief Called to set the correct frame | |
+ */ | |
+ void setCurrentFrame(); | |
+ | |
+ /** | |
+ * Releases all SDL handles | |
+ */ | |
+ void releaseResources(); | |
+ }; | |
+ | |
+ /** | |
+ * @brief Manages the cursor state of the game | |
+ */ | |
+ class CursorManager | |
+ { | |
+ private: | |
+ static CursorManager* mSingleton; //! The singleton manager | |
+ | |
+ SCP_vector<Cursor*> mLoadedCursors; //! A list of loaded cursors | |
+ | |
+ Cursor* mCurrentCursor; //! The current cursor | |
+ | |
+ bool mCursorShown; //! @c true of cursor is shown or @c false if not | |
+ bool mMouseGrabbed; //! @c true if the mouse is grabbed, @c false if not | |
+ | |
+ /** | |
+ * @brief Default constructor | |
+ * | |
+ * This class should not be instantiated outside from this module | |
+ */ | |
+ CursorManager(); | |
+ public: | |
+ | |
+ /** | |
+ * Releases the cursor resources | |
+ */ | |
+ ~CursorManager(); | |
+ | |
+ /** | |
+ * @brief Loads a cursor | |
+ * | |
+ * Loads the specified file name as a cursor, by default this will try to load an animated cursor | |
+ * | |
+ * @param fileName The file name | |
+ * @param animated @c true to also load animated images | |
+ * @return The cursor or @c NULL if the process failed | |
+ */ | |
+ Cursor* loadCursor(const char* fileName, bool animated = true); | |
+ | |
+ /** | |
+ * @brief Loads a cursor from a bitmap handle | |
+ * | |
+ * @param bitmapHandle The bitmap handle, must be a valid handle | |
+ * @return The new cursor | |
+ */ | |
+ Cursor* loadFromBitmap(int bitmapHandle); | |
+ | |
+ /** | |
+ * @brief Sets the current cursor | |
+ * @param cursor The cursor instance to be set, may not be @c NULL | |
+ */ | |
+ void setCurrentCursor(Cursor* cursor); | |
+ | |
+ /** | |
+ * @brief Show or hide the cursor. | |
+ * | |
+ * Optionally @c grab may be specified to grab or not grab the mouse when the cursor is hidden | |
+ * | |
+ * @param show @c true to show @c false to hide | |
+ * @param grab @c true to grab the mouse @c false to disable grabbing | |
+ */ | |
+ void showCursor(bool show, bool grab = false); | |
+ | |
+ /** | |
+ * @brief Specifies if the cursor is shown | |
+ * @return @c true if shown ,@c false otherwise | |
+ */ | |
+ bool isCursorShown() { return mCursorShown; } | |
+ | |
+ /** | |
+ * @brief Gets the current cursor | |
+ * @return The current cursor instance | |
+ */ | |
+ Cursor* getCurrentCursor() { return mCurrentCursor; } | |
+ | |
+ public: | |
+ /** | |
+ * @brief Gets the global CursorManager | |
+ * @return The CursorManager | |
+ */ | |
+ static CursorManager* get() { return mSingleton; } | |
+ | |
+ /** | |
+ * @brief Initializes the Cursor system | |
+ */ | |
+ static void init(); | |
+ | |
+ /** | |
+ * @brief Do a cursor frame | |
+ * This is needed for animated cursors | |
+ */ | |
+ static void doFrame(); | |
+ | |
+ /** | |
+ * @brief Releases cursor resources | |
+ */ | |
+ static void shutdown(); | |
+ }; | |
+ } | |
+} | |
+ | |
+#endif | |
Index: code/io/mouse.cpp | |
=================================================================== | |
--- code/io/mouse.cpp (revision 10476) | |
+++ code/io/mouse.cpp (working copy) | |
@@ -22,11 +22,6 @@ | |
#include "osapi/osapi.h" | |
#include "cmdline/cmdline.h" | |
-#define MOUSE_MODE_DI 0 | |
-#define MOUSE_MODE_WIN 1 | |
- | |
-LOCAL int Mouse_mode = MOUSE_MODE_WIN; | |
- | |
int mouse_inited = 0; | |
LOCAL int Mouse_x; | |
@@ -52,8 +47,6 @@ | |
int Mouse_sensitivity = 4; | |
int Use_mouse_to_fly = 0; | |
-int Mouse_hidden = 0; | |
-int Keep_mouse_centered = 0; | |
void mouse_force_pos(int x, int y); | |
@@ -78,11 +71,6 @@ | |
mouse_flush(); | |
} | |
-int mouse_is_visible() | |
-{ | |
- return !Mouse_hidden; | |
-} | |
- | |
void mouse_close() | |
{ | |
if (!mouse_inited) | |
@@ -107,8 +95,6 @@ | |
Mouse_x = gr_screen.max_w / 2; | |
Mouse_y = gr_screen.max_h / 2; | |
- Mouse_mode = MOUSE_MODE_WIN; | |
- | |
// we do want to make sure that button presses go through event polling though | |
// (should be on by default already, just here as a reminder) | |
SDL_EventState( SDL_MOUSEBUTTONDOWN, SDL_ENABLE ); | |
@@ -179,6 +165,8 @@ | |
SDL_UnlockMutex( mouse_lock ); | |
+ Script_system.SetHookVar("MouseButton", 'i', &mouse_flags); | |
+ | |
//WMC - On Mouse Pressed and On Mouse Released hooks | |
if(set == 1) | |
{ | |
@@ -188,6 +176,8 @@ | |
{ | |
Script_system.RunCondition(CHA_MOUSERELEASED); | |
} | |
+ | |
+ Script_system.RemHookVar("MouseButton"); | |
} | |
void mouse_flush() | |
@@ -341,11 +331,7 @@ | |
void mouse_force_pos(int x, int y) | |
{ | |
if (os_foreground()) { // only mess with windows's mouse if we are in control of it | |
- POINT pnt; | |
- | |
- pnt.x = x; | |
- pnt.y = y; | |
- setWindowMousePos(&pnt); | |
+ SDL_WarpMouseInWindow(os_get_window(), x, y); | |
} | |
} | |
@@ -366,8 +352,10 @@ | |
Mouse_x = x; | |
Mouse_y = y; | |
- Mouse_dx = dx; | |
- Mouse_dy = dy; | |
+ // Add up these delta values so we don't overwrite previous events, | |
+ // should be reset in gr_flip my mouse_reset_deltas() | |
+ Mouse_dx += dx; | |
+ Mouse_dy += dy; | |
if(Mouse_dx != 0 || Mouse_dy != 0) | |
{ | |
@@ -390,16 +378,6 @@ | |
return 0; | |
} | |
- if (Mouse_mode == MOUSE_MODE_DI) { | |
- if (xpos) | |
- *xpos = Mouse_x; | |
- | |
- if (ypos) | |
- *ypos = Mouse_y; | |
- | |
- return mouse_flags; | |
- } | |
- | |
if (!mouse_inited) { | |
*xpos = *ypos = 0; | |
return 0; | |
@@ -445,12 +423,6 @@ | |
void mouse_get_real_pos(int *mx, int *my) | |
{ | |
- if (Mouse_mode == MOUSE_MODE_DI) { | |
- *mx = Mouse_x; | |
- *my = Mouse_y; | |
- return; | |
- } | |
- | |
POINT pnt; | |
getWindowMousePos(&pnt); | |
@@ -460,15 +432,7 @@ | |
void mouse_set_pos(int xpos, int ypos) | |
{ | |
- if (Mouse_mode == MOUSE_MODE_DI) { | |
- Mouse_x = xpos; | |
- Mouse_y = ypos; | |
- return; | |
- } | |
- | |
- if ((xpos != Mouse_x) || (ypos != Mouse_y)){ | |
- mouse_force_pos(xpos, ypos); | |
- } | |
+ mouse_force_pos(xpos, ypos); | |
} | |
// portable routine to get the mouse position, relative | |
@@ -485,12 +449,3 @@ | |
pt->x = x; | |
pt->y = y; | |
} | |
- | |
-// portable routine to get the mouse position, relative | |
-// to current window | |
-void setWindowMousePos(POINT * pt) | |
-{ | |
- Assert(pt != NULL); | |
- | |
- SDL_WarpMouseInWindow(os_get_window(), pt->x, pt->y); | |
-} | |
Index: code/io/mouse.h | |
=================================================================== | |
--- code/io/mouse.h (revision 10476) | |
+++ code/io/mouse.h (working copy) | |
@@ -20,8 +20,6 @@ | |
extern int Mouse_sensitivity; | |
extern int Use_mouse_to_fly; | |
-extern int Mouse_hidden; | |
-extern int Keep_mouse_centered; | |
// call once to init the mouse | |
void mouse_init(); | |
@@ -59,7 +57,6 @@ | |
int mouse_down(int btn); // returns 1 if mouse button btn is down, 0 otherwise | |
float mouse_down_time(int btn); // returns the fraction of time btn has been down since last call | |
-int mouse_is_visible(); // returns 1 if mouse is visible, 0 otherwise | |
void mouse_lost_focus(); | |
void mouse_got_focus(); | |
Index: code/Makefile.am | |
=================================================================== | |
--- code/Makefile.am (revision 10476) | |
+++ code/Makefile.am (working copy) | |
@@ -384,6 +384,8 @@ | |
inetfile/chttpget.h \ | |
inetfile/inetgetfile.cpp \ | |
inetfile/inetgetfile.h \ | |
+ io/cursor.cpp \ | |
+ io/cursor.h \ | |
io/key.cpp \ | |
io/key.h \ | |
io/keycontrol.cpp \ | |
Index: code/missionui/missioncmdbrief.cpp | |
=================================================================== | |
--- code/missionui/missioncmdbrief.cpp (revision 10476) | |
+++ code/missionui/missioncmdbrief.cpp (working copy) | |
@@ -557,9 +557,7 @@ | |
gr_reset_clip(); | |
gr_clear(); | |
- Mouse_hidden++; | |
gr_flip(); | |
- Mouse_hidden--; | |
// first determine which layout to use | |
Uses_scroll_buttons = 1; // assume true | |
Index: code/network/multi_pxo.cpp | |
=================================================================== | |
--- code/network/multi_pxo.cpp (revision 10476) | |
+++ code/network/multi_pxo.cpp (working copy) | |
@@ -1136,8 +1136,8 @@ | |
Multi_pxo_buttons[gr_screen.res][MULTI_PXO_PLIST_DOWN].button.repeatable(1); | |
// set the mouseover cursor if it loaded ok | |
- if (Web_cursor_bitmap > 0) { | |
- Multi_pxo_buttons[gr_screen.res][MULTI_PXO_RANKINGS].button.set_custom_cursor_bmap(Web_cursor_bitmap); | |
+ if (Web_cursor != NULL) { | |
+ Multi_pxo_buttons[gr_screen.res][MULTI_PXO_RANKINGS].button.set_custom_cursor(Web_cursor); | |
} | |
// create the channel list select button and hide it | |
Index: code/osapi/osapi.cpp | |
=================================================================== | |
--- code/osapi/osapi.cpp (revision 10476) | |
+++ code/osapi/osapi.cpp (working copy) | |
@@ -152,7 +152,7 @@ | |
static SDL_Window* main_window = NULL; | |
// os-wide globals | |
-static int fAppActive = 0; | |
+static bool fAppActive = false; | |
static char szWinTitle[128]; | |
static char szWinClass[128]; | |
static int Os_inited = 0; | |
@@ -208,7 +208,7 @@ | |
mprintf((" Initializing SDL...\n")); | |
- if (SDL_Init(0) < 0) | |
+ if (SDL_Init(SDL_INIT_EVENTS) < 0) | |
{ | |
fprintf(stderr, "Couldn't init SDL: %s", SDL_GetError()); | |
mprintf(("Couldn't init SDL: %s", SDL_GetError())); | |
@@ -272,6 +272,7 @@ | |
void os_set_window(SDL_Window* new_handle) | |
{ | |
main_window = new_handle; | |
+ fAppActive = true; | |
} | |
// process management ----------------------------------------------------------------- | |
@@ -359,9 +360,7 @@ | |
} | |
} | |
- if (!Cmdline_no_unfocus_pause) { | |
- gr_activate(fAppActive); | |
- } | |
+ gr_activate(fAppActive); | |
break; | |
} | |
Index: code/parse/lua.cpp | |
=================================================================== | |
--- code/parse/lua.cpp (revision 10476) | |
+++ code/parse/lua.cpp (working copy) | |
@@ -23,6 +23,7 @@ | |
#include "io/key.h" | |
#include "io/mouse.h" | |
#include "io/timer.h" | |
+#include "io/cursor.h" | |
#include "external_dll/trackirpublic.h" | |
#include "jumpnode/jumpnode.h" | |
#include "lighting/lighting.h" | |
@@ -12252,25 +12253,26 @@ | |
ADE_FUNC(setCursorImage, l_Mouse, "Image filename, [LOCK or UNLOCK]", "Sets mouse cursor image, and allows you to lock/unlock the image. (A locked cursor may only be changed with the unlock parameter)", NULL, NULL) | |
{ | |
+ using namespace io::mouse; | |
+ | |
if(!mouse_inited || !Gr_inited) | |
return ADE_RETURN_NIL; | |
char *s = NULL; | |
- enum_h *u = NULL; | |
+ enum_h *u = NULL; // This isn't used anymore | |
+ | |
if(!ade_get_args(L, "s|o", &s, l_Enum.GetPtr(&u))) | |
return ADE_RETURN_NIL; | |
- int ul = 0; | |
- if(u != NULL) | |
+ Cursor* cursor = CursorManager::get()->loadCursor(s); | |
+ | |
+ if (cursor == NULL) | |
{ | |
- if(u->index == LE_LOCK) | |
- ul = GR_CURSOR_LOCK; | |
- else if(u->index == LE_UNLOCK) | |
- ul = GR_CURSOR_UNLOCK; | |
+ LuaError(L, "Failed to load cursor %s!", s); | |
+ return ADE_RETURN_NIL; | |
} | |
- gr_set_cursor_bitmap(bm_load(s), ul); | |
- | |
+ CursorManager::get()->setCurrentCursor(cursor); | |
return ADE_RETURN_NIL; | |
} | |
@@ -12282,10 +12284,7 @@ | |
bool b = false; | |
ade_get_args(L, "b", &b); | |
- if(b) | |
- Mouse_hidden = 1; | |
- else | |
- Mouse_hidden = 0; | |
+ io::mouse::CursorManager::get()->showCursor(!b); | |
return ADE_RETURN_NIL; | |
} | |
Index: code/popup/popup.cpp | |
=================================================================== | |
--- code/popup/popup.cpp (revision 10476) | |
+++ code/popup/popup.cpp (working copy) | |
@@ -517,12 +517,12 @@ | |
} | |
// webcursor setup | |
- if (Web_cursor_bitmap >= 0) { | |
+ if (Web_cursor != NULL) { | |
if (flags & PF_WEB_CURSOR_1) { | |
- Popup_buttons[1].set_custom_cursor_bmap(Web_cursor_bitmap); | |
+ Popup_buttons[1].set_custom_cursor(Web_cursor); | |
} | |
if (flags & PF_WEB_CURSOR_2) { | |
- Popup_buttons[2].set_custom_cursor_bmap(Web_cursor_bitmap); | |
+ Popup_buttons[2].set_custom_cursor(Web_cursor); | |
} | |
} | |
@@ -1007,7 +1007,7 @@ | |
gamesnd_play_iface(SND_POPUP_APPEAR); // play sound when popup appears | |
- Mouse_hidden = 0; | |
+ io::mouse::CursorManager::get()->showCursor(true); | |
Popup_is_active = 1; | |
choice = popup_do( &Popup_info, flags ); | |
@@ -1061,7 +1061,7 @@ | |
gamesnd_play_iface(SND_POPUP_APPEAR); // play sound when popup appears | |
- Mouse_hidden = 0; | |
+ io::mouse::CursorManager::get()->showCursor(true); | |
Popup_is_active = 1; | |
choice = popup_do_with_condition( &Popup_info, flags, condition ); | |
@@ -1106,7 +1106,7 @@ | |
gamesnd_play_iface(SND_POPUP_APPEAR); // play sound when popup appears | |
- Mouse_hidden = 0; | |
+ io::mouse::CursorManager::get()->showCursor(true); | |
Popup_is_active = 1; | |
// if the user cancelled | |
Index: code/ui/button.cpp | |
=================================================================== | |
--- code/ui/button.cpp (revision 10476) | |
+++ code/ui/button.cpp (working copy) | |
@@ -55,8 +55,8 @@ | |
m_flags |= BF_IGNORE_FOCUS; | |
} | |
- custom_cursor_bmap = -1; | |
- previous_cursor_bmap = -1; | |
+ custom_cursor = NULL; | |
+ previous_cursor = NULL; | |
} | |
void UI_BUTTON::destroy() | |
@@ -435,9 +435,10 @@ | |
// set the mouseover cursor | |
if (is_mouse_on()) { | |
- if ((custom_cursor_bmap >= 0) && (previous_cursor_bmap < 0)) { | |
- previous_cursor_bmap = gr_get_cursor_bitmap(); | |
- gr_set_cursor_bitmap(custom_cursor_bmap, GR_CURSOR_LOCK); // set and lock | |
+ if ((custom_cursor != NULL) && (previous_cursor == NULL)) { | |
+ previous_cursor = io::mouse::CursorManager::get()->getCurrentCursor(); | |
+ | |
+ io::mouse::CursorManager::get()->setCurrentCursor(custom_cursor); | |
} | |
} | |
} | |
@@ -444,8 +445,8 @@ | |
void UI_BUTTON::restore_previous_cursor() | |
{ | |
- if (previous_cursor_bmap >= 0) { | |
- gr_set_cursor_bitmap(previous_cursor_bmap, GR_CURSOR_UNLOCK); // restore and unlock | |
- previous_cursor_bmap = -1; | |
+ if (previous_cursor != NULL) { | |
+ io::mouse::CursorManager::get()->setCurrentCursor(previous_cursor); | |
+ previous_cursor = NULL; | |
} | |
} | |
Index: code/ui/ui.h | |
=================================================================== | |
--- code/ui/ui.h (revision 10476) | |
+++ code/ui/ui.h (working copy) | |
@@ -15,6 +15,8 @@ | |
#include "graphics/2d.h" | |
#include "graphics/font.h" | |
+#include "io/cursor.h" | |
+ | |
#define UI_KIND_BUTTON 1 | |
#define UI_KIND_KEYTRAP 2 | |
#define UI_KIND_CHECKBOX 3 | |
@@ -221,8 +223,8 @@ | |
virtual void process(int focus = 0); | |
virtual void destroy(); | |
- int custom_cursor_bmap; // bmap handle of special cursor used on mouseovers | |
- int previous_cursor_bmap; // store old cursor | |
+ io::mouse::Cursor* custom_cursor; // bmap handle of special cursor used on mouseovers | |
+ io::mouse::Cursor* previous_cursor; // store old cursor | |
void maybe_show_custom_cursor(); // call this in process() | |
void restore_previous_cursor(); // called in frame_reset() | |
@@ -245,7 +247,7 @@ | |
void reset_timestamps(); | |
void skip_first_highlight_callback(); | |
void repeatable(int yes); | |
- void set_custom_cursor_bmap(int bmap_id) { custom_cursor_bmap = bmap_id; }; | |
+ void set_custom_cursor(io::mouse::Cursor* cursor) { custom_cursor = cursor; }; | |
}; | |
class UI_KEYTRAP : public UI_GADGET | |
Index: projects/MSVC_2013/code.vcxproj | |
=================================================================== | |
--- projects/MSVC_2013/code.vcxproj (revision 10476) | |
+++ projects/MSVC_2013/code.vcxproj (working copy) | |
@@ -577,6 +577,7 @@ | |
<ClCompile Include="..\..\code\hud\hudtarget.cpp" /> | |
<ClCompile Include="..\..\code\hud\hudtargetbox.cpp" /> | |
<ClCompile Include="..\..\code\hud\hudwingmanstatus.cpp" /> | |
+ <ClCompile Include="..\..\code\io\cursor.cpp" /> | |
<ClCompile Include="..\..\code\io\joy-sdl.cpp" /> | |
<ClCompile Include="..\..\code\io\joy_ff-sdl.cpp" /> | |
<ClCompile Include="..\..\code\io\key.cpp" /> | |
@@ -865,6 +866,7 @@ | |
<ClInclude Include="..\..\code\hud\hudtarget.h" /> | |
<ClInclude Include="..\..\code\hud\hudtargetbox.h" /> | |
<ClInclude Include="..\..\code\hud\hudwingmanstatus.h" /> | |
+ <ClInclude Include="..\..\code\io\cursor.h" /> | |
<ClInclude Include="..\..\code\io\joy.h" /> | |
<ClInclude Include="..\..\code\io\joy_ff.h" /> | |
<ClInclude Include="..\..\code\io\key.h" /> | |
Index: projects/MSVC_2013/code.vcxproj.filters | |
=================================================================== | |
--- projects/MSVC_2013/code.vcxproj.filters (revision 10476) | |
+++ projects/MSVC_2013/code.vcxproj.filters (working copy) | |
@@ -1053,6 +1053,9 @@ | |
<ClCompile Include="..\..\code\io\joy-sdl.cpp"> | |
<Filter>Io</Filter> | |
</ClCompile> | |
+ <ClCompile Include="..\..\code\io\cursor.cpp"> | |
+ <Filter>Io</Filter> | |
+ </ClCompile> | |
</ItemGroup> | |
<ItemGroup> | |
<ClInclude Include="..\..\code\ai\ai.h"> | |
@@ -1853,6 +1856,9 @@ | |
<ClInclude Include="..\..\code\PilotFile\pilotfile.h"> | |
<Filter>PilotFile</Filter> | |
</ClInclude> | |
+ <ClInclude Include="..\..\code\io\cursor.h"> | |
+ <Filter>Io</Filter> | |
+ </ClInclude> | |
</ItemGroup> | |
<ItemGroup> | |
<Library Include="..\..\code\directx\dxguid.lib"> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment