Replaced SATURATE -> ADD, implemented objComposite, corrected minor things
authorThibaut GIRKA <thib@sitedethib.com>
Fri Dec 18 20:41:38 2009 +0100 (2009-12-18)
changeset 60e16e13d8cd68
parent 59 36d92d21300f
child 61 bdd8a5ff8f46
Replaced SATURATE -> ADD, implemented objComposite, corrected minor things
scn2k/scn2k_grp.cc
scn2k/scn2k_grp.h
scn2k/scn2k_grpimpl.cc
window/picture.cc
window/picture.h
window/render.cc
window/render.h
     1.1 --- a/scn2k/scn2k_grp.cc	Fri Dec 18 18:51:44 2009 +0100
     1.2 +++ b/scn2k/scn2k_grp.cc	Fri Dec 18 20:41:38 2009 +0100
     1.3 @@ -168,7 +168,7 @@
     1.4  	}
     1.5  	if (picture == NULL) return;
     1.6  	if (attr & UPDATE_POS) {
     1.7 -		if ( (attr & SATURATE) || zoom != -1) {
     1.8 +		if (zoom != -1) {
     1.9  			int w=0, h=0;
    1.10  			GetSrcGeom(w,h);
    1.11  			picture->Move(_posx-w/2, _posy-h/2);
    1.12 @@ -238,8 +238,8 @@
    1.13  			picture->SetSurface(path.c_str(), 0, 0);
    1.14  			picture->SetSurfaceRect(Rect(0,0,width,height));
    1.15  		}
    1.16 -		if (attr & SATURATE)
    1.17 -			picture->SetSurfaceAttribute(PicBase::BLIT_SATURATE);
    1.18 +		if (attr & BLIT_ADD)
    1.19 +			picture->SetSurfaceAttribute(PicBase::BLIT_ADD);
    1.20  	} else if (gtype == MOJI) { // テキスト描画
    1.21  		if (print_moji.length() == 0) return;
    1.22  		UpdateMoji();
    1.23 @@ -396,8 +396,7 @@
    1.24  		return;
    1.25  	}
    1.26  
    1.27 -	picture->SetSurfaceAttribute(PicBase::BLIT_SATURATE);
    1.28 -	attr = Attribute(attr | UPDATE_POS | SATURATE);
    1.29 +	attr = Attribute(attr | UPDATE_POS);
    1.30  
    1.31  	const char* buf = data + 16;
    1.32  	buf += strlen(buf) + 1; // 画像ファイル名が入っている
    1.33 @@ -631,7 +630,7 @@
    1.34  	RegisterCommand(1, 33, 100, "grpCopy", (CmdImpl) &Grp::impl_grpCopy);
    1.35  	RegisterCommand(1, 33, 1201, "recFill", (CmdImpl) &Grp::impl_recFill);
    1.36  	RegisterCommand(1, 33, 1100, "recCopy", (CmdImpl) &Grp::impl_recCopy);
    1.37 -	RegisterCommand(1, 33, 1101, "recMaskCopy", NULL); //FIXME
    1.38 +	RegisterCommand(1, 33, 1101, "recMaskCopy", NULL); //TODO: Same thing as recCopy, but using source's alpha
    1.39  	RegisterCommand(1, 33, 1600, "recAdd", (CmdImpl) &Grp::impl_recAdd);
    1.40  	RegisterCommand(1, 33, 406, "grpPan", (CmdImpl) &Grp::impl_grpPan);
    1.41  
    1.42 @@ -734,7 +733,7 @@
    1.43  	RegisterCommand(1, 82, 1019, "objBgColB", NULL);
    1.44  	RegisterCommand(1, 81, 1020, "objColLevel", NULL);
    1.45  	RegisterCommand(1, 82, 1020, "objBgColLevel", NULL);
    1.46 -	RegisterCommand(1, 81, 1021, "objComposite", NULL);//(CmdImpl) &Grp::impl_objComposite); //FIXME: May be broken
    1.47 +	RegisterCommand(1, 81, 1021, "objComposite", (CmdImpl) &Grp::impl_objComposite); //FIXME: May be broken
    1.48  	RegisterCommand(1, 82, 1021, "objBgComposite", (CmdImpl) &Grp::impl_objComposite);
    1.49  	RegisterCommand(1, 81, 1024, "objSetText", (CmdImpl) &Grp::impl_objSetText);
    1.50  	RegisterCommand(1, 82, 1024, "objBgSetText", (CmdImpl) &Grp::impl_objSetText);
    1.51 @@ -1553,22 +1552,17 @@
    1.52  	CommandHandler::Exec(cmd);
    1.53  
    1.54  	//TODO: ???
    1.55 -	if (cmd.cmd1 == 1 && cmd.cmd2 == 0x3c && cmd.cmd3 == 0) { // ??? : KANOGI : 画像オブジェクトの削除?
    1.56 +	if (cmd.cmd1 == 1 && cmd.cmd2 == 60 && cmd.cmd3 == 0) { // ??? : KANOGI : 画像オブジェクトの削除?
    1.57  		DeleteObjPic(cmd.args[0].value); // 旧ファイル名のsurfaceを削除
    1.58  		GrpObj& g = grpobj[cmd.args[0].value];
    1.59  		g.attr = GrpObj::Attribute(g.attr | GrpObj::HIDDEN);
    1.60  		cmd.clear();
    1.61  	}
    1.62  
    1.63 -	//TODO: ???
    1.64 -	if ( (cmd.cmd1 == 1 || cmd.cmd1 == 2) && cmd.cmd2 == 0x51) {
    1.65 -		/*GrpObj& g = grpobj[cmd.args[0].value];
    1.66 -		int attr;
    1.67 -		GrpObjMap::iterator it;
    1.68 -		for (it = g.children_obj.begin(); it != g.children_obj.end(); it++)
    1.69 -			attr |= it->second.attr;
    1.70 -		if (attr & GrpObj::UPDATE_ALL)
    1.71 -			SetObjChanged(cmd.args[0].value);*/
    1.72 +	// Refresh changed objects...
    1.73 +	//FIXME: should may be go away?
    1.74 +	//Seems it'll work only for objects in the foreground
    1.75 +	if ( (cmd.cmd1 == 1 || cmd.cmd1 == 2) && cmd.cmd2 == 81) {
    1.76  		GrpObj* g;
    1.77  		if (cmd.cmd1 == 2)
    1.78  			g = GetGraphicObj(cmd.args[0].value, cmd.args[1].value);
     2.1 --- a/scn2k/scn2k_grp.h	Fri Dec 18 18:51:44 2009 +0100
     2.2 +++ b/scn2k/scn2k_grp.h	Fri Dec 18 20:41:38 2009 +0100
     2.3 @@ -81,7 +81,7 @@
     2.4  
     2.5  	vector<Rect> src_pos;
     2.6  	enum GrpType { FILLRECT = 1, FILE = 2, GAN = 3, MOJI = 4, DIGIT = 5} gtype;
     2.7 -	enum Attribute { NONE=0, WIPEON=1, SATURATE=2, HIDDEN=4,
     2.8 +	enum Attribute { NONE=0, WIPEON=1, BLIT_ADD=2, HIDDEN=4,
     2.9  		UPDATE_PICTURE = 16, UPDATE_POS = 32, UPDATE_ALPHA = 64, UPDATE_SNUM = 128, UPDATE_CLIP = 256, UPDATE_VISIBLE = 512,
    2.10  		UPDATE_ALL = (UPDATE_PICTURE | UPDATE_POS | UPDATE_ALPHA | UPDATE_SNUM | UPDATE_CLIP | UPDATE_VISIBLE),
    2.11  		ANM_PLAYSTART = 0x8000, ANM_PLAYING = 0x10000,
     3.1 --- a/scn2k/scn2k_grpimpl.cc	Fri Dec 18 18:51:44 2009 +0100
     3.2 +++ b/scn2k/scn2k_grpimpl.cc	Fri Dec 18 20:41:38 2009 +0100
     3.3 @@ -155,6 +155,7 @@
     3.4  }
     3.5  
     3.6  void Grp::impl_recCopy(Cmd& cmd) {
     3.7 +	//TODO: Handle forms 0 and 1
     3.8  	int sx = cmd.args[0].value;
     3.9  	int sy = cmd.args[1].value;
    3.10  	int w = cmd.args[2].value;
    3.11 @@ -172,7 +173,6 @@
    3.12  		// if (dest == 0) screen->ReBlit(Rect(dx,dy,dx+w,dy+h));
    3.13  		cmd.cmd_type = CMD_SAVECMDGRP;
    3.14  	}
    3.15 -
    3.16  	else if (cmd.cmd4 == 3) { // alpha ゃcopy
    3.17  		unsigned char alpha;
    3.18  		if (cmd.args[8].value < 0) alpha = 0;
    3.19 @@ -191,7 +191,7 @@
    3.20  }
    3.21  
    3.22  void Grp::impl_recAdd(Cmd& cmd) {
    3.23 -	if (cmd.cmd4 == 3) { // saturate mode  alpha 篁 copy
    3.24 +	if (cmd.cmd4 == 3) { // add mode  alpha 篁 copy
    3.25  		int sx = cmd.args[0].value;
    3.26  		int sy = cmd.args[1].value;
    3.27  		int w = cmd.args[2].value;
    3.28 @@ -205,15 +205,15 @@
    3.29  		if (cmd.args[8].value < 0) alpha = 0;
    3.30  		else if (cmd.args[8].value > 255) alpha = 255;
    3.31  		else alpha = cmd.args[8].value;
    3.32 -		eprintf("copy surface w/ saturate %d:(%d,%d) size(%d,%d) -> %d:(%d,%d)\n",src,sx,sy,w,h,dest,dx,dy);
    3.33 +		eprintf("copy surface w/ add %d:(%d,%d) size(%d,%d) -> %d:(%d,%d)\n",src,sx,sy,w,h,dest,dx,dy);
    3.34  		if (src == dest) {
    3.35  			DSurfaceMove(Ssurface(src), rect, Dsurface(WORKPDT), rect);
    3.36  			src = WORKPDT;
    3.37  		}
    3.38  		if (alpha != 0) {
    3.39 -			// saturate mode : screen (picture) 筝篏
    3.40 +			// add mode : screen (picture) 筝篏
    3.41  			PicBase* screen_tmp = parent.create_leaf(Rect(0, 0, parent.Width(), parent.Height()), 0);
    3.42 -			screen_tmp->SetSurface(Ssurface(src), 0, 0, PicBase::BLIT_SATURATE);
    3.43 +			screen_tmp->SetSurface(Ssurface(src), 0, 0, PicBase::BLIT_ADD);
    3.44  			screen_tmp->SetSurfaceRect(rect);
    3.45  			screen_tmp->Move(dx, dy);
    3.46  			screen_tmp->SetSurfaceAlpha(&alpha, Rect(0,0,1,1));
    3.47 @@ -348,7 +348,7 @@
    3.48  		base_argc = 1;
    3.49  
    3.50  	if (cmd.cmd3 == 1000) { /* <ゃ荐絎 */
    3.51 -		g->gtype = GrpObj::FILE; //FIXME: Strange thing in the main menu; that happens with objComposite
    3.52 +		g->gtype = GrpObj::FILE;
    3.53  		string name = cmd.Str(cmd.args[base_argc + 1]);
    3.54  		if (name.find('?') != -1) {//TODO
    3.55  			//Used for shading, with DAT/tcdata.tcc or other filename provided by #TONECURVE_FILENAME
    3.56 @@ -516,12 +516,11 @@
    3.57  void Grp::impl_objComposite(Cmd& cmd) {//FIXME
    3.58  	int base_arg = 0;
    3.59  	GrpObj* g = GetGraphicObjVarMode(cmd, base_arg, (cmd.cmd2 == 0x51));
    3.60 -
    3.61  	if (cmd.args[base_arg + 1].value == 1) {
    3.62 -		g->attr = GrpObj::Attribute(g->attr | GrpObj::SATURATE);
    3.63 +		g->attr = GrpObj::Attribute(g->attr | GrpObj::BLIT_ADD);
    3.64  		cmd.clear();
    3.65  	} else if (cmd.args[base_arg + 1].value == 0) {
    3.66 -		g->attr = GrpObj::Attribute(g->attr & (~GrpObj::SATURATE));
    3.67 +		g->attr = GrpObj::Attribute(g->attr & (~GrpObj::BLIT_ADD));
    3.68  		cmd.clear();
    3.69  	}
    3.70  	g->SetUpdate();
    3.71 @@ -765,3 +764,4 @@
    3.72  		cmd.clear();
    3.73  	}
    3.74  }
    3.75 +
     4.1 --- a/window/picture.cc	Fri Dec 18 18:51:44 2009 +0100
     4.2 +++ b/window/picture.cc	Fri Dec 18 20:41:38 2009 +0100
     4.3 @@ -41,10 +41,9 @@
     4.4  
     4.5  using namespace std;
     4.6  
     4.7 -int print_blit = 0;
     4.8  /* render.cc */
     4.9  void DSurfaceBlitAlpha(Surface* src_o, const Rect& srcrect_o, Surface* dst_o, const Rect& dstrect_o, const unsigned char* alpha, const Rect& alpharect);
    4.10 -void DSurfaceBlitSaturate(Surface* src_o, const Rect& srcrect, Surface* dst_o, const Rect& dstrect, unsigned char alpha);
    4.11 +void DSurfaceBlitAdd(Surface* src_o, const Rect& srcrect, Surface* dst_o, const Rect& dstrect, unsigned char alpha);
    4.12  void DSurfaceBlitMultiply(Surface* src_o, const Rect& srcrect, Surface* dst_o, const Rect& dstrect);
    4.13  void DSurfaceFill(Surface* src, const Rect& rect, int r, int g, int b, int a=0xff); // クリア
    4.14  #if 0 /* DEBUG */
    4.15 @@ -180,13 +179,9 @@
    4.16  	Rect rpos = rpos_c;
    4.17  	Rect abs_r = QueryAbsPos(rpos);
    4.18  	Rect ppos = parent_pos(rpos);
    4.19 -if(print_blit) fprintf(stderr,"back.");
    4.20  	if (parent) parent->BlitBack(z_pos, ppos);
    4.21 -if(print_blit) fprintf(stderr,"self.");
    4.22  	if (!is_hidden_now) Blit(rpos);
    4.23 -if(print_blit) fprintf(stderr,"front.");
    4.24  	if (parent) parent->BlitFront(z_pos, ppos);
    4.25 -if(print_blit) fprintf(stderr,"end.");
    4.26  }
    4.27  
    4.28  void PicBase::ZMove(PicBase* move_to) {
    4.29 @@ -324,7 +319,7 @@
    4.30  void PicBase::SetSurfaceColorKey(int r, int g, int b) {
    4.31  	surface_alpha = 0;
    4.32  	surface_alpha_rect = Rect(0,0);
    4.33 -	attribute &= ~(BLIT_SATURATE | BLIT_MULTIPLY);
    4.34 +	attribute &= ~(BLIT_ADD | BLIT_MULTIPLY);
    4.35  	if (surface_own) {
    4.36  		int key = SDL_MapRGB( ((SDL_Surface*)surface_own)->format, r, g, b);
    4.37  		key |= 0xff000000;
    4.38 @@ -402,7 +397,7 @@
    4.39  	if (surface_own != NULL && (attribute & SURFACE_FREE)) {
    4.40  		root->DeleteSurface(surface_own);
    4.41  	}
    4.42 -	attribute &= ~(SURFACE_FREE | BLIT_SATURATE | BLIT_MULTIPLY | NO_PICTURE | SOLID);
    4.43 +	attribute &= ~(SURFACE_FREE | BLIT_ADD | BLIT_MULTIPLY | NO_PICTURE | SOLID);
    4.44  	attribute |= new_attr;
    4.45  	surface_own = new_surface;
    4.46  	surface_x = x;
    4.47 @@ -469,9 +464,9 @@
    4.48  }
    4.49  
    4.50  void PicBase::SetSurfaceAttribute(int new_attribute) {
    4.51 -	attribute &= ~(BLIT_SATURATE | BLIT_MULTIPLY);
    4.52 -	attribute |= new_attribute & (BLIT_SATURATE | BLIT_MULTIPLY);
    4.53 -	if (new_attribute & (BLIT_SATURATE | BLIT_MULTIPLY)) {
    4.54 +	attribute &= ~(BLIT_ADD | BLIT_MULTIPLY);
    4.55 +	attribute |= new_attribute & (BLIT_ADD | BLIT_MULTIPLY);
    4.56 +	if (new_attribute & (BLIT_ADD | BLIT_MULTIPLY)) {
    4.57  		rel_solid_area = Rect(0,0);
    4.58  	}
    4.59  }
    4.60 @@ -539,19 +534,16 @@
    4.61  		Rect cpos = child_pos(rpos, *z);
    4.62  		Rect apos = (*z)->QueryAbsPos(cpos);
    4.63  		Rect draw_rpos = (*z)->parent_pos(cpos);
    4.64 -if(print_blit) fprintf(stderr,"cahce.");
    4.65  		root->BlitSurface(surface_back, draw_rpos, root->surface, apos);
    4.66  		goto self_redraw;
    4.67  	}
    4.68  parent_redraw:
    4.69  	if (parent) {
    4.70  		Rect ppos = parent_pos(rpos);
    4.71 -if(print_blit) fprintf(stderr,"parent-back.");
    4.72  		parent->BlitBack(z_pos, ppos);
    4.73  	}
    4.74  	if (is_hidden_now) return;
    4.75  self_redraw:
    4.76 -if(print_blit) fprintf(stderr,"back-self.");
    4.77  	BlitSelf(rpos); // 子は描画せず、自分だけ描画
    4.78  children_redraw:
    4.79  	for (; it != z; it++) {
    4.80 @@ -564,10 +556,8 @@
    4.81  }
    4.82  
    4.83  void PicContainer::BlitChildren(Rect rpos) {
    4.84 -if (print_blit) fprintf(stderr,"bc.");
    4.85  	iterator end = children.end();
    4.86  	for (iterator it = children.begin(); it != end; it++) {
    4.87 -if ( (*it)->is_hidden_now) if(print_blit) fprintf(stderr,"bch %p;",*it);
    4.88  		if ( (*it)->is_hidden_now) continue;
    4.89  		if ( (*it)->rel_pos.is_crossed(rpos)) {
    4.90  			Rect cpos = child_pos(rpos, *it);
    4.91 @@ -601,7 +591,6 @@
    4.92  	if (rpos.empty()) return;
    4.93  	Rect apos = QueryAbsPos(rpos);
    4.94  	// 必要に応じて保存、描画
    4.95 -if(print_blit) fprintf(stderr,"self-back.");
    4.96  	if (attribute & CACHE_BACK) root->BlitSurface(root->surface, apos, surface_back, rpos);
    4.97  	if (! (attribute & NO_PICTURE)) {
    4.98  		rpos.rmove(surface_x, surface_y);
    4.99 @@ -610,7 +599,6 @@
   4.100  			clip.rmove(rpos.lx, rpos.ty);
   4.101  			rpos.intersect(clip);
   4.102  		}
   4.103 -if(print_blit) fprintf(stderr,"self-blit.");
   4.104  		root->BlitSurface(surface_own, rpos, surface_alpha, surface_alpha_rect, root->surface, apos, attribute);
   4.105  	} else if (parent == NULL) { // 親がいないなら背景消去の責任をもつ
   4.106  		DSurfaceFill(root->surface, apos, 0, 0, 0);
   4.107 @@ -894,14 +882,6 @@
   4.108  	vector<UpdateItem>::iterator it;
   4.109  	vector<UpdateItem>::iterator end = update_rects.end();
   4.110  
   4.111 -if(print_blit){
   4.112 -	fprintf(stderr,"ExecUpdate Start: \n\t");
   4.113 -	for (it=update_rects.begin(); it != end; it++) {
   4.114 -		fprintf(stderr,"(%d,%d,%d,%d), ",it->apos.lx,it->apos.ty,it->apos.rx,it->apos.by);
   4.115 -	}
   4.116 -	fprintf(stderr,"\n");
   4.117 -}
   4.118 -
   4.119  	for (it=update_rects.begin(); it != end; it++) {
   4.120  		if (it->rpos.width() == 0) continue;
   4.121  
   4.122 @@ -925,14 +905,6 @@
   4.123  		}
   4.124  	}
   4.125  
   4.126 -if(print_blit){
   4.127 -	fprintf(stderr,"->\t");
   4.128 -	for (it=update_rects.begin(); it != end; it++) {
   4.129 -		fprintf(stderr,"(%d,%d,%d,%d), ",it->apos.lx,it->apos.ty,it->apos.rx,it->apos.by);
   4.130 -	}
   4.131 -	fprintf(stderr,"\n");
   4.132 -}
   4.133 -
   4.134  	int num = update_rects.size();
   4.135  	SDL_Rect* r = new SDL_Rect[num];
   4.136  	Rect confine = Rect(0, 0, surface->w, surface->h);
   4.137 @@ -942,10 +914,9 @@
   4.138  		UpdateItem& item = update_rects[i];
   4.139  		Rect& ur = item.apos;
   4.140  		if (ur.width() == 0) continue;
   4.141 -if(print_blit)fprintf(stderr,"%p: %d,%d,%d,%d",item.pic, item.apos.lx, item.apos.ty, item.apos.rx, item.apos.by);
   4.142  
   4.143  		item.pic->ExecReBlit(item.rpos);
   4.144 -if(print_blit)fprintf(stderr,"\n");
   4.145 +
   4.146  		ur.intersect(confine);
   4.147  		r[n].x = ur.lx;
   4.148  		r[n].y = ur.ty;
   4.149 @@ -954,7 +925,7 @@
   4.150  		if (surface != hw_surface) SDL_BlitSurface(surface, &r[n], hw_surface, &r[n]);
   4.151  		n++;
   4.152  	}
   4.153 -if(print_blit)fprintf(stderr,"\n");
   4.154 +
   4.155  	SDL_UpdateRects(hw_surface, n, r);
   4.156  	delete[] r;
   4.157  	update_rects.clear();
   4.158 @@ -1016,36 +987,36 @@
   4.159  #ifndef ALPHA_MAX
   4.160  #define ALPHA_MAX 255
   4.161  #endif
   4.162 -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 {
   4.163 -if (print_blit) fprintf(stderr," s %p %d:%d:%d:%d;",src, dest_r.lx, dest_r.ty, dest_r.rx, dest_r.by);
   4.164 +void PicRoot::BlitSurface(Surface* src, const Rect& src_r, const unsigned char* alpha, const Rect& alpha_r,
   4.165 +                          Surface* dest, const Rect& dest_r, int attribute) const
   4.166 +{
   4.167  	SDL_Rect sr = SDLed(src_r); SDL_Rect dr = SDLed(dest_r);
   4.168  
   4.169 -	if (attribute & PicBase::BLIT_MULTIPLY) {
   4.170 -if (print_blit) fprintf(stderr,"M");
   4.171 +	if (attribute & PicBase::BLIT_MULTIPLY)
   4.172 +	{
   4.173  		DSurfaceBlitMultiply(src, src_r, dest, dest_r);
   4.174  		return;
   4.175 -	} else if (attribute & PicBase::BLIT_SATURATE && src->format->Amask == 0) {
   4.176 -if (print_blit) fprintf(stderr,"S");
   4.177 +	}
   4.178 +	else if (attribute & PicBase::BLIT_ADD)
   4.179 +	{
   4.180  		unsigned char a = 255;
   4.181 -		if (alpha && alpha_r.width() >= 1 && alpha_r.height() >= 1) a = *alpha;
   4.182 -		DSurfaceBlitSaturate(src, src_r, dest, dest_r, a);
   4.183 +		if (alpha != NULL && alpha_r.width() >= 1 && alpha_r.height() >= 1)
   4.184 +			a = *alpha;
   4.185 +		DSurfaceBlitAdd(src, src_r, dest, dest_r, a);
   4.186  		return;
   4.187  	}
   4.188  
   4.189 -if (print_blit) fprintf(stderr,"N");
   4.190 -	if (alpha == NULL || alpha_r.width() == 0) { // simple blit
   4.191 -if (print_blit) fprintf(stderr,"X");
   4.192 +	if (alpha == NULL || alpha_r.width() == 0) // simple blit
   4.193 +	{
   4.194  		SDL_BlitSurface(src, &sr, dest, &dr);
   4.195  		return;
   4.196  	}
   4.197  	if (alpha_r.width() == 1 && alpha_r.height() == 1) {
   4.198  		if (*alpha == 255) {
   4.199 -if (print_blit) fprintf(stderr,"Y");
   4.200  			SDL_BlitSurface(src, &sr, dest, &dr);
   4.201  			return;
   4.202  		}
   4.203  		if (src->format->Amask == 0) { // use per-surface alpha
   4.204 -if (print_blit) fprintf(stderr,"Z");
   4.205  			SDL_SetAlpha(src, SDL_SRCALPHA, *alpha);
   4.206  			SDL_BlitSurface(src, &sr, dest, &dr);
   4.207  			SDL_SetAlpha(src, 0, 0);
   4.208 @@ -1053,9 +1024,7 @@
   4.209  		}
   4.210  	}
   4.211  	// generic alpha blit
   4.212 -if (print_blit) fprintf(stderr,"W");
   4.213  	DSurfaceBlitAlpha(src, src_r, dest, dest_r, alpha, alpha_r);
   4.214 -	return;
   4.215  }
   4.216  
   4.217  bool PicRoot::with_mask(Surface* s) {
     5.1 --- a/window/picture.h	Fri Dec 18 18:51:44 2009 +0100
     5.2 +++ b/window/picture.h	Fri Dec 18 20:41:38 2009 +0100
     5.3 @@ -71,7 +71,7 @@
     5.4  		bool is_hidden_now;
     5.5  		bool is_cached;
     5.6  	public:
     5.7 -		enum { /*MOBILE=1,*/ CACHE_BACK=2, /* CACHE_SELF=4,*/ NO_PICTURE=8, SOLID = 16, SURFACE_FREE = 32, FIT_SURFACE = 64, BLIT_SATURATE = 128, BLIT_MULTIPLY = 256, ALPHA_FREE=512};
     5.8 +		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};
     5.9  	private:
    5.10  		int attribute;
    5.11  
     6.1 --- a/window/render.cc	Fri Dec 18 18:51:44 2009 +0100
     6.2 +++ b/window/render.cc	Fri Dec 18 20:41:38 2009 +0100
     6.3 @@ -251,49 +251,56 @@
     6.4  #define CMASK1 0xff00ff
     6.5  #define CMASK2 0x00ff00
     6.6  
     6.7 -inline void blit_pixel(Uint32* dmem, Uint32* smem, const unsigned char* amem, bool use_srcalpha) {
     6.8 -	Uint32 d = *dmem;
     6.9 -	Uint32 s = *smem;
    6.10 -	Uint32 as = s>>ASHIFT;
    6.11 +inline void blit_pixel(Uint32* dest, Uint32* src, const unsigned char* alpha, bool use_srcalpha) {
    6.12 +	Uint32 dest_value = *dest;
    6.13 +	Uint32 src_value = *src;
    6.14 +	Uint32 as = src_value >> ASHIFT;
    6.15  	if (as == 255 || (!use_srcalpha) ) {
    6.16 -		as = *amem;
    6.17 +		as = *alpha;
    6.18  	} else {
    6.19 -		as += as>>7; /* 0-0xff -> 0-0x100 */
    6.20 -		as *= *amem;
    6.21 +		as += (as >> 7); /* 0-0xff -> 0-0x100 */
    6.22 +		as *= *alpha;
    6.23  		as >>= 8;
    6.24  	}
    6.25 -	as += as>>7;
    6.26 -	Uint32 s1 = s & CMASK1;
    6.27 -	Uint32 d1 = d & CMASK1;
    6.28 -	d1 = (d1 + (((s1-d1) * as) >> 8)) & CMASK1;
    6.29 -	s &= CMASK2;
    6.30 -	d &= CMASK2;
    6.31 -	d = (d + (((s-d) * as) >> 8)) & CMASK2;
    6.32 -	*dmem = d1 | d | 0xff000000;
    6.33 +	as += as >> 7;
    6.34 +	// Isolate Red and Blue components
    6.35 +	Uint32 src_c1 = src_value & CMASK1;
    6.36 +	Uint32 dest_c1 = dest_value & CMASK1;
    6.37 +	// Blend Red and Blue components
    6.38 +	dest_c1 = (dest_c1 + (((src_c1-dest_c1) * as) >> 8)) & CMASK1;
    6.39 +	// Isolate Green component
    6.40 +	src_value &= CMASK2;
    6.41 +	dest_value &= CMASK2;
    6.42 +	// Blend Green component
    6.43 +	dest_value = (dest_value + (((src_value-dest_value) * as) >> 8)) & CMASK2;
    6.44 +	// Put it alltogether
    6.45 +	*dest = dest_c1 | dest_value | 0xff000000;
    6.46  }
    6.47  
    6.48 -static void blit_line(Uint32* dmem, Uint32* smem, const unsigned char* amem,int ax0, int ax1, int awidth, int aj0, int aj1, bool use_srcalpha) {
    6.49 +static void blit_line(Uint32* dest, Uint32* src, const unsigned char* alpha,int ax0, int ax1, int awidth, int aj0, int aj1, bool use_srcalpha) {
    6.50  	int j;
    6.51  	int ax = ax0;
    6.52 -	const unsigned char* a = amem + ax0;
    6.53 -	Uint32* d = dmem;
    6.54 -	Uint32* s = smem;
    6.55 +	const unsigned char* a = alpha + ax0;
    6.56  	if (awidth == 1) { //  わりとよくあるので最適化
    6.57  		for (j=aj0; j < aj1; j++) {
    6.58 -			blit_pixel(d++, s++, amem, use_srcalpha);
    6.59 +			blit_pixel(dest++, src++, alpha, use_srcalpha);
    6.60  		}
    6.61 -	} else {
    6.62 +	}
    6.63 +	else
    6.64 +	{
    6.65  		for (j=aj0; j < aj1; j++) {
    6.66  			for (; ax<awidth; ax++)
    6.67 -				blit_pixel(d++, s++, a++, use_srcalpha);
    6.68 +				blit_pixel(dest++, src++, a++, use_srcalpha);
    6.69  			ax = 0;
    6.70 -			a = amem;
    6.71 +			a = alpha;
    6.72  		}
    6.73 -		for (; ax < ax1; ax++) blit_pixel(d++, s++, a++, use_srcalpha);
    6.74 +		for (; ax < ax1; ax++)
    6.75 +			blit_pixel(dest++, src++, a++, use_srcalpha);
    6.76  	}
    6.77  }
    6.78  
    6.79 -void DSurfaceBlitAlpha(Surface* src_o, const Rect& srcrect_o, Surface* dst_o, const Rect& dstrect_o, const unsigned char* alpha, const Rect& alpharect) {
    6.80 +void DSurfaceBlitAlpha(Surface* src_o, const Rect& srcrect_o, Surface* dst_o, const Rect& dstrect_o, const unsigned char* alpha, const Rect& alpharect)
    6.81 +{
    6.82  	SDL_Surface* dst = (SDL_Surface*)dst_o;
    6.83  	SDL_Surface* src = (SDL_Surface*)src_o;
    6.84  	SDL_PixelFormat& fmt = *dst->format;
    6.85 @@ -346,7 +353,7 @@
    6.86  	SDL_UnlockSurface(dst);
    6.87  }
    6.88  
    6.89 -void DSurfaceBlitSaturate(Surface* src_o, const Rect& srcrect_o, Surface* dst_o, const Rect& dstrect_o, unsigned char alpha) {
    6.90 +void DSurfaceBlitAdd(Surface* src_o, const Rect& srcrect_o, Surface* dst_o, const Rect& dstrect_o, unsigned char alpha) {
    6.91  	SDL_Surface* dst = (SDL_Surface*)dst_o;
    6.92  	SDL_Surface* src = (SDL_Surface*)src_o;
    6.93  
    6.94 @@ -370,21 +377,31 @@
    6.95  	int rshift = fmt.Rshift - fmt.Rloss; int rmask = fmt.Rmask;
    6.96  	int gshift = fmt.Gshift - fmt.Gloss; int gmask = fmt.Gmask;
    6.97  	int bshift = fmt.Bshift - fmt.Bloss; int bmask = fmt.Bmask;
    6.98 +	int ashift = src->format->Ashift - src->format->Aloss; int amask = src->format->Amask;
    6.99  	int allmask = rmask | gmask | bmask;
   6.100 -	int i;
   6.101 -	for (i=0; i<height; i++) {
   6.102 +	int i, j;
   6.103 +	for (i=0; i < height; i++) {
   6.104  		char* d = dmem; char* s = smem;
   6.105 -		int j; for (j=0; j<width; j++) {
   6.106 +		for (j=0; j < width; j++) {
   6.107  			Uint32 sd = *(Uint32*)s;
   6.108  			Uint32 dd = *(Uint32*)d;
   6.109  			if (sd&allmask) {
   6.110  				Uint32 sr = (sd&rmask)>>rshift;
   6.111  				Uint32 sg = (sd&gmask)>>gshift;
   6.112  				Uint32 sb = (sd&bmask)>>bshift;
   6.113 -				if (alpha != ALPHA_MAX) {
   6.114 -					sr = (sr*alpha)>>8;
   6.115 -					sg = (sg*alpha)>>8;
   6.116 -					sb = (sb*alpha)>>8;
   6.117 +				Uint32 alpha2 = alpha;
   6.118 +				if (amask)
   6.119 +				{
   6.120 +					alpha2 = ((sd&amask)>>ashift);
   6.121 +					alpha2 += alpha2 >> 7;
   6.122 +					alpha2 *= alpha;
   6.123 +					alpha2 >>= 8;
   6.124 +				}
   6.125 +				
   6.126 +				if (alpha2 != ALPHA_MAX) {
   6.127 +					sr = (sr*alpha2)>>8;
   6.128 +					sg = (sg*alpha2)>>8;
   6.129 +					sb = (sb*alpha2)>>8;
   6.130  				}
   6.131  				Uint32 dr = sr + ((dd&rmask)>>rshift);
   6.132  				Uint32 dg = sg + ((dd&gmask)>>gshift);
     7.1 --- a/window/render.h	Fri Dec 18 18:51:44 2009 +0100
     7.2 +++ b/window/render.h	Fri Dec 18 20:41:38 2009 +0100
     7.3 @@ -38,7 +38,7 @@
     7.4  void DSurfaceFillA(Surface* src, const Rect& rect, int r, int g, int b, int a=0xff); // 促促足促孫促促促贈促坦促促揃テ棚
     7.5  void DSurfaceMove(Surface* src_o, const Rect& srcrect, Surface* dst_o, const Rect& dstrect); // 促続促臓
     7.6  void DSurfaceBlitAlpha(Surface* src_o, const Rect& srcrect_o, Surface* dst_o, const Rect& dstrect_o, const unsigned char* alpha, const Rect& alpharect);
     7.7 -void DSurfaceBlitSaturate(Surface* src_o, const Rect& srcrect, Surface* dst_o, const Rect& dstrect, unsigned char alpha);
     7.8 +void DSurfaceBlitAdd(Surface* src_o, const Rect& srcrect, Surface* dst_o, const Rect& dstrect, unsigned char alpha);
     7.9  void DSurfaceBlitMultiply(Surface* src_o, const Rect& srcrect_o, Surface* dst_o, const Rect& dstrect_o);
    7.10  
    7.11  #endif