diff scn2k/scn2k_grp.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 f1a27ee7e03c
children e16e13d8cd68
line wrap: on
line diff
--- a/scn2k/scn2k_grp.cc
+++ b/scn2k/scn2k_grp.cc
@@ -26,229 +26,14 @@
  */
 
 #include "scn2k.h"
-#include "window/widget.h"
 #include "system/file.h"
 #include "system/system_config.h"
 #include "font/text.h"
-#include <set>
-
-using namespace std;
+#include "window/render.h"
 
-extern void DSurfaceFill(Surface* dest, const Rect& rect, int r, int g, int b, int a=0xff);
-extern void DSurfaceMove(Surface* src_o, const Rect& srcrect, Surface* dst_o, const Rect& dstpos);
-extern Rect DSurfaceRenderText(TextGlyphStream::iterator start, TextGlyphStream::iterator end, const Rect& srcrect,
-        Surface* dst, const Rect& dstrect);
 extern XKFont::HorizLayout* DefaultLayout(int text_size);
 
 /*******************************************************************
-** GrpObj(interface)
-*/
-
-struct SEL {
-	Rect from;
-	Rect to;
-	int time;
-	int sel_no;
-	int args[8];
-	SEL() : from(0,0), to(0,0) {}
-};
-
-struct GrpObj;
-typedef std::map<int, GrpObj> GrpObjMap;
-
-struct GrpObj {
-	string name;
-	string gan_name;
-	PicContainer* pic_parent;
-	PicBase* picture;
-	WidAnmTime* anm;
-	int _posx, _posy;
-	int posx[9], posy[9];
-	Rect clip_area;
-	unsigned char alpha;
-	int order;
-	int surface_num;
-
-	GrpObjMap children_obj;
-
-	string print_moji;
-	int print_size, print_r, print_b, print_g;
-
-	int dig_number, dig_digit;
-
-	// zoom / rotate 関係
-	int zoom; // 256 で 1 倍
-	int rotate; // 0-360度
-
-	vector<Rect> src_pos;
-	enum GrpType { FILLRECT = 1, FILE = 2, GAN = 3, MOJI = 4, DIGIT = 5} gtype;
-	enum Attribute { NONE=0, WIPEON=1, SATURATE=2, HIDDEN=4,
-		UPDATE_PICTURE = 16, UPDATE_POS = 32, UPDATE_ALPHA = 64, UPDATE_SNUM = 128, UPDATE_CLIP = 256, UPDATE_VISIBLE = 512,
-		UPDATE_ALL = (UPDATE_PICTURE | UPDATE_POS | UPDATE_ALPHA | UPDATE_SNUM | UPDATE_CLIP | UPDATE_VISIBLE),
-		ANM_PLAYSTART = 0x8000, ANM_PLAYING = 0x10000,
-		DIG_ZERO = 0x10000*2, DIG_SIGN = 0x10000*4, DIG_PACK=0x10000*8,DIG_SPACE=0x10000*16
-		};
-	Attribute attr;
-
-	GrpObj(void);
-	~GrpObj(void);
-
-	void SetPos(int index, int x, int y);
-	void GetPos(int index, int& x, int& y);
-	int PosX(void);
-	int PosY(void);
-	void SetAlpha(void);
-	void SetAlpha(int alpha);
-	void SetSurfaceNum(int num = -1);
-	void SetZoomRotate(int zoom=-1, int rotate=-1);
-	void SetClipArea(int x, int y, int width, int height);
-	void GetSrcGeom(int& width, int& height);
-	void SetUpdate(void);
-	void UpdateMoji(void);
-	void UpdateDigit(void);
-	void UpdateSurface(void);
-	void ZoomRotate(void);
-	void Refresh(GrpObj& parent_obj);
-	void _debug_Dump(int, int);
-	void Update(void);
-	void CreateSurface(PicContainer* parent);
-	void CreateGan(Event::Container& event, int event_number);
-	void CreateGanSpecial(Event::Container& event, int event_number, int time);
-	PicBase* DeletePic(void);
-};
-
-/*******************************************************************
-** GrpObj(interface)
-*/
-
-class GrpImpl : public CommandHandler {
-#define MAXPDT 256
-#define WORKPDT 255
-	private:
-		void CreateObj(int number);
-		void CreateSubObj(int grp_num, int number);
-		void ZMoveObj(int number);
-		void SetObjChanged(int number);
-		void SwapObj(int a1, int a2);
-		void DeleteObjPic(int num);// object の surface のみ削除
-		void DeleteSubObjPic(int grp_num, int num);
-		void DeleteObj(int num);
-		void DeleteSubObj(int grp_num, int num);
-		void RefreshObj(void);
-
-		Surface* Dsurface(int pdt);
-		Surface* Ssurface(int pdt);
-
-		// cgmode 用画像処理関連
-		void LoadCgm(void);
-
-	public:
-		GrpImpl(Event::Container& _event, PicContainer& _parent, const Flags& _flag, set<int>& _cgm_data);
-		~GrpImpl();
-		bool Wait(unsigned int current_time, Cmd& cmd);
-		void Exec(Cmd& cmd);
-		void InitSel(void);
-		void Save(std::string& str);
-		void Load(const char* str);
-		void SaveSys(std::string& str);
-		void LoadSys(const char* str);
-		void SetSkipMode(SkipMode _mode);
-		void LoadSurface(const char* str, int pdt);
-
-	private:
-		void LoadSurface(const char* str);
-		void LoadSurface(void);
-		void AddSurface(const char* str);
-
-		void StartAnm(int type);
-		void StartShake(int total, const int* pattern);
-		void AbortAnm(void);
-		static bool Pressed(int x, int y, void* pointer);
-
-		GrpObj* GetGraphicObj(int grp, bool fg=true);
-		GrpObj* GetGraphicObj(int grp, int index, bool fg=true);
-		GrpObj* GetGraphicObjVarMode(Cmd& cmd, int &base_arg, bool fg=true);
-
-		// Opcode handling
-		void impl_stackClear(Cmd& cmd);
-		void impl_grpBuffer(Cmd& cmd);
-		void impl_grpMulti(Cmd &cmd);
-		void impl_grpOpen(Cmd &cmd);
-		void impl_shake(Cmd &cmd);
-		void impl_grpCopy(Cmd &cmd);
-		void impl_recFill(Cmd &cmd);
-		void impl_recCopy(Cmd &cmd);
-		void impl_recAdd(Cmd &cmd);
-		void impl_grpPan(Cmd &cmd);
-		void impl_snmPlay(Cmd &cmd);
-		void impl_snmBgScroll(Cmd &cmd);
-		void impl_cgGet(Cmd &cmd);
-		void impl_cgStatus(Cmd &cmd);
-		void impl_objClear(Cmd &cmd);
-		void impl_createObj(Cmd &cmd);
-		void impl_gan(Cmd &cmd);
-		void impl_objSetPos(Cmd &cmd);
-		void impl_objAlpha(Cmd &cmd);
-		void impl_objShow(Cmd &cmd);
-		void impl_objColour(Cmd &cmd);
-		void impl_objComposite(Cmd &cmd);
-		void impl_objSetText(Cmd &cmd);
-		void impl_objTextOpts(Cmd &cmd);
-		void impl_objOrder(Cmd &cmd);
-		void impl_objDispArea(Cmd &cmd);
-		void impl_objSetDigits(Cmd &cmd);
-		void impl_objNumOpts(Cmd &cmd);
-		void impl_objPattNo(Cmd &cmd);
-		void impl_objScale(Cmd &cmd);
-		void impl_objRotate(Cmd &cmd);
-		void impl_objPosDims(Cmd &cmd);
-		void impl_refresh(Cmd &cmd);
-		void impl_bgmLoop(Cmd &cmd);
-		void impl_bgmStop(Cmd &cmd);
-		void impl_playWav(Cmd &cmd);
-		void impl_playSE(Cmd &cmd);
-		void impl_stopWav(Cmd &cmd);
-		void impl_SetVolMod(Cmd &cmd);
-		void impl_GetVolMod(Cmd &cmd);
-		void impl_koePlay(Cmd &cmd);
-		void impl_movPlay(Cmd &cmd);
-
-	public:
-		AyuSysConfig *config;
-
-	private:
-		Event::Container& event;
-		const Flags& flags;
-		PicBase* screen;
-		PicBase* screen_front;
-		Surface* surface, *surface_update;
-
-		Surface* dsurface[MAXPDT]; // 書き込み可能な Surface
-		Surface* ssurface[MAXPDT]; // ファイルの内容等、読み込みのみ可能な状態の Surface
-		PicContainer& parent;
-
-		// 画像効果の保存用
-		WidAnmTime* anm1, *anm2;
-		typedef enum { NORMAL, WAIT_ANM, WAIT_SHAKE, WAIT_SE, WAIT_MOVIE} Status;
-		Status status;
-		SkipMode skip_mode;
-
-		std::string bg_name;
-		std::map<int, SEL> anmtype;
-		GrpObjMap grpobj;
-		GrpObjMap bs_obj;
-
-		std::map<std::string, int> cgm_info;
-		set<int>& cgm_data;
-		int cgm_size;
-
-		class MuSys *music;
-
-		std::set<int> changed_obj;
-		string reserved_load_surface0;
-		vector<PicBase*> deleted_pic;
-};
-/*******************************************************************
 ** GrpObj(implementation)
 */
 
