1
// -*- Mode: C++; tab-width:2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2
// vi:tw=80:et:ts=2:sts=2
4
// -----------------------------------------------------------------------
6
// This file is part of RLVM, a RealLive virtual machine clone.
8
// -----------------------------------------------------------------------
10
// Copyright (C) 2008 Elliot Glaysher
12
// This program is free software; you can redistribute it and/or modify
13
// it under the terms of the GNU General Public License as published by
14
// the Free Software Foundation; either version 3 of the License, or
15
// (at your option) any later version.
17
// This program is distributed in the hope that it will be useful,
18
// but WITHOUT ANY WARRANTY; without even the implied warranty of
19
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
// GNU General Public License for more details.
22
// You should have received a copy of the GNU General Public License
23
// along with this program; if not, write to the Free Software
24
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
26
// -----------------------------------------------------------------------
28
#include "systems/base/mouse_cursor.h"
30
#include "systems/base/event_system.h"
31
#include "systems/base/graphics_system.h"
32
#include "systems/base/surface.h"
33
#include "systems/base/system.h"
35
const int CURSOR_SIZE_INT = 32;
36
const Size CURSOR_SIZE = Size(CURSOR_SIZE_INT, CURSOR_SIZE_INT);
38
const int HOTSPOTMASK_X_OFFSET = 8;
39
const int HOTSPOTMASK_Y_OFFSET = 48;
41
// -----------------------------------------------------------------------
42
// MouseCursor (public)
43
// -----------------------------------------------------------------------
44
MouseCursor::MouseCursor(System& system,
45
const std::shared_ptr<const Surface>& cursor_surface,
48
: cursor_surface_(cursor_surface),
50
frame_speed_(speed / count_),
52
last_time_frame_incremented_(system.event().GetTicks()) {
53
// TODO(erg): Technically, each frame might have a hotspot. In practice, the
54
// hotspot is in the same place every frame.
57
int alphaR, alphaG, alphaB;
58
cursor_surface->GetDCPixel(Point(0, 0), alphaR, alphaG, alphaB);
60
cursor_surface_ = cursor_surface->ClipAsColorMask(
61
Rect(8, 8, Size(CURSOR_SIZE_INT * count_, CURSOR_SIZE_INT)),
67
MouseCursor::~MouseCursor() {}
69
void MouseCursor::Execute(System& system) {
70
unsigned int cur_time = system.event().GetTicks();
72
if (last_time_frame_incremented_ + frame_speed_ < cur_time) {
73
last_time_frame_incremented_ = cur_time;
75
system.graphics().MarkScreenAsDirty(GUT_MOUSE_MOTION);
78
if (current_frame_ >= count_)
83
void MouseCursor::RenderHotspotAt(const Point& mouse_location) {
84
Point render_point = GetTopLeftForHotspotAt(mouse_location);
85
cursor_surface_->RenderToScreen(
86
Rect(current_frame_ * CURSOR_SIZE_INT, 0, CURSOR_SIZE),
87
Rect(render_point, CURSOR_SIZE));
90
// -----------------------------------------------------------------------
91
// MouseCursor (private)
92
// -----------------------------------------------------------------------
94
Point MouseCursor::GetTopLeftForHotspotAt(const Point& mouse_location) {
95
return mouse_location - hotspot_offset_;
98
void MouseCursor::FindHotspot() {
101
for (int x = HOTSPOTMASK_X_OFFSET; x < HOTSPOTMASK_X_OFFSET + CURSOR_SIZE_INT;
103
for (int y = HOTSPOTMASK_Y_OFFSET;
104
y < HOTSPOTMASK_Y_OFFSET + CURSOR_SIZE_INT;
106
cursor_surface_->GetDCPixel(Point(x, y), r, g, b);
108
if (r == 255 && g == 255 && b == 255) {
110
Size(x - HOTSPOTMASK_X_OFFSET, y - HOTSPOTMASK_Y_OFFSET);