Mercurial > otakunoraifu
diff scn2k/scn2k_grpimpl.cc @ 56:c7bcc0ec2267
* replaced Grp and Text classes by the TextImpl and GrpImpl ones
* splitted scn2k.h into smaller header files
* moved some definitions from scn2k_*.cc to the header files
* moved opcode implementation to scn2k_*impl.cc
author | thib |
---|---|
date | Thu, 30 Apr 2009 19:05:09 +0000 |
parents | |
children | e16e13d8cd68 |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/scn2k/scn2k_grpimpl.cc @@ -0,0 +1,767 @@ +/* + * Copyright (c) 2009 Thibaut GIRKA + * Copyright (c) 2004-2006 Kazunori "jagarl" Ueno + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "scn2k_grp.h" +#include "system/system_config.h" +#include "music2/music.h" +#include "window/render.h" + +void Grp::impl_stackClear (Cmd& cmd) { + cmd.cmd_type = CMD_SAVECMDGRP_START; +} + +void Grp::impl_grpBuffer (Cmd& cmd) { + const char* name = cmd.Str(cmd.args[0]); + int pdt = cmd.args[1].value; + eprintf("load surface %s pdt %d\n",name, pdt); + if (pdt == 0) + reserved_load_surface0 = name; // 画像読み込みは 01-1f:0000 まで待つ + else if (pdt == 1) + LoadSurface(name); // 背景絵読み込み? + else + LoadSurface(name, pdt); + cmd.cmd_type = CMD_SAVECMDGRP; +} + +void Grp::impl_grpMulti(Cmd& cmd) { + int pos = cmd.args[0].value; + const char* name = cmd.Str(cmd.args[1]); + int sel = cmd.args[2].value; + eprintf("set foreground %s sel %d pos %d\n",name, sel, pos); + AddSurface(name); + StartAnm(sel); + event.RegisterGlobalPressFunc(&Pressed, (void*)this); + status = WAIT_ANM; + cmd.cmd_type = CMD_SAVECMDGRP_ONCE; +} + +void Grp::impl_grpOpen(Cmd& cmd) { + const char* name = cmd.Str(cmd.args[0]); + int sel = cmd.args[1].value; + + if (name[0] == '?') + LoadSurface(); + else if(cmd.cmd3 == 73) + LoadSurface(name, 1); + else + LoadSurface(name); + + StartAnm(sel); + status = WAIT_ANM; + event.RegisterGlobalPressFunc(&Pressed, (void*)this); + + if (name[0] == '?') + cmd.cmd_type = CMD_SAVECMDGRP_ONCE; + else + cmd.cmd_type = CMD_SAVECMDGRP_START; +} + +void Grp::impl_shake(Cmd& cmd) { + // shake screen + char key[11]; + sprintf(key, "#SHAKE.%03d", cmd.args[0].value); + if (config->SearchParam(key) != 2) { + fprintf(stderr,"Cannot find shake pattern %d; use default pattern\n",cmd.args[0].value); + strcpy(key, "#SHAKE.000"); // default key + } + int num; + const int* pattern; + pattern = config->GetParamArray(key, num); + if (pattern) { + StartShake(num, pattern); + status = WAIT_SHAKE; + } + cmd.clear(); +} + +void Grp::impl_grpCopy(Cmd& cmd) { + if (cmd.cmd4 == 2) { // copy (KANOGI) + int sx = cmd.args[0].value; + int sy = cmd.args[1].value; + int w = cmd.args[2].value - sx; + int h = cmd.args[3].value - sy; + Rect rect(sx, sy, sx+w, sy+h); + int src = cmd.args[4].value; + int dx = cmd.args[5].value; + int dy = cmd.args[6].value; + int dest = cmd.args[7].value; + unsigned char alpha; + eprintf("copy surface %d:(%d,%d) size(%d,%d) -> %d:(%d,%d)\n",src,sx,sy,w,h,dest,dx,dy); + printf("copy surface %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; + } + parent.Root().BlitSurface(Ssurface(src), rect, Dsurface(dest), Rect(dx,dy)); + if (dest == 0) screen->ReBlit(Rect(dx,dy,dx+w,dy+h)); + cmd.clear(); + } +} + +void Grp::impl_recFill(Cmd& cmd) { + int x = cmd.args[0].value; + int y = cmd.args[1].value; + int w = cmd.args[2].value; + int h = cmd.args[3].value; + Rect rect(x, y, x+w, y+w); + int pdt = cmd.args[4].value; + int r = cmd.args[5].value; + int g = cmd.args[6].value; + int b = cmd.args[7].value; + + if (cmd.cmd4 == 2) { + eprintf("clear %d:(%d,%d) size (%d,%d) r %d g %d b %d\n",pdt,x,y,w,h,r,g,b); + DSurfaceFill(Dsurface(pdt), rect, r, g, b); + // if (pdt == 0) screen->ReBlit(rect); + cmd.cmd_type = CMD_SAVECMDGRP; + } + else if (cmd.cmd4 == 3) { // alpha つきfill + int a = cmd.args[8].value; + eprintf("alpha-clear %d:(%d,%d) size (%d,%d) r %d g %d b %d a %d\n",pdt,x,y,w,h,r,g,b,a); + if (a <= 0) ; + else if (a >= 255) DSurfaceFill(Dsurface(pdt), rect, r, g, b); + else { + DSurfaceFill(Dsurface(WORKPDT), rect, r, g, b, a); + parent.Root().BlitSurface(Dsurface(WORKPDT), rect, Dsurface(pdt), rect); + } + // if (pdt == 0) screen->ReBlit(rect); + cmd.clear(); + } +} + +void Grp::impl_recCopy(Cmd& cmd) { + int sx = cmd.args[0].value; + int sy = cmd.args[1].value; + int w = cmd.args[2].value; + int h = cmd.args[3].value; + Rect rect(sx, sy, sx + w, sy + h); + int src = cmd.args[4].value; + int dx = cmd.args[5].value; + int dy = cmd.args[6].value; + int dest = cmd.args[7].value; + + if (cmd.cmd4 == 2) { + eprintf("copy surface %d:(%d,%d) size(%d,%d) -> %d:(%d,%d)\n",src,sx,sy,w,h,dest,dx,dy); + parent.Root().BlitSurface(Ssurface(src), rect, Dsurface(dest), Rect(dx,dy)); + //DSurfaceMove(Ssurface(src), Rect(sx,sy,sx+w,sy+h), Dsurface(dest), Rect(dx,dy)); + // 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; + else if (cmd.args[8].value > 255) alpha = 255; + else alpha = cmd.args[8].value; + eprintf("copy surface %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) + parent.Root().BlitSurface(Ssurface(src), rect, &alpha, Rect(0,0,1,1), Dsurface(dest), Rect(dx,dy), 0); + // if (dest == 0) screen->ReBlit(Rect(dx,dy,dx+w,dy+h)); + cmd.clear(); + } +} + +void Grp::impl_recAdd(Cmd& cmd) { + if (cmd.cmd4 == 3) { // saturate mode で alpha 付き copy + int sx = cmd.args[0].value; + int sy = cmd.args[1].value; + int w = cmd.args[2].value; + int h = cmd.args[3].value; + Rect rect(sx, sy, sx+w, sy+h); + int src = cmd.args[4].value; + int dx = cmd.args[5].value; + int dy = cmd.args[6].value; + int dest = cmd.args[7].value; + unsigned char alpha; + 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); + if (src == dest) { + DSurfaceMove(Ssurface(src), rect, Dsurface(WORKPDT), rect); + src = WORKPDT; + } + if (alpha != 0) { + // saturate 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->SetSurfaceRect(rect); + screen_tmp->Move(dx, dy); + screen_tmp->SetSurfaceAlpha(&alpha, Rect(0,0,1,1)); + screen_tmp->SimpleBlit(Dsurface(dest)); + delete screen_tmp; + } + cmd.clear(); + } +} + +void Grp::impl_grpPan(Cmd& cmd) { + if (cmd.cmd4 == 0) { + Rect r_from(cmd.args[0].value, cmd.args[1].value); + Rect r_to(cmd.args[2].value, cmd.args[3].value); + int src_pdt = cmd.args[4].value; + Rect r(cmd.args[5].value,cmd.args[6].value,cmd.args[7].value+1,cmd.args[8].value+1); + int tm = cmd.args[9].value; + fprintf(stderr,"??? cmd time %d\n",tm); + // anm1 = new ScnGrpMove(event, screen, parent.Root(), surface, r, Ssurface(2), r_from, r_to, tm); + // status = WAIT_ANM; + } +} + +void Grp::impl_snmBgScroll(Cmd& cmd) { + if (cmd.cmd4 == 0) { // スクロールする画像効果(Princess Bride) + if (anm2 != NULL) { + anm2->Abort(); + delete anm2; + anm2 = NULL; + } + PicBase* pic; Surface* s; + Rect r(cmd.args[1].value, cmd.args[2].value, cmd.args[3].value+1, cmd.args[4].value+1); + const char* name = cmd.Str(cmd.args[5]); + Rect sr_start(cmd.args[6].value,cmd.args[7].value); + Rect sr_end(cmd.args[8].value,cmd.args[9].value); + int tm = cmd.args[10].value; + LoadSurface(name, 2); /* PDT2 に読み込み、と決め打ち */ + + anm2 = new ScnGrpMove(event, screen, parent.Root(), Dsurface(1), r, Ssurface(2), sr_start, sr_end, tm); + cmd.cmd_type = CMD_SAVECMDGRP; + } +} + +void Grp::impl_snmPlay(Cmd& cmd) { + if (cmd.cmd4 == 0) { + // カードが落ちるアニメーション + int i; + ScnGrpAnm* new_anm = new ScnGrpAnm(event, screen, *this); + if (cmd.cmd3 == 0x834 || cmd.cmd3 == 0x835) { + AbortAnm(); + anm1 = new_anm; + if (cmd.cmd3 == 0x835) { + status = WAIT_ANM; + event.RegisterGlobalPressFunc(&Pressed, (void*)this); + } + } else { + anm2 = new_anm; + } + for (i=0; i<cmd.argc; i++) { + const char* name = cmd.Str(cmd.args[i*3+1]); + int tm = cmd.args[i*3+2].value; + new_anm->push_back(ScnGrpAnmAtom(name,tm)); + } + new_anm->CalcTotal(); + cmd.clear(); + } +} + +void Grp::impl_cgGet(Cmd& cmd) { + if (cmd.cmd3 == 0x5dc) // Total number of CG + cmd.SetSysvar(cgm_size); + + if (cmd.cmd3 == 0x5dd) // Number of CG viewed + cmd.SetSysvar(cgm_data.size()); + + if (cmd.cmd3 == 0x5de) // Percentage of CG viewed + cmd.SetSysvar(cgm_data.size() * 100 / cgm_size); +} + +void Grp::impl_cgStatus(Cmd& cmd) { + string s = cmd.Str(cmd.args[0]); + if (cgm_info.find(s) == cgm_info.end()) { + fprintf(stderr,"cmd 01-04:05e0 : cannot find cgm-info of '%s'\n",s.c_str()); + cmd.SetSysvar(-1); + } + else { + int n = cgm_info[s]; + if (cmd.cmd3 == 1503) cmd.SetSysvar(n); + else { + if (cgm_data.find(n) == cgm_data.end()) cmd.SetSysvar(0); + else cmd.SetSysvar(1); + } + } +} + +void Grp::impl_objClear(Cmd& cmd) { //FIXME: may be broken (doesn't reflect what Haeleth says) + if (cmd.cmd1 == 1) + DeleteObj(cmd.args[0].value); + if (cmd.cmd1 == 2) + DeleteSubObj(cmd.args[0].value, cmd.args[1].value); + cmd.clear(); +} + +void Grp::impl_createObj(Cmd& cmd) { + /**************: + 0x47 : オブジェクト内容の設定 + 1100: G00 file + 1003: GAN file + 1100: rect + 1200: string + 1300: weather effects + 1400: number + */ + int base_argc = 0; + + if (cmd.cmd1 == 1) { // 1: group object + DeleteObjPic(cmd.args[0].value); // 旧ファイル名のsurfaceを削除 + if (cmd.cmd2 == 71) + DeleteObjPic(cmd.args[0].value); // 旧ファイル名のsurfaceを削除 + } + else { // 2: single object in group + DeleteSubObjPic(cmd.args[0].value, cmd.args[1].value); // 旧ファイル名のsurfaceを削除 + if (cmd.cmd2 == 71) + DeleteSubObjPic(cmd.args[0].value, cmd.args[1].value); // 旧ファイル名のsurfaceを削除 + } + + GrpObj* g = (cmd.cmd2 == 71) ? &grpobj[cmd.args[0].value] : &bs_obj[cmd.args[0].value]; + if (cmd.cmd1 == 2) // 2: single object in a group + g = &g->children_obj[cmd.args[1].value]; + + if (cmd.cmd1 == 2) + base_argc = 1; + + if (cmd.cmd3 == 1000) { /* ファイル名設定 */ + g->gtype = GrpObj::FILE; //FIXME: Strange thing in the main menu; that happens with objComposite + 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 + printf("Warning: the part after the '?' was removed: '%s'\n", name.c_str()); + name.erase(name.find('?')); // '?' 以降の意味がわからない + } + g->name = name; + } else if (cmd.cmd3 == 1003) { /* ファイル名設定(GAN含む) */ + g->gtype = GrpObj::GAN; + if (cmd.Str(cmd.args[base_argc + 1]) == string("???")) + g->name = cmd.Str(cmd.args[base_argc + 2]); + else + g->name = cmd.Str(cmd.args[base_argc + 1]); + g->gan_name = cmd.Str(cmd.args[base_argc + 2]); + + if (cmd.cmd4 >= 1 && cmd.args[base_argc + 3].value == 0) + g->attr = GrpObj::Attribute(g->attr | GrpObj::HIDDEN); + else + g->attr = GrpObj::Attribute(g->attr & ~(GrpObj::HIDDEN)); + + if (cmd.argc >= base_argc + 5) + g->SetPos(1, cmd.args[base_argc + 4].value, -cmd.args[base_argc + 5].value); + + if (g->name.find('?') != -1) { + g->name.erase(g->name.find('?')); + g->gan_name = cmd.Str(cmd.args[base_argc + 2]); + } + } else if (cmd.cmd3 == 1200) { // 画像を文字列として指定 + g->gtype = GrpObj::MOJI; + g->print_moji = cmd.Str(cmd.args[base_argc + 1]); + g->attr = GrpObj::Attribute(g->attr & (~GrpObj::HIDDEN)); // 常に表示がデフォルト? + cmd.clear(); + } else if (cmd.cmd3 == 1400) { // 数値を画像として表示 + g->gtype = GrpObj::DIGIT; + g->name = cmd.Str(cmd.args[base_argc + 1]); + } + + CreateObj(cmd.args[0].value); + if (cmd.cmd1 == 2) + CreateSubObj(cmd.args[0].value, cmd.args[1].value); + + if (cmd.cmd3 == 1000 || cmd.cmd3 == 1003 || cmd.cmd3 == 1200 || cmd.cmd3 == 1400) { + // FILE, GAN, MOJI, DIGIT ならば座標等の設定を行う + if (cmd.cmd4 >= 1) { + if (cmd.args[2+base_argc].value == 0) { + g->attr = GrpObj::Attribute(g->attr | GrpObj::HIDDEN); + } else { + g->attr = GrpObj::Attribute(g->attr & (~GrpObj::HIDDEN)); + } + SetObjChanged(cmd.args[0].value); + } + if (cmd.cmd4 >= 2) { // 座標等も設定 + g->SetPos(0, cmd.args[3+base_argc].value, cmd.args[4+base_argc].value); + } + if ( (cmd.cmd3 == 1000 || cmd.cmd3 == 1003) && cmd.cmd4 >= 3) { // pattern 番号も設定 + g->SetSurfaceNum(cmd.args[5+base_argc].value); + base_argc++; // 1000 (FILE) / 1003 (GAN) の場合のみこのオプションは存在する + } + cmd.clear(); + } else { + fprintf(stderr,"CreateObj : cmd.cmd3 = %04x ; not supported!\n",cmd.cmd3); + } +} + +void Grp::impl_gan(Cmd& cmd) { + int base_arg = 0; + GrpObj* g = GetGraphicObjVarMode(cmd, base_arg); + + if (cmd.cmd3 == 3) { // ganIsPlaying + if (g->anm == NULL || g->anm->IsEnd()) + cmd.SetSysvar(0); + else + cmd.SetSysvar(1); + } + else if (cmd.cmd3 == 1000) { // ganStop + if (g->anm == NULL || g->anm->IsEnd()) + g->SetSurfaceNum(cmd.args[1].value); + else { + g->anm->Abort(); + g->SetSurfaceNum(cmd.args[1].value); + } + SetObjChanged(cmd.args[0].value); + cmd.clear(); + } + else if (cmd.cmd3 == 2003) { // objPlay + g->CreateGanSpecial(event, 0, cmd.args[1].value); + // g.attr = GrpObj::Attribute(g.attr & (~GrpObj::HIDDEN)); + SetObjChanged(cmd.args[0].value); + cmd.clear(); + } + else if (cmd.cmd3 == 3001 || cmd.cmd3 == 3003 || cmd.cmd3 == 3005 || + cmd.cmd3 == 1001 || cmd.cmd3 == 1003 || cmd.cmd3 == 1005) { // ganPlay* + g->CreateGan(event, cmd.args[1].value); + // g.attr = GrpObj::Attribute(g.attr & (~GrpObj::HIDDEN)); + SetObjChanged(cmd.args[0].value); + cmd.clear(); + } +} + +void Grp::impl_objSetPos(Cmd& cmd) { + //obj or objBg + int base_arg = 0; + GrpObj* g = GetGraphicObjVarMode(cmd, base_arg, (cmd.cmd2 == 0x51)); + + int index, x, y; + if (cmd.cmd3 == 1006 || cmd.cmd3 == 2006) { //objAdjust + index = cmd.args[1+base_arg].value + 1; + x = cmd.args[2+base_arg].value; + y = cmd.args[3+base_arg].value; + } + else { + index = 0; + if (cmd.cmd3 == 1000) { + x = cmd.args[1+base_arg].value; + y = cmd.args[2+base_arg].value; + } + else { + g->GetPos(index, x, y); + if (cmd.cmd3 == 1001) + x = cmd.args[1+base_arg].value; + else + y = cmd.args[1+base_arg].value; + } + } + + g->SetPos(index, x, y); + cmd.clear(); +} + +void Grp::impl_objAlpha(Cmd& cmd) { + int base_arg = 0; + GrpObj* g = GetGraphicObjVarMode(cmd, base_arg, (cmd.cmd2 == 0x51)); + + g->SetAlpha(cmd.args[base_arg + 1].value); + cmd.clear(); +} + +void Grp::impl_objShow(Cmd& cmd) { + int base_arg = 0; + GrpObj* g = GetGraphicObjVarMode(cmd, base_arg, (cmd.cmd2 == 0x51)); + + if (cmd.args[base_arg + 1].value) + g->attr = GrpObj::Attribute(g->attr & (~GrpObj::HIDDEN)); + else + g->attr = GrpObj::Attribute(g->attr | GrpObj::HIDDEN); + + g->attr = GrpObj::Attribute(g->attr | GrpObj::UPDATE_VISIBLE); + // グループ単位で次の RefreshObj で表示・消去 + if (cmd.cmd2 == 0x51) //not Bg + SetObjChanged(cmd.args[0].value); + cmd.clear(); +} + +void Grp::impl_objColour(Cmd& cmd) { + int base_arg = 0; + GrpObj* g = GetGraphicObjVarMode(cmd, base_arg, (cmd.cmd2 == 0x51)); + + g->print_r = cmd.args[base_arg+1].value; + g->print_g = cmd.args[base_arg+2].value; + g->print_b = cmd.args[base_arg+3].value; + g->SetUpdate(); + cmd.clear(); +} + +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); + cmd.clear(); + } else if (cmd.args[base_arg + 1].value == 0) { + g->attr = GrpObj::Attribute(g->attr & (~GrpObj::SATURATE)); + cmd.clear(); + } + g->SetUpdate(); +} + +void Grp::impl_objSetText(Cmd& cmd) { + int base_arg = 0; + GrpObj* g = GetGraphicObjVarMode(cmd, base_arg, (cmd.cmd2 == 0x51)); + + g->print_moji = cmd.Str(cmd.args[base_arg + 1]); + g->SetUpdate(); + cmd.clear(); +} + +void Grp::impl_objTextOpts(Cmd& cmd) { + int base_arg = 0; + GrpObj* g = GetGraphicObjVarMode(cmd, base_arg, (cmd.cmd2 == 0x51)); + + // 画像を文字列として設定:文字の大きさなど + g->print_size = cmd.args[base_arg + 1].value; + /* 前景色を得る */ + int cr, cg, cb; + char key[17]; + sprintf(key, "#COLOR_TABLE.%03d", cmd.args[base_arg + 5].value); + if (config->GetParam(key, 3, &cr, &cg, &cb)) { // color not found + cr = cg = cb = 0; + } + g->print_r = cr; + g->print_g = cg; + g->print_b = cb; + g->SetUpdate(); + cmd.clear(); +} + +void Grp::impl_objOrder(Cmd& cmd) { + int base_arg = 0; + GrpObj* g = GetGraphicObjVarMode(cmd, base_arg, (cmd.cmd2 == 0x51)); + + int order = cmd.args[base_arg + 1].value; + g->order = order; + ZMoveObj(cmd.args[0].value); + cmd.clear(); +} + +void Grp::impl_objDispArea(Cmd& cmd) { + int base_arg = 0; + GrpObj* g = GetGraphicObjVarMode(cmd, base_arg, (cmd.cmd2 == 0x51)); + + // オブジェクトのどの部分を画面に表示するか(クリップ領域)の設定 + int rx, ry, w, h; + if (cmd.args.size() == base_arg + 5) { + int rx = cmd.args[base_arg + 1].value; + int ry = cmd.args[base_arg + 2].value; + int w = cmd.args[base_arg + 3].value; + int h = cmd.args[base_arg + 4].value; + if (cmd.cmd3 == 1005) { + w -= rx; + h -= ry; + } + } + else { + rx = ry = 0; + w = screen->Width(); + h = screen->Height(); + } + g->SetClipArea(rx, ry, w, h); //TODO: case when cmd.args.size() == 1 + cmd.clear(); +} + +void Grp::impl_objSetDigits(Cmd& cmd) { + int base_arg = 0; + GrpObj* g = GetGraphicObjVarMode(cmd, base_arg, (cmd.cmd2 == 0x51)); + + g->dig_number = cmd.args[base_arg + 1].value; + g->SetUpdate(); + cmd.clear(); +} + +void Grp::impl_objNumOpts(Cmd& cmd) { + int base_arg = 0; + GrpObj* g = GetGraphicObjVarMode(cmd, base_arg, (cmd.cmd2 == 0x51)); + + g->dig_digit = cmd.args[base_arg + 1].value; + int attr = g->attr; + attr &= ~(GrpObj::DIG_ZERO | GrpObj::DIG_SIGN | GrpObj::DIG_PACK); + if (cmd.args[base_arg + 2].value) attr |= GrpObj::DIG_ZERO; + if (cmd.args[base_arg + 3].value) attr |= GrpObj::DIG_SIGN; + if (cmd.args[base_arg + 4].value) attr |= GrpObj::DIG_PACK; + g->attr = GrpObj::Attribute(attr); + g->SetUpdate(); + cmd.clear(); +} + +void Grp::impl_objPattNo(Cmd& cmd) { + int base_arg = 0; + GrpObj* g = GetGraphicObjVarMode(cmd, base_arg, (cmd.cmd2 == 0x51)); + + g->SetSurfaceNum(cmd.args[base_arg + 1].value); + cmd.clear(); +} + +void Grp::impl_objScale(Cmd& cmd) { + int base_arg = 0; + GrpObj* g = GetGraphicObjVarMode(cmd, base_arg, (cmd.cmd2 == 0x51)); + + int zoom = (cmd.args[base_arg + 1].value + cmd.args[base_arg + 2].value)/2; //FIXME: eurk + zoom = zoom*256/100; + g->SetZoomRotate(zoom, -1); + cmd.clear(); +} + +void Grp::impl_objRotate(Cmd& cmd) { + int base_arg = 0; + GrpObj* g = GetGraphicObjVarMode(cmd, base_arg, (cmd.cmd2 == 0x51)); + + int angle = cmd.args[base_arg + 1].value; + angle /= 10; + if (angle < 0) { + angle %= 360; + angle += 360; + } + angle %= 360; + g->SetZoomRotate(-1, angle); + cmd.clear(); +} + +void Grp::impl_objPosDims(Cmd& cmd) { + int base_arg = 0; + GrpObj* g = GetGraphicObjVarMode(cmd, base_arg, true); + + VarInfo arg1 = cmd.args[base_arg + 1]; + VarInfo arg2 = cmd.args[base_arg + 2]; + + int val1, val2; + + if (cmd.cmd3 == 1000) + g->GetPos(0, val1, val2); + else if (cmd.cmd3 == 1100) + g->GetSrcGeom(val1, val2); + + cmd.SetFlagvar(arg1, val1); + cmd.SetFlagvar(arg2, val2); +} + +void Grp::impl_refresh(Cmd& cmd) { + // 本来は grpstack clear らしい + RefreshObj(); + // Princess Bride の中途 Staff roll + // このタイミングで描画するのが都合がいいので、 + //シナリオループを抜けて描画を起動 + cmd.cmd_type = CMD_WAITFRAMEUPDATE; +} + +void Grp::impl_bgmLoop(Cmd& cmd) { + if (cmd.cmd4 == 0 || cmd.cmd4 == 2) { + int count = 8000; + if (cmd.cmd3 == 2) + count = 0; //bgmPlay, play once + music->PlayCDROM((char*)cmd.Str(cmd.args[0]), count); + cmd.cmd_type = CMD_SAVECMD_ONCE; + } +} + +void Grp::impl_bgmStop(Cmd& cmd) { + if (cmd.cmd4 == 0) { + if (cmd.cmd3 == 5) + music->StopCDROM(0); + else if (cmd.cmd3 == 105) + music->StopCDROM(cmd.args[0].value); + cmd.cmd_type = CMD_SAVECMD_ONCE; + } +} + +void Grp::impl_playWav(Cmd& cmd) { + if (cmd.cmd3 == 2) { + music->PlaySE(cmd.Str(cmd.args[0]), 1); //loop + cmd.cmd_type = CMD_SAVECMD_ONCE; + } + else { + music->PlaySE(cmd.Str(cmd.args[0])); + cmd.clear(); + } + if (cmd.cmd3 == 1) + status = WAIT_SE; +} + +void Grp::impl_playSE(Cmd& cmd) { + music->PlaySE(cmd.args[0].value); + cmd.clear(); +} + +void Grp::impl_stopWav(Cmd& cmd) { + if (cmd.cmd3 == 5) + music->StopSE(); + else if (cmd.cmd3 == 105) + music->StopSE(cmd.args[0].value); + + cmd.cmd_type = CMD_SAVECMD_ONCE; +} + +void Grp::impl_SetVolMod(Cmd& cmd) { + music->volmod[cmd.cmd3-0x8b6] = cmd.args[0].value; + config->SetParam("#VOLMOD", 4, music->volmod[0], music->volmod[1], music->volmod[2], music->volmod[3]); + cmd.clear(); +} + +void Grp::impl_GetVolMod(Cmd& cmd) { + cmd.SetSysvar(music->volmod[cmd.cmd3-0x91a]); +} + +void Grp::impl_koePlay(Cmd& cmd) { + eprintf("play koe %d",cmd.args[0].value); + if (cmd.cmd4 == 1) { + eprintf(", para? %d",cmd.args[1].value); + } + eprintf("\n"); + char buf[1024]; sprintf(buf, "%d",cmd.args[0].value); + if ( !(skip_mode & SKIP_TEXT)) music->PlayKoe(buf); + cmd.clear(); +} + +/*It may be useful... or not. +void Grp::impl_objSwap(Cmd& cmd) { + if (cmd.cmd1 == 1 && cmd.args.size() == 2) { + SwapObj(cmd.args[0].value, cmd.args[1].value); + } + cmd.clear(); +}*/ + +void Grp::impl_movPlay(Cmd& cmd) { + if ( cmd.cmd4 == 0) { + const char* str = cmd.Str(cmd.args[0]); + int x = cmd.args[1].value; + int y = cmd.args[2].value; + int x2 = cmd.args[3].value; + int y2 = cmd.args[4].value; + eprintf("play movie ; name %s pos %d,%d - %d,%d\n",str,x,y,x2,y2); + music->PlayMovie(str, x, y, x2, y2,1); + status = WAIT_MOVIE; + event.RegisterGlobalPressFunc(&Pressed, (void*)this); + cmd.clear(); + } +}