| 1 | /* |
|---|
| 2 | * Copyright (c) 2004-2006 Kazunori "jagarl" Ueno |
|---|
| 3 | * All rights reserved. |
|---|
| 4 | * |
|---|
| 5 | * Redistribution and use in source and binary forms, with or without |
|---|
| 6 | * modification, are permitted provided that the following conditions |
|---|
| 7 | * are met: |
|---|
| 8 | * 1. Redistributions of source code must retain the above copyright |
|---|
| 9 | * notice, this list of conditions and the following disclaimer. |
|---|
| 10 | * 2. Redistributions in binary form must reproduce the above copyright |
|---|
| 11 | * notice, this list of conditions and the following disclaimer in the |
|---|
| 12 | * documentation and/or other materials provided with the distribution. |
|---|
| 13 | * 3. The name of the author may not be used to endorse or promote products |
|---|
| 14 | * derived from this software without specific prior written permission. |
|---|
| 15 | * |
|---|
| 16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
|---|
| 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
|---|
| 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
|---|
| 19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
|---|
| 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
|---|
| 21 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|---|
| 22 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|---|
| 23 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|---|
| 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
|---|
| 25 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|---|
| 26 | */ |
|---|
| 27 | |
|---|
| 28 | #ifndef __PICTURE__ |
|---|
| 29 | #define __PICTURE__ |
|---|
| 30 | |
|---|
| 31 | #include <vector> |
|---|
| 32 | #include <list> |
|---|
| 33 | #ifdef HAVE_CONFIG_H |
|---|
| 34 | # include "config.h" |
|---|
| 35 | #endif |
|---|
| 36 | |
|---|
| 37 | class PicBase; |
|---|
| 38 | class PicContainer; |
|---|
| 39 | class PicRoot; |
|---|
| 40 | |
|---|
| 41 | class Surface; |
|---|
| 42 | |
|---|
| 43 | namespace Event { |
|---|
| 44 | class Video; |
|---|
| 45 | } |
|---|
| 46 | |
|---|
| 47 | /* PicBase ã®å
容ãã€ãã³ããšé£åãããããã®ã€ã³ã¿ãŒãã§ãŒã¹ */ |
|---|
| 48 | class PicAnm { |
|---|
| 49 | public: |
|---|
| 50 | typedef std::vector<PicBase*>::iterator iterator; |
|---|
| 51 | std::vector<PicBase*> pic; |
|---|
| 52 | PicAnm(PicBase* pic); |
|---|
| 53 | PicAnm(std::vector<PicBase*> pic); |
|---|
| 54 | virtual ~PicAnm(); |
|---|
| 55 | }; |
|---|
| 56 | |
|---|
| 57 | class PicBase { |
|---|
| 58 | private: |
|---|
| 59 | friend class PicContainer; |
|---|
| 60 | friend class PicWidget; |
|---|
| 61 | |
|---|
| 62 | typedef std::list<PicBase*> List; |
|---|
| 63 | typedef std::list<PicBase*>::iterator iterator; |
|---|
| 64 | |
|---|
| 65 | PicContainer* parent; |
|---|
| 66 | class PicWidget* widget; |
|---|
| 67 | Rect rel_pos; // relative position to the parent |
|---|
| 68 | Rect rel_solid_area; // solid area(not alpha-blended) to the parent |
|---|
| 69 | Rect clip_area; // clip area on the parent |
|---|
| 70 | bool is_hidden; |
|---|
| 71 | bool is_hidden_now; |
|---|
| 72 | bool is_cached; |
|---|
| 73 | public: |
|---|
| 74 | enum { /*MOBILE=1,*/ CACHE_BACK=2, /* CACHE_SELF=4,*/ NO_PICTURE=8, SOLID = 16, SURFACE_FREE = 32, FIT_SURFACE = 64, BLIT_ADD = 128, BLIT_MULTIPLY = 256, ALPHA_FREE=512}; |
|---|
| 75 | private: |
|---|
| 76 | int attribute; |
|---|
| 77 | |
|---|
| 78 | PicRoot* root; |
|---|
| 79 | iterator z_pos; |
|---|
| 80 | int surface_x, surface_y, surface_w, surface_h; |
|---|
| 81 | Surface* surface_back; |
|---|
| 82 | Surface* surface_own; |
|---|
| 83 | const unsigned char* surface_alpha; |
|---|
| 84 | Rect surface_alpha_rect; |
|---|
| 85 | int distance_root; |
|---|
| 86 | |
|---|
| 87 | void Blit(const Rect& rpos); |
|---|
| 88 | void Blit(void) { |
|---|
| 89 | is_cached = true; |
|---|
| 90 | Blit(Rect(0, 0, rel_pos.width(), rel_pos.height())); |
|---|
| 91 | } |
|---|
| 92 | /* |
|---|
| 93 | ** rpos : relative position to the widget |
|---|
| 94 | ** ppos : relative position to the parent |
|---|
| 95 | ** ppos = parent_pos(rpos) |
|---|
| 96 | ** rpos = child_pos(ppos, parent->this_widget) |
|---|
| 97 | ** cpos : relative position to a child widget |
|---|
| 98 | ** cpos = child_pos(rpos, a_child_widget) |
|---|
| 99 | ** apos : absolute position in the screen |
|---|
| 100 | ** apos = QueryAbsPos(rpos); |
|---|
| 101 | ** or |
|---|
| 102 | ** Rect ppos = rel_pos; |
|---|
| 103 | ** apos = parent->QueryAbsPos(ppos); |
|---|
| 104 | ** the latter form is used for 'rel_pos', |
|---|
| 105 | ** because rel_pos is defined as the relative position to the parent |
|---|
| 106 | */ |
|---|
| 107 | Rect QueryAbsPos(Rect& ppos); // ãã® picture å
ã® rel_pos ã衚瀺ããã®ã«å®éã«å¿
èŠãªçµ¶å¯Ÿåº§æšãåŸã |
|---|
| 108 | |
|---|
| 109 | static Rect child_pos(Rect rpos, PicBase* child) { /* return 'cpos' */ |
|---|
| 110 | rpos.intersect(child->rel_pos); |
|---|
| 111 | rpos.rmove( -(child->rel_pos.lx), -(child->rel_pos.ty)); |
|---|
| 112 | return rpos; |
|---|
| 113 | } |
|---|
| 114 | Rect parent_pos(Rect rpos) { /* return 'ppos' */ |
|---|
| 115 | rpos.rmove(rel_pos.lx, rel_pos.ty); |
|---|
| 116 | rpos.intersect(rel_pos); |
|---|
| 117 | return rpos; |
|---|
| 118 | } |
|---|
| 119 | void SetEventWidget(class PicWidget* widget); |
|---|
| 120 | public: |
|---|
| 121 | PicBase(const Rect& rel_pos, PicContainer* parent, int attr); |
|---|
| 122 | virtual ~PicBase(); |
|---|
| 123 | void InitRoot(PicRoot* r) { root = r;} // only called from PicRoot::PicRoot |
|---|
| 124 | |
|---|
| 125 | void ReBlit(const Rect& rpos); |
|---|
| 126 | void ReBlit(void) { ReBlit(Rect(0, 0, rel_pos.width(), rel_pos.height()));} |
|---|
| 127 | void ExecReBlit(const Rect& rpos); |
|---|
| 128 | void SimpleBlit(Surface* screen); |
|---|
| 129 | |
|---|
| 130 | virtual void RMove(int add_x, int add_y); |
|---|
| 131 | void Move(int new_rx, int new_ry); |
|---|
| 132 | #define ZMOVE_TOP ((PicBase*)0xffff00ff) /* æåé¢ãž */ |
|---|
| 133 | #define ZMOVE_BOTTOM ((PicBase*)0xffff0fff) /* æèé¢ãž */ |
|---|
| 134 | void ZMove(PicBase* back); // back ã®åã«ç§»å(back ãšèªåã¯åã芪ãæã€ããš) |
|---|
| 135 | |
|---|
| 136 | void SetSurface(Surface* new_surface, int x, int y, int attribute = 0); |
|---|
| 137 | void SetSurface(const char* new_surface, int x, int y); |
|---|
| 138 | void SetSurfacePos(int x, int y); |
|---|
| 139 | int SurfacePosX(void); |
|---|
| 140 | int SurfacePosY(void); |
|---|
| 141 | void SetSurfaceRect(const Rect& r); |
|---|
| 142 | void SetSurfaceAlpha(const unsigned char* alpha, const Rect& rect); |
|---|
| 143 | void SetSurfaceAlphaFile(const char* file); |
|---|
| 144 | void SetSurfaceColorKey(int r, int g, int b); |
|---|
| 145 | void SetSurfaceAttribute(int attribute); |
|---|
| 146 | void SetSurfaceFreeFlag(bool flag=true); |
|---|
| 147 | void SetClipArea(const Rect& r); |
|---|
| 148 | |
|---|
| 149 | void hide(void); |
|---|
| 150 | void show_all(void); |
|---|
| 151 | void show(void); |
|---|
| 152 | |
|---|
| 153 | int PosX(void) const { return rel_pos.lx;} |
|---|
| 154 | int PosY(void) const { return rel_pos.ty;} |
|---|
| 155 | int Width(void) const { return rel_pos.width();} |
|---|
| 156 | int Height(void) const { return rel_pos.height();} |
|---|
| 157 | int DistanceRoot(void) const { return distance_root; } |
|---|
| 158 | bool IsHidden(void) { return is_hidden_now;} |
|---|
| 159 | bool IsParent(PicBase* pic); |
|---|
| 160 | |
|---|
| 161 | std::vector<PicAnm*> anm; |
|---|
| 162 | void ClearAnm(void); |
|---|
| 163 | }; |
|---|
| 164 | |
|---|
| 165 | class PicContainer : public PicBase { |
|---|
| 166 | private: |
|---|
| 167 | friend class PicBase; |
|---|
| 168 | |
|---|
| 169 | void BlitBack(iterator z, Rect rpos); // z ããåŸãã®é åãæç» |
|---|
| 170 | void BlitFront(iterator z, Rect rpos); // z ãå«ããzããåã®é åãæç» |
|---|
| 171 | void BlitChildren(Rect rpos); |
|---|
| 172 | void BlitSelf(Rect rpos); |
|---|
| 173 | void BlitSelf(void) { |
|---|
| 174 | is_cached = true; |
|---|
| 175 | BlitSelf(Rect(0, 0, rel_pos.width(), rel_pos.height())); |
|---|
| 176 | } |
|---|
| 177 | public: |
|---|
| 178 | List children; |
|---|
| 179 | private: |
|---|
| 180 | |
|---|
| 181 | void set_showflag(void); |
|---|
| 182 | void set_nowhiddenflag(bool is_hide); |
|---|
| 183 | public: |
|---|
| 184 | PicContainer(const Rect& rel_pos, PicContainer* parent, int attr); |
|---|
| 185 | ~PicContainer(); |
|---|
| 186 | PicBase* create_leaf(const Rect& rel_pos, int attr); |
|---|
| 187 | PicContainer* create_node(const Rect& rel_pos, int attr); |
|---|
| 188 | PicRoot& Root(void) { return *root;} |
|---|
| 189 | void RMove(int add_x, int add_y); |
|---|
| 190 | }; |
|---|
| 191 | |
|---|
| 192 | typedef enum { NO_MASK, ALPHA_MASK, COLOR_MASK} MaskType; |
|---|
| 193 | struct PicRoot { |
|---|
| 194 | public: |
|---|
| 195 | class PicContainer* root; |
|---|
| 196 | private: |
|---|
| 197 | class FileToSurface* ftosurface; |
|---|
| 198 | struct UpdateItem { |
|---|
| 199 | PicBase* pic; |
|---|
| 200 | Rect rpos; |
|---|
| 201 | Rect apos; |
|---|
| 202 | static bool less(const UpdateItem&, const UpdateItem&); |
|---|
| 203 | UpdateItem(PicBase* p, const Rect& _rpos, const Rect& _apos) : pic(p), rpos(_rpos), apos(_apos) {} |
|---|
| 204 | }; |
|---|
| 205 | std::vector<UpdateItem> update_rects; |
|---|
| 206 | |
|---|
| 207 | friend class FileToSurface; |
|---|
| 208 | void DeleteSurfaceImpl(Surface* s) const; |
|---|
| 209 | public: |
|---|
| 210 | void Update(PicBase* pic, const Rect& rpos, const Rect& apos); |
|---|
| 211 | void DeleteUpdatePic(PicBase* pic); |
|---|
| 212 | void ExecUpdate(void); |
|---|
| 213 | void SetWindowCaption(const char* caption); |
|---|
| 214 | |
|---|
| 215 | // Surface æäœ |
|---|
| 216 | Surface* NewSurfaceFromRGBAData(int w, int h, char* data, MaskType with_mask) const; // data 㯠malloc ããããã®ã§ããããš(SDLã®å
éšä»æ§) |
|---|
| 217 | Surface* NewSurface(int w, int h, MaskType with_mask) const; |
|---|
| 218 | Surface* NewSurface(const char* filename, MaskType with_mask = ALPHA_MASK); |
|---|
| 219 | Surface* RotZoomSurface(Surface* from, double zoom, double rotate_angle); |
|---|
| 220 | void DeleteSurface(Surface* s); |
|---|
| 221 | void BlitSurface(Surface* src, const Rect& src_rpos, const unsigned char* alpha, const Rect& alpha_r, Surface* dest, const Rect& dest_rpos, int attribute) const; |
|---|
| 222 | void BlitSurface(Surface* src, const Rect& src_rpos, Surface* dest, const Rect& dest_rpos) const { |
|---|
| 223 | BlitSurface(src, src_rpos, 0, Rect(0,0), dest, dest_rpos, 0); |
|---|
| 224 | } |
|---|
| 225 | static bool with_mask(Surface* src); |
|---|
| 226 | |
|---|
| 227 | Surface* surface; |
|---|
| 228 | Surface* hw_surface; |
|---|
| 229 | int width, height; |
|---|
| 230 | PicRoot(void); |
|---|
| 231 | ~PicRoot(); |
|---|
| 232 | PicBase* create_leaf(const Rect& apos, int attr) { |
|---|
| 233 | return root->create_leaf(apos, attr); |
|---|
| 234 | } |
|---|
| 235 | PicContainer* create_node(const Rect& apos, int attr) { |
|---|
| 236 | return root->create_node(apos, attr); |
|---|
| 237 | } |
|---|
| 238 | }; |
|---|
| 239 | |
|---|
| 240 | class PicWidget { |
|---|
| 241 | private: |
|---|
| 242 | PicBase* pic; /* æ¬æ¥ç¶æ¿ããã¹ãã ããé
å»¶åæåãããã®ã§ instance */ |
|---|
| 243 | public: |
|---|
| 244 | PicWidget(void); |
|---|
| 245 | virtual ~PicWidget(); |
|---|
| 246 | void SetPic(PicBase* new_pic); |
|---|
| 247 | PicBase* Pic(void); |
|---|
| 248 | PicContainer* PicNode(void); |
|---|
| 249 | virtual void activate(void); |
|---|
| 250 | virtual void deactivate(void); |
|---|
| 251 | virtual void SetRegion(const Rect& apos); |
|---|
| 252 | void show(void); |
|---|
| 253 | void hide(void); |
|---|
| 254 | void show_all(void); |
|---|
| 255 | }; |
|---|
| 256 | |
|---|
| 257 | #endif /* PICTURE */ |
|---|