root/scn2k/scn2k_grp.cc

Revision 65:4416cfac86ae, 53.1 KB (checked in by Thibaut Girka <thib@…>, 18 months ago)
Convert EUC-JP files to UTF8
Line 
1/*
2 * Copyright (c) 2004-2006  Kazunori "jagarl" Ueno
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 *    derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include "scn2k.h"
29#include "system/file.h"
30#include "system/system_config.h"
31#include "font/text.h"
32#include "window/render.h"
33
34extern XKFont::HorizLayout* DefaultLayout(int text_size);
35
36/*******************************************************************
37** GrpObj(implementation)
38*/
39
40GrpObj::GrpObj(void) :
41        name(""), gan_name(""), pic_parent(0), picture(0), anm(0),
42        _posx(0), _posy(0), clip_area(0,0,0,0),
43        alpha(255), order(0), surface_num(0), print_moji(""), print_size(0), print_r(-1),print_g(-1),print_b(-1),
44        dig_number(0), dig_digit(0),
45        zoom(-1), rotate(-1), attr(GrpObj::HIDDEN) {
46        int i;
47        for (i=0; i<9; i++) {
48                posx[i] = posy[i] = 0;
49        }
50}
51
52GrpObj::~GrpObj() {
53        if (picture != NULL) delete picture;
54}
55
56int GrpObj::PosX() {
57        return _posx;
58}
59
60int GrpObj::PosY() {
61        return _posy;
62}
63
64void GrpObj::SetUpdate(void) {
65        attr = Attribute (attr | UPDATE_PICTURE);
66        //Update(); //FIXME
67}
68
69void GrpObj::SetPos(int index, int x, int y) {
70        if (index < 0 || index > 8) {
71                fprintf(stderr,"GrpObj::SetPos: Invalid index %d <- %d,%d\n",index,x,y);
72                return;
73        }
74        if (x == posx[index] && y == posy[index]) return;
75        attr = Attribute(attr | UPDATE_POS);
76        _posx += x-posx[index];
77        _posy += y-posy[index];
78        posx[index] = x;
79        posy[index] = y;
80}
81
82void GrpObj::GetPos(int index, int& x, int& y) {
83        if (index < 0 || index > 8) {
84                fprintf(stderr,"GrpObj::GetPos: Invalid index %d\n",index);
85                x = 0; y = 0;
86                return;
87        }
88        x = posx[index];
89        y = posy[index];
90}
91
92void GrpObj::SetAlpha(int new_alpha) {
93        if (alpha == new_alpha) return;
94        alpha = new_alpha;
95        attr = Attribute(attr | UPDATE_ALPHA);
96        return;
97}
98
99void GrpObj::SetSurfaceNum(int num) {
100        if (num != -1) {
101                if (surface_num == num) return;
102                surface_num = num;
103        }
104        attr = Attribute(attr | UPDATE_SNUM);
105}
106
107void GrpObj::SetClipArea(int x, int y, int w, int h) {
108        Rect new_clip(x,y,x+w,y+h);
109        if (clip_area == new_clip) return;
110        clip_area = new_clip;
111        attr = Attribute(attr | UPDATE_CLIP);
112}
113
114PicBase* GrpObj::DeletePic(void) {
115        PicBase* p = picture;
116        anm = NULL;
117        picture = NULL;
118        src_pos.clear();
119        attr = Attribute(attr & HIDDEN);
120        return p;
121}
122
123void GrpObj::GetSrcGeom(int& width, int& height) {
124        if (src_pos.empty()) {
125                width = 0; height = 0;
126                if (name.length() == 0) {
127                        return;
128                }
129                /* ボタンの䜍眮情報を求める */
130                /* g00 ファむルのヘッダ郚分に䜍眮情報は入っおいる */
131                string path(name);
132                path += ".g00";
133                ARCINFO* info = FileSearcher::GetInstance()->Find(FileSearcher::PDT, path.c_str(), "g00");
134                if (info == NULL) { // ファむルが芋぀からない
135                        fprintf(stderr, "GrpObj::GetSrcGeom : Cannot find file %s\n", path.c_str());
136                        return;
137                }
138                const char* data = info->Read();
139                if (data != NULL && *data == 2) { // 画像ファむル内にボタン情報が存圚する
140                        int srclen = read_little_endian_int(data+5);
141                        int i;
142                        for (i=0; i<srclen; i++) {
143                                int x1 = read_little_endian_int(data+9+i*24+0);
144                                int y1 = read_little_endian_int(data+9+i*24+4);
145                                int x2 = read_little_endian_int(data+9+i*24+8);
146                                int y2 = read_little_endian_int(data+9+i*24+12);
147                                src_pos.push_back(Rect(x1, y1, x2+1, y2+1));
148                                if (width < src_pos.back().width()) width = src_pos.back().width();
149                                if (height < src_pos.back().height()) height = src_pos.back().height();
150                        }
151                } else { // 画像ファむルから倧きさ取埗
152                        width = read_little_endian_short(data+1);
153                        height = read_little_endian_short(data+3);
154                        src_pos.push_back(Rect(0,0,width,height));
155                }
156                delete info;
157        }
158        int sn = surface_num;
159        if (sn < 0 || sn > src_pos.size()) sn = 0;
160        width = src_pos[sn].width();
161        height = src_pos[sn].height();
162}
163
164void GrpObj::Update(void) {
165        if (attr & UPDATE_PICTURE) {
166                UpdateSurface();
167                attr = Attribute( (attr | UPDATE_ALL) & (~UPDATE_PICTURE));
168        }
169        if (picture == NULL) return;
170        if (attr & UPDATE_POS) {
171                if (zoom != -1) {
172                        int w=0, h=0;
173                        GetSrcGeom(w,h);
174                        picture->Move(_posx-w/2, _posy-h/2);
175                } else {
176                        picture->Move(_posx, _posy);
177                }
178        }
179        if (attr & UPDATE_ALPHA) {
180                if (alpha <= 0) {
181                        picture->SetSurfaceAlpha(0, Rect(0,0));
182                        picture->hide();
183                } else if (alpha >= ALPHA_MAX) {
184                        picture->SetSurfaceAlpha(0, Rect(0,0));
185                        if (attr & HIDDEN) picture->hide();
186                        else picture->show();
187                } else {
188                        picture->SetSurfaceAlpha(&alpha, Rect(0,0,1,1));
189                        if (attr & HIDDEN) picture->hide();
190                        else picture->show();
191                }
192        }
193        if ( (attr & UPDATE_SNUM) && (!src_pos.empty())) {
194                if (surface_num < 0 || surface_num >= src_pos.size()) surface_num = 0;
195                picture->SetSurfacePos(src_pos[surface_num].lx, src_pos[surface_num].ty);
196        }
197        if (attr & UPDATE_CLIP) {
198                picture->SetClipArea(clip_area);
199        }
200        attr = Attribute(attr & (~UPDATE_ALL));
201        if (attr & ANM_PLAYSTART) {
202                if (anm != NULL) {
203                        anm->Play();
204                        attr = Attribute(attr | ANM_PLAYING);
205                }
206                attr = Attribute(attr & (~ANM_PLAYSTART));
207        }
208}
209
210void GrpObj::CreateSurface(PicContainer* parent) {
211        if (picture != NULL) {
212                PicBase* p = DeletePic();
213                delete p;
214        }
215        src_pos.clear();
216        // picture を䜜成
217        pic_parent = parent;
218        picture = parent->create_leaf(Rect(_posx,_posy,_posx+1,_posy+1), 0);
219        picture->hide();
220        UpdateSurface();
221}
222 
223void GrpObj::UpdateSurface(void) {
224        if (pic_parent == NULL || picture == NULL) return;
225        int width = 0, height = 0;
226        if (gtype == FILE || gtype == GAN) {
227                if (name.length() == 0) return;
228                // ファむル名が存圚する堎合、ファむルを読み蟌み
229                GetSrcGeom(width, height);
230                if (width <= 0 || height <= 0) return;
231                // surface の蚭定
232                if (surface_num == 0 && ( (zoom > 0 && zoom != 256) || rotate > 0)) {
233                        ZoomRotate();
234                } else {
235                        // 普通に surface を蚭定
236                        string path(name);
237                        path += ".g00";
238                        picture->SetSurface(path.c_str(), 0, 0);
239                        picture->SetSurfaceRect(Rect(0,0,width,height));
240                }
241                if (attr & BLIT_ADD)
242                        picture->SetSurfaceAttribute(PicBase::BLIT_ADD);
243        } else if (gtype == MOJI) { // テキスト描画
244                if (print_moji.length() == 0) return;
245                UpdateMoji();
246        } else if (gtype == DIGIT) { // 数倀を画像衚瀺
247                UpdateDigit();
248        }
249}
250
251void GrpObj::ZoomRotate(void) {
252        picture->SetSurface( (Surface*)0, 0, 0);
253
254        // 回転、瞮小拡倧は座暙原点が画像の䞭心になる
255        string path(name);
256        path += ".g00";
257        Surface* surface_orig = pic_parent->Root().NewSurface(path.c_str());
258        if (surface_orig == NULL) return;
259
260        Surface* zoom_surface = pic_parent->Root().RotZoomSurface(surface_orig, double(zoom)/256.0, rotate);
261        Rect zoom_r (*zoom_surface);
262        picture->SetSurface(zoom_surface, 0, 0);
263        picture->SetSurfaceFreeFlag();
264        //picture->Move(PosX() + - zoom_r.width()/2, PosY() + - zoom_r.height()/2);
265// 䞭心座暙がわからん・・・
266        picture->Move(320 - zoom_r.width()/2, 240 - zoom_r.height()/2);
267        picture->SetSurfaceRect(Rect(0, 0, zoom_r.width(), zoom_r.height()));
268
269        pic_parent->Root().DeleteSurface(surface_orig);
270}
271
272void GrpObj::UpdateMoji(void) { // 文字の倧きさ、色などを倉曎
273        if (print_moji.length() == 0 || print_size <= 2) return;
274        if (pic_parent == 0) return;
275        /* テキストの倧きさを埗る */
276        int r, g, b;
277        if (print_r == -1 || print_g == -1 || print_b == -1) {// 色蚭定なし
278                r = g = b = 0;  // ずりあえず黒(clannad のSave/Loadメニュヌ甚)
279        } else {
280                r = print_r;
281                g = print_g;
282                b = print_b;
283        }
284        TextStream ts = TextStream::ParseMoji(print_moji.c_str(), r, g, b, print_size);
285        TextGlyphStream gs;
286        vector<int> lh;
287        // ずりあえず drawable width は充分に倧きく(2048)取る
288        DefaultLayout(print_size-2)->Layout(ts, gs, lh, 2048); // print_size そのたただず匱干倧きすぎるので -2
289        int width = gs.width();
290        int height = gs.height();
291        Surface* surface = pic_parent->Root().NewSurface(width, height, ALPHA_MASK);
292        DSurfaceFill(surface, Rect(*surface), 0, 0, 0, 0);
293        DSurfaceRenderText(gs.begin(), gs.end(), Rect(0, 0, width, height), surface, Rect(0,0));
294        picture->SetSurface(surface, 0, 0);
295        picture->SetSurfaceRect(Rect(0,0,width,height));
296        picture->SetSurfaceFreeFlag();
297}
298
299void GrpObj::UpdateDigit(void) {
300        // 画像衚瀺の数倀文字列を衚瀺する
301        if (name.length() == 0) return;
302        // ファむル名が存圚する堎合、ファむルを読み蟌み
303        string path(name);
304        path += ".g00";
305        Surface* surface_orig = pic_parent->Root().NewSurface(path.c_str());
306        if (surface_orig == NULL) return;
307
308        int width, height;
309        int i;
310        GetSrcGeom(width, height);
311        if (width <= 0 || height <= 0) return;
312        if (src_pos.size() < 14) {
313                // 必芁な数の object がない
314                // 衚瀺できない分の空の rect を远加しおおく
315                for (i=src_pos.size(); i<14; i++)
316                        src_pos.push_back(Rect(0,0,0,0));
317                pic_parent->Root().DeleteSurface(surface_orig);
318                return;
319        }
320        // 桁数の蚈算
321        char num_str[20];
322        if (dig_number < 0) sprintf(num_str, "%d", -dig_number);
323        else sprintf(num_str, "%d", dig_number);
324        int sign_count = 0;
325        int space_count = 0;
326        int total_count;
327        int dig_count = strlen(num_str);
328        if (dig_number < 0 && (attr&DIG_SIGN) == 0) dig_count++;
329        if (dig_count < dig_digit) space_count = dig_digit - dig_count;
330        if (attr & DIG_SIGN) sign_count = 1;
331        total_count = dig_count + space_count + sign_count;
332
333        Surface* surface = pic_parent->Root().NewSurface(width*total_count, height, ALPHA_MASK);
334        DSurfaceFill(surface, Rect(*surface), 0, 0, 0, 0);
335
336        /* surface にコピヌする */
337        int cur_x = 0;
338        if ( (attr & DIG_PACK) && !(attr & DIG_ZERO)) { // 始めに空癜を挿入
339                cur_x += space_count * width;
340        }
341        int plus = 10, minus = 11, plusminus = 12;
342        if (dig_number < 0) {
343                DSurfaceMove(surface, src_pos[minus], surface, Rect(cur_x,0));
344                cur_x += width;
345        } else if (attr & DIG_SIGN) {
346                if (dig_number == 0)
347                        DSurfaceMove(surface, src_pos[plusminus], surface, Rect(cur_x,0));
348                else
349                        DSurfaceMove(surface, src_pos[plus], surface, Rect(cur_x,0));
350                cur_x += width;
351        }
352        if (attr & DIG_ZERO) { // れロ・パディング
353                for (i=0; i<space_count; i++) {
354                        DSurfaceMove(surface, src_pos[0], surface, Rect(cur_x, 0));
355                        cur_x += width;;
356                }
357        } else if (!(attr & DIG_PACK)) { // PACK オプションなし
358                cur_x += space_count * width;
359        }
360        for (i=0; num_str[i] != 0; i++) {
361                DSurfaceMove(surface_orig, src_pos[num_str[i]-'0'], surface, Rect(cur_x, 0));
362                cur_x += width;
363        }
364       
365        /* picture に蚭定 */
366        picture->SetSurface(surface, 0, 0);
367        picture->SetSurfaceRect(Rect(0,0,width*total_count,height));
368        picture->SetSurfaceFreeFlag();
369
370        pic_parent->Root().DeleteSurface(surface_orig);
371}
372
373void GrpObj::CreateGan(Event::Container& event, int event_number) {
374        if (picture == NULL) {
375                fprintf(stderr,"GrpObj::CreateGan() is called before Create()\n");
376                return;
377        }
378        if (anm != NULL) {
379                anm->Abort();
380                delete anm;
381                anm = NULL;
382        }
383        if (gan_name.empty()) return;
384        /* アニヌメション情報 (.GAN ファむル)を求める */
385        string path(gan_name);
386        path += ".gan";
387        ARCINFO* info = FileSearcher::GetInstance()->Find(FileSearcher::GAN, path.c_str(), "gan");
388        if (info == NULL) {
389                fprintf(stderr,"GrpObj::CreateGan: Cannot Find 'GAN' file %s\n", path.c_str());
390                return;
391        }
392        const char* data = info->Read();
393        if (read_little_endian_int(data) != 10000 || read_little_endian_int(data+4) != 10000) {
394                fprintf(stderr,"GrpObj::CreateGan: Invalid'GAN' file %s\n", path.c_str());
395                delete info;
396                return;
397        }
398
399        attr = Attribute(attr | UPDATE_POS);
400
401        const char* buf = data + 16;
402        buf += strlen(buf) + 1; // 画像ファむル名が入っおいる
403        buf += 4; // 定数 20000
404        int pics = read_little_endian_int(buf); buf += 4; // 耇数のアニメヌション情報が入っおいる堎合、情報数
405        // 以䞋、pics 回繰り返し
406        // アニメヌションを行う実䜓を䜜成
407        AnmAlphaMove* wid = new AnmAlphaMove(event, picture);
408
409        if (event_number && event_number < pics) { // 耇数のアニメヌション情報がある堎合、先の情報を読み飛ばす */
410                int i; for (i=0; i<event_number; i++) {
411                        buf += 4; // 定数 30000
412                        int ptns = read_little_endian_int(buf); buf += 4;
413                        buf += ptns*52;
414                }
415        }
416        buf += 4; // 定数 30000
417        int ptns = read_little_endian_int(buf); buf += 4;
418        int total_time = 0;
419        int i;
420        for (i=0; i<ptns; i++) {
421                int p = read_little_endian_int(buf+i*52+0*8+4);
422                int x = read_little_endian_int(buf+i*52+1*8+4);
423                int y = read_little_endian_int(buf+i*52+2*8+4);
424                int t = read_little_endian_int(buf+i*52+3*8+4);
425                int a = read_little_endian_int(buf+i*52+4*8+4);
426                x += PosX();
427                y += PosY();
428                if (p == -1) { a = 0; p = 0; } // p == -1 ならなにも衚瀺しない
429                if (p >= src_pos.size()) {
430                        fprintf(stderr,"Reading GAN file %s (G00 %s) : not enough pictures in .G00 file\n", path.c_str(), name.c_str());
431                        a = 0; p = 0;
432                }
433                total_time += t;
434                wid->ptns.push_back(AnmAlphaMove::Ptn(Rect(x,y), src_pos[p], a, total_time));
435        }
436        wid->SetPtn(); // パタヌン登録終了
437        attr = Attribute(attr | ANM_PLAYSTART);
438        anm = wid;
439}
440
441void GrpObj::CreateGanSpecial(Event::Container& event, int event_number, int time) {
442        if (picture == NULL) {
443                fprintf(stderr,"GrpObj::CreateGan() is called before Create()\n");
444                return;
445        }
446        if (anm != NULL) {
447                anm->Abort();
448                delete anm;
449                anm = NULL;
450        }
451
452        // アニメヌションを行う実䜓を䜜成
453        AnmAlphaMove* wid = new AnmAlphaMove(event, picture);
454
455        int i;
456        switch(event_number) {
457                case 0: // pattern を 0 から最埌たで倉化させる
458                        for (i=0; i<src_pos.size(); i++) {
459                                wid->ptns.push_back(AnmAlphaMove::Ptn(Rect(PosX(), PosY()), src_pos[i], 255, time*i));
460                        }
461                        wid->SetPtn(); // パタヌン登録終了
462                        anm = wid;
463                        attr = Attribute(attr | ANM_PLAYSTART);
464                        break;
465                default:
466                        break;
467        }
468}
469
470void GrpObj::SetZoomRotate(int new_zoom, int new_rotate) {
471        if (zoom == new_zoom && rotate == new_rotate) return;
472        if ( zoom == -1 || new_zoom == -1) {
473                attr = Attribute(attr | UPDATE_POS); // centering する
474        }
475        zoom = new_zoom;
476        if (new_rotate != -1) rotate = new_rotate;
477        if (zoom < 0) zoom = 256;
478        if (rotate < 0) rotate = 0;
479        else if (rotate > 360) rotate %= 360;
480
481        attr = Attribute(attr | UPDATE_PICTURE);
482}
483
484void GrpObj::Refresh(GrpObj& parent_obj) {
485        //if (&parent_obj != this) printf("Toto\n"); //FIXME
486
487        GrpObjMap::iterator it;
488
489        for (it = children_obj.begin(); it != children_obj.end(); it++)
490                it->second.Refresh(parent_obj);
491
492        if (picture == NULL) return;
493        if (alpha == 0 || (attr & GrpObj::HIDDEN) || (parent_obj.attr & GrpObj::HIDDEN)) {
494                if (attr & GrpObj::ANM_PLAYING) {
495                        attr = GrpObj::Attribute(attr & ~(GrpObj::ANM_PLAYING));
496                        if (anm != NULL) anm->Abort();
497                }
498                picture->hide();
499        } else {
500                Update();
501                picture->show();
502        }
503}
504
505void GrpObj::_debug_Dump(int id, int indent)
506{
507        const char* repr;
508
509        if (indent == 0)
510                repr = "obj %04d(%p): name %10s  pos %d,%d alpha %d (%d/%d/%d)\n";
511        else
512                repr = "  * obj %04d(%p): name %10s  pos %d,%d alpha %d (%d/%d/%d)\n";
513
514        if (picture != NULL) {
515                if (!name.empty())
516                        fprintf(stderr, repr,
517                                id, this, name.c_str(), PosX(), PosY(), alpha, attr&GrpObj::HIDDEN ? 1 : 0, 0,
518                                picture->IsHidden());
519                else if (!print_moji.empty())
520                        fprintf(stderr, repr,
521                                id, this, print_moji.c_str(), PosX(), PosY(), alpha, attr&GrpObj::HIDDEN ? 1 : 0,
522                                0, picture->IsHidden());
523                else
524                        fprintf(stderr, repr,
525                                id, this, "<EMPTY>", PosX(), PosY(), alpha, attr&GrpObj::HIDDEN ? 1 : 0, 0,
526                                picture->IsHidden());
527        }
528
529        GrpObjMap::iterator it;
530        for (it = children_obj.begin(); it != children_obj.end(); it++)
531                it->second._debug_Dump(it->first, indent+1);
532}
533
534/******************************************************************
535**
536**      class ScnGrp*
537*/
538/* Princess Bride: 背景画の䞀郚のみ移動、の実装 */
539
540ScnGrpMove::ScnGrpMove(Event::Container& container, PicBase* _pic, PicRoot& _root, Surface* _dest, const Rect& _dest_r, Surface* _src, const Rect& _from, const Rect& _to, int total_time) :
541        WidAnmTime(container, _pic, total_time),
542        dest(_dest), src(_src), root(_root),dest_r(_dest_r), from(_from), to(_to) {
543        int dx = to.lx - from.lx;
544        int dy = to.ty - from.ty;
545        if (dx < 0) dx = -dx;
546        if (dy < 0) dy = -dy;
547        if (dx < dy) dx = dy;
548        if (dx == 0) dx = 1;
549        SetAllCount(dx);
550}
551
552void ScnGrpMove::Exec(int count) {
553        Rect r(0,0,dest_r.width(),dest_r.height());
554        int dx = to.lx - from.lx;
555        int dy = to.ty - from.ty;
556        int x = dx*count/all_count + from.lx;
557        int y = dy*count/all_count + from.ty;
558        r.rmove(x, y);
559        root.BlitSurface(src, r, dest, dest_r);
560        iterator it;
561        for (it=pic.begin(); it!=pic.end(); it++)
562                (*it)->SetSurface(dest, 0, 0);
563}
564
565void ScnGrpAnm::CalcTotal(void) {
566        /* total time を蚈算 */
567        if (empty()) return;
568        int tm = 0;
569        vector<ScnGrpAnmAtom>::iterator it;
570        for (it=begin(); it != end(); it++) tm += it->time;
571        total_time = tm;
572        SetAllCount(tm);
573}
574
575void ScnGrpAnm::Exec(int count) {
576        int tm = 0; vector<ScnGrpAnmAtom>::iterator it;
577        for (it=begin(); it != end(); it++) {
578                tm += it->time;
579                if (count < tm) break;
580        }
581        if (it == end()) it--;
582        owner.LoadSurface(it->name.c_str(), 0);
583}
584
585
586/*****************************************************
587*
588*  Grp
589*
590*/
591
592#include "music2/music.h"
593
594Grp::Grp(Event::Container& _event, PicContainer& _parent, const Flags& f, set<int>& _cgm_data):
595        event(_event),
596        flags(f), 
597        parent(_parent),
598        status(NORMAL),
599        skip_mode(SKIP_NO),
600        cgm_data(_cgm_data)
601{
602        int i;
603        for (i=0; i<MAXPDT; i++) {
604                ssurface[i] = 0;
605                dsurface[i] = 0;
606        }
607
608        music = MuSys::GetInstance();
609        config = AyuSysConfig::GetInstance();
610
611        screen = parent.create_leaf(Rect(0, 0, parent.Width(), parent.Height()), 0);
612        screen_front = parent.create_leaf(Rect(0, 0, parent.Width(), parent.Height()), 0);
613        surface = parent.Root().NewSurface(parent.Width(), parent.Height(), NO_MASK);
614        surface_update = parent.Root().NewSurface(parent.Width(), parent.Height(), NO_MASK);
615        DSurfaceFill(surface, Rect(*surface), 0, 0, 0);
616        DSurfaceFill(surface_update, Rect(*surface), 0, 0, 0);
617        screen->SetSurface(surface, 0, 0);
618        screen->show();
619        screen_front->hide();
620        screen_front->ZMove(screen);
621
622        LoadCgm();
623
624        RegisterCommand(1, 30, 0, "stackClear", (CmdImpl) &Grp::impl_stackClear);
625        RegisterCommand(1, 33, 70, "grpBuffer", (CmdImpl) &Grp::impl_grpBuffer);
626        RegisterCommand(1, 33, 73, "grpOpenBG", (CmdImpl) &Grp::impl_grpOpen);
627        RegisterCommand(1, 33, 75, "grpMulti", (CmdImpl) &Grp::impl_grpMulti); //FIXME: or not...
628        RegisterCommand(1, 33, 76, "grpOpen", (CmdImpl) &Grp::impl_grpOpen);
629        RegisterCommand(1, 33, 32, "shake", (CmdImpl) &Grp::impl_shake);
630        RegisterCommand(1, 33, 100, "grpCopy", (CmdImpl) &Grp::impl_grpCopy);
631        RegisterCommand(1, 33, 1201, "recFill", (CmdImpl) &Grp::impl_recFill);
632        RegisterCommand(1, 33, 1100, "recCopy", (CmdImpl) &Grp::impl_recCopy);
633        RegisterCommand(1, 33, 1101, "recMaskCopy", NULL); //TODO: Same thing as recCopy, but using source's alpha
634        RegisterCommand(1, 33, 1600, "recAdd", (CmdImpl) &Grp::impl_recAdd);
635        RegisterCommand(1, 33, 406, "grpPan", (CmdImpl) &Grp::impl_grpPan);
636
637        RegisterCommand(1, 34, 3120, "snmBgScroll", (CmdImpl) &Grp::impl_snmBgScroll);
638        RegisterCommand(1, 34, 3100, "snmBgPlay", (CmdImpl) &Grp::impl_snmPlay);
639        RegisterCommand(1, 34, 2100, "snmPlay", (CmdImpl) &Grp::impl_snmPlay);
640        RegisterCommand(1, 34, 2101, "snmPlayEx", (CmdImpl) &Grp::impl_snmPlay);
641
642        RegisterCommand(1, 4, 1500, "cgGetTotal", (CmdImpl) &Grp::impl_cgGet);
643        RegisterCommand(1, 4, 1501, "cgGetViewed", (CmdImpl) &Grp::impl_cgGet);
644        RegisterCommand(1, 4, 1502, "cgGetViewedPcnt", (CmdImpl) &Grp::impl_cgGet);
645        RegisterCommand(1, 4, 1503, "cgGetFlag", (CmdImpl) &Grp::impl_cgStatus);
646        RegisterCommand(1, 4, 1504, "cgStatus", (CmdImpl) &Grp::impl_cgStatus);
647
648        RegisterCommand(1, 4, 0x6a4, "CreateInput", NULL);
649        RegisterCommand(1, 4, 0x6ae, "SetInput", NULL);
650
651        RegisterCommand(1, 61, 10, "objClear", (CmdImpl) &Grp::impl_objClear);
652        RegisterCommand(1, 61, 11, "objDelete", (CmdImpl) &Grp::impl_objClear);
653
654        RegisterCommand(1, 71, 1000, "objOfFile", (CmdImpl) &Grp::impl_createObj);
655        RegisterCommand(1, 71, 1003, "objOfFileGan", (CmdImpl) &Grp::impl_createObj);
656        RegisterCommand(1, 71, 1100, "objOfArea", (CmdImpl) &Grp::impl_createObj);
657        RegisterCommand(1, 71, 1200, "objOfText", (CmdImpl) &Grp::impl_createObj);
658        RegisterCommand(1, 71, 1300, "objDriftOfFile", (CmdImpl) &Grp::impl_createObj);
659        RegisterCommand(1, 71, 1400, "objOfDigits", (CmdImpl) &Grp::impl_createObj);
660
661        RegisterCommand(2, 71, 1000, "subObjOfFile", (CmdImpl) &Grp::impl_createObj);
662        RegisterCommand(2, 71, 1003, "subObjOfGan", (CmdImpl) &Grp::impl_createObj);
663        RegisterCommand(2, 71, 1100, "subObjOfArea", (CmdImpl) &Grp::impl_createObj);
664        RegisterCommand(2, 71, 1200, "subObjOfText", (CmdImpl) &Grp::impl_createObj);
665        RegisterCommand(2, 71, 1300, "subObjDriftOfFile", (CmdImpl) &Grp::impl_createObj);
666        RegisterCommand(2, 71, 1400, "subObjOfDigits", (CmdImpl) &Grp::impl_createObj);
667
668        //I suppose it's the same thing as createObj*, but I didn't see it in action. For now, mark it unhandled.
669        RegisterCommand(1, 72, 1000, "objBgOfFile", (CmdImpl) &Grp::impl_createObj);
670        RegisterCommand(1, 72, 1003, "objBgOfFileGan", (CmdImpl) &Grp::impl_createObj);
671        RegisterCommand(1, 72, 1100, "objBgOfArea", (CmdImpl) &Grp::impl_createObj);
672        RegisterCommand(1, 72, 1200, "objBgOfText", (CmdImpl) &Grp::impl_createObj);
673        RegisterCommand(1, 72, 1300, "objBgDriftOfFile", (CmdImpl) &Grp::impl_createObj);
674        RegisterCommand(1, 72, 1400, "objBgOfDigits", (CmdImpl) &Grp::impl_createObj);
675
676        RegisterCommand(2, 72, 1000, "subObjBgOfFile", NULL);//FIXME
677        RegisterCommand(2, 72, 1003, "subObjBgOfGan", NULL);//FIXME
678        RegisterCommand(2, 72, 1100, "subObjBgOfArea", NULL);//FIXME
679        RegisterCommand(2, 72, 1200, "subObjBgOfText", NULL);//FIXME
680        RegisterCommand(2, 72, 1300, "subObjBgDriftOfFile", NULL);//FIXME
681        RegisterCommand(2, 72, 1400, "subObjBgOfDigits", NULL);//FIXME;
682
683        RegisterCommand(1, 73, 0, "ganStop?", NULL); //That's what xclannad says, but I'm not sure...
684        RegisterCommand(1, 73, 1000, "ganStop", (CmdImpl) &Grp::impl_gan); //That's what rldev says
685        RegisterCommand(1, 73, 3, "ganIsPlaying", (CmdImpl) &Grp::impl_gan);
686        RegisterCommand(1, 73, 2003, "objPlay", (CmdImpl) &Grp::impl_gan);
687        RegisterCommand(1, 73, 1001, "ganLoop", (CmdImpl) &Grp::impl_gan);
688        RegisterCommand(1, 73, 1003, "ganPlay", (CmdImpl) &Grp::impl_gan);
689        RegisterCommand(1, 73, 1005, "ganPlayOnce", (CmdImpl) &Grp::impl_gan);
690        RegisterCommand(1, 73, 3001, "ganLoop2", (CmdImpl) &Grp::impl_gan);
691        RegisterCommand(1, 73, 3003, "ganPlay2", (CmdImpl) &Grp::impl_gan);
692        RegisterCommand(1, 73, 3005, "ganPlayOnce2", (CmdImpl) &Grp::impl_gan);
693
694        RegisterCommand(2, 73, 0, "ganSubStop?", NULL); //FIXME
695        RegisterCommand(2, 73, 1000, "ganSubStop", NULL); //FIXME
696        RegisterCommand(2, 73, 3, "ganSubIsPlaying", NULL); //FIXME
697        RegisterCommand(2, 73, 2003, "objSubPlay", NULL); //FIXME
698        RegisterCommand(2, 73, 1001, "ganSubLoop", NULL); //FIXME
699        RegisterCommand(2, 73, 1003, "ganSubPlay", NULL); //FIXME
700        RegisterCommand(2, 73, 1005, "ganSubPlayOnce", NULL); //FIXME
701        RegisterCommand(2, 73, 3001, "ganSubLoop2", (CmdImpl) &Grp::impl_gan); //FIXME
702        RegisterCommand(2, 73, 3003, "ganSubPlay2", NULL); //FIXME
703        RegisterCommand(2, 73, 3005, "ganSubPlayOnce2", NULL); //FIXME
704
705
706        RegisterCommand(1, 81, 1000, "objMove", (CmdImpl) &Grp::impl_objSetPos);
707        RegisterCommand(1, 82, 1000, "objBgMove", (CmdImpl) &Grp::impl_objSetPos);
708        RegisterCommand(1, 81, 1001, "objLeft", (CmdImpl) &Grp::impl_objSetPos);
709        RegisterCommand(1, 82, 1001, "objBgLeft", (CmdImpl) &Grp::impl_objSetPos);
710        RegisterCommand(1, 81, 1002, "objTop", (CmdImpl) &Grp::impl_objSetPos);
711        RegisterCommand(1, 82, 1002, "objBgTop", (CmdImpl) &Grp::impl_objSetPos);
712        RegisterCommand(1, 81, 1003, "objAlpha", (CmdImpl) &Grp::impl_objAlpha);
713        RegisterCommand(1, 82, 1003, "objBgAlpha", (CmdImpl) &Grp::impl_objAlpha);
714        RegisterCommand(1, 81, 1004, "objShow", (CmdImpl) &Grp::impl_objShow);
715        RegisterCommand(1, 82, 1004, "objBgShow", (CmdImpl) &Grp::impl_objShow);
716        RegisterCommand(1, 81, 1005, "objDispArea", NULL);
717        RegisterCommand(1, 82, 1005, "objBgDispArea", NULL);
718        RegisterCommand(1, 81, 1006, "objAdjust", (CmdImpl) &Grp::impl_objSetPos);
719        RegisterCommand(1, 82, 1006, "objBgAdjust", NULL); //FIXME: (CmdImpl) &Grp::impl_objSetPos);
720        RegisterCommand(1, 81, 1007, "objAdjustX", NULL);
721        RegisterCommand(1, 82, 1007, "objBgAdjustX", NULL);
722        RegisterCommand(1, 81, 1008, "objAdjustY", NULL);
723        RegisterCommand(1, 82, 1008, "objBgAdjustY", NULL);
724        RegisterCommand(1, 81, 2006, "objAdjust2?", NULL); //FIXME: (CmdImpl) &Grp::impl_objSetPos); I don't know if it is usefull or properly implemented
725        RegisterCommand(1, 82, 2006, "objBgAdjust2?", NULL); //FIXME: (CmdImpl) &Grp::impl_objSetPos); See above
726        RegisterCommand(1, 81, 1016, "objColour", NULL); //FIXME: (CmdImpl) &Grp::impl_objColour);
727        RegisterCommand(1, 82, 1016, "objBgColour", NULL); //FIXME: (CmdImpl) &Grp::impl_objColour);
728        RegisterCommand(1, 81, 1017, "objColR", NULL);
729        RegisterCommand(1, 82, 1017, "objBgColR", NULL);
730        RegisterCommand(1, 81, 1018, "objColG", NULL);
731        RegisterCommand(1, 82, 1018, "objBgColG", NULL);
732        RegisterCommand(1, 81, 1019, "objColB", NULL);
733        RegisterCommand(1, 82, 1019, "objBgColB", NULL);
734        RegisterCommand(1, 81, 1020, "objColLevel", NULL);
735        RegisterCommand(1, 82, 1020, "objBgColLevel", NULL);
736        RegisterCommand(1, 81, 1021, "objComposite", (CmdImpl) &Grp::impl_objComposite); //FIXME: May be broken
737        RegisterCommand(1, 82, 1021, "objBgComposite", (CmdImpl) &Grp::impl_objComposite);
738        RegisterCommand(1, 81, 1024, "objSetText", (CmdImpl) &Grp::impl_objSetText);
739        RegisterCommand(1, 82, 1024, "objBgSetText", (CmdImpl) &Grp::impl_objSetText);
740        RegisterCommand(1, 81, 1025, "objTextOpts", (CmdImpl) &Grp::impl_objTextOpts); //FIXME: Incomplete
741        RegisterCommand(1, 82, 1025, "objBgTextOpts", (CmdImpl) &Grp::impl_objTextOpts);
742        RegisterCommand(1, 81, 1032, "objOrder", (CmdImpl) &Grp::impl_objOrder);
743        RegisterCommand(1, 82, 1032, "objBgOrder", (CmdImpl) &Grp::impl_objOrder);
744        RegisterCommand(1, 81, 1034, "objDispRect", (CmdImpl) &Grp::impl_objDispArea);
745        RegisterCommand(1, 82, 1034, "objBgDispRect", (CmdImpl) &Grp::impl_objDispArea);
746        RegisterCommand(1, 81, 1037, "objSetDigits", (CmdImpl) &Grp::impl_objSetDigits);
747        RegisterCommand(1, 82, 1037, "objBgSetDigits", (CmdImpl) &Grp::impl_objSetDigits);
748        RegisterCommand(1, 81, 1038, "objNumOpts", (CmdImpl) &Grp::impl_objNumOpts);
749        RegisterCommand(1, 82, 1038, "objBgNumOpts", (CmdImpl) &Grp::impl_objNumOpts);
750        RegisterCommand(1, 81, 1039, "objPattNo", (CmdImpl) &Grp::impl_objPattNo);
751        RegisterCommand(1, 82, 1039, "objBgPattNo", (CmdImpl) &Grp::impl_objPattNo);
752        RegisterCommand(1, 81, 1046, "objScale", (CmdImpl) &Grp::impl_objScale); //FIXME: Broken behaviour
753        RegisterCommand(1, 82, 1046, "objBgScale", (CmdImpl) &Grp::impl_objScale);
754        RegisterCommand(1, 81, 1047, "objWidth", NULL);
755        RegisterCommand(1, 82, 1047, "objBgWidth", NULL);
756        RegisterCommand(1, 81, 1049, "objRotate", (CmdImpl) &Grp::impl_objRotate);
757        RegisterCommand(1, 82, 1049, "objBgRotate", (CmdImpl) &Grp::impl_objRotate);
758
759        RegisterCommand(2, 81, 1000, "childObjMove", (CmdImpl) &Grp::impl_objSetPos);
760        RegisterCommand(2, 82, 1000, "childObjBgMove", (CmdImpl) &Grp::impl_objSetPos);
761        RegisterCommand(2, 81, 1001, "childObjLeft", NULL);
762        RegisterCommand(2, 82, 1001, "childObjBgLeft", NULL);
763        RegisterCommand(2, 81, 1002, "childObjTop", NULL);
764        RegisterCommand(2, 82, 1002, "childObjBgTop", NULL);
765        RegisterCommand(2, 81, 1003, "childObjAlpha", (CmdImpl) &Grp::impl_objAlpha);
766        RegisterCommand(2, 82, 1003, "childObjBgAlpha", (CmdImpl) &Grp::impl_objAlpha);
767        RegisterCommand(2, 81, 1004, "childObjShow", (CmdImpl) &Grp::impl_objShow);
768        RegisterCommand(2, 82, 1004, "childObjBgShow", (CmdImpl) &Grp::impl_objShow);
769        RegisterCommand(2, 81, 1005, "childObjDispArea", NULL);
770        RegisterCommand(2, 82, 1005, "childObjBgDispArea", NULL);
771        RegisterCommand(2, 81, 1006, "childObjAdjust", (CmdImpl) &Grp::impl_objSetPos);
772        RegisterCommand(2, 82, 1006, "childObjBgAdjust", (CmdImpl) &Grp::impl_objSetPos);
773        RegisterCommand(2, 81, 1007, "childObjAdjustX", NULL);
774        RegisterCommand(2, 82, 1007, "childObjBgAdjustX", NULL);
775        RegisterCommand(2, 81, 1008, "childObjAdjustY", NULL);
776        RegisterCommand(2, 82, 1008, "childObjBgAdjustY", NULL);
777        RegisterCommand(2, 81, 2006, "childObjAdjust2?", NULL);
778        RegisterCommand(2, 82, 2006, "childObjBgAdjust2?", NULL);
779        RegisterCommand(2, 81, 1016, "childObjColour", NULL);
780        RegisterCommand(2, 82, 1016, "childObjBgColour", NULL);
781        RegisterCommand(2, 81, 1017, "childObjColR", NULL);
782        RegisterCommand(2, 82, 1017, "childObjBgColR", NULL);
783        RegisterCommand(2, 81, 1018, "childObjColG", NULL);
784        RegisterCommand(2, 82, 1018, "childObjBgColG", NULL);
785        RegisterCommand(2, 81, 1019, "childObjColB", NULL);
786        RegisterCommand(2, 82, 1019, "childObjBgColB", NULL);
787        RegisterCommand(2, 81, 1020, "childObjColLevel", NULL);
788        RegisterCommand(2, 82, 1020, "childObjBgColLevel", NULL);
789        RegisterCommand(2, 81, 1021, "childObjComposite", NULL);
790        RegisterCommand(2, 82, 1021, "childObjBgComposite", NULL);
791        RegisterCommand(2, 81, 1024, "childObjSetText", (CmdImpl) &Grp::impl_objSetText);
792        RegisterCommand(2, 82, 1024, "childObjBgSetText", (CmdImpl) &Grp::impl_objSetText);
793        RegisterCommand(2, 81, 1025, "childObjTextOpts", (CmdImpl) &Grp::impl_objTextOpts);
794        RegisterCommand(2, 82, 1025, "childObjBgTextOpts", (CmdImpl) &Grp::impl_objTextOpts);
795        RegisterCommand(2, 81, 1032, "childObjOrder", NULL);
796        RegisterCommand(2, 82, 1032, "childObjBgOrder", NULL);
797        RegisterCommand(2, 81, 1034, "childObjDispRect", NULL);
798        RegisterCommand(2, 82, 1034, "childObjBgDispRect", NULL);
799        RegisterCommand(2, 81, 1037, "childObjSetDigits", (CmdImpl) &Grp::impl_objSetDigits);
800        RegisterCommand(2, 82, 1037, "childObjBgSetDigits", (CmdImpl) &Grp::impl_objSetDigits);
801        RegisterCommand(2, 81, 1038, "childObjNumOpts", (CmdImpl) &Grp::impl_objNumOpts);
802        RegisterCommand(2, 82, 1038, "childObjBgNumOpts", (CmdImpl) &Grp::impl_objNumOpts);
803        RegisterCommand(2, 81, 1039, "childObjPattNo", (CmdImpl) &Grp::impl_objPattNo);
804        RegisterCommand(2, 82, 1039, "childObjBgPattNo", (CmdImpl) &Grp::impl_objPattNo);
805        RegisterCommand(2, 81, 1046, "childObjScale", (CmdImpl) &Grp::impl_objScale);
806        RegisterCommand(2, 82, 1046, "childObjBgScale", (CmdImpl) &Grp::impl_objScale);
807        RegisterCommand(2, 81, 1047, "childObjWidth", NULL);
808        RegisterCommand(2, 82, 1047, "childObjBgWidth", NULL);
809        RegisterCommand(2, 81, 1049, "childObjRotate", NULL);
810        RegisterCommand(2, 82, 1049, "childObjBgRotate", NULL);
811
812        RegisterCommand(1, 84, 1000, "objGetPos", (CmdImpl) &Grp::impl_objPosDims);
813        RegisterCommand(1, 84, 1100, "objGetDims", (CmdImpl) &Grp::impl_objPosDims);
814
815        RegisterCommand(2, 84, 1000, "childObjGetPos", (CmdImpl) &Grp::impl_objPosDims);
816        RegisterCommand(2, 84, 1100, "childObjGetDims", (CmdImpl) &Grp::impl_objPosDims);
817
818        RegisterCommand(1, 31, 0, "refresh", (CmdImpl) &Grp::impl_refresh);
819
820        RegisterCommand(1, 20, 0, "bgmLoop", (CmdImpl) &Grp::impl_bgmLoop);
821        RegisterCommand(1, 20, 1, "bgmPlayEx", (CmdImpl) &Grp::impl_bgmLoop); //FIXME: wait
822        RegisterCommand(1, 20, 2, "bgmPlay", (CmdImpl) &Grp::impl_bgmLoop);
823        RegisterCommand(1, 20, 5, "bgmStop", (CmdImpl) &Grp::impl_bgmStop);
824        RegisterCommand(1, 20, 105, "bgmFadeOut", (CmdImpl) &Grp::impl_bgmStop);
825
826        RegisterCommand(1, 21, 0, "wavPlay", (CmdImpl) &Grp::impl_playWav);
827        RegisterCommand(1, 21, 1, "wavPlayEx", (CmdImpl) &Grp::impl_playWav);
828        RegisterCommand(1, 21, 2, "wavLoop", (CmdImpl) &Grp::impl_playWav);
829        RegisterCommand(1, 21, 3, "wavWait", NULL);
830        RegisterCommand(1, 21, 4, "wavPlaying", NULL);
831        RegisterCommand(1, 21, 5, "wavStop", (CmdImpl) &Grp::impl_stopWav);
832        RegisterCommand(1, 21, 105, "wavFadeout", (CmdImpl) &Grp::impl_stopWav);
833
834        RegisterCommand(1, 22, 0, "sePlay", (CmdImpl) &Grp::impl_playSE);
835
836        RegisterCommand(1, 4, 2230, "SetBgmVolMod", (CmdImpl) &Grp::impl_SetVolMod);
837        RegisterCommand(1, 4, 2231, "SetKoeVolMod", (CmdImpl) &Grp::impl_SetVolMod);
838        RegisterCommand(1, 4, 2232, "SetPCMVolMod", (CmdImpl) &Grp::impl_SetVolMod);
839        RegisterCommand(1, 4, 2233, "SetSeVolMod", (CmdImpl) &Grp::impl_SetVolMod);
840        RegisterCommand(1, 4, 2330, "BgmVolMod", (CmdImpl) &Grp::impl_GetVolMod);
841        RegisterCommand(1, 4, 2331, "KoeVolMod", (CmdImpl) &Grp::impl_GetVolMod);
842        RegisterCommand(1, 4, 2332, "PCMVolMod", (CmdImpl) &Grp::impl_GetVolMod);
843        RegisterCommand(1, 4, 2333, "SeVolMod", (CmdImpl) &Grp::impl_GetVolMod);
844
845        RegisterCommand(1, 23, 0, "koePlay", (CmdImpl) &Grp::impl_koePlay);
846        RegisterCommand(1, 23, 1, "koePlayEx", (CmdImpl) &Grp::impl_koePlay); //FIXME
847        RegisterCommand(1, 23, 7, "koePlayExC", (CmdImpl) &Grp::impl_koePlay); //FIXME
848        RegisterCommand(1, 23, 8, "koeDoPlay", (CmdImpl) &Grp::impl_koePlay); //FIXME
849        RegisterCommand(1, 23, 9, "koeDoPlayEx", (CmdImpl) &Grp::impl_koePlay); //FIXME
850        RegisterCommand(1, 23, 10, "koeDoPlayExC", (CmdImpl) &Grp::impl_koePlay); //FIXME
851
852        RegisterCommand(1, 26, 1, "movPlayEx", (CmdImpl) &Grp::impl_movPlay);
853        RegisterCommand(1, 26, 20, "movPlayExC", (CmdImpl) &Grp::impl_movPlay);
854
855        RegisterCommand(1, 61, 14, "objSwap?", NULL);
856        RegisterCommand(1, 62, 14, "objSwap?", NULL);
857
858        RegisterCommand(1, 4, 1211, "EnableSyscom", NULL);
859        RegisterCommand(1, 4, 1212, "HideSyscom", NULL);
860        RegisterCommand(1, 4, 1213, "DisableSyscom", NULL);
861
862        anm1 = NULL;
863        anm2 = NULL;
864}
865
866Grp::~Grp() {
867        map<int,GrpObj>::iterator it;
868        for (it=grpobj.begin(); it!=grpobj.end(); it++) {
869                PicBase* p = it->second.DeletePic();
870                delete p;
871        }
872
873        delete screen;
874        delete screen_front;
875        parent.Root().DeleteSurface(surface);
876        parent.Root().DeleteSurface(surface_update);
877        int i;
878        for (i=0; i<MAXPDT; i++) {
879                if (ssurface[i]) parent.Root().DeleteSurface(ssurface[i]);
880                if (dsurface[i]) parent.Root().DeleteSurface(dsurface[i]);
881        }
882}
883
884Surface* Grp::Dsurface(int pdt) {
885        if (pdt == 0) return surface;
886        if (dsurface[pdt] == 0) { // ずりあえず画面の倧きさずいうこずにする
887                if (pdt == WORKPDT)
888                        dsurface[pdt] = parent.Root().NewSurface(parent.Width(), parent.Height(), ALPHA_MASK);
889                else
890                        dsurface[pdt] = parent.Root().NewSurface(parent.Width(), parent.Height(), NO_MASK);
891        }
892        if (ssurface[pdt]) { // ssurface が存圚すれば、dsurface にコピヌしお返す
893                DSurfaceMove(ssurface[pdt], Rect(*ssurface[pdt]), dsurface[pdt], Rect(0,0));
894                parent.Root().DeleteSurface(ssurface[pdt]);
895                ssurface[pdt] = 0;
896        }
897        return dsurface[pdt];
898}
899
900GrpObj* Grp::GetGraphicObj(int grp, bool fg) {
901        if (fg)
902                return &grpobj[grp];
903        else
904                return &bs_obj[grp];
905}
906
907GrpObj* Grp::GetGraphicObj(int grp, int index, bool fg) {
908        GrpObj* g = GetGraphicObj(grp, fg);
909        return &g->children_obj[index];
910}
911
912GrpObj* Grp::GetGraphicObjVarMode(Cmd& cmd, int &base_arg, bool fg) {
913        GrpObj* g;
914        if (cmd.cmd1 == 2) {
915                g = GetGraphicObj(cmd.args[base_arg].value, cmd.args[base_arg+1].value, fg);
916                base_arg += 1;
917        }
918        else
919                g = GetGraphicObj(cmd.args[base_arg].value, fg);
920        return g;
921}
922
923#include <SDL.h>
924Surface* Grp::Ssurface(int pdt) {
925        if (pdt == 0) return surface;
926        if (ssurface[pdt]) {
927                return ssurface[pdt];
928        }
929        return Dsurface(pdt);
930}
931
932void Grp::LoadSurface(const char* str, int pdt) {
933        string s = str;
934        if (cgm_info.find(s) != cgm_info.end()) {
935                cgm_data.insert(cgm_info[s]);
936        }
937        Surface* bg = parent.Root().NewSurface(s.c_str());
938        if (bg == NULL) {
939                s += ".g00";
940                bg = parent.Root().NewSurface(s.c_str());
941        }
942        if (bg != NULL) {
943                if (ssurface[pdt]) parent.Root().DeleteSurface(ssurface[pdt]);
944                ssurface[pdt] = bg;
945                if (pdt == 0) {
946                        /* ずりあえず Princess Bride のアニメヌション効果専甚 */
947                        Rect r(*ssurface[0]);
948                        Rect dr(*surface);
949                        int x = (dr.width()-r.width())/2;
950                        int y = (dr.height()-r.height())/2;
951                        DSurfaceMove(ssurface[0], r, surface, Rect(x,y));
952                        parent.Root().DeleteSurface(ssurface[0]);
953                        ssurface[0] = NULL;
954                        screen->SetSurface(surface, 0, 0);
955                }
956        } else {
957                if (str[0] != 0)
958                        fprintf(stderr,"Cannot find surface %d <- '%s'\n",pdt,str);
959        }
960}
961
962void Grp::InitSel(void) {
963        int i;
964        int args[16];
965        char key[10];
966        for (i=0; i<999; i++) {
967                sprintf(key, "#SEL.%03d",i);
968                if (config->GetParam(key, 15, &args[0], &args[1],
969                        &args[2], &args[3], &args[4], &args[5], &args[6], &args[7],
970                        &args[8], &args[9], &args[10], &args[11], &args[12], &args[13],
971                        &args[14])) {
972
973                        sprintf(key, "#SELR.%03d", i);
974                        if (config->GetParam(key, 16, &args[0], &args[1],
975                                &args[2], &args[3], &args[4], &args[5], &args[6], &args[7],
976                                &args[8], &args[9], &args[10], &args[11], &args[12], &args[13],
977                                &args[14], &args[15]))  continue;
978                }
979                SEL& s = anmtype[i];
980                s.from = Rect(args[0], args[1], args[2]+1, args[3]+1);
981                s.to = Rect(args[4], args[5]);
982                s.time = args[6];
983                s.sel_no = args[7];
984                int j;
985                for (j=0; j<8; j++) s.args[j] = args[8+j];
986        }
987}
988
989void Grp::SetSkipMode(SkipMode _mode) {
990        if ( (skip_mode & SKIP_IN_MENU) && (_mode & SKIP_IN_MENU) == 0) {
991                RefreshObj();
992        } else if ( (skip_mode & SKIP_IN_MENU) == 0 && (_mode & SKIP_IN_MENU) ) {
993        }
994        skip_mode = _mode;
995}
996
997void Grp::SetObjChanged(int num) {
998        changed_obj.insert(num);
999}
1000
1001void Grp::RefreshObj(void) {
1002        if (!deleted_pic.empty()) {
1003                vector<PicBase*>::iterator it;
1004                for (it=deleted_pic.begin(); it!=deleted_pic.end(); it++) {
1005                        if (*it) delete *it;
1006                }
1007                deleted_pic.clear();
1008        }
1009        if (!changed_obj.empty()) {
1010                set<int>::iterator it;
1011                for (it=changed_obj.begin(); it != changed_obj.end(); it++) {
1012                        if (grpobj.find(*it) == grpobj.end()) continue;
1013                        GrpObj& obj = grpobj[*it];
1014                        obj.Refresh(obj);
1015                }
1016                changed_obj.clear();
1017        }
1018        if (reserved_load_surface0.length() != 0) {
1019                LoadSurface(reserved_load_surface0.c_str(), 0);
1020                reserved_load_surface0 = "";
1021        }
1022        screen->ReBlit();
1023}
1024
1025
1026#include <SDL.h>
1027void Grp::StartAnm(int type) {
1028        SEL sel;
1029
1030        if (anmtype.find(type) == anmtype.end()) {
1031                if (anmtype.find(0) == anmtype.end()) {
1032                        sel.sel_no = 1;
1033                        sel.from = Rect(*surface);
1034                        sel.to = Rect(0,0);
1035                        sel.time = 0;
1036                } else {
1037                        sel = anmtype[0];
1038                }
1039        } else {
1040                sel = anmtype[type];
1041        }
1042        if (anm1 != NULL) {
1043                fprintf(stderr,"Warning: StartAnm() called before anm1 finished\n");
1044                anm1->Abort();
1045                delete anm1;
1046                anm1 = NULL;
1047        }
1048        map<int,GrpObj>::iterator it;
1049        // 珟圚衚瀺䞭のobjectを消去
1050        deleted_pic.push_back(screen);
1051        for (it=grpobj.begin(); it!=grpobj.end(); it++) {
1052                if (! (it->second.attr & GrpObj::WIPEON)) { // 画像切り替え時に object 削陀
1053                        deleted_pic.push_back(it->second.DeletePic());
1054                } else {
1055                        GrpObj& new_obj = bs_obj[it->first];
1056                        if (new_obj.name.empty()) { // 新しい object が存圚しなければ内容を匕き継ぐ
1057                                new_obj = it->second;
1058                                it->second.DeletePic();
1059                        } else {
1060                                new_obj.attr = GrpObj::Attribute(new_obj.attr | GrpObj::WIPEON);
1061                                deleted_pic.push_back(it->second.DeletePic());
1062                        }
1063                }
1064        }
1065        grpobj.clear(); // 党オブゞェクト削陀
1066
1067        // 党画像オブゞェクトの前にscreen 移動
1068        // 新しい screen_front を䜜成しおおく
1069        screen = screen_front;
1070        screen->hide();
1071        screen->SetSurface(surface_update, 0, 0);
1072        parent.Root().BlitSurface(Dsurface(1), Rect(*surface_update), surface_update, Rect(0,0));
1073
1074        screen_front = parent.create_leaf(Rect(0, 0, parent.Width(), parent.Height()), 0);
1075        screen_front->hide();
1076        screen_front->ZMove(screen);
1077       
1078        // 新しい object ぞ曎新、surface_update ぞ新しい object を衚瀺
1079        // (object 䜜成時は picture は hide されおいる)
1080        for (it=bs_obj.begin(); it!=bs_obj.end(); it++) {
1081                grpobj[it->first] = it->second;
1082                it->second.DeletePic();
1083                CreateObj(it->first);//FIXME: Adapt to groups
1084                GrpObj& g = grpobj[it->first];
1085                if (g.picture) {
1086                        g.Update();
1087                        if (g.alpha == 0 || (g.attr & GrpObj::HIDDEN)) ;
1088                        else g.picture->SimpleBlit(surface_update);
1089                        g.picture->hide();
1090                }
1091        }
1092        bs_obj.clear();
1093        // 画像効果開始
1094        switch(sel.sel_no) {
1095                default:
1096                case 0: case 50: // 0 ず 50 の違いが良くわからない
1097                        if (skip_mode & SKIP_GRP_NOEFFEC)
1098                                anm1 = new WidAnmAlpha(event, screen, ALPHA_MAX, ALPHA_MAX, 0);
1099                        else if (skip_mode & SKIP_GRP_FAST)
1100                                anm1 = new WidAnmAlpha(event, screen, 0, ALPHA_MAX, sel.time/4);
1101                        else
1102                                anm1 = new WidAnmAlpha(event, screen, 0, ALPHA_MAX, sel.time);
1103                        break;
1104        }
1105        if (anm1) anm1->Play();
1106        if (skip_mode & SKIP_GRP_NOEFFEC) AbortAnm();
1107}
1108
1109void Grp::StartShake(int total, const int* pattern) {
1110        if (anm2) {
1111                fprintf(stderr,"Warning: StartShake() called before another animation finished\n");
1112                anm2->Abort();
1113                delete anm2;
1114                anm2 = NULL;
1115        }
1116        if (skip_mode & SKIP_GRP_NOEFFEC) return;
1117        AnmAlphaMove* new_anm = new AnmAlphaMove(event, &parent); // shake screen では元画面の座暙を揺らす
1118        int i;
1119        int tm = 0;
1120        for (i=0; i<total; i+=3) {
1121                int x = pattern[i];
1122                int y = pattern[i+1];
1123                new_anm->ptns.push_back(AnmAlphaMove::Ptn(Rect(x,y), Rect(0,0), 255, tm));
1124                tm += pattern[i+2];
1125        }
1126        new_anm->ptns.push_back(AnmAlphaMove::Ptn(Rect(0,0), Rect(0,0), 255, tm));
1127        new_anm->SetPtn(); // パタヌン登録終了
1128        new_anm->Play();
1129        anm2 = new_anm;
1130}
1131
1132void Grp::AbortAnm(void) {
1133        if (anm1 == NULL) return;
1134        anm1->Abort();
1135        delete anm1;
1136        anm1 = NULL;
1137        /* 画像効果終了 */
1138        /* 叀い画面ぞの画像効果があれば消去 */
1139        if (anm2 && anm2->pic[0] != screen) {
1140                anm2->Abort();
1141                delete anm2;
1142                anm2 = NULL;
1143        }
1144        /* pdt1 -> pdt0 ぞコピヌ */
1145        DSurfaceMove(dsurface[1], Rect(*dsurface[1]), surface, Rect(0,0));
1146        screen->SetSurface(surface, 0, 0);
1147        // 画像効果開始時に存圚したobjectを消去
1148        // 新しい object 衚瀺
1149        RefreshObj();
1150        return;
1151}
1152
1153void Grp::LoadSurface(const char* str) {
1154        if (anm1 != NULL) AbortAnm(); // 前の描画が終わっおなければ匷制終了
1155        LoadSurface(str, 1);
1156        bg_name = str;
1157}
1158
1159void Grp::LoadSurface(void) {
1160        if (anm1 != NULL) AbortAnm(); // 前の描画が終わっおなければ匷制終了
1161        LoadSurface(bg_name.c_str(), 1);
1162}
1163
1164void Grp::AddSurface(const char* str) {
1165        if (anm1 != NULL) AbortAnm(); // 前の描画が終わっおなければ匷制終了
1166        LoadSurface(bg_name.c_str());
1167
1168        string s = str;
1169        Surface* front = parent.Root().NewSurface(s.c_str());
1170        if (front == NULL) {
1171                s += ".g00";
1172                front = parent.Root().NewSurface(s.c_str());
1173        }
1174        if (front != NULL) {
1175                parent.Root().BlitSurface(front, Rect(*front), Dsurface(1), Rect(0,0));
1176                parent.Root().DeleteSurface(front);
1177        } else {
1178                fprintf(stderr,"Cannot find surface %s\n",str);
1179        }
1180}
1181
1182void Grp::CreateObj(int index) {
1183        GrpObjMap::iterator cur = grpobj.find(index);
1184        if (cur == grpobj.end()) return;
1185        GrpObj& g = grpobj[index];
1186        g.CreateSurface(&parent);
1187        g.order = index;
1188        if (g.picture == NULL) return; // ゚ラヌsurface が存圚しない
1189        g.picture->hide();
1190        SetObjChanged(index);
1191        ZMoveObj(index);
1192}
1193
1194void Grp::CreateSubObj(int grp_index, int index) {
1195        GrpObjMap::iterator cur = grpobj.find(grp_index);
1196        if (cur == grpobj.end()) return;
1197        GrpObj* g = &grpobj[grp_index];
1198        cur = g->children_obj.find(index);
1199        if (cur == g->children_obj.end()) return;
1200        g = &g->children_obj[index];
1201        g->CreateSurface(&parent);
1202        g->order = index;
1203        if (g->picture == NULL) return; // ゚ラヌsurface が存圚しない
1204        g->picture->hide();
1205        //TODO
1206        SetObjChanged(grp_index);
1207        /*ZMoveObj(index);*/
1208}
1209
1210void Grp::ZMoveObj(int index) {
1211        GrpObjMap::iterator cur = grpobj.find(index);
1212        if (cur == grpobj.end()) return;
1213        GrpObj& g = grpobj[index];
1214        if (g.picture == NULL) return;
1215        // 自分より前に object があれば、その前に衚瀺
1216        // そうでなければ screen の前に衚瀺
1217        GrpObjMap::iterator cur_backobj = grpobj.end();
1218        GrpObjMap::iterator it;
1219        for (it = grpobj.begin(); it != grpobj.end(); it++) {
1220                if (it == cur) continue;
1221                if (it->second.picture == NULL) continue;
1222                if (it->second.order < g.order) {
1223                        if (cur_backobj == grpobj.end()) {
1224                                cur_backobj = it;
1225                        } else if (cur_backobj->second.order < it->second.order) {
1226                                cur_backobj = it;
1227                        }
1228                }
1229        }
1230        if (cur_backobj == grpobj.end()) {
1231                g.picture->ZMove(screen);
1232        } else {
1233                g.picture->ZMove(cur_backobj->second.picture);
1234        }
1235}
1236
1237void Grp::SwapObj(int index1, int index2) {
1238        // デフォルト倀から order が倉曎されおいた堎合のみ、order は保存される
1239        // たずは䞡方のobjectをswap
1240        if (grpobj.find(index1) == grpobj.end()) {
1241                if (grpobj.find(index2) == grpobj.end()) return; // どちらの object も存圚しない
1242                grpobj[index1] = grpobj[index2];
1243                if (grpobj[index1].order == index2)
1244                        grpobj[index1].order = index1;
1245                grpobj[index2].DeletePic();
1246                grpobj.erase(index2);
1247                ZMoveObj(index1);
1248                return;
1249        } else if (grpobj.find(index2) == grpobj.end()) { // index2 が存圚しない堎合
1250                grpobj[index2] = grpobj[index1];
1251                if (grpobj[index2].order == index1)
1252                        grpobj[index2].order = index2;
1253                grpobj[index1].DeletePic();
1254                grpobj.erase(index1);
1255                ZMoveObj(index2);
1256                return;
1257        } else {
1258                GrpObj obj = grpobj[index1];
1259                grpobj[index1] = grpobj[index2];
1260                grpobj[index2].DeletePic();
1261                if (grpobj[index1].order == index2)
1262                        grpobj[index1].order = index1;
1263                ZMoveObj(index1);
1264                grpobj[index2] = obj;
1265                if (grpobj[index2].order == index1)
1266                        grpobj[index2].order = index2;
1267                ZMoveObj(index2);
1268                obj.DeletePic();
1269        }
1270}
1271
1272bool Grp::Pressed(int x, int y, void* pointer) { // マりスクリックでキャンセル
1273        Grp* g = (Grp*)pointer;
1274        if (g->status == WAIT_MOVIE)
1275                g->music->StopMovie();
1276        if (g->status == WAIT_ANM)
1277                g->AbortAnm();
1278        if (g->status == WAIT_SHAKE && g->anm2 != NULL) {
1279                g->anm2->Abort();
1280                delete g->anm2;
1281                g->anm2 = NULL;
1282        }
1283        return false; // event deleted
1284}
1285
1286/* mode.cgm の decode 甹 */
1287static unsigned char decode_char[256] = {
1288        0x8b, 0xe5, 0x5d, 0xc3, 0xa1, 0xe0, 0x30, 0x44, 
1289        0x00, 0x85, 0xc0, 0x74, 0x09, 0x5f, 0x5e, 0x33, 
1290        0xc0, 0x5b, 0x8b, 0xe5, 0x5d, 0xc3, 0x8b, 0x45, 
1291        0x0c, 0x85, 0xc0, 0x75, 0x14, 0x8b, 0x55, 0xec, 
1292        0x83, 0xc2, 0x20, 0x52, 0x6a, 0x00, 0xe8, 0xf5, 
1293        0x28, 0x01, 0x00, 0x83, 0xc4, 0x08, 0x89, 0x45, 
1294        0x0c, 0x8b, 0x45, 0xe4, 0x6a, 0x00, 0x6a, 0x00, 
1295        0x50, 0x53, 0xff, 0x15, 0x34, 0xb1, 0x43, 0x00, 
1296        0x8b, 0x45, 0x10, 0x85, 0xc0, 0x74, 0x05, 0x8b, 
1297        0x4d, 0xec, 0x89, 0x08, 0x8a, 0x45, 0xf0, 0x84, 
1298        0xc0, 0x75, 0x78, 0xa1, 0xe0, 0x30, 0x44, 0x00, 
1299        0x8b, 0x7d, 0xe8, 0x8b, 0x75, 0x0c, 0x85, 0xc0, 
1300        0x75, 0x44, 0x8b, 0x1d, 0xd0, 0xb0, 0x43, 0x00, 
1301        0x85, 0xff, 0x76, 0x37, 0x81, 0xff, 0x00, 0x00, 
1302        0x04, 0x00, 0x6a, 0x00, 0x76, 0x43, 0x8b, 0x45, 
1303        0xf8, 0x8d, 0x55, 0xfc, 0x52, 0x68, 0x00, 0x00, 
1304        0x04, 0x00, 0x56, 0x50, 0xff, 0x15, 0x2c, 0xb1, 
1305        0x43, 0x00, 0x6a, 0x05, 0xff, 0xd3, 0xa1, 0xe0, 
1306        0x30, 0x44, 0x00, 0x81, 0xef, 0x00, 0x00, 0x04, 
1307        0x00, 0x81, 0xc6, 0x00, 0x00, 0x04, 0x00, 0x85, 
1308        0xc0, 0x74, 0xc5, 0x8b, 0x5d, 0xf8, 0x53, 0xe8, 
1309        0xf4, 0xfb, 0xff, 0xff, 0x8b, 0x45, 0x0c, 0x83, 
1310        0xc4, 0x04, 0x5f, 0x5e, 0x5b, 0x8b, 0xe5, 0x5d, 
1311        0xc3, 0x8b, 0x55, 0xf8, 0x8d, 0x4d, 0xfc, 0x51, 
1312        0x57, 0x56, 0x52, 0xff, 0x15, 0x2c, 0xb1, 0x43, 
1313        0x00, 0xeb, 0xd8, 0x8b, 0x45, 0xe8, 0x83, 0xc0, 
1314        0x20, 0x50, 0x6a, 0x00, 0xe8, 0x47, 0x28, 0x01, 
1315        0x00, 0x8b, 0x7d, 0xe8, 0x89, 0x45, 0xf4, 0x8b, 
1316        0xf0, 0xa1, 0xe0, 0x30, 0x44, 0x00, 0x83, 0xc4, 
1317        0x08, 0x85, 0xc0, 0x75, 0x56, 0x8b, 0x1d, 0xd0, 
1318        0xb0, 0x43, 0x00, 0x85, 0xff, 0x76, 0x49, 0x81, 
1319        0xff, 0x00, 0x00, 0x04, 0x00, 0x6a, 0x00, 0x76
1320};
1321
1322void Grp::LoadCgm() {
1323        /* cgm ファむル読み蟌み */
1324        const char* fname = config->GetParaStr("#CGTABLE_FILE");
1325        if (fname == NULL) return;
1326        ARCINFO* info = FileSearcher::GetInstance()->Find(FileSearcher::ALL, fname, "");
1327        if (info == NULL) return;
1328        char* data = info->CopyRead();
1329        int sz = info->Size();
1330        delete info;
1331
1332       
1333        if ( strncmp(data, "CGTABLE", 7) != 0) {
1334                delete[] data;
1335                return;
1336        }
1337        cgm_size = read_little_endian_int(data+0x10);
1338
1339        int i, j;
1340        // xor 解陀
1341        for (i=0; i < sz-0x20; i++) {
1342                data[i+0x20]^=decode_char[i&0xff];
1343        }
1344        // 展開
1345        int dest_size = cgm_size * 36;
1346        char* dest = new char[dest_size+1024];
1347        char* src = data + 0x28;
1348        char* dest_orig = dest;
1349        ARCINFO::Extract2k(dest,src,dest+dest_size,data+sz);
1350        dest = dest_orig;
1351        for (i=0; i<cgm_size; i++) {
1352                char* s = dest + i * 36;
1353                int n = read_little_endian_int(dest + i * 36 + 32);
1354                cgm_info[s] = n;
1355        }
1356        delete[] data;
1357        delete[] dest_orig;
1358}
1359
1360/*****************************************************
1361*
1362*   Grp :: Save, Load : セヌブファむル凊理
1363*
1364*/
1365void Grp::Save(std::string& str) {
1366}
1367
1368void Grp::Load(const char* str) {
1369        status = NORMAL;
1370        if (anm1 != NULL) {
1371                AbortAnm();
1372        }
1373        if (anm2 != NULL) {
1374                anm2->Abort();
1375                delete anm2;
1376                anm2 = NULL;
1377        }
1378        map<int,GrpObj>::iterator it;
1379        for (it=grpobj.begin(); it!=grpobj.end(); it++) {
1380                PicBase* p = it->second.DeletePic();
1381                delete p;
1382        }
1383        grpobj.clear();
1384       
1385        bg_name = "";
1386        music->StopCDROM(100);
1387}
1388
1389void Grp::SaveSys(string& save) {
1390        char buf[1024];
1391        save = "\n[Graphics]\n";
1392        save += "CGM_CG=";
1393
1394        set<int>::iterator it;
1395        for (it=cgm_data.begin(); it != cgm_data.end(); it++) {
1396                sprintf(buf,"%d,",*it);
1397                save += buf;
1398        }
1399        save += "\n";
1400}
1401
1402void Grp::LoadSys(const char* save) {
1403        cgm_data.clear();
1404        save = strstr(save, "\n[Graphics]\n");
1405
1406        if (save) {
1407                save += strlen("\n[Graphics]\n");
1408                do {
1409                        if (save[0] == '[') break; // next section
1410                        if (strncmp(save, "CGM_CG=",7) == 0) {
1411                                save += 7;
1412                                while(isdigit(*save)) {
1413                                        int n = atoi(save);
1414                                        cgm_data.insert(n);
1415                                        save = strchr(save, ',');
1416                                        if (save) save++;
1417                                }
1418                        }
1419                        save = strchr(save, '\n');
1420                        if (save) save++;
1421                } while (save);
1422        }
1423        return;
1424}
1425
1426
1427/*****************************************************
1428*
1429*   Grp :: Wait , Exec : コマンド実行郚
1430*
1431*/
1432static vector<int> drawn_images;
1433static int draw_n = 0;
1434extern bool grpdump_req;
1435bool Grp::Wait(unsigned int current_time, Cmd& cmd) {
1436        if (grpdump_req) {
1437                grpdump_req = 0;
1438                GrpObjMap::iterator it;
1439                fprintf(stderr,"front %p(%d) / %p(%d)\n",screen,screen->IsHidden(),screen_front,screen_front->IsHidden());
1440                for (it=grpobj.begin(); it != grpobj.end(); it++) {
1441                        GrpObj& obj = it->second;
1442                        obj._debug_Dump(it->first, 0);
1443                }
1444                std::list<PicBase*>::iterator it2;
1445                for (it2=parent.children.begin(); it2!=parent.children.end();it2++) {
1446                        fprintf(stderr,"%p(%d)\n",*it2,(*it2)->IsHidden());
1447                }
1448                RefreshObj();
1449
1450        }
1451#if 0
1452        if (event.presscount(MOUSE_UP)) {
1453                std::list<PicBase*>::iterator lit;
1454                draw_n++; int i=0;
1455                for (lit=parent.children.end(); lit!=parent.children.begin(); ) {
1456                        lit--;
1457                        (*lit)->hide();
1458                        i++;
1459                        if (i >= draw_n) break;
1460                }
1461                if (drawn_images.empty()) {
1462                        map<int, GrpObj>::iterator it;
1463                        for (it=grpobj.begin(); it!=grpobj.end(); it++) {
1464                                if (it->second.picture) {
1465                                        drawn_images.push_back(it->first);
1466                                        PicBase* p = it->second.DeletePic();
1467                                        delete p;
1468                                }
1469                        }
1470                } else {
1471                        vector<int>::iterator it;
1472                        for (it=drawn_images.begin(); it!=drawn_images.end(); it++) {
1473                                CreateObj(*it);
1474                        }
1475                        drawn_images.clear();
1476                }
1477        }
1478#endif
1479        if (status == WAIT_ANM) {
1480                if (anm1 != NULL) {
1481                        if (!anm1->IsEnd()) return true;
1482                        //FIXME: Handle animation loops
1483                        AbortAnm();
1484                }
1485        } else if (status == WAIT_SHAKE) {
1486                if (anm2 != NULL) {
1487                        if (!anm2->IsEnd()) return true;
1488                        delete anm2;
1489                        anm2 = NULL;
1490                }
1491                status = NORMAL;
1492        } else if (status == WAIT_SE) {
1493                if (music->IsStopSE()) status = NORMAL;
1494                return true;
1495        } else if (status == WAIT_MOVIE) {
1496                if (music->IsStopMovie()) {
1497                        music->StopMovie();
1498                        status = NORMAL;
1499                        screen->ReBlit();
1500                }
1501                return true;
1502        }
1503        if (anm2 != NULL) {
1504                if (anm2->IsEnd()) {
1505                        delete anm2;
1506                        anm2 = NULL;
1507                }
1508        }
1509        return false;
1510}
1511
1512void Grp::DeleteObjPic(int num) { // object の surface のみ削陀
1513        if (grpobj.find(num) == grpobj.end()) return;
1514        deleted_pic.push_back(grpobj[num].DeletePic());
1515}
1516
1517void Grp::DeleteSubObjPic(int num_grp, int num) {
1518        if (grpobj.find(num_grp) == grpobj.end()) return;
1519        if (grpobj[num_grp].children_obj.find(num) == grpobj[num_grp].children_obj.end()) return;
1520        deleted_pic.push_back(grpobj[num_grp].children_obj[num].DeletePic());
1521}
1522
1523void Grp::DeleteObj(int num) {
1524        if (grpobj.find(num) == grpobj.end()) return;
1525        deleted_pic.push_back(grpobj[num].DeletePic());
1526        GrpObjMap::iterator it;
1527        for (it = grpobj[num].children_obj.begin(); it != grpobj[num].children_obj.end(); it++) {
1528                deleted_pic.push_back(it->second.DeletePic());
1529        }
1530        grpobj.erase(num);
1531}
1532
1533void Grp::DeleteSubObj(int num_grp, int num) {
1534        if (grpobj.find(num_grp) == grpobj.end()) return;
1535        if (grpobj[num_grp].children_obj.find(num) == grpobj[num_grp].children_obj.end()) return;
1536        deleted_pic.push_back(grpobj[num_grp].children_obj[num].DeletePic());
1537        grpobj[num_grp].children_obj.erase(num);
1538}
1539
1540void Grp::Exec(Cmd& cmd) {
1541        if (cmd.cmd_type == CMD_TEXTEND) {
1542                music->StopKoe(500); // テキスト終了で声を止める
1543                cmd.clear();
1544                return;
1545        }
1546        if (cmd.cmd_type == CMD_WAITFRAMEUPDATE) {
1547                // wait する堎合は RefreshObj() しおおく
1548                RefreshObj();
1549        }
1550        if (cmd.cmd_type != CMD_OTHER) return;
1551
1552        CommandHandler::Exec(cmd);
1553
1554        //TODO: ???
1555        if (cmd.cmd1 == 1 && cmd.cmd2 == 60 && cmd.cmd3 == 0) { // ??? : KANOGI : 画像オブゞェクトの削陀
1556                DeleteObjPic(cmd.args[0].value); // 旧ファむル名のsurfaceを削陀
1557                GrpObj& g = grpobj[cmd.args[0].value];
1558                g.attr = GrpObj::Attribute(g.attr | GrpObj::HIDDEN);
1559                cmd.clear();
1560        }
1561
1562        // Refresh changed objects...
1563        //FIXME: should may be go away?
1564        //Seems it'll work only for objects in the foreground
1565        if ( (cmd.cmd1 == 1 || cmd.cmd1 == 2) && cmd.cmd2 == 81) {
1566                GrpObj* g;
1567                if (cmd.cmd1 == 2)
1568                        g = GetGraphicObj(cmd.args[0].value, cmd.args[1].value);
1569                else
1570                        g = GetGraphicObj(cmd.args[0].value);
1571                if (g->attr & GrpObj::UPDATE_ALL)
1572                        SetObjChanged(cmd.args[0].value);
1573        }
1574}
1575
Note: See TracBrowser for help on using the browser.