added support for cursors

This commit is contained in:
Dave White 2004-03-31 01:45:31 +00:00
parent 35a30b1fa0
commit 14ed0e4385
13 changed files with 186 additions and 3 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 B

BIN
images/cursors-bw/move.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 B

BIN
images/cursors-bw/wait.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 280 B

115
src/cursor.cpp Normal file
View file

@ -0,0 +1,115 @@
#include "cursor.hpp"
#include "image.hpp"
#include "preferences.hpp"
#include "scoped_resource.hpp"
#include "sdl_utils.hpp"
#include "SDL.h"
#include <vector>
namespace
{
SDL_Cursor* create_cursor(SDL_Surface* surface)
{
const scoped_sdl_surface surf(make_neutral_surface(surface));
if(surf == NULL) {
return NULL;
}
//the width must be a multiple of 8 (SDL requirement)
size_t cursor_width = surf->w;
if((cursor_width%8) != 0) {
cursor_width += 8 - (cursor_width%8);
}
std::vector<Uint8> data((cursor_width*surf->h)/8,0);
std::vector<Uint8> mask(data.size(),0);
//see http://sdldoc.csn.ul.ie/sdlcreatecursor.php for documentation on
//the format that data has to be in to pass to SDL_CreateCursor
surface_lock lock(surf);
const Uint32* const pixels = reinterpret_cast<Uint32*>(lock.pixels());
for(size_t y = 0; y != surf->h; ++y) {
for(size_t x = 0; x != surf->w; ++x) {
Uint8 r,g,b,a;
SDL_GetRGBA(pixels[y*surf->w + x],surf->format,&r,&g,&b,&a);
const size_t index = y*cursor_width + x;
const size_t shift = 7 - (index%8);
const Uint8 trans = (a < 128 ? 0 : 1) << shift;
const Uint8 black = (trans == 0 || (r+g+b)/3 > 128 ? 0 : 1) << shift;
data[index/8] |= black;
mask[index/8] |= trans;
}
}
return SDL_CreateCursor(&data[0],&mask[0],cursor_width,surf->h,0,0);
}
SDL_Cursor* cache[cursor::NUM_CURSORS] = { NULL, NULL, NULL, NULL };
//this array must have members corresponding to cursor::CURSOR_TYPE enum members
const std::string images[cursor::NUM_CURSORS] = { "normal.png", "wait.png", "move.png", "attack.png" };
cursor::CURSOR_TYPE current_cursor = cursor::NUM_CURSORS;
SDL_Cursor* get_cursor(cursor::CURSOR_TYPE type)
{
if(cache[type] == NULL) {
static const std::string prefix = "cursors-bw/";
const scoped_sdl_surface surf(image::get_image(prefix + images[type],image::UNSCALED));
cache[type] = create_cursor(surf);
}
return cache[type];
}
void clear_cache()
{
for(size_t n = 0; n != cursor::NUM_CURSORS; ++n) {
if(cache[n] != NULL) {
SDL_FreeCursor(cache[n]);
cache[n] = NULL;
}
}
}
}
namespace cursor
{
manager::manager()
{
}
manager::~manager()
{
clear_cache();
}
void set(CURSOR_TYPE type)
{
SDL_Cursor* const cursor = get_cursor(type);
if(cursor != NULL) {
SDL_SetCursor(cursor);
current_cursor = type;
}
}
setter::setter(CURSOR_TYPE type) : old_(current_cursor)
{
set(type);
}
setter::~setter()
{
set(old_);
}
}

28
src/cursor.hpp Normal file
View file

@ -0,0 +1,28 @@
#ifndef CURSOR_HPP_INCLUDED
#define CURSOR_HPP_INCLUDED
namespace cursor
{
struct manager
{
manager();
~manager();
};
enum CURSOR_TYPE { NORMAL, WAIT, MOVE, ATTACK, NUM_CURSORS };
void set(CURSOR_TYPE type);
struct setter
{
setter(CURSOR_TYPE type);
~setter();
private:
CURSOR_TYPE old_;
};
}
#endif

