Mercurial > otakunoraifu
comparison window/picture.cc @ 60:e16e13d8cd68
Replaced SATURATE -> ADD, implemented objComposite, corrected minor things
author | Thibaut GIRKA <thib@sitedethib.com> |
---|---|
date | Fri, 18 Dec 2009 20:41:38 +0100 |
parents | ddbcbd000206 |
children | 4416cfac86ae |
comparison
equal
deleted
inserted
replaced
59:36d92d21300f | 60:e16e13d8cd68 |
---|---|
39 | 39 |
40 #include "picture.h" | 40 #include "picture.h" |
41 | 41 |
42 using namespace std; | 42 using namespace std; |
43 | 43 |
44 int print_blit = 0; | |
45 /* render.cc */ | 44 /* render.cc */ |
46 void DSurfaceBlitAlpha(Surface* src_o, const Rect& srcrect_o, Surface* dst_o, const Rect& dstrect_o, const unsigned char* alpha, const Rect& alpharect); | 45 void DSurfaceBlitAlpha(Surface* src_o, const Rect& srcrect_o, Surface* dst_o, const Rect& dstrect_o, const unsigned char* alpha, const Rect& alpharect); |
47 void DSurfaceBlitSaturate(Surface* src_o, const Rect& srcrect, Surface* dst_o, const Rect& dstrect, unsigned char alpha); | 46 void DSurfaceBlitAdd(Surface* src_o, const Rect& srcrect, Surface* dst_o, const Rect& dstrect, unsigned char alpha); |
48 void DSurfaceBlitMultiply(Surface* src_o, const Rect& srcrect, Surface* dst_o, const Rect& dstrect); | 47 void DSurfaceBlitMultiply(Surface* src_o, const Rect& srcrect, Surface* dst_o, const Rect& dstrect); |
49 void DSurfaceFill(Surface* src, const Rect& rect, int r, int g, int b, int a=0xff); // クリア | 48 void DSurfaceFill(Surface* src, const Rect& rect, int r, int g, int b, int a=0xff); // クリア |
50 #if 0 /* DEBUG */ | 49 #if 0 /* DEBUG */ |
51 #include<sys/types.h> | 50 #include<sys/types.h> |
52 #include<sys/time.h> | 51 #include<sys/time.h> |
178 | 177 |
179 void PicBase::ExecReBlit(const Rect& rpos_c) { | 178 void PicBase::ExecReBlit(const Rect& rpos_c) { |
180 Rect rpos = rpos_c; | 179 Rect rpos = rpos_c; |
181 Rect abs_r = QueryAbsPos(rpos); | 180 Rect abs_r = QueryAbsPos(rpos); |
182 Rect ppos = parent_pos(rpos); | 181 Rect ppos = parent_pos(rpos); |
183 if(print_blit) fprintf(stderr,"back."); | |
184 if (parent) parent->BlitBack(z_pos, ppos); | 182 if (parent) parent->BlitBack(z_pos, ppos); |
185 if(print_blit) fprintf(stderr,"self."); | |
186 if (!is_hidden_now) Blit(rpos); | 183 if (!is_hidden_now) Blit(rpos); |
187 if(print_blit) fprintf(stderr,"front."); | |
188 if (parent) parent->BlitFront(z_pos, ppos); | 184 if (parent) parent->BlitFront(z_pos, ppos); |
189 if(print_blit) fprintf(stderr,"end."); | |
190 } | 185 } |
191 | 186 |
192 void PicBase::ZMove(PicBase* move_to) { | 187 void PicBase::ZMove(PicBase* move_to) { |
193 if (parent == NULL) { | 188 if (parent == NULL) { |
194 fprintf(stderr,"Warning: PicBase::ZMove is called by root.\n"); | 189 fprintf(stderr,"Warning: PicBase::ZMove is called by root.\n"); |
322 } | 317 } |
323 | 318 |
324 void PicBase::SetSurfaceColorKey(int r, int g, int b) { | 319 void PicBase::SetSurfaceColorKey(int r, int g, int b) { |
325 surface_alpha = 0; | 320 surface_alpha = 0; |
326 surface_alpha_rect = Rect(0,0); | 321 surface_alpha_rect = Rect(0,0); |
327 attribute &= ~(BLIT_SATURATE | BLIT_MULTIPLY); | 322 attribute &= ~(BLIT_ADD | BLIT_MULTIPLY); |
328 if (surface_own) { | 323 if (surface_own) { |
329 int key = SDL_MapRGB( ((SDL_Surface*)surface_own)->format, r, g, b); | 324 int key = SDL_MapRGB( ((SDL_Surface*)surface_own)->format, r, g, b); |
330 key |= 0xff000000; | 325 key |= 0xff000000; |
331 SDL_SetColorKey( (SDL_Surface*)surface_own, SDL_SRCCOLORKEY, key); | 326 SDL_SetColorKey( (SDL_Surface*)surface_own, SDL_SRCCOLORKEY, key); |
332 } | 327 } |
400 | 395 |
401 void PicBase::SetSurface(Surface* new_surface, int x, int y, int new_attr) { | 396 void PicBase::SetSurface(Surface* new_surface, int x, int y, int new_attr) { |
402 if (surface_own != NULL && (attribute & SURFACE_FREE)) { | 397 if (surface_own != NULL && (attribute & SURFACE_FREE)) { |
403 root->DeleteSurface(surface_own); | 398 root->DeleteSurface(surface_own); |
404 } | 399 } |
405 attribute &= ~(SURFACE_FREE | BLIT_SATURATE | BLIT_MULTIPLY | NO_PICTURE | SOLID); | 400 attribute &= ~(SURFACE_FREE | BLIT_ADD | BLIT_MULTIPLY | NO_PICTURE | SOLID); |
406 attribute |= new_attr; | 401 attribute |= new_attr; |
407 surface_own = new_surface; | 402 surface_own = new_surface; |
408 surface_x = x; | 403 surface_x = x; |
409 surface_y = y; | 404 surface_y = y; |
410 surface_w = -1; | 405 surface_w = -1; |
467 clip_area = r; | 462 clip_area = r; |
468 parent->ReBlit(rel_pos); | 463 parent->ReBlit(rel_pos); |
469 } | 464 } |
470 | 465 |
471 void PicBase::SetSurfaceAttribute(int new_attribute) { | 466 void PicBase::SetSurfaceAttribute(int new_attribute) { |
472 attribute &= ~(BLIT_SATURATE | BLIT_MULTIPLY); | 467 attribute &= ~(BLIT_ADD | BLIT_MULTIPLY); |
473 attribute |= new_attribute & (BLIT_SATURATE | BLIT_MULTIPLY); | 468 attribute |= new_attribute & (BLIT_ADD | BLIT_MULTIPLY); |
474 if (new_attribute & (BLIT_SATURATE | BLIT_MULTIPLY)) { | 469 if (new_attribute & (BLIT_ADD | BLIT_MULTIPLY)) { |
475 rel_solid_area = Rect(0,0); | 470 rel_solid_area = Rect(0,0); |
476 } | 471 } |
477 } | 472 } |
478 | 473 |
479 void PicBase::SetSurfaceFreeFlag(bool flag) { | 474 void PicBase::SetSurfaceFreeFlag(bool flag) { |
537 } | 532 } |
538 if ( (attribute & CACHE_BACK) && is_cached) { | 533 if ( (attribute & CACHE_BACK) && is_cached) { |
539 Rect cpos = child_pos(rpos, *z); | 534 Rect cpos = child_pos(rpos, *z); |
540 Rect apos = (*z)->QueryAbsPos(cpos); | 535 Rect apos = (*z)->QueryAbsPos(cpos); |
541 Rect draw_rpos = (*z)->parent_pos(cpos); | 536 Rect draw_rpos = (*z)->parent_pos(cpos); |
542 if(print_blit) fprintf(stderr,"cahce."); | |
543 root->BlitSurface(surface_back, draw_rpos, root->surface, apos); | 537 root->BlitSurface(surface_back, draw_rpos, root->surface, apos); |
544 goto self_redraw; | 538 goto self_redraw; |
545 } | 539 } |
546 parent_redraw: | 540 parent_redraw: |
547 if (parent) { | 541 if (parent) { |
548 Rect ppos = parent_pos(rpos); | 542 Rect ppos = parent_pos(rpos); |
549 if(print_blit) fprintf(stderr,"parent-back."); | |
550 parent->BlitBack(z_pos, ppos); | 543 parent->BlitBack(z_pos, ppos); |
551 } | 544 } |
552 if (is_hidden_now) return; | 545 if (is_hidden_now) return; |
553 self_redraw: | 546 self_redraw: |
554 if(print_blit) fprintf(stderr,"back-self."); | |
555 BlitSelf(rpos); // 子は描画せず、自分だけ描画 | 547 BlitSelf(rpos); // 子は描画せず、自分だけ描画 |
556 children_redraw: | 548 children_redraw: |
557 for (; it != z; it++) { | 549 for (; it != z; it++) { |
558 if ( (*it)->is_hidden_now) continue; | 550 if ( (*it)->is_hidden_now) continue; |
559 if ( (*it)->rel_pos.is_crossed(rpos)) { | 551 if ( (*it)->rel_pos.is_crossed(rpos)) { |
562 } | 554 } |
563 } | 555 } |
564 } | 556 } |
565 | 557 |
566 void PicContainer::BlitChildren(Rect rpos) { | 558 void PicContainer::BlitChildren(Rect rpos) { |
567 if (print_blit) fprintf(stderr,"bc."); | |
568 iterator end = children.end(); | 559 iterator end = children.end(); |
569 for (iterator it = children.begin(); it != end; it++) { | 560 for (iterator it = children.begin(); it != end; it++) { |
570 if ( (*it)->is_hidden_now) if(print_blit) fprintf(stderr,"bch %p;",*it); | |
571 if ( (*it)->is_hidden_now) continue; | 561 if ( (*it)->is_hidden_now) continue; |
572 if ( (*it)->rel_pos.is_crossed(rpos)) { | 562 if ( (*it)->rel_pos.is_crossed(rpos)) { |
573 Rect cpos = child_pos(rpos, *it); | 563 Rect cpos = child_pos(rpos, *it); |
574 (*it)->Blit(cpos); | 564 (*it)->Blit(cpos); |
575 } | 565 } |
599 // 実際に描画する領域を得る | 589 // 実際に描画する領域を得る |
600 rpos.intersect(Rect(0, 0, rel_pos.width(), rel_pos.height())); | 590 rpos.intersect(Rect(0, 0, rel_pos.width(), rel_pos.height())); |
601 if (rpos.empty()) return; | 591 if (rpos.empty()) return; |
602 Rect apos = QueryAbsPos(rpos); | 592 Rect apos = QueryAbsPos(rpos); |
603 // 必要に応じて保存、描画 | 593 // 必要に応じて保存、描画 |
604 if(print_blit) fprintf(stderr,"self-back."); | |
605 if (attribute & CACHE_BACK) root->BlitSurface(root->surface, apos, surface_back, rpos); | 594 if (attribute & CACHE_BACK) root->BlitSurface(root->surface, apos, surface_back, rpos); |
606 if (! (attribute & NO_PICTURE)) { | 595 if (! (attribute & NO_PICTURE)) { |
607 rpos.rmove(surface_x, surface_y); | 596 rpos.rmove(surface_x, surface_y); |
608 if (surface_w >= 0 && surface_h >= 0) { | 597 if (surface_w >= 0 && surface_h >= 0) { |
609 Rect clip(0, 0, surface_w, surface_h); | 598 Rect clip(0, 0, surface_w, surface_h); |
610 clip.rmove(rpos.lx, rpos.ty); | 599 clip.rmove(rpos.lx, rpos.ty); |
611 rpos.intersect(clip); | 600 rpos.intersect(clip); |
612 } | 601 } |
613 if(print_blit) fprintf(stderr,"self-blit."); | |
614 root->BlitSurface(surface_own, rpos, surface_alpha, surface_alpha_rect, root->surface, apos, attribute); | 602 root->BlitSurface(surface_own, rpos, surface_alpha, surface_alpha_rect, root->surface, apos, attribute); |
615 } else if (parent == NULL) { // 親がいないなら背景消去の責任をもつ | 603 } else if (parent == NULL) { // 親がいないなら背景消去の責任をもつ |
616 DSurfaceFill(root->surface, apos, 0, 0, 0); | 604 DSurfaceFill(root->surface, apos, 0, 0, 0); |
617 } | 605 } |
618 } | 606 } |
892 /* 共通する領域を消去する */ | 880 /* 共通する領域を消去する */ |
893 sort(update_rects.begin(), update_rects.end(), UpdateItem::less); | 881 sort(update_rects.begin(), update_rects.end(), UpdateItem::less); |
894 vector<UpdateItem>::iterator it; | 882 vector<UpdateItem>::iterator it; |
895 vector<UpdateItem>::iterator end = update_rects.end(); | 883 vector<UpdateItem>::iterator end = update_rects.end(); |
896 | 884 |
897 if(print_blit){ | |
898 fprintf(stderr,"ExecUpdate Start: \n\t"); | |
899 for (it=update_rects.begin(); it != end; it++) { | |
900 fprintf(stderr,"(%d,%d,%d,%d), ",it->apos.lx,it->apos.ty,it->apos.rx,it->apos.by); | |
901 } | |
902 fprintf(stderr,"\n"); | |
903 } | |
904 | |
905 for (it=update_rects.begin(); it != end; it++) { | 885 for (it=update_rects.begin(); it != end; it++) { |
906 if (it->rpos.width() == 0) continue; | 886 if (it->rpos.width() == 0) continue; |
907 | 887 |
908 Rect apos = it->apos; | 888 Rect apos = it->apos; |
909 PicBase* pic = it->pic; | 889 PicBase* pic = it->pic; |
923 } | 903 } |
924 } | 904 } |
925 } | 905 } |
926 } | 906 } |
927 | 907 |
928 if(print_blit){ | |
929 fprintf(stderr,"->\t"); | |
930 for (it=update_rects.begin(); it != end; it++) { | |
931 fprintf(stderr,"(%d,%d,%d,%d), ",it->apos.lx,it->apos.ty,it->apos.rx,it->apos.by); | |
932 } | |
933 fprintf(stderr,"\n"); | |
934 } | |
935 | |
936 int num = update_rects.size(); | 908 int num = update_rects.size(); |
937 SDL_Rect* r = new SDL_Rect[num]; | 909 SDL_Rect* r = new SDL_Rect[num]; |
938 Rect confine = Rect(0, 0, surface->w, surface->h); | 910 Rect confine = Rect(0, 0, surface->w, surface->h); |
939 int n = 0; | 911 int n = 0; |
940 int i; | 912 int i; |
941 for (i=0; i<num; i++) { | 913 for (i=0; i<num; i++) { |
942 UpdateItem& item = update_rects[i]; | 914 UpdateItem& item = update_rects[i]; |
943 Rect& ur = item.apos; | 915 Rect& ur = item.apos; |
944 if (ur.width() == 0) continue; | 916 if (ur.width() == 0) continue; |
945 if(print_blit)fprintf(stderr,"%p: %d,%d,%d,%d",item.pic, item.apos.lx, item.apos.ty, item.apos.rx, item.apos.by); | |
946 | 917 |
947 item.pic->ExecReBlit(item.rpos); | 918 item.pic->ExecReBlit(item.rpos); |
948 if(print_blit)fprintf(stderr,"\n"); | 919 |
949 ur.intersect(confine); | 920 ur.intersect(confine); |
950 r[n].x = ur.lx; | 921 r[n].x = ur.lx; |
951 r[n].y = ur.ty; | 922 r[n].y = ur.ty; |
952 r[n].w = ur.rx - ur.lx; | 923 r[n].w = ur.rx - ur.lx; |
953 r[n].h = ur.by - ur.ty; | 924 r[n].h = ur.by - ur.ty; |
954 if (surface != hw_surface) SDL_BlitSurface(surface, &r[n], hw_surface, &r[n]); | 925 if (surface != hw_surface) SDL_BlitSurface(surface, &r[n], hw_surface, &r[n]); |
955 n++; | 926 n++; |
956 } | 927 } |
957 if(print_blit)fprintf(stderr,"\n"); | 928 |
958 SDL_UpdateRects(hw_surface, n, r); | 929 SDL_UpdateRects(hw_surface, n, r); |
959 delete[] r; | 930 delete[] r; |
960 update_rects.clear(); | 931 update_rects.clear(); |
961 } | 932 } |
962 | 933 |
1014 } | 985 } |
1015 | 986 |
1016 #ifndef ALPHA_MAX | 987 #ifndef ALPHA_MAX |
1017 #define ALPHA_MAX 255 | 988 #define ALPHA_MAX 255 |
1018 #endif | 989 #endif |
1019 void PicRoot::BlitSurface(Surface* src, const Rect& src_r, const unsigned char* alpha, const Rect& alpha_r, Surface* dest, const Rect& dest_r, int attribute) const { | 990 void PicRoot::BlitSurface(Surface* src, const Rect& src_r, const unsigned char* alpha, const Rect& alpha_r, |
1020 if (print_blit) fprintf(stderr," s %p %d:%d:%d:%d;",src, dest_r.lx, dest_r.ty, dest_r.rx, dest_r.by); | 991 Surface* dest, const Rect& dest_r, int attribute) const |
992 { | |
1021 SDL_Rect sr = SDLed(src_r); SDL_Rect dr = SDLed(dest_r); | 993 SDL_Rect sr = SDLed(src_r); SDL_Rect dr = SDLed(dest_r); |
1022 | 994 |
1023 if (attribute & PicBase::BLIT_MULTIPLY) { | 995 if (attribute & PicBase::BLIT_MULTIPLY) |
1024 if (print_blit) fprintf(stderr,"M"); | 996 { |
1025 DSurfaceBlitMultiply(src, src_r, dest, dest_r); | 997 DSurfaceBlitMultiply(src, src_r, dest, dest_r); |
1026 return; | 998 return; |
1027 } else if (attribute & PicBase::BLIT_SATURATE && src->format->Amask == 0) { | 999 } |
1028 if (print_blit) fprintf(stderr,"S"); | 1000 else if (attribute & PicBase::BLIT_ADD) |
1001 { | |
1029 unsigned char a = 255; | 1002 unsigned char a = 255; |
1030 if (alpha && alpha_r.width() >= 1 && alpha_r.height() >= 1) a = *alpha; | 1003 if (alpha != NULL && alpha_r.width() >= 1 && alpha_r.height() >= 1) |
1031 DSurfaceBlitSaturate(src, src_r, dest, dest_r, a); | 1004 a = *alpha; |
1005 DSurfaceBlitAdd(src, src_r, dest, dest_r, a); | |
1032 return; | 1006 return; |
1033 } | 1007 } |
1034 | 1008 |
1035 if (print_blit) fprintf(stderr,"N"); | 1009 if (alpha == NULL || alpha_r.width() == 0) // simple blit |
1036 if (alpha == NULL || alpha_r.width() == 0) { // simple blit | 1010 { |
1037 if (print_blit) fprintf(stderr,"X"); | |
1038 SDL_BlitSurface(src, &sr, dest, &dr); | 1011 SDL_BlitSurface(src, &sr, dest, &dr); |
1039 return; | 1012 return; |
1040 } | 1013 } |
1041 if (alpha_r.width() == 1 && alpha_r.height() == 1) { | 1014 if (alpha_r.width() == 1 && alpha_r.height() == 1) { |
1042 if (*alpha == 255) { | 1015 if (*alpha == 255) { |
1043 if (print_blit) fprintf(stderr,"Y"); | |
1044 SDL_BlitSurface(src, &sr, dest, &dr); | 1016 SDL_BlitSurface(src, &sr, dest, &dr); |
1045 return; | 1017 return; |
1046 } | 1018 } |
1047 if (src->format->Amask == 0) { // use per-surface alpha | 1019 if (src->format->Amask == 0) { // use per-surface alpha |
1048 if (print_blit) fprintf(stderr,"Z"); | |
1049 SDL_SetAlpha(src, SDL_SRCALPHA, *alpha); | 1020 SDL_SetAlpha(src, SDL_SRCALPHA, *alpha); |
1050 SDL_BlitSurface(src, &sr, dest, &dr); | 1021 SDL_BlitSurface(src, &sr, dest, &dr); |
1051 SDL_SetAlpha(src, 0, 0); | 1022 SDL_SetAlpha(src, 0, 0); |
1052 return; | 1023 return; |
1053 } | 1024 } |
1054 } | 1025 } |
1055 // generic alpha blit | 1026 // generic alpha blit |
1056 if (print_blit) fprintf(stderr,"W"); | |
1057 DSurfaceBlitAlpha(src, src_r, dest, dest_r, alpha, alpha_r); | 1027 DSurfaceBlitAlpha(src, src_r, dest, dest_r, alpha, alpha_r); |
1058 return; | |
1059 } | 1028 } |
1060 | 1029 |
1061 bool PicRoot::with_mask(Surface* s) { | 1030 bool PicRoot::with_mask(Surface* s) { |
1062 return s->format->Amask != 0; | 1031 return s->format->Amask != 0; |
1063 } | 1032 } |