Mercurial > otakunoraifu
diff window/picture.cc @ 52:15a18fbe6f21
* Known bugs added to the README
* Code cleaning (0 -> NULL when needed, indentation, spaces, ...)
author | thib |
---|---|
date | Sat, 18 Apr 2009 18:35:39 +0000 |
parents | ed6c21dde840 |
children | ddbcbd000206 |
line wrap: on
line diff
--- a/window/picture.cc +++ b/window/picture.cc @@ -25,23 +25,23 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include<stdio.h> -#include<vector> -#include<list> -#include<algorithm> +#include <stdio.h> +#include <vector> +#include <list> +#include <algorithm> -#include"rect.h" -#include"event.h" -#include"font/font.h" -#include"font/text.h" -#include<SDL_rotozoom.h> -#include"system/file.h" +#include "rect.h" +#include "event.h" +#include "font/font.h" +#include "font/text.h" +#include <SDL_rotozoom.h> +#include "system/file.h" -#include"picture.h" +#include "picture.h" using namespace std; -int print_blit=0; +int print_blit = 0; /* render.cc */ void DSurfaceBlitAlpha(Surface* src_o, const Rect& srcrect_o, Surface* dst_o, const Rect& dstrect_o, const unsigned char* alpha, const Rect& alpharect); void DSurfaceBlitSaturate(Surface* src_o, const Rect& srcrect, Surface* dst_o, const Rect& dstrect, unsigned char alpha); @@ -71,13 +71,13 @@ PicBase::PicBase(const Rect& _rel_pos, P is_hidden(true), is_hidden_now(true), is_cached(false), attribute(_attr), surface_alpha_rect(0,0) { if (parent) root = parent->root; - else root = 0; - surface_back = 0; - surface_own = 0; + else root = NULL; + surface_back = NULL; + surface_own = NULL; surface_alpha = 0; surface_x = 0; surface_y = 0; surface_w = -1; surface_h = -1; - widget = 0; + widget = NULL; attribute |= NO_PICTURE; if ( (attribute & CACHE_BACK) && root) { surface_back = root->NewSurface(rel_pos.width(), rel_pos.height(), NO_MASK); @@ -91,15 +91,16 @@ PicBase::PicBase(const Rect& _rel_pos, P distance_root = 1; } } + PicBase::~PicBase() { ClearAnm(); - if (widget) { + if (widget != NULL) { fprintf(stderr,"Warning: PicBase::~PicBase: surface is disallocated but widget is still alive.\n"); widget->deactivate(); } - if (surface_back) root->DeleteSurface(surface_back); - if (surface_own && (attribute & SURFACE_FREE)) root->DeleteSurface(surface_own); - if (surface_alpha && (attribute & ALPHA_FREE)) delete surface_alpha; + if (surface_back != NULL) root->DeleteSurface(surface_back); + if (surface_own != NULL && (attribute & SURFACE_FREE)) root->DeleteSurface(surface_own); + if (surface_alpha != NULL && (attribute & ALPHA_FREE)) delete surface_alpha; iterator it; if (parent) { // 自分を親から削除 parent->children.remove(this); @@ -111,6 +112,7 @@ PicBase::~PicBase() { parent->ReBlit(old_ppos); } } + void PicBase::Blit(const Rect& rpos_orig) { // 実際に描画する領域を得る Rect rpos = rpos_orig; @@ -141,6 +143,7 @@ void PicBase::Blit(const Rect& rpos_orig cur->BlitChildren(rpos); } } + void PicBase::SimpleBlit(Surface* screen) { // 実際に描画する領域を得る Rect rpos(0, 0, rel_pos.width(), rel_pos.height()); @@ -157,7 +160,7 @@ void PicBase::SimpleBlit(Surface* screen Rect PicBase::QueryAbsPos(Rect& rpos) { rpos.intersect(Rect(0, 0, rel_pos.width(), rel_pos.height())); - if (parent == 0) { // root container + if (parent == NULL) { // root container return rpos; } // 親の座標に変換後、Query する @@ -165,13 +168,14 @@ Rect PicBase::QueryAbsPos(Rect& rpos) { Rect apos = parent->QueryAbsPos(ppos); rpos = child_pos(ppos, this); return apos; -}; +} + void PicBase::ReBlit(const Rect& rpos_c) { Rect rpos = rpos_c; Rect apos = QueryAbsPos(rpos); - root->Update(this, rpos, apos); } + void PicBase::ExecReBlit(const Rect& rpos_c) { Rect rpos = rpos_c; Rect abs_r = QueryAbsPos(rpos); @@ -186,7 +190,7 @@ if(print_blit) fprintf(stderr,"end."); } void PicBase::ZMove(PicBase* move_to) { - if (parent == 0) { + if (parent == NULL) { fprintf(stderr,"Warning: PicBase::ZMove is called by root.\n"); return; } @@ -231,7 +235,8 @@ void PicBase::ZMove(PicBase* move_to) { parent->ReBlit(ppos); */ } -}; +} + void PicBase::RMove(int add_x, int add_y) { Rect old_ppos = rel_pos; rel_pos.rmove(add_x, add_y); @@ -239,45 +244,50 @@ void PicBase::RMove(int add_x, int add_y parent->ReBlit(old_ppos); ReBlit(); - if (widget) { + if (widget != NULL) { Rect new_ppos = rel_pos; Rect new_apos = parent->QueryAbsPos(new_ppos); widget->SetRegion(new_apos); } } + void PicBase::Move(int new_rx, int new_ry) { RMove(new_rx-rel_pos.lx, new_ry-rel_pos.ty); } + void PicBase::SetEventWidget(PicWidget* new_widget) { widget = new_widget; - if (widget) { + if (widget != NULL) { Rect new_ppos = rel_pos; Rect apos = parent->QueryAbsPos(new_ppos); widget->SetRegion(apos); } } + void PicBase::show_all(void) { PicContainer* cont = dynamic_cast<PicContainer*>(this); if (cont && (!cont->children.empty())) cont->set_showflag(); show(); } + bool PicBase::IsParent(PicBase* to) { if (parent == 0) return false; if (parent == to) return true; return parent->IsParent(to); } + void PicBase::show(void) { /* 自分の親がすべて shown か? */ PicContainer* cur; for (cur = parent; cur != 0; cur = cur->parent) if (cur->is_hidden) break; - if (cur) { // 親が隠れているので表示はしない + if (cur != NULL) { // 親が隠れているので表示はしない is_hidden = false; is_hidden_now = true; return; } if (is_hidden == false) return; // すでに表示されているのでなにもしない - if (widget) { + if (widget != NULL) { widget->activate(); } is_hidden = false; @@ -287,9 +297,10 @@ void PicBase::show(void) { if (cur && (!cur->children.empty())) cur->set_nowhiddenflag(false); ReBlit(); } + void PicBase::hide(void) { if (is_hidden) return; - if (widget) { + if (widget != NULL) { widget->deactivate(); } is_hidden = true; @@ -299,6 +310,7 @@ void PicBase::hide(void) { if (cur && (!cur->children.empty())) cur->set_nowhiddenflag(true); ReBlit(); } + void PicBase::SetSurfaceAlpha(const unsigned char* alpha, const Rect& alpha_r) { if (attribute & ALPHA_FREE) { if (surface_alpha) delete[] surface_alpha; @@ -308,6 +320,7 @@ void PicBase::SetSurfaceAlpha(const unsi surface_alpha_rect = alpha_r; if (!is_hidden) ReBlit(); } + void PicBase::SetSurfaceColorKey(int r, int g, int b) { surface_alpha = 0; surface_alpha_rect = Rect(0,0); @@ -319,17 +332,18 @@ void PicBase::SetSurfaceColorKey(int r, } if (!is_hidden) ReBlit(); } + void PicBase::SetSurfaceAlphaFile(const char* file) { /* ファイルを元に alpha 画像を作成する */ /* ファイル: パルフェの 'fil' ファイル */ ARCINFO* info = file_searcher.Find(FILESEARCH::PDT, file,"fil"); - if (info == 0) return; + if (info == NULL) return; char* new_alpha = info->CopyRead(); int alpha_size = info->Size(); delete info; Rect sr(0,0); int w,h; - if (surface_own == 0 || new_alpha == 0) { + if (surface_own == NULL || new_alpha == NULL) { err_ret: if (new_alpha) delete[] new_alpha; SetSurfaceAlpha(0,Rect(0,0)); @@ -378,12 +392,14 @@ err_ret: attribute |= ALPHA_FREE; } } + void PicBase::SetSurface(const char* filename, int x, int y) { Surface* s = root->NewSurface(filename); SetSurface(s, x, y, SURFACE_FREE); } + void PicBase::SetSurface(Surface* new_surface, int x, int y, int new_attr) { - if (surface_own && (attribute & SURFACE_FREE)) { + if (surface_own != NULL && (attribute & SURFACE_FREE)) { root->DeleteSurface(surface_own); } attribute &= ~(SURFACE_FREE | BLIT_SATURATE | BLIT_MULTIPLY | NO_PICTURE | SOLID); @@ -408,38 +424,44 @@ void PicBase::SetSurface(Surface* new_su } rel_solid_area = Rect(0,0,0,0); - if (! surface_own) attribute |= NO_PICTURE; + if (surface_own == NULL) attribute |= NO_PICTURE; else if (root->with_mask(surface_own) == 0) { attribute |= SOLID; rel_solid_area = rel_pos; } if (!is_hidden) ReBlit(); } + void PicBase::SetSurfacePos(int x, int y) { if (surface_x == x && surface_y == y && surface_w == -1 && surface_h == -1) return; surface_x = x; surface_y = y; surface_w = -1; surface_h = -1; if (!is_hidden_now) ReBlit(); } + int PicBase::SurfacePosX(void) { return surface_x; } + int PicBase::SurfacePosY(void) { return surface_y; } + void PicBase::SetSurfaceRect(const Rect& r) { if (surface_x == r.lx && surface_y == r.ty && surface_w == r.width() && surface_h == r.height()) return; - surface_x = r.lx; surface_y = r.ty; + surface_x = r.lx; + surface_y = r.ty; surface_w = r.width(); surface_h = r.height(); parent->ReBlit(rel_pos); rel_pos = Rect(rel_pos.lx, rel_pos.ty, rel_pos.lx+surface_w, rel_pos.ty+surface_h); - if (widget) { + if (widget != NULL) { Rect new_ppos = rel_pos; Rect apos = parent->QueryAbsPos(new_ppos); widget->SetRegion(apos); } if (!is_hidden_now) ReBlit(); } + void PicBase::SetClipArea(const Rect& r) { if (clip_area == r) return; clip_area = r; @@ -453,6 +475,7 @@ void PicBase::SetSurfaceAttribute(int ne rel_solid_area = Rect(0,0); } } + void PicBase::SetSurfaceFreeFlag(bool flag) { if (flag) attribute |= SURFACE_FREE; else attribute &= ~SURFACE_FREE; @@ -465,19 +488,22 @@ void PicBase::SetSurfaceFreeFlag(bool fl PicContainer::PicContainer(const Rect& rel_pos, PicContainer* parent, int attr) : PicBase(rel_pos, parent, attr) { } + PicContainer::~PicContainer() { iterator end = children.end(); for (iterator it = children.begin(); it != end; ) { iterator it_next = it; it_next++; - if ((*it)->widget) delete (*it)->widget; // picture にwidget が付属しているなら、そちらをdelete + if ((*it)->widget != NULL) delete (*it)->widget; // picture にwidget が付属しているなら、そちらをdelete else delete (*it); it = it_next; } } + void PicContainer::BlitBack(iterator z, Rect rpos) { rpos.intersect(Rect(0, 0, rel_pos.width(), rel_pos.height())); if (rpos.empty()) return; - iterator end = children.end(), begin = children.begin(); iterator it = begin; + iterator end = children.end(), begin = children.begin(); + iterator it = begin; Rect ppos = parent_pos(rpos); if (is_hidden_now) goto parent_redraw; @@ -536,6 +562,7 @@ children_redraw: } } } + void PicContainer::BlitChildren(Rect rpos) { if (print_blit) fprintf(stderr,"bc."); iterator end = children.end(); @@ -548,10 +575,12 @@ if ( (*it)->is_hidden_now) if(print_blit } } } + void PicContainer::BlitFront(iterator z, Rect rpos) { rpos.intersect(Rect(0, 0, rel_pos.width(), rel_pos.height())); if (rpos.empty()) return; - iterator end = children.end(); iterator it; + iterator end = children.end(); + iterator it; z++; for (it = z; it != end; it++) { if ( (*it)->is_hidden_now) continue; @@ -564,7 +593,8 @@ void PicContainer::BlitFront(iterator z, Rect ppos = parent_pos(rpos); parent->BlitFront(z_pos, ppos); } -}; +} + void PicContainer::BlitSelf(Rect rpos) { // 実際に描画する領域を得る rpos.intersect(Rect(0, 0, rel_pos.width(), rel_pos.height())); @@ -582,7 +612,7 @@ if(print_blit) fprintf(stderr,"self-back } if(print_blit) fprintf(stderr,"self-blit."); root->BlitSurface(surface_own, rpos, surface_alpha, surface_alpha_rect, root->surface, apos, attribute); - } else if (parent == 0) { // 親がいないなら背景消去の責任をもつ + } else if (parent == NULL) { // 親がいないなら背景消去の責任をもつ DSurfaceFill(root->surface, apos, 0, 0, 0); } } @@ -595,12 +625,13 @@ void PicContainer::set_showflag(void) { if (next && (!next->children.empty())) next->set_showflag(); } } + void PicContainer::set_nowhiddenflag(bool is_hide) { iterator end = children.end(); for (iterator it = children.begin(); it != end; it++) { if (is_hide) (*it)->is_hidden_now = true; else (*it)->is_hidden_now = (*it)->is_hidden; - if ( (*it)->widget) { + if ( (*it)->widget != NULL) { if ((*it)->is_hidden_now) (*it)->widget->deactivate(); else (*it)->widget->activate(); } @@ -608,6 +639,7 @@ void PicContainer::set_nowhiddenflag(boo if (next && (!next->children.empty())) next->set_nowhiddenflag(is_hide); } } + void PicContainer::RMove(int add_x, int add_y) { // event widget の移動があり得るので子についてもRMoveを呼び出す PicBase::RMove(add_x, add_y); iterator end = children.end(); @@ -619,6 +651,7 @@ void PicContainer::RMove(int add_x, int add_y) { // event widget の移動があり得るので子についてもRMoveを呼び出す PicBase* PicContainer::create_leaf(const Rect& rel_pos, int attr) { return new PicBase(rel_pos, this, attr); } + PicContainer* PicContainer::create_node(const Rect& rel_pos, int attr) { return new PicContainer(rel_pos, this, attr); } @@ -629,32 +662,36 @@ PicContainer* PicContainer::create_node( */ PicWidget::PicWidget(void) { - pic = 0; + pic = NULL; } + PicWidget::~PicWidget() { - if (pic) { + if (pic != NULL) { pic->SetEventWidget(0); delete pic; } - pic = 0; + pic = NULL; } + void PicWidget::SetPic(PicBase* new_pic) { - if (pic) { + if (pic != NULL) { pic->SetEventWidget(0); delete pic; } pic = new_pic; - if (pic) pic->SetEventWidget(this); + if (pic != NULL) pic->SetEventWidget(this); } + PicBase* PicWidget::Pic(void) { - if (pic == 0) { + if (pic == NULL) { fprintf(stderr,"Error: PicWidget::Pic returns zero.\n"); } return pic; } + PicContainer* PicWidget::PicNode(void) { PicContainer* node = dynamic_cast<PicContainer*>(pic); - if (node == 0) { + if (node == NULL) { fprintf(stderr,"Error: PicWidget::PicNode returns zero.\n"); } return node; @@ -664,9 +701,10 @@ PicContainer* PicWidget::PicNode(void) { ** FileToSurface */ -#include<list> -#include<map> -#include<string> +#include <list> +#include <map> +#include <string> + using namespace std; struct SurfaceIndex { typedef list<SurfaceIndex*>::iterator qiterator; @@ -677,27 +715,30 @@ struct SurfaceIndex { }; class FileToSurface { - typedef list<SurfaceIndex*>::iterator qiterator; + private: + typedef list<SurfaceIndex*>::iterator qiterator; - list<SurfaceIndex*> queue; - map<string, SurfaceIndex*> findex; - map<Surface*, SurfaceIndex*> mindex; - int count; - int count_max; - const PicRoot& root; - bool DeleteData(SurfaceIndex* data); - Surface* LoadSurface(string name, char*& mem); -public: - FileToSurface(const PicRoot& root); - ~FileToSurface(void); - Surface* Load(string name); - bool Free(Surface* s); + list<SurfaceIndex*> queue; + map<string, SurfaceIndex*> findex; + map<Surface*, SurfaceIndex*> mindex; + int count; + int count_max; + const PicRoot& root; + bool DeleteData(SurfaceIndex* data); + Surface* LoadSurface(string name, char*& mem); + + public: + FileToSurface(const PicRoot& root); + ~FileToSurface(void); + Surface* Load(string name); + bool Free(Surface* s); }; FileToSurface::FileToSurface(const PicRoot& _root) : root(_root) { count = 0; count_max = 32; // キャッシュ量(決め打ち) }; + FileToSurface::~FileToSurface() { qiterator it; for (it=queue.begin(); it != queue.end(); it++) { @@ -708,6 +749,7 @@ FileToSurface::~FileToSurface() { delete *it; } } + inline bool FileToSurface::DeleteData(SurfaceIndex* data) { if ( data->ref_count) return false; findex.erase(data->filename); @@ -718,13 +760,17 @@ inline bool FileToSurface::DeleteData(Su count--; return true; } + inline Surface* FileToSurface::LoadSurface(string name, char*& mem) { ARCINFO* info = file_searcher.Find(FILESEARCH::PDT, name.c_str(),"pdt"); - if (info == 0) return 0; + if (info == NULL) return NULL; GRPCONV* conv = GRPCONV::AssignConverter(info); - if (conv == 0) { delete info;return 0;} + if (conv == NULL) { + delete info; + return NULL; + } mem = (char*)malloc(conv->Width() * conv->Height() * 4 + 1024); - Surface* s = 0; + Surface* s = NULL; if (conv->Read(mem)) { MaskType is_mask = conv->IsMask() ? ALPHA_MASK : NO_MASK; if (is_mask == ALPHA_MASK) { // alpha がすべて 0xff ならマスク無しとする @@ -743,6 +789,7 @@ inline Surface* FileToSurface::LoadSurfa delete conv; delete info; // delete data; return s; } + Surface* FileToSurface::Load(string name) { if (findex.find(name) != findex.end()) { findex[name]->ref_count++; @@ -750,7 +797,7 @@ Surface* FileToSurface::Load(string name } char* mem; Surface* surface = LoadSurface(name, mem); - if (surface == 0) return 0; + if (surface == NULL) return NULL; while (count >= count_max) { // count_max 以上のデータを可能なら削除する qiterator it; @@ -770,6 +817,7 @@ Surface* FileToSurface::Load(string name count++; return surface; } + bool FileToSurface::Free(Surface* s) { if (mindex.find(s) == mindex.end()) { return false; @@ -783,9 +831,9 @@ bool FileToSurface::Free(Surface* s) { /****************************************** ** PicRoot */ -#include<SDL.h> +#include <SDL.h> -#include"surface.h" +#include "surface.h" #define DefaultRmask 0xff0000 #define DefaultGmask 0xff00 @@ -811,18 +859,22 @@ PicRoot::PicRoot(void) { height = surface->h; return; } + PicRoot::~PicRoot() { // if (surface) DeleteSurfaceImpl(surface); // SDL_GetVideoSurface() した surface は開放の必要がないらしい - surface = 0; + surface = NULL; delete root; delete ftosurface; } + void PicRoot::Update(PicBase* pic, const Rect& rpos, const Rect& apos) { update_rects.push_back(UpdateItem(pic, rpos, apos)); } + bool PicRoot::UpdateItem::less(const PicRoot::UpdateItem& a, const PicRoot::UpdateItem& b) { return a.pic->DistanceRoot() < b.pic->DistanceRoot(); } + void PicRoot::DeleteUpdatePic(PicBase* pic) { vector<UpdateItem>::iterator it = update_rects.begin(); while(it != update_rects.end()) { @@ -835,11 +887,13 @@ void PicRoot::DeleteUpdatePic(PicBase* p } return; } + void PicRoot::ExecUpdate(void) { /* 共通する領域を消去する */ sort(update_rects.begin(), update_rects.end(), UpdateItem::less); vector<UpdateItem>::iterator it; vector<UpdateItem>::iterator end = update_rects.end(); + if(print_blit){ fprintf(stderr,"ExecUpdate Start: \n\t"); for (it=update_rects.begin(); it != end; it++) { @@ -847,6 +901,7 @@ if(print_blit){ } fprintf(stderr,"\n"); } + for (it=update_rects.begin(); it != end; it++) { if (it->rpos.width() == 0) continue; @@ -869,6 +924,7 @@ if(print_blit){ } } } + if(print_blit){ fprintf(stderr,"->\t"); for (it=update_rects.begin(); it != end; it++) { @@ -900,7 +956,8 @@ if(print_blit)fprintf(stderr,"\n"); } if(print_blit)fprintf(stderr,"\n"); SDL_UpdateRects(hw_surface, n, r); - delete[] r; update_rects.clear(); + delete[] r; + update_rects.clear(); } Surface* PicRoot::NewSurface(int w, int h, MaskType with_mask) const { @@ -918,11 +975,12 @@ Surface* PicRoot::NewSurfaceFromRGBAData Surface* s = (Surface*)SDL_CreateRGBSurfaceFrom(data, w, h, DefaultBpp, w*4, DefaultRmask, DefaultGmask, DefaultBmask, amask); s->flags &= ~SDL_PREALLOC; return s; -}; +} + Surface* PicRoot::NewSurface(const char* f, MaskType with_mask) { - if (f == 0) return 0; + if (f == NULL) return NULL; Surface* s = ftosurface->Load(f); - if (s == 0) return 0; + if (s == NULL) return NULL; if (with_mask == COLOR_MASK) { SDL_SetColorKey( (SDL_Surface*)s, SDL_SRCCOLORKEY, *(Uint32*)s->pixels); } @@ -931,17 +989,21 @@ Surface* PicRoot::NewSurface(const char* SDL_SetColorKey(s, SDL_SRCCOLORKEY, 0x55aa66); return s; } + Surface* PicRoot::RotZoomSurface(Surface* from, double zoom, double rotate) { Surface* ret = (Surface*)rotozoomSurface( (SDL_Surface*)from, rotate, zoom, SMOOTHING_OFF); return ret; } + void PicRoot::DeleteSurfaceImpl(Surface* s) const { SDL_FreeSurface(s); } + void PicRoot::DeleteSurface(Surface* s) { if (!ftosurface->Free(s)) DeleteSurfaceImpl(s); } + inline SDL_Rect SDLed(const Rect& rect) { SDL_Rect r; r.x = rect.lx; @@ -971,7 +1033,7 @@ if (print_blit) fprintf(stderr,"S"); } if (print_blit) fprintf(stderr,"N"); - if (alpha == 0 || alpha_r.width() == 0) { // simple blit + if (alpha == NULL || alpha_r.width() == 0) { // simple blit if (print_blit) fprintf(stderr,"X"); SDL_BlitSurface(src, &sr, dest, &dr); return; @@ -1001,9 +1063,9 @@ bool PicRoot::with_mask(Surface* s) { } #if USE_X11 -#include<SDL_syswm.h> -#include<X11/Xlib.h> -#include<X11/Xutil.h> +#include <SDL_syswm.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> #endif /* USE_X11 */ void PicRoot::SetWindowCaption(const char* caption) { #if USE_X11