@@ -752,14 +537,7 @@ void GrpObj::_debug_Dump(int id, int ind
 **	class ScnGrp*
 */
 /* Princess Bride: 背景画の一部のみ移動、の実装 */
-struct ScnGrpMove : public WidAnmTime {
-	Surface* dest;
-	Surface* src;
-	PicRoot& root;
-	Rect dest_r, from, to;
-	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);
-	void Exec(int count);
-};
+
 ScnGrpMove::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) :
 	WidAnmTime(container, _pic, total_time),
 	dest(_dest), src(_src), root(_root),dest_r(_dest_r), from(_from), to(_to) {
@@ -785,23 +563,6 @@ void ScnGrpMove::Exec(int count) {
 		(*it)->SetSurface(dest, 0, 0);
 }
 
-/* Princess Bride: カードがおちるアニメーション */
-
-struct ScnGrpAnmAtom {
-	string name;
-	int time;
-	ScnGrpAnmAtom(const char* _n, int _t) : name(_n), time(_t) {}
-};
-
-struct ScnGrpAnm : public WidAnmTime, vector<ScnGrpAnmAtom> {
-	GrpImpl& owner;
-	ScnGrpAnm(Event::Container& container, PicBase* _pic, GrpImpl& _owner) :
-		WidAnmTime(container, _pic, 0), owner(_owner) {
-	}
-	void CalcTotal(void);
-	void Exec(int count);
-};
-
 void ScnGrpAnm::CalcTotal(void) {
 	/* total time を計算 */
 	if (empty()) return;
@@ -825,13 +586,13 @@ void ScnGrpAnm::Exec(int count) {
 
 /*****************************************************
 *
-*  GrpImpl(implementation) : 定義
+*  Grp
 *
 */
 
 #include "music2/music.h"
 
-GrpImpl::GrpImpl(Event::Container& _event, PicContainer& _parent, const Flags& f, set<int>& _cgm_data):
+Grp::Grp(Event::Container& _event, PicContainer& _parent, const Flags& f, set<int>& _cgm_data):
 	event(_event),
 	flags(f), 
 	parent(_parent),
@@ -861,76 +622,75 @@ GrpImpl::GrpImpl(Event::Container& _even
 
 	LoadCgm();
 
-	RegisterCommand(1, 30, 0, "stackClear", (CmdImpl) &GrpImpl::impl_stackClear);
-	RegisterCommand(1, 33, 70, "grpBuffer", (CmdImpl) &GrpImpl::impl_grpBuffer);
-	RegisterCommand(1, 33, 73, "grpOpenBG", (CmdImpl) &GrpImpl::impl_grpOpen);
-	RegisterCommand(1, 33, 75, "grpMulti", (CmdImpl) &GrpImpl::impl_grpMulti); //FIXME: or not...
-	RegisterCommand(1, 33, 76, "grpOpen", (CmdImpl) &GrpImpl::impl_grpOpen);
-	RegisterCommand(1, 33, 32, "shake", (CmdImpl) &GrpImpl::impl_shake);
-	RegisterCommand(1, 33, 100, "grpCopy", (CmdImpl) &GrpImpl::impl_grpCopy);
-	RegisterCommand(1, 33, 1201, "recFill", (CmdImpl) &GrpImpl::impl_recFill);
-	RegisterCommand(1, 33, 1100, "recCopy", (CmdImpl) &GrpImpl::impl_recCopy);
+	RegisterCommand(1, 30, 0, "stackClear", (CmdImpl) &Grp::impl_stackClear);
+	RegisterCommand(1, 33, 70, "grpBuffer", (CmdImpl) &Grp::impl_grpBuffer);
+	RegisterCommand(1, 33, 73, "grpOpenBG", (CmdImpl) &Grp::impl_grpOpen);
+	RegisterCommand(1, 33, 75, "grpMulti", (CmdImpl) &Grp::impl_grpMulti); //FIXME: or not...
+	RegisterCommand(1, 33, 76, "grpOpen", (CmdImpl) &Grp::impl_grpOpen);
+	RegisterCommand(1, 33, 32, "shake", (CmdImpl) &Grp::impl_shake);
+	RegisterCommand(1, 33, 100, "grpCopy", (CmdImpl) &Grp::impl_grpCopy);
+	RegisterCommand(1, 33, 1201, "recFill", (CmdImpl) &Grp::impl_recFill);
+	RegisterCommand(1, 33, 1100, "recCopy", (CmdImpl) &Grp::impl_recCopy);
 	RegisterCommand(1, 33, 1101, "recMaskCopy", NULL); //FIXME
-	RegisterCommand(1, 33, 1600, "recAdd", (CmdImpl) &GrpImpl::impl_recAdd);
-	RegisterCommand(1, 33, 406, "grpPan", (CmdImpl) &GrpImpl::impl_grpPan);
+	RegisterCommand(1, 33, 1600, "recAdd", (CmdImpl) &Grp::impl_recAdd);
+	RegisterCommand(1, 33, 406, "grpPan", (CmdImpl) &Grp::impl_grpPan);
 
-	RegisterCommand(1, 34, 3120, "snmBgScroll", (CmdImpl) &GrpImpl::impl_snmBgScroll);
-	RegisterCommand(1, 34, 3100, "snmBgPlay", (CmdImpl) &GrpImpl::impl_snmPlay);
-	RegisterCommand(1, 34, 2100, "snmPlay", (CmdImpl) &GrpImpl::impl_snmPlay);
-	RegisterCommand(1, 34, 2101, "snmPlayEx", (CmdImpl) &GrpImpl::impl_snmPlay);
+	RegisterCommand(1, 34, 3120, "snmBgScroll", (CmdImpl) &Grp::impl_snmBgScroll);
+	RegisterCommand(1, 34, 3100, "snmBgPlay", (CmdImpl) &Grp::impl_snmPlay);
+	RegisterCommand(1, 34, 2100, "snmPlay", (CmdImpl) &Grp::impl_snmPlay);
+	RegisterCommand(1, 34, 2101, "snmPlayEx", (CmdImpl) &Grp::impl_snmPlay);
 
-	RegisterCommand(1, 4, 1500, "cgGetTotal", (CmdImpl) &GrpImpl::impl_cgGet);
-	RegisterCommand(1, 4, 1501, "cgGetViewed", (CmdImpl) &GrpImpl::impl_cgGet);
-	RegisterCommand(1, 4, 1502, "cgGetViewedPcnt", (CmdImpl) &GrpImpl::impl_cgGet);
-	RegisterCommand(1, 4, 1503, "cgGetFlag", (CmdImpl) &GrpImpl::impl_cgStatus);
-	RegisterCommand(1, 4, 1504, "cgStatus", (CmdImpl) &GrpImpl::impl_cgStatus);
+	RegisterCommand(1, 4, 1500, "cgGetTotal", (CmdImpl) &Grp::impl_cgGet);
+	RegisterCommand(1, 4, 1501, "cgGetViewed", (CmdImpl) &Grp::impl_cgGet);
+	RegisterCommand(1, 4, 1502, "cgGetViewedPcnt", (CmdImpl) &Grp::impl_cgGet);
+	RegisterCommand(1, 4, 1503, "cgGetFlag", (CmdImpl) &Grp::impl_cgStatus);
+	RegisterCommand(1, 4, 1504, "cgStatus", (CmdImpl) &Grp::impl_cgStatus);
 
 	RegisterCommand(1, 4, 0x6a4, "CreateInput", NULL);
 	RegisterCommand(1, 4, 0x6ae, "SetInput", NULL);
 
-	RegisterCommand(1, 61, 10, "objClear", (CmdImpl) &GrpImpl::impl_objClear);
-	RegisterCommand(1, 61, 11, "objDelete", (CmdImpl) &GrpImpl::impl_objClear);
+	RegisterCommand(1, 61, 10, "objClear", (CmdImpl) &Grp::impl_objClear);
+	RegisterCommand(1, 61, 11, "objDelete", (CmdImpl) &Grp::impl_objClear);
 
-	RegisterCommand(1, 71, 1000, "createObjG00", (CmdImpl) &GrpImpl::impl_createObj);
-	RegisterCommand(1, 71, 1003, "createObjGAN", (CmdImpl) &GrpImpl::impl_createObj);
-	RegisterCommand(1, 71, 1100, "createObjRect", (CmdImpl) &GrpImpl::impl_createObj);
-	RegisterCommand(1, 71, 1200, "createObjText", (CmdImpl) &GrpImpl::impl_createObj);
-	RegisterCommand(1, 71, 1300, "createObjWeaver", (CmdImpl) &GrpImpl::impl_createObj);
-	RegisterCommand(1, 71, 1400, "createObjDigit", (CmdImpl) &GrpImpl::impl_createObj);
+	RegisterCommand(1, 71, 1000, "objOfFile", (CmdImpl) &Grp::impl_createObj);
+	RegisterCommand(1, 71, 1003, "objOfFileGan", (CmdImpl) &Grp::impl_createObj);
+	RegisterCommand(1, 71, 1100, "objOfArea", (CmdImpl) &Grp::impl_createObj);
+	RegisterCommand(1, 71, 1200, "objOfText", (CmdImpl) &Grp::impl_createObj);
+	RegisterCommand(1, 71, 1300, "objDriftOfFile", (CmdImpl) &Grp::impl_createObj);
+	RegisterCommand(1, 71, 1400, "objOfDigits", (CmdImpl) &Grp::impl_createObj);
 
-	RegisterCommand(2, 71, 1000, "createSubObjG00", (CmdImpl) &GrpImpl::impl_createObj);
-	RegisterCommand(2, 71, 1003, "createSubObjGAN", (CmdImpl) &GrpImpl::impl_createObj);
-	RegisterCommand(2, 71, 1100, "createSubObjRect", (CmdImpl) &GrpImpl::impl_createObj);
-	RegisterCommand(2, 71, 1200, "createSubObjText", (CmdImpl) &GrpImpl::impl_createObj);
-	RegisterCommand(2, 71, 1300, "createSubObjWeaver", (CmdImpl) &GrpImpl::impl_createObj);
-	RegisterCommand(2, 71, 1400, "createSubObjDigit", (CmdImpl) &GrpImpl::impl_createObj);
+	RegisterCommand(2, 71, 1000, "subObjOfFile", (CmdImpl) &Grp::impl_createObj);
+	RegisterCommand(2, 71, 1003, "subObjOfGan", (CmdImpl) &Grp::impl_createObj);
+	RegisterCommand(2, 71, 1100, "subObjOfArea", (CmdImpl) &Grp::impl_createObj);
+	RegisterCommand(2, 71, 1200, "subObjOfText", (CmdImpl) &Grp::impl_createObj);
+	RegisterCommand(2, 71, 1300, "subObjDriftOfFile", (CmdImpl) &Grp::impl_createObj);
+	RegisterCommand(2, 71, 1400, "subObjOfDigits", (CmdImpl) &Grp::impl_createObj);
 
 	//I suppose it's the same thing as createObj*, but I didn't see it in action. For now, mark it unhandled.
-	RegisterCommand(1, 72, 1000, "createBgObjG00", (CmdImpl) &GrpImpl::impl_createObj);
-	RegisterCommand(1, 72, 1003, "createBgObjGAN", (CmdImpl) &GrpImpl::impl_createObj);
-	RegisterCommand(1, 72, 1100, "createBgObjRect", (CmdImpl) &GrpImpl::impl_createObj);
-	RegisterCommand(1, 72, 1200, "createBgObjText", (CmdImpl) &GrpImpl::impl_createObj);
-	RegisterCommand(1, 72, 1300, "createBgObjWeaver", (CmdImpl) &GrpImpl::impl_createObj);
-	RegisterCommand(1, 72, 1400, "createBgObjDigit", (CmdImpl) &GrpImpl::impl_createObj);
+	RegisterCommand(1, 72, 1000, "objBgOfFile", (CmdImpl) &Grp::impl_createObj);
+	RegisterCommand(1, 72, 1003, "objBgOfFileGan", (CmdImpl) &Grp::impl_createObj);
+	RegisterCommand(1, 72, 1100, "objBgOfArea", (CmdImpl) &Grp::impl_createObj);
+	RegisterCommand(1, 72, 1200, "objBgOfText", (CmdImpl) &Grp::impl_createObj);
+	RegisterCommand(1, 72, 1300, "objBgDriftOfFile", (CmdImpl) &Grp::impl_createObj);
+	RegisterCommand(1, 72, 1400, "objBgOfDigits", (CmdImpl) &Grp::impl_createObj);
 
-	RegisterCommand(2, 72, 1000, "createBgSubObjG00", NULL);//FIXME
-	RegisterCommand(2, 72, 1003, "createBgSubObjGAN", NULL);//FIXME
-	RegisterCommand(2, 72, 1100, "createBgSubObjRect", NULL);//FIXME
-	RegisterCommand(2, 72, 1200, "createBgSubObjText", NULL);//FIXME
-	RegisterCommand(2, 72, 1300, "createBgSubObjWeaver", NULL);//FIXME
-	RegisterCommand(2, 72, 1400, "createBgSubObjDigit", NULL);//FIXME
-
+	RegisterCommand(2, 72, 1000, "subObjBgOfFile", NULL);//FIXME
+	RegisterCommand(2, 72, 1003, "subObjBgOfGan", NULL);//FIXME
+	RegisterCommand(2, 72, 1100, "subObjBgOfArea", NULL);//FIXME
+	RegisterCommand(2, 72, 1200, "subObjBgOfText", NULL);//FIXME
+	RegisterCommand(2, 72, 1300, "subObjBgDriftOfFile", NULL);//FIXME
+	RegisterCommand(2, 72, 1400, "subObjBgOfDigits", NULL);//FIXME;
 
 	RegisterCommand(1, 73, 0, "ganStop?", NULL); //That's what xclannad says, but I'm not sure...
-	RegisterCommand(1, 73, 1000, "ganStop", (CmdImpl) &GrpImpl::impl_gan); //That's what rldev says
-	RegisterCommand(1, 73, 3, "ganIsPlaying", (CmdImpl) &GrpImpl::impl_gan);
-	RegisterCommand(1, 73, 2003, "objPlay", (CmdImpl) &GrpImpl::impl_gan);
-	RegisterCommand(1, 73, 1001, "ganLoop", (CmdImpl) &GrpImpl::impl_gan);
-	RegisterCommand(1, 73, 1003, "ganPlay", (CmdImpl) &GrpImpl::impl_gan);
-	RegisterCommand(1, 73, 1005, "ganPlayOnce", (CmdImpl) &GrpImpl::impl_gan);
-	RegisterCommand(1, 73, 3001, "ganLoop2", (CmdImpl) &GrpImpl::impl_gan);
-	RegisterCommand(1, 73, 3003, "ganPlay2", (CmdImpl) &GrpImpl::impl_gan);
-	RegisterCommand(1, 73, 3005, "ganPlayOnce2", (CmdImpl) &GrpImpl::impl_gan);
+	RegisterCommand(1, 73, 1000, "ganStop", (CmdImpl) &Grp::impl_gan); //That's what rldev says
+	RegisterCommand(1, 73, 3, "ganIsPlaying", (CmdImpl) &Grp::impl_gan);
+	RegisterCommand(1, 73, 2003, "objPlay", (CmdImpl) &Grp::impl_gan);
+	RegisterCommand(1, 73, 1001, "ganLoop", (CmdImpl) &Grp::impl_gan);
+	RegisterCommand(1, 73, 1003, "ganPlay", (CmdImpl) &Grp::impl_gan);
+	RegisterCommand(1, 73, 1005, "ganPlayOnce", (CmdImpl) &Grp::impl_gan);
+	RegisterCommand(1, 73, 3001, "ganLoop2", (CmdImpl) &Grp::impl_gan);
+	RegisterCommand(1, 73, 3003, "ganPlay2", (CmdImpl) &Grp::impl_gan);
+	RegisterCommand(1, 73, 3005, "ganPlayOnce2", (CmdImpl) &Grp::impl_gan);
 
 	RegisterCommand(2, 73, 0, "ganSubStop?", NULL); //FIXME
 	RegisterCommand(2, 73, 1000, "ganSubStop", NULL); //FIXME
@@ -939,33 +699,33 @@ GrpImpl::GrpImpl(Event::Container& _even
 	RegisterCommand(2, 73, 1001, "ganSubLoop", NULL); //FIXME
 	RegisterCommand(2, 73, 1003, "ganSubPlay", NULL); //FIXME
 	RegisterCommand(2, 73, 1005, "ganSubPlayOnce", NULL); //FIXME
-	RegisterCommand(2, 73, 3001, "ganSubLoop2", (CmdImpl) &GrpImpl::impl_gan); //FIXME
+	RegisterCommand(2, 73, 3001, "ganSubLoop2", (CmdImpl) &Grp::impl_gan); //FIXME
 	RegisterCommand(2, 73, 3003, "ganSubPlay2", NULL); //FIXME
 	RegisterCommand(2, 73, 3005, "ganSubPlayOnce2", NULL); //FIXME
 
 
-	RegisterCommand(1, 81, 1000, "objMove", (CmdImpl) &GrpImpl::impl_objSetPos);
-	RegisterCommand(1, 82, 1000, "objBgMove", (CmdImpl) &GrpImpl::impl_objSetPos);
-	RegisterCommand(1, 81, 1001, "objLeft", (CmdImpl) &GrpImpl::impl_objSetPos);
-	RegisterCommand(1, 82, 1001, "objBgLeft", (CmdImpl) &GrpImpl::impl_objSetPos);
-	RegisterCommand(1, 81, 1002, "objTop", (CmdImpl) &GrpImpl::impl_objSetPos);
-	RegisterCommand(1, 82, 1002, "objBgTop", (CmdImpl) &GrpImpl::impl_objSetPos);
-	RegisterCommand(1, 81, 1003, "objAlpha", (CmdImpl) &GrpImpl::impl_objAlpha);
-	RegisterCommand(1, 82, 1003, "objBgAlpha", (CmdImpl) &GrpImpl::impl_objAlpha);
-	RegisterCommand(1, 81, 1004, "objShow", (CmdImpl) &GrpImpl::impl_objShow);
-	RegisterCommand(1, 82, 1004, "objBgShow", (CmdImpl) &GrpImpl::impl_objShow);
+	RegisterCommand(1, 81, 1000, "objMove", (CmdImpl) &Grp::impl_objSetPos);
+	RegisterCommand(1, 82, 1000, "objBgMove", (CmdImpl) &Grp::impl_objSetPos);
+	RegisterCommand(1, 81, 1001, "objLeft", (CmdImpl) &Grp::impl_objSetPos);
+	RegisterCommand(1, 82, 1001, "objBgLeft", (CmdImpl) &Grp::impl_objSetPos);
+	RegisterCommand(1, 81, 1002, "objTop", (CmdImpl) &Grp::impl_objSetPos);
+	RegisterCommand(1, 82, 1002, "objBgTop", (CmdImpl) &Grp::impl_objSetPos);
+	RegisterCommand(1, 81, 1003, "objAlpha", (CmdImpl) &Grp::impl_objAlpha);
+	RegisterCommand(1, 82, 1003, "objBgAlpha", (CmdImpl) &Grp::impl_objAlpha);
+	RegisterCommand(1, 81, 1004, "objShow", (CmdImpl) &Grp::impl_objShow);
+	RegisterCommand(1, 82, 1004, "objBgShow", (CmdImpl) &Grp::impl_objShow);
 	RegisterCommand(1, 81, 1005, "objDispArea", NULL);
 	RegisterCommand(1, 82, 1005, "objBgDispArea", NULL);
-	RegisterCommand(1, 81, 1006, "objAdjust", (CmdImpl) &GrpImpl::impl_objSetPos);
-	RegisterCommand(1, 82, 1006, "objBgAdjust", NULL); //FIXME: (CmdImpl) &GrpImpl::impl_objSetPos);
+	RegisterCommand(1, 81, 1006, "objAdjust", (CmdImpl) &Grp::impl_objSetPos);
+	RegisterCommand(1, 82, 1006, "objBgAdjust", NULL); //FIXME: (CmdImpl) &Grp::impl_objSetPos);
 	RegisterCommand(1, 81, 1007, "objAdjustX", NULL);
 	RegisterCommand(1, 82, 1007, "objBgAdjustX", NULL);
 	RegisterCommand(1, 81, 1008, "objAdjustY", NULL);
 	RegisterCommand(1, 82, 1008, "objBgAdjustY", NULL);
-	RegisterCommand(1, 81, 2006, "objAdjust2?", NULL); //FIXME: (CmdImpl) &GrpImpl::impl_objSetPos); I don't know if it is usefull or properly implemented
-	RegisterCommand(1, 82, 2006, "objBgAdjust2?", NULL); //FIXME: (CmdImpl) &GrpImpl::impl_objSetPos); See above
-	RegisterCommand(1, 81, 1016, "objColour", NULL); //FIXME: (CmdImpl) &GrpImpl::impl_objColour);
-	RegisterCommand(1, 82, 1016, "objBgColour", NULL); //FIXME: (CmdImpl) &GrpImpl::impl_objColour);
+	RegisterCommand(1, 81, 2006, "objAdjust2?", NULL); //FIXME: (CmdImpl) &Grp::impl_objSetPos); I don't know if it is usefull or properly implemented
+	RegisterCommand(1, 82, 2006, "objBgAdjust2?", NULL); //FIXME: (CmdImpl) &Grp::impl_objSetPos); See above
+	RegisterCommand(1, 81, 1016, "objColour", NULL); //FIXME: (CmdImpl) &Grp::impl_objColour);
+	RegisterCommand(1, 82, 1016, "objBgColour", NULL); //FIXME: (CmdImpl) &Grp::impl_objColour);
 	RegisterCommand(1, 81, 1017, "objColR", NULL);
 	RegisterCommand(1, 82, 1017, "objBgColR", NULL);
 	RegisterCommand(1, 81, 1018, "objColG", NULL);
@@ -974,43 +734,43 @@ GrpImpl::GrpImpl(Event::Container& _even
 	RegisterCommand(1, 82, 1019, "objBgColB", NULL);
 	RegisterCommand(1, 81, 1020, "objColLevel", NULL);
 	RegisterCommand(1, 82, 1020, "objBgColLevel", NULL);
-	RegisterCommand(1, 81, 1021, "objComposite", NULL);//(CmdImpl) &GrpImpl::impl_objComposite); //FIXME: May be broken
-	RegisterCommand(1, 82, 1021, "objBgComposite", (CmdImpl) &GrpImpl::impl_objComposite);
-	RegisterCommand(1, 81, 1024, "objSetText", (CmdImpl) &GrpImpl::impl_objSetText);
-	RegisterCommand(1, 82, 1024, "objBgSetText", (CmdImpl) &GrpImpl::impl_objSetText);
-	RegisterCommand(1, 81, 1025, "objTextOpts", (CmdImpl) &GrpImpl::impl_objTextOpts); //FIXME: Incomplete
-	RegisterCommand(1, 82, 1025, "objBgTextOpts", (CmdImpl) &GrpImpl::impl_objTextOpts);
-	RegisterCommand(1, 81, 1032, "objOrder", (CmdImpl) &GrpImpl::impl_objOrder);
-	RegisterCommand(1, 82, 1032, "objBgOrder", (CmdImpl) &GrpImpl::impl_objOrder);
-	RegisterCommand(1, 81, 1034, "objDispRect", (CmdImpl) &GrpImpl::impl_objDispArea);
-	RegisterCommand(1, 82, 1034, "objBgDispRect", (CmdImpl) &GrpImpl::impl_objDispArea);
-	RegisterCommand(1, 81, 1037, "objSetDigits", (CmdImpl) &GrpImpl::impl_objSetDigits);
-	RegisterCommand(1, 82, 1037, "objBgSetDigits", (CmdImpl) &GrpImpl::impl_objSetDigits);
-	RegisterCommand(1, 81, 1038, "objNumOpts", (CmdImpl) &GrpImpl::impl_objNumOpts);
-	RegisterCommand(1, 82, 1038, "objBgNumOpts", (CmdImpl) &GrpImpl::impl_objNumOpts);
-	RegisterCommand(1, 81, 1039, "objPattNo", (CmdImpl) &GrpImpl::impl_objPattNo);
-	RegisterCommand(1, 82, 1039, "objBgPattNo", (CmdImpl) &GrpImpl::impl_objPattNo);
-	RegisterCommand(1, 81, 1046, "objScale", (CmdImpl) &GrpImpl::impl_objScale); //FIXME: Broken behaviour
-	RegisterCommand(1, 82, 1046, "objBgScale", (CmdImpl) &GrpImpl::impl_objScale);
+	RegisterCommand(1, 81, 1021, "objComposite", NULL);//(CmdImpl) &Grp::impl_objComposite); //FIXME: May be broken
+	RegisterCommand(1, 82, 1021, "objBgComposite", (CmdImpl) &Grp::impl_objComposite);
+	RegisterCommand(1, 81, 1024, "objSetText", (CmdImpl) &Grp::impl_objSetText);
+	RegisterCommand(1, 82, 1024, "objBgSetText", (CmdImpl) &Grp::impl_objSetText);
+	RegisterCommand(1, 81, 1025, "objTextOpts", (CmdImpl) &Grp::impl_objTextOpts); //FIXME: Incomplete
+	RegisterCommand(1, 82, 1025, "objBgTextOpts", (CmdImpl) &Grp::impl_objTextOpts);
+	RegisterCommand(1, 81, 1032, "objOrder", (CmdImpl) &Grp::impl_objOrder);
+	RegisterCommand(1, 82, 1032, "objBgOrder", (CmdImpl) &Grp::impl_objOrder);
+	RegisterCommand(1, 81, 1034, "objDispRect", (CmdImpl) &Grp::impl_objDispArea);
+	RegisterCommand(1, 82, 1034, "objBgDispRect", (CmdImpl) &Grp::impl_objDispArea);
+	RegisterCommand(1, 81, 1037, "objSetDigits", (CmdImpl) &Grp::impl_objSetDigits);
+	RegisterCommand(1, 82, 1037, "objBgSetDigits", (CmdImpl) &Grp::impl_objSetDigits);
+	RegisterCommand(1, 81, 1038, "objNumOpts", (CmdImpl) &Grp::impl_objNumOpts);
+	RegisterCommand(1, 82, 1038, "objBgNumOpts", (CmdImpl) &Grp::impl_objNumOpts);
+	RegisterCommand(1, 81, 1039, "objPattNo", (CmdImpl) &Grp::impl_objPattNo);
+	RegisterCommand(1, 82, 1039, "objBgPattNo", (CmdImpl) &Grp::impl_objPattNo);
+	RegisterCommand(1, 81, 1046, "objScale", (CmdImpl) &Grp::impl_objScale); //FIXME: Broken behaviour
+	RegisterCommand(1, 82, 1046, "objBgScale", (CmdImpl) &Grp::impl_objScale);
 	RegisterCommand(1, 81, 1047, "objWidth", NULL);
 	RegisterCommand(1, 82, 1047, "objBgWidth", NULL);
-	RegisterCommand(1, 81, 1049, "objRotate", (CmdImpl) &GrpImpl::impl_objRotate);
-	RegisterCommand(1, 82, 1049, "objBgRotate", (CmdImpl) &GrpImpl::impl_objRotate);
+	RegisterCommand(1, 81, 1049, "objRotate", (CmdImpl) &Grp::impl_objRotate);
+	RegisterCommand(1, 82, 1049, "objBgRotate", (CmdImpl) &Grp::impl_objRotate);
 
-	RegisterCommand(2, 81, 1000, "childObjMove", (CmdImpl) &GrpImpl::impl_objSetPos);
-	RegisterCommand(2, 82, 1000, "childObjBgMove", (CmdImpl) &GrpImpl::impl_objSetPos);
+	RegisterCommand(2, 81, 1000, "childObjMove", (CmdImpl) &Grp::impl_objSetPos);
+	RegisterCommand(2, 82, 1000, "childObjBgMove", (CmdImpl) &Grp::impl_objSetPos);
 	RegisterCommand(2, 81, 1001, "childObjLeft", NULL);
 	RegisterCommand(2, 82, 1001, "childObjBgLeft", NULL);
 	RegisterCommand(2, 81, 1002, "childObjTop", NULL);
 	RegisterCommand(2, 82, 1002, "childObjBgTop", NULL);
-	RegisterCommand(2, 81, 1003, "childObjAlpha", (CmdImpl) &GrpImpl::impl_objAlpha);
-	RegisterCommand(2, 82, 1003, "childObjBgAlpha", (CmdImpl) &GrpImpl::impl_objAlpha);
-	RegisterCommand(2, 81, 1004, "childObjShow", (CmdImpl) &GrpImpl::impl_objShow);
-	RegisterCommand(2, 82, 1004, "childObjBgShow", (CmdImpl) &GrpImpl::impl_objShow);
+	RegisterCommand(2, 81, 1003, "childObjAlpha", (CmdImpl) &Grp::impl_objAlpha);
+	RegisterCommand(2, 82, 1003, "childObjBgAlpha", (CmdImpl) &Grp::impl_objAlpha);
+	RegisterCommand(2, 81, 1004, "childObjShow", (CmdImpl) &Grp::impl_objShow);
+	RegisterCommand(2, 82, 1004, "childObjBgShow", (CmdImpl) &Grp::impl_objShow);
 	RegisterCommand(2, 81, 1005, "childObjDispArea", NULL);
 	RegisterCommand(2, 82, 1005, "childObjBgDispArea", NULL);
-	RegisterCommand(2, 81, 1006, "childObjAdjust", (CmdImpl) &GrpImpl::impl_objSetPos);
-	RegisterCommand(2, 82, 1006, "childObjBgAdjust", (CmdImpl) &GrpImpl::impl_objSetPos);
+	RegisterCommand(2, 81, 1006, "childObjAdjust", (CmdImpl) &Grp::impl_objSetPos);
+	RegisterCommand(2, 82, 1006, "childObjBgAdjust", (CmdImpl) &Grp::impl_objSetPos);
 	RegisterCommand(2, 81, 1007, "childObjAdjustX", NULL);
 	RegisterCommand(2, 82, 1007, "childObjBgAdjustX", NULL);
 	RegisterCommand(2, 81, 1008, "childObjAdjustY", NULL);
@@ -1029,69 +789,69 @@ GrpImpl::GrpImpl(Event::Container& _even
 	RegisterCommand(2, 82, 1020, "childObjBgColLevel", NULL);
 	RegisterCommand(2, 81, 1021, "childObjComposite", NULL);
 	RegisterCommand(2, 82, 1021, "childObjBgComposite", NULL);
-	RegisterCommand(2, 81, 1024, "childObjSetText", (CmdImpl) &GrpImpl::impl_objSetText);
-	RegisterCommand(2, 82, 1024, "childObjBgSetText", (CmdImpl) &GrpImpl::impl_objSetText);
-	RegisterCommand(2, 81, 1025, "childObjTextOpts", (CmdImpl) &GrpImpl::impl_objTextOpts);
-	RegisterCommand(2, 82, 1025, "childObjBgTextOpts", (CmdImpl) &GrpImpl::impl_objTextOpts);
+	RegisterCommand(2, 81, 1024, "childObjSetText", (CmdImpl) &Grp::impl_objSetText);
+	RegisterCommand(2, 82, 1024, "childObjBgSetText", (CmdImpl) &Grp::impl_objSetText);
+	RegisterCommand(2, 81, 1025, "childObjTextOpts", (CmdImpl) &Grp::impl_objTextOpts);
+	RegisterCommand(2, 82, 1025, "childObjBgTextOpts", (CmdImpl) &Grp::impl_objTextOpts);
 	RegisterCommand(2, 81, 1032, "childObjOrder", NULL);
 	RegisterCommand(2, 82, 1032, "childObjBgOrder", NULL);
 	RegisterCommand(2, 81, 1034, "childObjDispRect", NULL);
 	RegisterCommand(2, 82, 1034, "childObjBgDispRect", NULL);
-	RegisterCommand(2, 81, 1037, "childObjSetDigits", (CmdImpl) &GrpImpl::impl_objSetDigits);
-	RegisterCommand(2, 82, 1037, "childObjBgSetDigits", (CmdImpl) &GrpImpl::impl_objSetDigits);
-	RegisterCommand(2, 81, 1038, "childObjNumOpts", (CmdImpl) &GrpImpl::impl_objNumOpts);
-	RegisterCommand(2, 82, 1038, "childObjBgNumOpts", (CmdImpl) &GrpImpl::impl_objNumOpts);
-	RegisterCommand(2, 81, 1039, "childObjPattNo", (CmdImpl) &GrpImpl::impl_objPattNo);
-	RegisterCommand(2, 82, 1039, "childObjBgPattNo", (CmdImpl) &GrpImpl::impl_objPattNo);
-	RegisterCommand(2, 81, 1046, "childObjScale", (CmdImpl) &GrpImpl::impl_objScale);
-	RegisterCommand(2, 82, 1046, "childObjBgScale", (CmdImpl) &GrpImpl::impl_objScale);
+	RegisterCommand(2, 81, 1037, "childObjSetDigits", (CmdImpl) &Grp::impl_objSetDigits);
+	RegisterCommand(2, 82, 1037, "childObjBgSetDigits", (CmdImpl) &Grp::impl_objSetDigits);
+	RegisterCommand(2, 81, 1038, "childObjNumOpts", (CmdImpl) &Grp::impl_objNumOpts);
+	RegisterCommand(2, 82, 1038, "childObjBgNumOpts", (CmdImpl) &Grp::impl_objNumOpts);
+	RegisterCommand(2, 81, 1039, "childObjPattNo", (CmdImpl) &Grp::impl_objPattNo);
+	RegisterCommand(2, 82, 1039, "childObjBgPattNo", (CmdImpl) &Grp::impl_objPattNo);
+	RegisterCommand(2, 81, 1046, "childObjScale", (CmdImpl) &Grp::impl_objScale);
+	RegisterCommand(2, 82, 1046, "childObjBgScale", (CmdImpl) &Grp::impl_objScale);
 	RegisterCommand(2, 81, 1047, "childObjWidth", NULL);
 	RegisterCommand(2, 82, 1047, "childObjBgWidth", NULL);
 	RegisterCommand(2, 81, 1049, "childObjRotate", NULL);
 	RegisterCommand(2, 82, 1049, "childObjBgRotate", NULL);
 
-	RegisterCommand(1, 84, 1000, "objGetPos", (CmdImpl) &GrpImpl::impl_objPosDims);
-	RegisterCommand(1, 84, 1100, "objGetDims", (CmdImpl) &GrpImpl::impl_objPosDims);
+	RegisterCommand(1, 84, 1000, "objGetPos", (CmdImpl) &Grp::impl_objPosDims);
+	RegisterCommand(1, 84, 1100, "objGetDims", (CmdImpl) &Grp::impl_objPosDims);
 
-	RegisterCommand(2, 84, 1000, "childObjGetPos", (CmdImpl) &GrpImpl::impl_objPosDims);
-	RegisterCommand(2, 84, 1100, "childObjGetDims", (CmdImpl) &GrpImpl::impl_objPosDims);
+	RegisterCommand(2, 84, 1000, "childObjGetPos", (CmdImpl) &Grp::impl_objPosDims);
+	RegisterCommand(2, 84, 1100, "childObjGetDims", (CmdImpl) &Grp::impl_objPosDims);
 
-	RegisterCommand(1, 31, 0, "refresh", (CmdImpl) &GrpImpl::impl_refresh);
+	RegisterCommand(1, 31, 0, "refresh", (CmdImpl) &Grp::impl_refresh);
 
-	RegisterCommand(1, 20, 0, "bgmLoop", (CmdImpl) &GrpImpl::impl_bgmLoop);
-	RegisterCommand(1, 20, 1, "bgmPlayEx", (CmdImpl) &GrpImpl::impl_bgmLoop); //FIXME: wait
-	RegisterCommand(1, 20, 2, "bgmPlay", (CmdImpl) &GrpImpl::impl_bgmLoop);
-	RegisterCommand(1, 20, 5, "bgmStop", (CmdImpl) &GrpImpl::impl_bgmStop);
-	RegisterCommand(1, 20, 105, "bgmFadeOut", (CmdImpl) &GrpImpl::impl_bgmStop);
+	RegisterCommand(1, 20, 0, "bgmLoop", (CmdImpl) &Grp::impl_bgmLoop);
+	RegisterCommand(1, 20, 1, "bgmPlayEx", (CmdImpl) &Grp::impl_bgmLoop); //FIXME: wait
+	RegisterCommand(1, 20, 2, "bgmPlay", (CmdImpl) &Grp::impl_bgmLoop);
+	RegisterCommand(1, 20, 5, "bgmStop", (CmdImpl) &Grp::impl_bgmStop);
+	RegisterCommand(1, 20, 105, "bgmFadeOut", (CmdImpl) &Grp::impl_bgmStop);
 
-	RegisterCommand(1, 21, 0, "wavPlay", (CmdImpl) &GrpImpl::impl_playWav);
-	RegisterCommand(1, 21, 1, "wavPlayEx", (CmdImpl) &GrpImpl::impl_playWav);
-	RegisterCommand(1, 21, 2, "wavLoop", (CmdImpl) &GrpImpl::impl_playWav);
+	RegisterCommand(1, 21, 0, "wavPlay", (CmdImpl) &Grp::impl_playWav);
+	RegisterCommand(1, 21, 1, "wavPlayEx", (CmdImpl) &Grp::impl_playWav);
+	RegisterCommand(1, 21, 2, "wavLoop", (CmdImpl) &Grp::impl_playWav);
 	RegisterCommand(1, 21, 3, "wavWait", NULL);
 	RegisterCommand(1, 21, 4, "wavPlaying", NULL);
-	RegisterCommand(1, 21, 5, "wavStop", (CmdImpl) &GrpImpl::impl_stopWav);
-	RegisterCommand(1, 21, 105, "wavFadeout", (CmdImpl) &GrpImpl::impl_stopWav);
+	RegisterCommand(1, 21, 5, "wavStop", (CmdImpl) &Grp::impl_stopWav);
+	RegisterCommand(1, 21, 105, "wavFadeout", (CmdImpl) &Grp::impl_stopWav);
 
-	RegisterCommand(1, 22, 0, "sePlay", (CmdImpl) &GrpImpl::impl_playSE);
+	RegisterCommand(1, 22, 0, "sePlay", (CmdImpl) &Grp::impl_playSE);
 
-	RegisterCommand(1, 4, 2230, "SetBgmVolMod", (CmdImpl) &GrpImpl::impl_SetVolMod);
-	RegisterCommand(1, 4, 2231, "SetKoeVolMod", (CmdImpl) &GrpImpl::impl_SetVolMod);
-	RegisterCommand(1, 4, 2232, "SetPCMVolMod", (CmdImpl) &GrpImpl::impl_SetVolMod);
-	RegisterCommand(1, 4, 2233, "SetSeVolMod", (CmdImpl) &GrpImpl::impl_SetVolMod);
-	RegisterCommand(1, 4, 2330, "BgmVolMod", (CmdImpl) &GrpImpl::impl_GetVolMod);
-	RegisterCommand(1, 4, 2331, "KoeVolMod", (CmdImpl) &GrpImpl::impl_GetVolMod);
-	RegisterCommand(1, 4, 2332, "PCMVolMod", (CmdImpl) &GrpImpl::impl_GetVolMod);
-	RegisterCommand(1, 4, 2333, "SeVolMod", (CmdImpl) &GrpImpl::impl_GetVolMod);
+	RegisterCommand(1, 4, 2230, "SetBgmVolMod", (CmdImpl) &Grp::impl_SetVolMod);
+	RegisterCommand(1, 4, 2231, "SetKoeVolMod", (CmdImpl) &Grp::impl_SetVolMod);
+	RegisterCommand(1, 4, 2232, "SetPCMVolMod", (CmdImpl) &Grp::impl_SetVolMod);
+	RegisterCommand(1, 4, 2233, "SetSeVolMod", (CmdImpl) &Grp::impl_SetVolMod);
+	RegisterCommand(1, 4, 2330, "BgmVolMod", (CmdImpl) &Grp::impl_GetVolMod);
+	RegisterCommand(1, 4, 2331, "KoeVolMod", (CmdImpl) &Grp::impl_GetVolMod);
+	RegisterCommand(1, 4, 2332, "PCMVolMod", (CmdImpl) &Grp::impl_GetVolMod);
+	RegisterCommand(1, 4, 2333, "SeVolMod", (CmdImpl) &Grp::impl_GetVolMod);
 
-	RegisterCommand(1, 23, 0, "koePlay", (CmdImpl) &GrpImpl::impl_koePlay);
-	RegisterCommand(1, 23, 1, "koePlayEx", (CmdImpl) &GrpImpl::impl_koePlay); //FIXME
-	RegisterCommand(1, 23, 7, "koePlayExC", (CmdImpl) &GrpImpl::impl_koePlay); //FIXME
-	RegisterCommand(1, 23, 8, "koeDoPlay", (CmdImpl) &GrpImpl::impl_koePlay); //FIXME
-	RegisterCommand(1, 23, 9, "koeDoPlayEx", (CmdImpl) &GrpImpl::impl_koePlay); //FIXME
-	RegisterCommand(1, 23, 10, "koeDoPlayExC", (CmdImpl) &GrpImpl::impl_koePlay); //FIXME
+	RegisterCommand(1, 23, 0, "koePlay", (CmdImpl) &Grp::impl_koePlay);
+	RegisterCommand(1, 23, 1, "koePlayEx", (CmdImpl) &Grp::impl_koePlay); //FIXME
+	RegisterCommand(1, 23, 7, "koePlayExC", (CmdImpl) &Grp::impl_koePlay); //FIXME
+	RegisterCommand(1, 23, 8, "koeDoPlay", (CmdImpl) &Grp::impl_koePlay); //FIXME
+	RegisterCommand(1, 23, 9, "koeDoPlayEx", (CmdImpl) &Grp::impl_koePlay); //FIXME
+	RegisterCommand(1, 23, 10, "koeDoPlayExC", (CmdImpl) &Grp::impl_koePlay); //FIXME
 
-	RegisterCommand(1, 26, 1, "movPlayEx", (CmdImpl) &GrpImpl::impl_movPlay);
-	RegisterCommand(1, 26, 20, "movPlayExC", (CmdImpl) &GrpImpl::impl_movPlay);
+	RegisterCommand(1, 26, 1, "movPlayEx", (CmdImpl) &Grp::impl_movPlay);
+	RegisterCommand(1, 26, 20, "movPlayExC", (CmdImpl) &Grp::impl_movPlay);
 
 	RegisterCommand(1, 61, 14, "objSwap?", NULL);
 	RegisterCommand(1, 62, 14, "objSwap?", NULL);
@@ -1104,8 +864,7 @@ GrpImpl::GrpImpl(Event::Container& _even
 	anm2 = NULL;
 }
 
-GrpImpl::~GrpImpl() {
-
+Grp::~Grp() {
 	map<int,GrpObj>::iterator it;
 	for (it=grpobj.begin(); it!=grpobj.end(); it++) {
 		PicBase* p = it->second.DeletePic();
@@ -1123,7 +882,7 @@ GrpImpl::~GrpImpl() {
 	}
 }
 
-Surface* GrpImpl::Dsurface(int pdt) {
+Surface* Grp::Dsurface(int pdt) {
 	if (pdt == 0) return surface;
 	if (dsurface[pdt] == 0) { // とりあえず画面の大きさということにする
 		if (pdt == WORKPDT)
@@ -1139,19 +898,19 @@ Surface* GrpImpl::Dsurface(int pdt) {
 	return dsurface[pdt];
 }
 
-GrpObj* GrpImpl::GetGraphicObj(int grp, bool fg) {
+GrpObj* Grp::GetGraphicObj(int grp, bool fg) {
 	if (fg)
 		return &grpobj[grp];
 	else
 		return &bs_obj[grp];
 }
 
-GrpObj* GrpImpl::GetGraphicObj(int grp, int index, bool fg) {
+GrpObj* Grp::GetGraphicObj(int grp, int index, bool fg) {
 	GrpObj* g = GetGraphicObj(grp, fg);
 	return &g->children_obj[index];
 }
 
-GrpObj* GrpImpl::GetGraphicObjVarMode(Cmd& cmd, int &base_arg, bool fg) {
+GrpObj* Grp::GetGraphicObjVarMode(Cmd& cmd, int &base_arg, bool fg) {
 	GrpObj* g;
 	if (cmd.cmd1 == 2) {
 		g = GetGraphicObj(cmd.args[base_arg].value, cmd.args[base_arg+1].value, fg);
@@ -1163,7 +922,7 @@ GrpObj* GrpImpl::GetGraphicObjVarMode(Cm
 }
 
 #include <SDL.h>
-Surface* GrpImpl::Ssurface(int pdt) {
+Surface* Grp::Ssurface(int pdt) {
 	if (pdt == 0) return surface;
 	if (ssurface[pdt]) {
 		return ssurface[pdt];
@@ -1171,7 +930,7 @@ Surface* GrpImpl::Ssurface(int pdt) {
 	return Dsurface(pdt);
 }
 
-void GrpImpl::LoadSurface(const char* str, int pdt) {
+void Grp::LoadSurface(const char* str, int pdt) {
 	string s = str;
 	if (cgm_info.find(s) != cgm_info.end()) {
 		cgm_data.insert(cgm_info[s]);
@@ -1201,7 +960,7 @@ void GrpImpl::LoadSurface(const char* st
 	}
 }
 
-void GrpImpl::InitSel(void) {
+void Grp::InitSel(void) {
 	int i;
 	int args[16];
 	char key[10];
@@ -1228,7 +987,7 @@ void GrpImpl::InitSel(void) {
 	}
 }
 
-void GrpImpl::SetSkipMode(SkipMode _mode) {
+void Grp::SetSkipMode(SkipMode _mode) {
 	if ( (skip_mode & SKIP_IN_MENU) && (_mode & SKIP_IN_MENU) == 0) {
 		RefreshObj();
 	} else if ( (skip_mode & SKIP_IN_MENU) == 0 && (_mode & SKIP_IN_MENU) ) {
@@ -1236,11 +995,11 @@ void GrpImpl::SetSkipMode(SkipMode _mode
 	skip_mode = _mode;
 }
 
-void GrpImpl::SetObjChanged(int num) {
+void Grp::SetObjChanged(int num) {
 	changed_obj.insert(num);
 }
 
-void GrpImpl::RefreshObj(void) {
+void Grp::RefreshObj(void) {
 	if (!deleted_pic.empty()) {
 		vector<PicBase*>::iterator it;
 		for (it=deleted_pic.begin(); it!=deleted_pic.end(); it++) {
@@ -1266,7 +1025,7 @@ void GrpImpl::RefreshObj(void) {
 
 
 #include <SDL.h>
-void GrpImpl::StartAnm(int type) {
+void Grp::StartAnm(int type) {
 	SEL sel;
 
 	if (anmtype.find(type) == anmtype.end()) {
@@ -1348,7 +1107,7 @@ void GrpImpl::StartAnm(int type) {
 	if (skip_mode & SKIP_GRP_NOEFFEC) AbortAnm();
 }
 
-void GrpImpl::StartShake(int total, const int* pattern) {
+void Grp::StartShake(int total, const int* pattern) {
 	if (anm2) {
 		fprintf(stderr,"Warning: StartShake() called before another animation finished\n");
 		anm2->Abort();
@@ -1371,7 +1130,7 @@ void GrpImpl::StartShake(int total, cons
 	anm2 = new_anm;
 }
 
-void GrpImpl::AbortAnm(void) {
+void Grp::AbortAnm(void) {
 	if (anm1 == NULL) return;
 	anm1->Abort();
 	delete anm1;
@@ -1392,18 +1151,18 @@ void GrpImpl::AbortAnm(void) {
 	return;
 }
 
-void GrpImpl::LoadSurface(const char* str) {
+void Grp::LoadSurface(const char* str) {
 	if (anm1 != NULL) AbortAnm(); // 前の描画が終わってなければ強制終了
 	LoadSurface(str, 1);
 	bg_name = str;
 }
 
-void GrpImpl::LoadSurface(void) {
+void Grp::LoadSurface(void) {
 	if (anm1 != NULL) AbortAnm(); // 前の描画が終わってなければ強制終了
 	LoadSurface(bg_name.c_str(), 1);
 }
 
-void GrpImpl::AddSurface(const char* str) {
+void Grp::AddSurface(const char* str) {
 	if (anm1 != NULL) AbortAnm(); // 前の描画が終わってなければ強制終了
 	LoadSurface(bg_name.c_str());
 
@@ -1421,7 +1180,7 @@ void GrpImpl::AddSurface(const char* str
 	}
 }
 
-void GrpImpl::CreateObj(int index) {
+void Grp::CreateObj(int index) {
 	GrpObjMap::iterator cur = grpobj.find(index);
 	if (cur == grpobj.end()) return;
 	GrpObj& g = grpobj[index];
@@ -1433,7 +1192,7 @@ void GrpImpl::CreateObj(int index) {
 	ZMoveObj(index);
 }
 
-void GrpImpl::CreateSubObj(int grp_index, int index) {
+void Grp::CreateSubObj(int grp_index, int index) {
 	GrpObjMap::iterator cur = grpobj.find(grp_index);
 	if (cur == grpobj.end()) return;
 	GrpObj* g = &grpobj[grp_index];
@@ -1449,7 +1208,7 @@ void GrpImpl::CreateSubObj(int grp_index
 	/*ZMoveObj(index);*/
 }
 
-void GrpImpl::ZMoveObj(int index) {
+void Grp::ZMoveObj(int index) {
 	GrpObjMap::iterator cur = grpobj.find(index);
 	if (cur == grpobj.end()) return;
 	GrpObj& g = grpobj[index];
@@ -1476,7 +1235,7 @@ void GrpImpl::ZMoveObj(int index) {
 	}
 }
 
-void GrpImpl::SwapObj(int index1, int index2) {
+void Grp::SwapObj(int index1, int index2) {
 	// デフォルト値から order が変更されていた場合のみ、order は保存される
 	// まずは両方のobjectをswap
 	if (grpobj.find(index1) == grpobj.end()) {
@@ -1511,8 +1270,8 @@ void GrpImpl::SwapObj(int index1, int in
 	}
 }
 
-bool GrpImpl::Pressed(int x, int y, void* pointer) { // マウスクリックでキャンセル
-	GrpImpl* g = (GrpImpl*)pointer;
+bool Grp::Pressed(int x, int y, void* pointer) { // マウスクリックでキャンセル
+	Grp* g = (Grp*)pointer;
 	if (g->status == WAIT_MOVIE)
 		g->music->StopMovie();
 	if (g->status == WAIT_ANM)
@@ -1561,7 +1320,7 @@ static unsigned char decode_char[256] = 
 	0xff, 0x00, 0x00, 0x04, 0x00, 0x6a, 0x00, 0x76
 };
 
-void GrpImpl::LoadCgm() {
+void Grp::LoadCgm() {
 	/* cgm ファイル読み込み */
 	const char* fname = config->GetParaStr("#CGTABLE_FILE");
 	if (fname == NULL) return;
@@ -1601,13 +1360,13 @@ void GrpImpl::LoadCgm() {
 
 /*****************************************************
 *
-*   GrpImpl :: Save, Load : セーブファイル処理
+*   Grp :: Save, Load : セーブファイル処理
 *
 */
-void GrpImpl::Save(std::string& str) {
+void Grp::Save(std::string& str) {
 }
 
-void GrpImpl::Load(const char* str) {
+void Grp::Load(const char* str) {
 	status = NORMAL;
 	if (anm1 != NULL) {
 		AbortAnm();
@@ -1628,7 +1387,7 @@ void GrpImpl::Load(const char* str) {
 	music->StopCDROM(100);
 }
 
-void GrpImpl::SaveSys(string& save) {
+void Grp::SaveSys(string& save) {
 	char buf[1024];
 	save = "\n[Graphics]\n";
 	save += "CGM_CG=";
@@ -1641,7 +1400,7 @@ void GrpImpl::SaveSys(string& save) {
 	save += "\n";
 }
 
-void GrpImpl::LoadSys(const char* save) {
+void Grp::LoadSys(const char* save) {
 	cgm_data.clear();
 	save = strstr(save, "\n[Graphics]\n");
 
@@ -1668,13 +1427,13 @@ void GrpImpl::LoadSys(const char* save) 
 
 /*****************************************************
 *
-*   GrpImpl :: Wait , Exec : コマンド実行部
+*   Grp :: Wait , Exec : コマンド実行部
 *
 */
 static vector<int> drawn_images;
 static int draw_n = 0;
 extern bool grpdump_req;
-bool GrpImpl::Wait(unsigned int current_time, Cmd& cmd) {
+bool Grp::Wait(unsigned int current_time, Cmd& cmd) {
 	if (grpdump_req) {
 		grpdump_req = 0;
 		GrpObjMap::iterator it;
@@ -1751,18 +1510,18 @@ bool GrpImpl::Wait(unsigned int current_
 	return false;
 }
 
-void GrpImpl::DeleteObjPic(int num) { // object の surface のみ削除
+void Grp::DeleteObjPic(int num) { // object の surface のみ削除
 	if (grpobj.find(num) == grpobj.end()) return;
 	deleted_pic.push_back(grpobj[num].DeletePic());
 }
 
-void GrpImpl::DeleteSubObjPic(int num_grp, int num) {
+void Grp::DeleteSubObjPic(int num_grp, int num) {
 	if (grpobj.find(num_grp) == grpobj.end()) return;
 	if (grpobj[num_grp].children_obj.find(num) == grpobj[num_grp].children_obj.end()) return;
 	deleted_pic.push_back(grpobj[num_grp].children_obj[num].DeletePic());
 }
 
-void GrpImpl::DeleteObj(int num) {
+void Grp::DeleteObj(int num) {
 	if (grpobj.find(num) == grpobj.end()) return;
 	deleted_pic.push_back(grpobj[num].DeletePic());
 	GrpObjMap::iterator it;
@@ -1772,749 +1531,14 @@ void GrpImpl::DeleteObj(int num) {
 	grpobj.erase(num);
 }
 
-void GrpImpl::DeleteSubObj(int num_grp, int num) {
+void Grp::DeleteSubObj(int num_grp, int num) {
 	if (grpobj.find(num_grp) == grpobj.end()) return;
 	if (grpobj[num_grp].children_obj.find(num) == grpobj[num_grp].children_obj.end()) return;
 	deleted_pic.push_back(grpobj[num_grp].children_obj[num].DeletePic());
 	grpobj[num_grp].children_obj.erase(num);
 }
 
-void GrpImpl::impl_stackClear (Cmd& cmd) {
-	cmd.cmd_type = CMD_SAVECMDGRP_START;
-}
-
-void GrpImpl::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 GrpImpl::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 GrpImpl::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 GrpImpl::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 GrpImpl::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 GrpImpl::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 GrpImpl::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 GrpImpl::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 GrpImpl::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 GrpImpl::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 GrpImpl::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 GrpImpl::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 GrpImpl::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 GrpImpl::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 GrpImpl::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) {
-			//Maybe it's for shading or something like that?
-			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 GrpImpl::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 GrpImpl::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 GrpImpl::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 GrpImpl::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 GrpImpl::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 GrpImpl::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 GrpImpl::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 GrpImpl::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 GrpImpl::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 GrpImpl::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 GrpImpl::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 GrpImpl::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 GrpImpl::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 GrpImpl::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 GrpImpl::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 GrpImpl::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 GrpImpl::impl_refresh(Cmd& cmd) {
-	// 本来は grpstack clear らしい
-	RefreshObj();
-	// Princess Bride の中途 Staff roll
-	// このタイミングで描画するのが都合がいいので、
-	//シナリオループを抜けて描画を起動
-	cmd.cmd_type = CMD_WAITFRAMEUPDATE;
-}
-
-void GrpImpl::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 GrpImpl::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 GrpImpl::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 GrpImpl::impl_playSE(Cmd& cmd) {
-	music->PlaySE(cmd.args[0].value);
-	cmd.clear();
-}
-
-void GrpImpl::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 GrpImpl::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 GrpImpl::impl_GetVolMod(Cmd& cmd) {
-	cmd.SetSysvar(music->volmod[cmd.cmd3-0x91a]);
-}
-
-void GrpImpl::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 GrpImpl::impl_objSwap(Cmd& cmd) {
-	if (cmd.cmd1 == 1 && cmd.args.size() == 2) {
-		SwapObj(cmd.args[0].value, cmd.args[1].value);
-	}
-	cmd.clear();
-}*/
-
-void GrpImpl::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();
-	}
-}
-
-void GrpImpl::Exec(Cmd& cmd) {
+void Grp::Exec(Cmd& cmd) {
 	if (cmd.cmd_type == CMD_TEXTEND) {
 		music->StopKoe(500); // テキスト終了で声を止める
 		cmd.clear();
@@ -2555,47 +1579,3 @@ void GrpImpl::Exec(Cmd& cmd) {
 	}
 }
 
-
-/********************************************************
-**
-**	class Grp
-*/
-
-Grp::Grp(Event::Container& _event, PicContainer& _parent, const Flags& f, set<int>& _cgm) {
-	pimpl = new GrpImpl(_event, _parent, f, _cgm);
-}
-
-Grp::~Grp() {
-	delete pimpl;
-}
-
-bool Grp::Wait(unsigned int current_time, Cmd& cmd) {
-	return pimpl->Wait(current_time, cmd);
-}
-
-void Grp::Exec(Cmd& cmd) {
-	pimpl->Exec(cmd);
-}
-
-void Grp::SetSkipMode(SkipMode mode) {
-	pimpl->SetSkipMode(mode);
-}
-
-void Grp::InitSel(void) {
-	pimpl->InitSel();
-}
-
-void Grp::Save(std::string& str) {
-	pimpl->Save(str);
-}
-
-void Grp::Load(const char* str) {
-	pimpl->Load(str);
-}
-void Grp::SaveSys(std::string& str) {
-	pimpl->SaveSys(str);
-}
-
-void Grp::LoadSys(const char* str) {
-	pimpl->LoadSys(str);
-}