summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/viewgeom.h
blob: 49e94ca5c46c0c88142238fc0341c4585e050435 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#ifndef VIEWGEOM_H
#define VIEWGEOM_H

#include "tilecell.h"

struct screen_cell_t
{
    ucs_t glyph;
    unsigned short colour; // TODO: check if this is real colour (8 bit)
    unsigned short flash_colour;
#ifdef USE_TILE
    packed_cell tile;
#endif
};

class crawl_view_buffer
{
public:
    crawl_view_buffer();
    crawl_view_buffer(const coord_def &sz);
    ~crawl_view_buffer();

    coord_def size() const { return m_size; }
    void resize(const coord_def &sz);
    bool empty() const;

    operator screen_cell_t * () { return m_buffer; }
    operator const screen_cell_t * () const { return m_buffer; }
    const crawl_view_buffer & operator = (const crawl_view_buffer &rhs);

    void clear();
    void draw();
private:
    coord_def m_size;
    screen_cell_t *m_buffer;
};

struct crawl_view_geometry
{
public:
    coord_def termp;               // Left-top pos of terminal.
    coord_def termsz;              // Size of the terminal.
    coord_def viewp;               // Left-top pos of viewport.
    coord_def viewsz;              // Size of the viewport (play area).
    coord_def hudp;                // Left-top pos of status area.
    coord_def hudsz;               // Size of the status area.
    coord_def msgp;                // Left-top pos of the message pane.
    coord_def msgsz;               // Size of the message pane.
    coord_def mlistp;              // Left-top pos of the monster list.
    coord_def mlistsz;             // Size of the monster list.

    crawl_view_buffer vbuf;        // Buffer for drawing the main game map.

    coord_def vgrdc;               // What grid pos is at the centre of the view
                                   // usually you.pos().

    coord_def viewhalfsz;

    coord_def glos1, glos2;        // LOS limit grid coords (inclusive)
    coord_def vlos1, vlos2;        // LOS limit viewport coords (inclusive)

    coord_def mousep;              // Where the mouse is.

private:
    coord_def last_player_pos;

public:
    crawl_view_geometry();
    void init_geometry();

    void init_view();
    void set_player_at(const coord_def &c, bool force_centre = false);
    // Set new location, but preserve scrolling as if the player didn't move.
    void shift_player_to(const coord_def &c);
    // Recalculate vlos1 and vlos2.
    void calc_vlos();

    inline coord_def view2grid(const coord_def &pos) const
    {
        return pos - viewhalfsz + vgrdc - coord_def(1, 1);
    }

    inline coord_def grid2view(const coord_def &pos) const
    {
        return pos - vgrdc + viewhalfsz + coord_def(1, 1);
    }

    inline coord_def view2show(const coord_def &pos) const
    {
        return pos - vlos1;
    }

    inline coord_def show2view(const coord_def &pos) const
    {
        return pos + vlos1;
    }

    inline coord_def grid2show(const coord_def &pos) const
    {
        return view2show(grid2view(pos));
    }

    inline coord_def show2grid(const coord_def &pos) const
    {
        return view2grid(show2view(pos));
    }

    inline coord_def screen2view(const coord_def& pos) const
    {
        return pos - viewp + termp;
    }

    inline coord_def view2screen(const coord_def& pos) const
    {
        return pos + viewp - termp;
    }

    inline coord_def screen2grid(const coord_def& pos) const
    {
        return view2grid(screen2view(pos));
    }

    inline coord_def grid2screen(const coord_def& pos) const
    {
        return view2screen(grid2view(pos));
    }

    coord_def glosc() const
    {
        return (glos1 + glos2) / 2;
    }

    bool in_los_bounds_g(const coord_def &c) const
    {
        return c.x >= glos1.x && c.x <= glos2.x
               && c.y >= glos1.y && c.y <= glos2.y;
    }

    bool in_los_bounds_v(const coord_def &c) const
    {
        return in_los_bounds_g(view2grid(c));
    }

    bool in_viewport_v(const coord_def &c) const
    {
        return c.x > 0 && c.y > 0
               && c.x <= viewsz.x && c.y <= viewsz.y;
    }

    bool in_viewport_s(const coord_def &c) const
    {
        return in_viewport_v(screen2view(c));
    }

    bool in_viewport_g(const coord_def &c) const
    {
        return in_viewport_v(grid2view(c));
    }
};

extern crawl_view_geometry crawl_view;

static inline coord_def view2grid(const coord_def &pos)
{
    return crawl_view.view2grid(pos);
}

static inline coord_def grid2view(const coord_def &pos)
{
    return crawl_view.grid2view(pos);
}

static inline coord_def view2show(const coord_def &pos)
{
    return crawl_view.view2show(pos);
}

static inline coord_def show2view(const coord_def &pos)
{
    return crawl_view.show2view(pos);
}

static inline coord_def grid2show(const coord_def &pos)
{
    return crawl_view.grid2show(pos);
}

static inline coord_def show2grid(const coord_def &pos)
{
    return crawl_view.show2grid(pos);
}

static inline bool in_los_bounds_v(const coord_def& pos)
{
    return crawl_view.in_los_bounds_v(pos);
}

static inline bool in_los_bounds_g(const coord_def& pos)
{
    return crawl_view.in_los_bounds_g(pos);
}

#endif