Mercurial > otakunoraifu
changeset 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 | 36d92d21300f |
children | bdd8a5ff8f46 |
files | scn2k/scn2k_grp.cc scn2k/scn2k_grp.h scn2k/scn2k_grpimpl.cc window/picture.cc window/picture.h window/render.cc window/render.h |
diffstat | 7 files changed, 94 insertions(+), 114 deletions(-) [+] |
line wrap: on
line diff
--- a/scn2k/scn2k_grp.cc +++ b/scn2k/scn2k_grp.cc @@ -168,7 +168,7 @@ void GrpObj::Update(void) { } if (picture == NULL) return; if (attr & UPDATE_POS) { - if ( (attr & SATURATE) || zoom != -1) { + if (zoom != -1) { int w=0, h=0; GetSrcGeom(w,h); picture->Move(_posx-w/2, _posy-h/2); @@ -238,8 +238,8 @@ void GrpObj::UpdateSurface(void) { picture->SetSurface(path.c_str(), 0, 0); picture->SetSurfaceRect(Rect(0,0,width,height)); } - if (attr & SATURATE) - picture->SetSurfaceAttribute(PicBase::BLIT_SATURATE); + if (attr & BLIT_ADD) + picture->SetSurfaceAttribute(PicBase::BLIT_ADD); } else if (gtype == MOJI) { // テキスト描画 if (print_moji.length() == 0) return; UpdateMoji(); @@ -396,8 +396,7 @@ void GrpObj::CreateGan(Event::Container& return; } - picture->SetSurfaceAttribute(PicBase::BLIT_SATURATE); - attr = Attribute(attr | UPDATE_POS | SATURATE); + attr = Attribute(attr | UPDATE_POS); const char* buf = data + 16; buf += strlen(buf) + 1; // 画像ファイル名が入っている @@ -631,7 +630,7 @@ Grp::Grp(Event::Container& _event, PicCo RegisterCommand(1, 33, 100, "grpCopy", (CmdImpl) &Grp::impl_grpCopy); RegisterCommand(1, 33, 1201, "recFill", (CmdImpl) &Grp::impl_recFill); RegisterCommand(1, 33, 1100, "recCopy", (CmdImpl) &Grp::impl_recCopy); - RegisterCommand(1, 33, 1101, "recMaskCopy", NULL); //FIXME + RegisterCommand(1, 33, 1101, "recMaskCopy", NULL); //TODO: Same thing as recCopy, but using source's alpha RegisterCommand(1, 33, 1600, "recAdd", (CmdImpl) &Grp::impl_recAdd); RegisterCommand(1, 33, 406, "grpPan", (CmdImpl) &Grp::impl_grpPan); @@ -734,7 +733,7 @@ Grp::Grp(Event::Container& _event, PicCo RegisterCommand(1, 82, 1019, "objBgColB", NULL); RegisterCommand(1, 81, 1020, "objColLevel", NULL); RegisterCommand(1, 82, 1020, "objBgColLevel", NULL); - RegisterCommand(1, 81, 1021, "objComposite", NULL);//(CmdImpl) &Grp::impl_objComposite); //FIXME: May be broken + RegisterCommand(1, 81, 1021, "objComposite", (CmdImpl) &Grp::impl_objComposite); //FIXME: May be broken RegisterCommand(1, 82, 1021, "objBgComposite", (CmdImpl) &Grp::impl_objComposite); RegisterCommand(1, 81, 1024, "objSetText", (CmdImpl) &Grp::impl_objSetText); RegisterCommand(1, 82, 1024, "objBgSetText", (CmdImpl) &Grp::impl_objSetText); @@ -1553,22 +1552,17 @@ void Grp::Exec(Cmd& cmd) { CommandHandler::Exec(cmd); //TODO: ??? - if (cmd.cmd1 == 1 && cmd.cmd2 == 0x3c && cmd.cmd3 == 0) { // ??? : KANOGI : 画像オブジェクトの削除? + if (cmd.cmd1 == 1 && cmd.cmd2 == 60 && cmd.cmd3 == 0) { // ??? : KANOGI : 画像オブジェクトの削除? DeleteObjPic(cmd.args[0].value); // 旧ファイル名のsurfaceを削除 GrpObj& g = grpobj[cmd.args[0].value]; g.attr = GrpObj::Attribute(g.attr | GrpObj::HIDDEN); cmd.clear(); } - //TODO: ??? - if ( (cmd.cmd1 == 1 || cmd.cmd1 == 2) && cmd.cmd2 == 0x51) { - /*GrpObj& g = grpobj[cmd.args[0].value]; - int attr; - GrpObjMap::iterator it; - for (it = g.children_obj.begin(); it != g.children_obj.end(); it++) - attr |= it->second.attr; - if (attr & GrpObj::UPDATE_ALL) - SetObjChanged(cmd.args[0].value);*/ + // Refresh changed objects... + //FIXME: should may be go away? + //Seems it'll work only for objects in the foreground + if ( (cmd.cmd1 == 1 || cmd.cmd1 == 2) && cmd.cmd2 == 81) { GrpObj* g; if (cmd.cmd1 == 2) g = GetGraphicObj(cmd.args[0].value, cmd.args[1].value);
--- a/scn2k/scn2k_grp.h +++ b/scn2k/scn2k_grp.h @@ -81,7 +81,7 @@ struct GrpObj { vector<Rect> src_pos; enum GrpType { FILLRECT = 1, FILE = 2, GAN = 3, MOJI = 4, DIGIT = 5} gtype; - enum Attribute { NONE=0, WIPEON=1, SATURATE=2, HIDDEN=4, + enum Attribute { NONE=0, WIPEON=1, BLIT_ADD=2, HIDDEN=4, UPDATE_PICTURE = 16, UPDATE_POS = 32, UPDATE_ALPHA = 64, UPDATE_SNUM = 128, UPDATE_CLIP = 256, UPDATE_VISIBLE = 512, UPDATE_ALL = (UPDATE_PICTURE | UPDATE_POS | UPDATE_ALPHA | UPDATE_SNUM | UPDATE_CLIP | UPDATE_VISIBLE), ANM_PLAYSTART = 0x8000, ANM_PLAYING = 0x10000,
--- a/scn2k/scn2k_grpimpl.cc +++ b/scn2k/scn2k_grpimpl.cc @@ -155,6 +155,7 @@ void Grp::impl_recFill(Cmd& cmd) { } void Grp::impl_recCopy(Cmd& cmd) { + //TODO: Handle forms 0 and 1 int sx = cmd.args[0].value; int sy = cmd.args[1].value; int w = cmd.args[2].value; @@ -172,7 +173,6 @@ void Grp::impl_recCopy(Cmd& cmd) { // if (dest == 0) screen->ReBlit(Rect(dx,dy,dx+w,dy+h)); cmd.cmd_type = CMD_SAVECMDGRP; } - else if (cmd.cmd4 == 3) { // alpha ゃcopy unsigned char alpha; if (cmd.args[8].value < 0) alpha = 0; @@ -191,7 +191,7 @@ void Grp::impl_recCopy(Cmd& cmd) { } void Grp::impl_recAdd(Cmd& cmd) { - if (cmd.cmd4 == 3) { // saturate mode alpha 篁 copy + if (cmd.cmd4 == 3) { // add mode alpha 篁 copy int sx = cmd.args[0].value; int sy = cmd.args[1].value; int w = cmd.args[2].value; @@ -205,15 +205,15 @@ void Grp::impl_recAdd(Cmd& cmd) { if (cmd.args[8].value < 0) alpha = 0; else if (cmd.args[8].value > 255) alpha = 255; else alpha = cmd.args[8].value; - eprintf("copy surface w/ saturate %d:(%d,%d) size(%d,%d) -> %d:(%d,%d)\n",src,sx,sy,w,h,dest,dx,dy); + eprintf("copy surface w/ add %d:(%d,%d) size(%d,%d) -> %d:(%d,%d)\n",src,sx,sy,w,h,dest,dx,dy); if (src == dest) { DSurfaceMove(Ssurface(src), rect, Dsurface(WORKPDT), rect); src = WORKPDT; } if (alpha != 0) { - // saturate mode : screen (picture) 筝篏 + // add mode : screen (picture) 筝篏 PicBase* screen_tmp = parent.create_leaf(Rect(0, 0, parent.Width(), parent.Height()), 0); - screen_tmp->SetSurface(Ssurface(src), 0, 0, PicBase::BLIT_SATURATE); + screen_tmp->SetSurface(Ssurface(src), 0, 0, PicBase::BLIT_ADD); screen_tmp->SetSurfaceRect(rect); screen_tmp->Move(dx, dy); screen_tmp->SetSurfaceAlpha(&alpha, Rect(0,0,1,1)); @@ -348,7 +348,7 @@ void Grp::impl_createObj(Cmd& cmd) { base_argc = 1; if (cmd.cmd3 == 1000) { /* <ゃ荐絎 */ - g->gtype = GrpObj::FILE; //FIXME: Strange thing in the main menu; that happens with objComposite + g->gtype = GrpObj::FILE; string name = cmd.Str(cmd.args[base_argc + 1]); if (name.find('?') != -1) {//TODO //Used for shading, with DAT/tcdata.tcc or other filename provided by #TONECURVE_FILENAME @@ -516,12 +516,11 @@ void Grp::impl_objColour(Cmd& cmd) { void Grp::impl_objComposite(Cmd& cmd) {//FIXME int base_arg = 0; GrpObj* g = GetGraphicObjVarMode(cmd, base_arg, (cmd.cmd2 == 0x51)); - if (cmd.args[base_arg + 1].value == 1) { - g->attr = GrpObj::Attribute(g->attr | GrpObj::SATURATE); + g->attr = GrpObj::Attribute(g->attr | GrpObj::BLIT_ADD); cmd.clear(); } else if (cmd.args[base_arg + 1].value == 0) { - g->attr = GrpObj::Attribute(g->attr & (~GrpObj::SATURATE)); + g->attr = GrpObj::Attribute(g->attr & (~GrpObj::BLIT_ADD)); cmd.clear(); } g->SetUpdate(); @@ -765,3 +764,4 @@ void Grp::impl_movPlay(Cmd& cmd) { cmd.clear(); } } +
--- a/window/picture.cc +++ b/window/picture.cc @@ -41,10 +41,9 @@ using namespace std; -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); +void DSurfaceBlitAdd(Surface* src_o, const Rect& srcrect, Surface* dst_o, const Rect& dstrect, unsigned char alpha); void DSurfaceBlitMultiply(Surface* src_o, const Rect& srcrect, Surface* dst_o, const Rect& dstrect); void DSurfaceFill(Surface* src, const Rect& rect, int r, int g, int b, int a=0xff); // クリア #if 0 /* DEBUG */ @@ -180,13 +179,9 @@ void PicBase::ExecReBlit(const Rect& rpo Rect rpos = rpos_c; Rect abs_r = QueryAbsPos(rpos); Rect ppos = parent_pos(rpos); -if(print_blit) fprintf(stderr,"back."); if (parent) parent->BlitBack(z_pos, ppos); -if(print_blit) fprintf(stderr,"self."); if (!is_hidden_now) Blit(rpos); -if(print_blit) fprintf(stderr,"front."); if (parent) parent->BlitFront(z_pos, ppos); -if(print_blit) fprintf(stderr,"end."); } void PicBase::ZMove(PicBase* move_to) { @@ -324,7 +319,7 @@ void PicBase::SetSurfaceAlpha(const unsi void PicBase::SetSurfaceColorKey(int r, int g, int b) { surface_alpha = 0; surface_alpha_rect = Rect(0,0); - attribute &= ~(BLIT_SATURATE | BLIT_MULTIPLY); + attribute &= ~(BLIT_ADD | BLIT_MULTIPLY); if (surface_own) { int key = SDL_MapRGB( ((SDL_Surface*)surface_own)->format, r, g, b); key |= 0xff000000; @@ -402,7 +397,7 @@ void PicBase::SetSurface(Surface* new_su if (surface_own != NULL && (attribute & SURFACE_FREE)) { root->DeleteSurface(surface_own); } - attribute &= ~(SURFACE_FREE | BLIT_SATURATE | BLIT_MULTIPLY | NO_PICTURE | SOLID); + attribute &= ~(SURFACE_FREE | BLIT_ADD | BLIT_MULTIPLY | NO_PICTURE | SOLID); attribute |= new_attr; surface_own = new_surface; surface_x = x; @@ -469,9 +464,9 @@ void PicBase::SetClipArea(const Rect& r) } void PicBase::SetSurfaceAttribute(int new_attribute) { - attribute &= ~(BLIT_SATURATE | BLIT_MULTIPLY); - attribute |= new_attribute & (BLIT_SATURATE | BLIT_MULTIPLY); - if (new_attribute & (BLIT_SATURATE | BLIT_MULTIPLY)) { + attribute &= ~(BLIT_ADD | BLIT_MULTIPLY); + attribute |= new_attribute & (BLIT_ADD | BLIT_MULTIPLY); + if (new_attribute & (BLIT_ADD | BLIT_MULTIPLY)) { rel_solid_area = Rect(0,0); } } @@ -539,19 +534,16 @@ void PicContainer::BlitBack(iterator z, Rect cpos = child_pos(rpos, *z); Rect apos = (*z)->QueryAbsPos(cpos); Rect draw_rpos = (*z)->parent_pos(cpos); -if(print_blit) fprintf(stderr,"cahce."); root->BlitSurface(surface_back, draw_rpos, root->surface, apos); goto self_redraw; } parent_redraw: if (parent) { Rect ppos = parent_pos(rpos); -if(print_blit) fprintf(stderr,"parent-back."); parent->BlitBack(z_pos, ppos); } if (is_hidden_now) return; self_redraw: -if(print_blit) fprintf(stderr,"back-self."); BlitSelf(rpos); // 子は描画せず、自分だけ描画 children_redraw: for (; it != z; it++) { @@ -564,10 +556,8 @@ children_redraw: } void PicContainer::BlitChildren(Rect rpos) { -if (print_blit) fprintf(stderr,"bc."); iterator end = children.end(); for (iterator it = children.begin(); it != end; it++) { -if ( (*it)->is_hidden_now) if(print_blit) fprintf(stderr,"bch %p;",*it); if ( (*it)->is_hidden_now) continue; if ( (*it)->rel_pos.is_crossed(rpos)) { Rect cpos = child_pos(rpos, *it); @@ -601,7 +591,6 @@ void PicContainer::BlitSelf(Rect rpos) { if (rpos.empty()) return; Rect apos = QueryAbsPos(rpos); // 必要に応じて保存、描画 -if(print_blit) fprintf(stderr,"self-back."); if (attribute & CACHE_BACK) root->BlitSurface(root->surface, apos, surface_back, rpos); if (! (attribute & NO_PICTURE)) { rpos.rmove(surface_x, surface_y); @@ -610,7 +599,6 @@ if(print_blit) fprintf(stderr,"self-back clip.rmove(rpos.lx, rpos.ty); rpos.intersect(clip); } -if(print_blit) fprintf(stderr,"self-blit."); root->BlitSurface(surface_own, rpos, surface_alpha, surface_alpha_rect, root->surface, apos, attribute); } else if (parent == NULL) { // 親がいないなら背景消去の責任をもつ DSurfaceFill(root->surface, apos, 0, 0, 0); @@ -894,14 +882,6 @@ void PicRoot::ExecUpdate(void) { 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++) { - fprintf(stderr,"(%d,%d,%d,%d), ",it->apos.lx,it->apos.ty,it->apos.rx,it->apos.by); - } - fprintf(stderr,"\n"); -} - for (it=update_rects.begin(); it != end; it++) { if (it->rpos.width() == 0) continue; @@ -925,14 +905,6 @@ if(print_blit){ } } -if(print_blit){ - fprintf(stderr,"->\t"); - for (it=update_rects.begin(); it != end; it++) { - fprintf(stderr,"(%d,%d,%d,%d), ",it->apos.lx,it->apos.ty,it->apos.rx,it->apos.by); - } - fprintf(stderr,"\n"); -} - int num = update_rects.size(); SDL_Rect* r = new SDL_Rect[num]; Rect confine = Rect(0, 0, surface->w, surface->h); @@ -942,10 +914,9 @@ if(print_blit){ UpdateItem& item = update_rects[i]; Rect& ur = item.apos; if (ur.width() == 0) continue; -if(print_blit)fprintf(stderr,"%p: %d,%d,%d,%d",item.pic, item.apos.lx, item.apos.ty, item.apos.rx, item.apos.by); item.pic->ExecReBlit(item.rpos); -if(print_blit)fprintf(stderr,"\n"); + ur.intersect(confine); r[n].x = ur.lx; r[n].y = ur.ty; @@ -954,7 +925,7 @@ if(print_blit)fprintf(stderr,"\n"); if (surface != hw_surface) SDL_BlitSurface(surface, &r[n], hw_surface, &r[n]); n++; } -if(print_blit)fprintf(stderr,"\n"); + SDL_UpdateRects(hw_surface, n, r); delete[] r; update_rects.clear(); @@ -1016,36 +987,36 @@ inline SDL_Rect SDLed(const Rect& rect) #ifndef ALPHA_MAX #define ALPHA_MAX 255 #endif -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 { -if (print_blit) fprintf(stderr," s %p %d:%d:%d:%d;",src, dest_r.lx, dest_r.ty, dest_r.rx, dest_r.by); +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 +{ SDL_Rect sr = SDLed(src_r); SDL_Rect dr = SDLed(dest_r); - if (attribute & PicBase::BLIT_MULTIPLY) { -if (print_blit) fprintf(stderr,"M"); + if (attribute & PicBase::BLIT_MULTIPLY) + { DSurfaceBlitMultiply(src, src_r, dest, dest_r); return; - } else if (attribute & PicBase::BLIT_SATURATE && src->format->Amask == 0) { -if (print_blit) fprintf(stderr,"S"); + } + else if (attribute & PicBase::BLIT_ADD) + { unsigned char a = 255; - if (alpha && alpha_r.width() >= 1 && alpha_r.height() >= 1) a = *alpha; - DSurfaceBlitSaturate(src, src_r, dest, dest_r, a); + if (alpha != NULL && alpha_r.width() >= 1 && alpha_r.height() >= 1) + a = *alpha; + DSurfaceBlitAdd(src, src_r, dest, dest_r, a); return; } -if (print_blit) fprintf(stderr,"N"); - if (alpha == NULL || alpha_r.width() == 0) { // simple blit -if (print_blit) fprintf(stderr,"X"); + if (alpha == NULL || alpha_r.width() == 0) // simple blit + { SDL_BlitSurface(src, &sr, dest, &dr); return; } if (alpha_r.width() == 1 && alpha_r.height() == 1) { if (*alpha == 255) { -if (print_blit) fprintf(stderr,"Y"); SDL_BlitSurface(src, &sr, dest, &dr); return; } if (src->format->Amask == 0) { // use per-surface alpha -if (print_blit) fprintf(stderr,"Z"); SDL_SetAlpha(src, SDL_SRCALPHA, *alpha); SDL_BlitSurface(src, &sr, dest, &dr); SDL_SetAlpha(src, 0, 0); @@ -1053,9 +1024,7 @@ if (print_blit) fprintf(stderr,"Z"); } } // generic alpha blit -if (print_blit) fprintf(stderr,"W"); DSurfaceBlitAlpha(src, src_r, dest, dest_r, alpha, alpha_r); - return; } bool PicRoot::with_mask(Surface* s) {
--- a/window/picture.h +++ b/window/picture.h @@ -71,7 +71,7 @@ class PicBase { bool is_hidden_now; bool is_cached; public: - 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}; + 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}; private: int attribute;
--- a/window/render.cc +++ b/window/render.cc @@ -251,49 +251,56 @@ void DSurfaceFillA(Surface* dsto, const #define CMASK1 0xff00ff #define CMASK2 0x00ff00 -inline void blit_pixel(Uint32* dmem, Uint32* smem, const unsigned char* amem, bool use_srcalpha) { - Uint32 d = *dmem; - Uint32 s = *smem; - Uint32 as = s>>ASHIFT; +inline void blit_pixel(Uint32* dest, Uint32* src, const unsigned char* alpha, bool use_srcalpha) { + Uint32 dest_value = *dest; + Uint32 src_value = *src; + Uint32 as = src_value >> ASHIFT; if (as == 255 || (!use_srcalpha) ) { - as = *amem; + as = *alpha; } else { - as += as>>7; /* 0-0xff -> 0-0x100 */ - as *= *amem; + as += (as >> 7); /* 0-0xff -> 0-0x100 */ + as *= *alpha; as >>= 8; } - as += as>>7; - Uint32 s1 = s & CMASK1; - Uint32 d1 = d & CMASK1; - d1 = (d1 + (((s1-d1) * as) >> 8)) & CMASK1; - s &= CMASK2; - d &= CMASK2; - d = (d + (((s-d) * as) >> 8)) & CMASK2; - *dmem = d1 | d | 0xff000000; + as += as >> 7; + // Isolate Red and Blue components + Uint32 src_c1 = src_value & CMASK1; + Uint32 dest_c1 = dest_value & CMASK1; + // Blend Red and Blue components + dest_c1 = (dest_c1 + (((src_c1-dest_c1) * as) >> 8)) & CMASK1; + // Isolate Green component + src_value &= CMASK2; + dest_value &= CMASK2; + // Blend Green component + dest_value = (dest_value + (((src_value-dest_value) * as) >> 8)) & CMASK2; + // Put it alltogether + *dest = dest_c1 | dest_value | 0xff000000; } -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) { +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) { int j; int ax = ax0; - const unsigned char* a = amem + ax0; - Uint32* d = dmem; - Uint32* s = smem; + const unsigned char* a = alpha + ax0; if (awidth == 1) { // わりとよくあるので最適化 for (j=aj0; j < aj1; j++) { - blit_pixel(d++, s++, amem, use_srcalpha); + blit_pixel(dest++, src++, alpha, use_srcalpha); } - } else { + } + else + { for (j=aj0; j < aj1; j++) { for (; ax<awidth; ax++) - blit_pixel(d++, s++, a++, use_srcalpha); + blit_pixel(dest++, src++, a++, use_srcalpha); ax = 0; - a = amem; + a = alpha; } - for (; ax < ax1; ax++) blit_pixel(d++, s++, a++, use_srcalpha); + for (; ax < ax1; ax++) + blit_pixel(dest++, src++, a++, use_srcalpha); } } -void DSurfaceBlitAlpha(Surface* src_o, const Rect& srcrect_o, Surface* dst_o, const Rect& dstrect_o, const unsigned char* alpha, const Rect& alpharect) { +void DSurfaceBlitAlpha(Surface* src_o, const Rect& srcrect_o, Surface* dst_o, const Rect& dstrect_o, const unsigned char* alpha, const Rect& alpharect) +{ SDL_Surface* dst = (SDL_Surface*)dst_o; SDL_Surface* src = (SDL_Surface*)src_o; SDL_PixelFormat& fmt = *dst->format; @@ -346,7 +353,7 @@ void DSurfaceBlitAlpha(Surface* src_o, c SDL_UnlockSurface(dst); } -void DSurfaceBlitSaturate(Surface* src_o, const Rect& srcrect_o, Surface* dst_o, const Rect& dstrect_o, unsigned char alpha) { +void DSurfaceBlitAdd(Surface* src_o, const Rect& srcrect_o, Surface* dst_o, const Rect& dstrect_o, unsigned char alpha) { SDL_Surface* dst = (SDL_Surface*)dst_o; SDL_Surface* src = (SDL_Surface*)src_o; @@ -370,21 +377,31 @@ void DSurfaceBlitSaturate(Surface* src_o int rshift = fmt.Rshift - fmt.Rloss; int rmask = fmt.Rmask; int gshift = fmt.Gshift - fmt.Gloss; int gmask = fmt.Gmask; int bshift = fmt.Bshift - fmt.Bloss; int bmask = fmt.Bmask; + int ashift = src->format->Ashift - src->format->Aloss; int amask = src->format->Amask; int allmask = rmask | gmask | bmask; - int i; - for (i=0; i<height; i++) { + int i, j; + for (i=0; i < height; i++) { char* d = dmem; char* s = smem; - int j; for (j=0; j<width; j++) { + for (j=0; j < width; j++) { Uint32 sd = *(Uint32*)s; Uint32 dd = *(Uint32*)d; if (sd&allmask) { Uint32 sr = (sd&rmask)>>rshift; Uint32 sg = (sd&gmask)>>gshift; Uint32 sb = (sd&bmask)>>bshift; - if (alpha != ALPHA_MAX) { - sr = (sr*alpha)>>8; - sg = (sg*alpha)>>8; - sb = (sb*alpha)>>8; + Uint32 alpha2 = alpha; + if (amask) + { + alpha2 = ((sd&amask)>>ashift); + alpha2 += alpha2 >> 7; + alpha2 *= alpha; + alpha2 >>= 8; + } + + if (alpha2 != ALPHA_MAX) { + sr = (sr*alpha2)>>8; + sg = (sg*alpha2)>>8; + sb = (sb*alpha2)>>8; } Uint32 dr = sr + ((dd&rmask)>>rshift); Uint32 dg = sg + ((dd&gmask)>>gshift);
--- a/window/render.h +++ b/window/render.h @@ -38,7 +38,7 @@ void DSurfaceFill(Surface* src, const Rect& rect, int r, int g, int b, int a=0xff); // 促俗促棚促蔵 void DSurfaceFillA(Surface* src, const Rect& rect, int r, int g, int b, int a=0xff); // 促促足促孫促促促贈促坦促促揃テ棚 void DSurfaceMove(Surface* src_o, const Rect& srcrect, Surface* dst_o, const Rect& dstrect); // 促続促臓 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); +void DSurfaceBlitAdd(Surface* src_o, const Rect& srcrect, Surface* dst_o, const Rect& dstrect, unsigned char alpha); void DSurfaceBlitMultiply(Surface* src_o, const Rect& srcrect_o, Surface* dst_o, const Rect& dstrect_o); #endif