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 }