View file

@ -17,6 +17,7 @@
#include "actions.hpp"
#include "ai.hpp"
#include "config.hpp"
#include "cursor.hpp"
#include "dialogs.hpp"
#include "display.hpp"
#include "events.hpp"
@ -210,6 +211,7 @@ int play_game(int argc, char** argv)
const preferences::manager prefs_manager;
const image::manager image_manager;
const events::event_context main_event_context;
const cursor::manager cursor_manager;
std::cerr << "initialized managers\n";
@ -336,6 +338,8 @@ int play_game(int argc, char** argv)
<< resolution.second << "x16 is not supported\n";
return 0;
}
cursor::set(cursor::NORMAL);
} else {
video.make_fake();
}

View file

@ -11,6 +11,7 @@
See the COPYING file for more details.
*/
#include "cursor.hpp"
#include "events.hpp"
#include "game_events.hpp"
#include "hotkeys.hpp"
@ -416,6 +417,7 @@ redo_turn:
gui.recalculate_minimap();
const hotkey::basic_handler key_events_handler(gui);
const cursor::setter cursor_setter(cursor::WAIT);
const int start_command = recorder.ncommands();

View file

@ -295,6 +295,24 @@ void turn_info::mouse_motion(const SDL_MouseMotionEvent& event)
gui_.highlight_hex(new_hex);
//see if we should show the normal cursor, the movement cursor, or
//the attack cursor
const unit_map::const_iterator selected_unit = units_.find(selected_hex_);
const unit_map::const_iterator mouseover_unit = units_.find(new_hex);
if(selected_unit != units_.end() && current_paths_.routes.count(new_hex)) {
if(mouseover_unit == units_.end()) {
cursor::set(cursor::MOVE);
} else if(current_team.is_enemy(mouseover_unit->second.side())) {
cursor::set(cursor::ATTACK);
} else {
cursor::set(cursor::NORMAL);
}
} else {
cursor::set(cursor::NORMAL);
}
if(enemy_paths_) {
enemy_paths_ = false;
current_paths_ = paths();

View file

@ -394,6 +394,11 @@ void set_theme(const std::string& theme)
}
}
bool use_colour_cursors()
{
return false;
}
void show_preferences_dialog(display& disp)
{
const events::resize_lock prevent_resizing;

View file

@ -82,6 +82,8 @@ namespace preferences {
void set_ask_delete_saves(bool value);
bool ask_delete_saves();
bool use_colour_cursors();
std::string client_type();
void set_theme(const std::string& theme);

View file

@ -12,6 +12,7 @@
*/
#include "config.hpp"
#include "cursor.hpp"
#include "events.hpp"
#include "font.hpp"
#include "image.hpp"
@ -37,8 +38,15 @@ namespace gui {
bool in_dialog() { return is_in_dialog; }
dialog_manager::dialog_manager() : reset_to(is_in_dialog) {is_in_dialog = true;}
dialog_manager::~dialog_manager() { is_in_dialog = reset_to; }
dialog_manager::dialog_manager() : cursor::setter(cursor::NORMAL), reset_to(is_in_dialog)
{
is_in_dialog = true;
}
dialog_manager::~dialog_manager()
{
is_in_dialog = reset_to;
}
void draw_dialog_frame(int x, int y, int w, int h, display& disp, const std::string* dialog_style)
{

View file

@ -15,6 +15,7 @@
#define SHOW_DIALOG_HPP_INCLUDED
#include "config.hpp"
#include "cursor.hpp"
#include "display.hpp"
#include "network.hpp"
#include "unit.hpp"
@ -30,7 +31,7 @@ namespace gui
bool in_dialog();
struct dialog_manager {
struct dialog_manager : private cursor::setter {
dialog_manager();
~dialog_manager();