From ca1e47c0936bb571352d6d8fc4bd75a02ff6274f Mon Sep 17 00:00:00 2001 From: kichikuou Date: Sun, 7 Nov 2021 14:46:14 +0900 Subject: [PATCH] Fix reference counting of SACT CGs This fixes a bug where enemies disappear in Rance 5D battles. --- modules/NIGHTDLL/sactcg.c | 103 ++++++++++++++----------------------- modules/NIGHTDLL/sactcg.h | 4 +- modules/NIGHTDLL/sprite.c | 25 ++++----- modules/SACT/sactcg.c | 104 ++++++++++++++------------------------ modules/SACT/sactcg.h | 4 +- modules/SACT/sprite.c | 20 ++++---- 6 files changed, 100 insertions(+), 160 deletions(-) diff --git a/modules/NIGHTDLL/sactcg.c b/modules/NIGHTDLL/sactcg.c index 6dd584d..dff195d 100644 --- a/modules/NIGHTDLL/sactcg.c +++ b/modules/NIGHTDLL/sactcg.c @@ -56,11 +56,8 @@ static cginfo_t *cgs[CGMAX]; CG_xxxで作成したCGを参照する @param no: 読み込むCG番号 - @param refinc: 参照カウンタを増やすかどうか。 - spriteから参照されるときは増やし、CG_xxxを作る時に - 参照されるときは増やさない。 */ -cginfo_t *nt_scg_loadcg_no(int no, boolean refinc) { +static cginfo_t *nt_scg_get(int no) { cginfo_t *i; if (no >= (CGMAX -1)) { @@ -68,19 +65,13 @@ cginfo_t *nt_scg_loadcg_no(int no, boolean refinc) { return NULL; } - // すでに ロードされているか、CG_xxx で作成ずみの場合は - // 参照カウンタを増やす - if (cgs[no] != NULL) { - if (refinc) { - cgs[no]->refcnt++; - } + if (cgs[no] != NULL) return cgs[no]; - } i = malloc(sizeof(cginfo_t)); i->type = CG_LINKED; i->no = no; - i->refcnt = (refinc ? 1 : 0); + i->refcnt = 1; i->sf = sf_loadcg_no(no -1); if (i->sf == NULL) { WARNING("load fail (%d)\n", no -1); @@ -93,6 +84,22 @@ cginfo_t *nt_scg_loadcg_no(int no, boolean refinc) { return i; } +cginfo_t *nt_scg_addref(int no) { + cginfo_t *info = nt_scg_get(no); + if (info) + info->refcnt++; + return info; +} + +void nt_scg_deref(cginfo_t *cg) { + if (--cg->refcnt > 0) + return; + + if (cg->sf) + sf_free(cg->sf); + free(cg); +} + // 指定の大きさ、色の矩形の CG を作成 int nt_scg_create(int wNumCG, int wWidth, int wHeight, int wR, int wG, int wB, int wBlendRate) { cginfo_t *i; @@ -124,14 +131,14 @@ int nt_scg_create_reverse(int wNumCG, int wNumSrcCG, int wReverseX, int wReverse spcg_assert_no(wNumSrcCG); // 元にするCGを参照 (LINKCGなら読み込み) - if (NULL == (srccg = nt_scg_loadcg_no(wNumSrcCG, FALSE))) { + if (!(srccg = nt_scg_get(wNumSrcCG))) { return NG; } i = malloc(sizeof(cginfo_t)); i->type = CG_REVERSE; i->no = wNumCG; - i->refcnt = 0; + i->refcnt = 1; src = srccg->sf; i->sf = stretch(src, src->width, src->height, (wReverseX << 1) | wReverseY); @@ -152,14 +159,14 @@ int nt_scg_create_stretch(int wNumCG, int wWidth, int wHeight, int wNumSrcCG) { spcg_assert_no(wNumSrcCG); // 元にするCGを参照 (LINKCGなら読み込み) - if (NULL == (srccg = nt_scg_loadcg_no(wNumSrcCG, FALSE))) { + if (!(srccg = nt_scg_get(wNumSrcCG))) { return NG; } i = malloc(sizeof(cginfo_t)); i->type = CG_STRETCH; i->no = wNumCG; - i->refcnt = 0; + i->refcnt = 1; src = srccg->sf; i->sf = stretch(src, wWidth, wHeight, 0); @@ -181,14 +188,14 @@ int nt_scg_create_blend(int wNumDstCG, int wNumBaseCG, int wX, int wY, int wNumB spcg_assert_no(wNumBlendCG); // 元にするCGを参照 (LINKCGなら読み込み) - basecg = nt_scg_loadcg_no(wNumBaseCG, FALSE); - blendcg = nt_scg_loadcg_no(wNumBlendCG, FALSE); - if (basecg == NULL || blendcg == NULL) return NG; + basecg = nt_scg_get(wNumBaseCG); + blendcg = nt_scg_get(wNumBlendCG); + if (!basecg || !blendcg) return NG; i = malloc(sizeof(cginfo_t)); i->type = CG_SET; i->no = wNumDstCG; - i->refcnt = 0; + i->refcnt = 1; i->sf = blend(basecg->sf, wX , wY, blendcg->sf, wAlphaMapMode); @@ -214,7 +221,7 @@ int nt_scg_create_text(int wNumCG, int wSize, int wR, int wG, int wB, char *cTex i = malloc(sizeof(cginfo_t)); i->type = CG_SET; i->no = wNumCG; - i->refcnt = 0; + i->refcnt = 1; i->sf = sf_create_surface(glyph->width, wSize, nact->ags.dib->depth); gr_fill(i->sf, 0, 0, glyph->width, wSize, wR, wG, wB); @@ -250,7 +257,7 @@ int nt_scg_create_textnum(int wNumCG, int wSize, int wR, int wG, int wB, int wFi i = malloc(sizeof(cginfo_t)); i->type = CG_SET; i->no = wNumCG; - i->refcnt = 0; + i->refcnt = 1; i->sf = sf_create_surface(glyph->width, wSize, nact->ags.dib->depth); gr_fill(i->sf, 0, 0, glyph->width, wSize, wR, wG, wB); gr_draw_amap(i->sf, 0, 0, glyph->pixel, glyph->width, wSize, glyph->bytes_per_line); @@ -271,14 +278,14 @@ int nt_scg_copy(int wNumDstCG, int wNumSrcCG) { spcg_assert_no(wNumSrcCG); // 元にするCGを参照 (LINKCGなら読み込み) - if (NULL == (srccg = nt_scg_loadcg_no(wNumSrcCG, FALSE))) { + if (!(srccg = nt_scg_get(wNumSrcCG))) { return NG; } i = malloc(sizeof(cginfo_t)); i->type = CG_SET; i->no = wNumDstCG; - i->refcnt = 0; + i->refcnt = 1; i->sf = sf_dup(srccg->sf); // もし前に作成したものがあり、未開放の場合は開放 @@ -298,14 +305,14 @@ int nt_scg_cut(int wNumDstCG, int wNumSrcCG, int wX, int wY, int wWidth, int wHe spcg_assert_no(wNumSrcCG); // 元にするCGを参照 (LINKCGなら読み込み) - if (NULL == (srccg = nt_scg_loadcg_no(wNumSrcCG, FALSE))) { + if (!(srccg = nt_scg_get(wNumSrcCG))) { return NG; } i = malloc(sizeof(cginfo_t)); i->type = CG_SET; i->no = wNumDstCG; - i->refcnt = 0; + i->refcnt = 1; src = srccg->sf; if (src->alpha) { @@ -339,14 +346,14 @@ int nt_scg_partcopy(int wNumDstCG, int wNumSrcCG, int wX, int wY, int wWidth, in spcg_assert_no(wNumSrcCG); // 元にするCGを参照 (LINKCGなら読み込み) - if (NULL == (srccg = nt_scg_loadcg_no(wNumSrcCG, FALSE))) { + if (!(srccg = nt_scg_get(wNumSrcCG))) { return NG; } i = malloc(sizeof(cginfo_t)); i->type = CG_SET; i->no = wNumDstCG; - i->refcnt = 0; + i->refcnt = 1; src = srccg->sf; if (src->alpha) { @@ -388,51 +395,17 @@ int nt_scg_freeall() { * されていない(参照数が0の)場合のみ、オブジェクトを削除 */ int nt_scg_free(int no) { - cginfo_t *cg; - spcg_assert_no(no); - if (NULL == (cg = cgs[no])) return NG; + cginfo_t *cg = cgs[no]; + if (!cg) return NG; - // 参照数が0の時のみオブジェクトを開放 - if (cg->refcnt == 0) { - nt_scg_free_cgobj(cg); - } - - // 番号で消したときはオブジェクトが開放されなくても - // オブジェクトリストから削除 + nt_scg_deref(cg); cgs[no] = NULL; return OK; } -/** - * CG オブジェクトの開放 - */ -int nt_scg_free_cgobj(cginfo_t *cg) { - if (cg == NULL) return NG; - - (cg->refcnt)--; - // 他でまだ参照していれば開放しない - if (cg->refcnt > 0) { - return NG; - } - - // CG本体の開放 - if (cg->sf) { - sf_free(cg->sf); - } - - // 削除するオブジェクトを参照しているオブジェクトリストも削除 - if (cg == cgs[cg->no]) { - cgs[cg->no] = NULL; - } - - free(cg); - - return OK; -} - // CGの種類を取得 int nt_scg_querytype(int wNumCG, int *ret) { if (wNumCG >= (CGMAX -1)) goto errexit; diff --git a/modules/NIGHTDLL/sactcg.h b/modules/NIGHTDLL/sactcg.h index f1dc84f..0dc9df9 100644 --- a/modules/NIGHTDLL/sactcg.h +++ b/modules/NIGHTDLL/sactcg.h @@ -27,7 +27,8 @@ #include "portab.h" #include "night.h" -extern cginfo_t *nt_scg_loadcg_no(int no, boolean refinc); +extern cginfo_t *nt_scg_addref(int no); +extern void nt_scg_deref(cginfo_t *cg); extern int nt_scg_create(int wNumCG, int wWidth, int wHeight, int wR, int wG, int wB, int wBlendRate); extern int nt_scg_create_reverse(int NumCG, int wNumSrcCG, int wReverseX, int wReverseY); extern int nt_scg_create_stretch(int wNumCG, int wWidth, int wHeight, int wNumSrcCG); @@ -39,7 +40,6 @@ extern int nt_scg_cut(int wNumDstCG, int wNumSrcCG, int wX, int wY, int wWidth, extern int nt_scg_partcopy(int wNumDstCG, int wNumSrcCG, int wX, int wY, int wWidth, int wHeight); extern int nt_scg_freeall(); extern int nt_scg_free(int cg); -extern int nt_scg_free_cgobj(cginfo_t *cg); extern int nt_scg_querytype(int wNumCG, int *ret); extern int nt_scg_querysize(int wNumCG, int *w, int *h); extern int nt_scg_querybpp(int wNumCG, int *ret); diff --git a/modules/NIGHTDLL/sprite.c b/modules/NIGHTDLL/sprite.c index 843e41f..2b6328e 100644 --- a/modules/NIGHTDLL/sprite.c +++ b/modules/NIGHTDLL/sprite.c @@ -17,9 +17,9 @@ sprite_t *nt_sp_new(int no, int cg1, int cg2, int cg3, int type) { sp->no = no; sp->type = type; - if (cg1) sp->cg1 = nt_scg_loadcg_no(cg1, TRUE); else sp->cg1 = NULL; - if (cg2) sp->cg2 = nt_scg_loadcg_no(cg2, TRUE); else sp->cg2 = NULL; - if (cg3) sp->cg3 = nt_scg_loadcg_no(cg3, TRUE); else sp->cg3 = NULL; + sp->cg1 = cg1 ? nt_scg_addref(cg1) : NULL; + sp->cg2 = cg2 ? nt_scg_addref(cg2) : NULL; + sp->cg3 = cg3 ? nt_scg_addref(cg3) : NULL; sp->curcg = sp->cg1; sp->show = TRUE; @@ -72,9 +72,9 @@ sprite_t *nt_sp_msg_new(int no, int x, int y, int width, int height) { void nt_sp_free(sprite_t *sp) { if (sp == NULL) return; - if (sp->cg1) nt_scg_free_cgobj(sp->cg1); - if (sp->cg2) nt_scg_free_cgobj(sp->cg2); - if (sp->cg3) nt_scg_free_cgobj(sp->cg3); + if (sp->cg1) nt_scg_deref(sp->cg1); + if (sp->cg2) nt_scg_deref(sp->cg2); + if (sp->cg3) nt_scg_deref(sp->cg3); if (sp->type == SPRITE_MSG) { sf_free(sp->u.msg.canvas); @@ -102,15 +102,10 @@ void nt_sp_set_cg(sprite_t *sp, int no) { if (sp == NULL) return; - if (sp->curcg) { - nt_scg_free_cgobj(sp->curcg); - } - - if (no) { - cg = nt_scg_loadcg_no(no, TRUE); - } else { - cg = NULL; - } + if (sp->curcg) + nt_scg_deref(sp->curcg); + + cg = no ? nt_scg_addref(no) : NULL; if (cg == NULL) { sp->cursize.width = 0; diff --git a/modules/SACT/sactcg.c b/modules/SACT/sactcg.c index 6449aec..788a415 100644 --- a/modules/SACT/sactcg.c +++ b/modules/SACT/sactcg.c @@ -53,11 +53,8 @@ CG_xxxで作成したCGを参照する @param no: 読み込むCG番号 - @param refinc: 参照カウンタを増やすかどうか。 - spriteから参照されるときは増やし、CG_xxxを作る時に - 参照されるときは増やさない。 */ -cginfo_t *scg_loadcg_no(int no, boolean refinc) { +static cginfo_t *scg_get(int no) { cginfo_t *i; if (no >= (CGMAX -1)) { @@ -65,19 +62,13 @@ cginfo_t *scg_loadcg_no(int no, boolean refinc) { return NULL; } - // すでに ロードされているか、CG_xxx で作成ずみの場合は - // 参照カウンタを増やす - if (sact.cg[no] != NULL) { - if (refinc) { - sact.cg[no]->refcnt++; - } + if (sact.cg[no] != NULL) return sact.cg[no]; - } i = malloc(sizeof(cginfo_t)); i->type = CG_LINKED; i->no = no; - i->refcnt = (refinc ? 1 : 0); + i->refcnt = 1; i->sf = sf_loadcg_no(no -1); if (i->sf == NULL) { WARNING("load fail (%d)\n", no -1); @@ -90,6 +81,21 @@ cginfo_t *scg_loadcg_no(int no, boolean refinc) { return i; } +cginfo_t *scg_addref(int no) { + cginfo_t *info = scg_get(no); + if (info) + info->refcnt++; + return info; +} + +void scg_deref(cginfo_t *cg) { + if (--cg->refcnt > 0) + return; + + if (cg->sf) + sf_free(cg->sf); + free(cg); +} // 指定の大きさ、色の矩形の CG を作成 int scg_create(int wNumCG, int wWidth, int wHeight, int wR, int wG, int wB, int wBlendRate) { @@ -100,7 +106,7 @@ int scg_create(int wNumCG, int wWidth, int wHeight, int wR, int wG, int wB, int i = malloc(sizeof(cginfo_t)); i->type = CG_SET; i->no = wNumCG; - i->refcnt = 0; + i->refcnt = 1; i->sf = sf_create_surface(wWidth, wHeight, sf0->depth); gr_fill(i->sf, 0, 0, wWidth, wHeight, wR, wG, wB); gr_fill_alpha_map(i->sf, 0, 0, wWidth, wHeight, wBlendRate); @@ -122,14 +128,14 @@ int scg_create_reverse(int wNumCG, int wNumSrcCG, int wReverseX, int wReverseY) spcg_assert_no(wNumSrcCG); // 元にするCGを参照 (LINKCGなら読み込み) - if (NULL == (srccg = scg_loadcg_no(wNumSrcCG, FALSE))) { + if (!(srccg = scg_get(wNumSrcCG))) { return NG; } i = malloc(sizeof(cginfo_t)); i->type = CG_REVERSE; i->no = wNumCG; - i->refcnt = 0; + i->refcnt = 1; src = srccg->sf; i->sf = stretch(src, src->width, src->height, (wReverseX << 1) | wReverseY); @@ -150,14 +156,14 @@ int scg_create_stretch(int wNumCG, int wWidth, int wHeight, int wNumSrcCG) { spcg_assert_no(wNumSrcCG); // 元にするCGを参照 (LINKCGなら読み込み) - if (NULL == (srccg = scg_loadcg_no(wNumSrcCG, FALSE))) { + if (!(srccg = scg_get(wNumSrcCG))) { return NG; } i = malloc(sizeof(cginfo_t)); i->type = CG_STRETCH; i->no = wNumCG; - i->refcnt = 0; + i->refcnt = 1; src = srccg->sf; i->sf = stretch(src, wWidth, wHeight, 0); @@ -179,14 +185,14 @@ int scg_create_blend(int wNumDstCG, int wNumBaseCG, int wX, int wY, int wNumBlen spcg_assert_no(wNumBlendCG); // 元にするCGを参照 (LINKCGなら読み込み) - basecg = scg_loadcg_no(wNumBaseCG, FALSE); - blendcg = scg_loadcg_no(wNumBlendCG, FALSE); - if (basecg == NULL || blendcg == NULL) return NG; + basecg = scg_get(wNumBaseCG); + blendcg = scg_get(wNumBlendCG); + if (!basecg || !blendcg) return NG; i = malloc(sizeof(cginfo_t)); i->type = CG_SET; i->no = wNumDstCG; - i->refcnt = 0; + i->refcnt = 1; i->sf = blend(basecg->sf, wX , wY, blendcg->sf, wAlphaMapMode); @@ -212,7 +218,7 @@ int scg_create_text(int wNumCG, int wSize, int wR, int wG, int wB, int wText) { i = malloc(sizeof(cginfo_t)); i->type = CG_SET; i->no = wNumCG; - i->refcnt = 0; + i->refcnt = 1; i->sf = sf_create_surface(glyph->width, wSize, nact->ags.dib->depth); gr_fill(i->sf, 0, 0, glyph->width, wSize, wR, wG, wB); @@ -248,7 +254,7 @@ int scg_create_textnum(int wNumCG, int wSize, int wR, int wG, int wB, int wFigs, i = malloc(sizeof(cginfo_t)); i->type = CG_SET; i->no = wNumCG; - i->refcnt = 0; + i->refcnt = 1; i->sf = sf_create_surface(glyph->width, wSize, nact->ags.dib->depth); gr_fill(i->sf, 0, 0, glyph->width, wSize, wR, wG, wB); gr_draw_amap(i->sf, 0, 0, glyph->pixel, glyph->width, wSize, glyph->bytes_per_line); @@ -269,14 +275,14 @@ int scg_copy(int wNumDstCG, int wNumSrcCG) { spcg_assert_no(wNumSrcCG); // 元にするCGを参照 (LINKCGなら読み込み) - if (NULL == (srccg = scg_loadcg_no(wNumSrcCG, FALSE))) { + if (!(srccg = scg_get(wNumSrcCG))) { return NG; } i = malloc(sizeof(cginfo_t)); i->type = CG_SET; i->no = wNumDstCG; - i->refcnt = 0; + i->refcnt = 1; i->sf = sf_dup(srccg->sf); // もし前に作成したものがあり、未開放の場合は開放 @@ -296,14 +302,14 @@ int scg_cut(int wNumDstCG, int wNumSrcCG, int wX, int wY, int wWidth, int wHeigh spcg_assert_no(wNumSrcCG); // 元にするCGを参照 (LINKCGなら読み込み) - if (NULL == (srccg = scg_loadcg_no(wNumSrcCG, FALSE))) { + if (!(srccg = scg_get(wNumSrcCG))) { return NG; } i = malloc(sizeof(cginfo_t)); i->type = CG_SET; i->no = wNumDstCG; - i->refcnt = 0; + i->refcnt = 1; src = srccg->sf; if (src->alpha) { @@ -337,14 +343,14 @@ int scg_partcopy(int wNumDstCG, int wNumSrcCG, int wX, int wY, int wWidth, int w spcg_assert_no(wNumSrcCG); // 元にするCGを参照 (LINKCGなら読み込み) - if (NULL == (srccg = scg_loadcg_no(wNumSrcCG, FALSE))) { + if (!(srccg = scg_get(wNumSrcCG))) { return NG; } i = malloc(sizeof(cginfo_t)); i->type = CG_SET; i->no = wNumDstCG; - i->refcnt = 0; + i->refcnt = 1; src = srccg->sf; if (src->alpha) { @@ -386,51 +392,17 @@ int scg_freeall() { * されていない(参照数が0の)場合のみ、オブジェクトを削除 */ int scg_free(int no) { - cginfo_t *cg; - spcg_assert_no(no); - if (NULL == (cg = sact.cg[no])) return NG; + cginfo_t *cg = sact.cg[no]; + if (!cg) return NG; - // 参照数が0の時のみオブジェクトを開放 - if (cg->refcnt == 0) { - scg_free_cgobj(cg); - } - - // 番号で消したときはオブジェクトが開放されなくても - // オブジェクトリストから削除 + scg_deref(cg); sact.cg[no] = NULL; return OK; } -/** - * CG オブジェクトの開放 - */ -int scg_free_cgobj(cginfo_t *cg) { - if (cg == NULL) return NG; - - (cg->refcnt)--; - // 他でまだ参照していれば開放しない - if (cg->refcnt > 0) { - return NG; - } - - // CG本体の開放 - if (cg->sf) { - sf_free(cg->sf); - } - - // 削除するオブジェクトを参照しているオブジェクトリストも削除 - if (cg == sact.cg[cg->no]) { - sact.cg[cg->no] = NULL; - } - - free(cg); - - return OK; -} - // CGの種類を取得 int scg_querytype(int wNumCG, int *ret) { if (wNumCG >= (CGMAX -1)) goto errexit; diff --git a/modules/SACT/sactcg.h b/modules/SACT/sactcg.h index f5c4061..3bd7140 100644 --- a/modules/SACT/sactcg.h +++ b/modules/SACT/sactcg.h @@ -27,7 +27,8 @@ #include "portab.h" #include "sact.h" -extern cginfo_t *scg_loadcg_no(int no, boolean refinc); +extern cginfo_t *scg_addref(int no); +extern void scg_deref(cginfo_t *cg); extern int scg_create(int wNumCG, int wWidth, int wHeight, int wR, int wG, int wB, int wBlendRate); extern int scg_create_reverse(int NumCG, int wNumSrcCG, int wReverseX, int wReverseY); extern int scg_create_stretch(int wNumCG, int wWidth, int wHeight, int wNumSrcCG); @@ -39,7 +40,6 @@ extern int scg_cut(int wNumDstCG, int wNumSrcCG, int wX, int wY, int wWidth, int extern int scg_partcopy(int wNumDstCG, int wNumSrcCG, int wX, int wY, int wWidth, int wHeight); extern int scg_freeall(); extern int scg_free(int cg); -extern int scg_free_cgobj(cginfo_t *cg); extern int scg_querytype(int wNumCG, int *ret); extern int scg_querysize(int wNumCG, int *w, int *h); extern int scg_querybpp(int wNumCG, int *ret); diff --git a/modules/SACT/sprite.c b/modules/SACT/sprite.c index 9573b85..656c56c 100644 --- a/modules/SACT/sprite.c +++ b/modules/SACT/sprite.c @@ -147,9 +147,9 @@ int sp_new(int no, int cg1, int cg2, int cg3, int type) { sp->no = no; // set時点でのcgが使用される(draw時ではない) - if (cg1) sp->cg1 = scg_loadcg_no(cg1, TRUE); else sp->cg1 = NULL; - if (cg2) sp->cg2 = scg_loadcg_no(cg2, TRUE); else sp->cg2 = NULL; - if (cg3) sp->cg3 = scg_loadcg_no(cg3, TRUE); else sp->cg3 = NULL; + sp->cg1 = cg1 ? scg_addref(cg1) : NULL; + sp->cg2 = cg2 ? scg_addref(cg2) : NULL; + sp->cg3 = cg3 ? scg_addref(cg3) : NULL; //初期のcurcgはcg1 sp->curcg = sp->cg1; @@ -238,11 +238,10 @@ int sp_new_msg(int no, int x, int y, int width, int height) { int sp_set_wall_paper(int no) { sprite_t *sp = sact.sp[0]; - if (sp->curcg) { - scg_free_cgobj(sp->curcg); - } + if (sp->curcg) + scg_deref(sp->curcg); - sp->curcg = no ? scg_loadcg_no(no, TRUE) : NULL; + sp->curcg = no ? scg_addref(no) : NULL; if (sp->curcg) { // display specified CG sp->update = DEFAULT_UPDATE; @@ -287,9 +286,10 @@ int sp_free(int no) { } // CGオブジェクトの削除 - if (sp->cg1) scg_free_cgobj(sp->cg1); - if (sp->cg2) scg_free_cgobj(sp->cg2); - if (sp->cg3) scg_free_cgobj(sp->cg3); + if (sp->cg1) scg_deref(sp->cg1); + if (sp->cg2) scg_deref(sp->cg2); + if (sp->cg3) scg_deref(sp->cg3); + sp->cg1 = sp->cg2 = sp->cg3 = NULL; // remove時の処理があれば実行 if (sp->remove) {