494 lines
15 KiB
C++
494 lines
15 KiB
C++
/******************************************************************************/
|
|
/* Mednafen Virtual Boy Emulation Module */
|
|
/******************************************************************************/
|
|
/* vip_draw.inc:
|
|
** Copyright (C) 2010-2016 Mednafen Team
|
|
**
|
|
** This program is free software; you can redistribute it and/or
|
|
** modify it under the terms of the GNU General Public License
|
|
** as published by the Free Software Foundation; either version 2
|
|
** of the License, or (at your option) any later version.
|
|
**
|
|
** This program is distributed in the hope that it will be useful,
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
** GNU General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#define BGM_AFFINE 0x2
|
|
#define BGM_OBJ 0x3
|
|
|
|
|
|
static void DrawBG(uint8 *target, uint16 RealY, bool lr, uint8 bgmap_base_raw, bool overplane, uint16 overplane_char, uint32 SourceX, uint32 SourceY, uint32 scx, uint32 scy, uint16 DestX, uint16 DestY, uint16 DestWidth, uint16 DestHeight)
|
|
{
|
|
const uint16 *CHR16 = CHR_RAM;
|
|
const uint16 *BGMap = DRAM;
|
|
uint32 BGMap_Base = bgmap_base_raw << 12;
|
|
int32 start_x, final_x;
|
|
const uint32 bgsc_overplane = DRAM[overplane_char];
|
|
const uint32 BGMap_XCount = 1 << scx;
|
|
const uint32 BGMap_YCount = 1 << scy;
|
|
const uint32 SourceX_Size = 512 * BGMap_XCount;
|
|
const uint32 SourceY_Size = 512 * BGMap_YCount;
|
|
const uint32 SourceX_Mask = overplane ? 0x1FFF : (SourceX_Size - 1);
|
|
const uint32 SourceY_Mask = overplane ? 0x1FFF : (SourceY_Size - 1);
|
|
|
|
if((uint16)(RealY - DestY) > DestHeight)
|
|
return;
|
|
|
|
//printf("%d, %d, %d, %d\n", overplane, srcXSize, srcYSize, bgmap_base_raw);
|
|
|
|
DestX = sign_10_to_s16(DestX);
|
|
|
|
if(DestX & 0x8000)
|
|
SourceX -= DestX;
|
|
|
|
start_x = (int16)DestX;
|
|
final_x = (int16)DestX + DestWidth;
|
|
|
|
if(start_x < 0)
|
|
start_x = 0;
|
|
|
|
if(final_x > 383)
|
|
final_x = 383;
|
|
|
|
if(start_x > final_x)
|
|
return;
|
|
|
|
// Optimization:
|
|
SourceY &= SourceY_Mask;
|
|
BGMap_Base |= (((SourceY >> 3) & 0x3F) * 0x40) | (((SourceY << 3) & ~0xFFF) << scx);
|
|
|
|
for(int x = start_x; x <= final_x; x++)
|
|
{
|
|
uint32 bgsc;
|
|
uint32 char_no;
|
|
uint32 palette_selector;
|
|
uint32 hflip_xor;
|
|
uint32 vflip_xor;
|
|
|
|
SourceX &= SourceX_Mask;
|
|
|
|
bgsc = bgsc_overplane;
|
|
|
|
if(SourceX < SourceX_Size && SourceY < SourceY_Size)
|
|
bgsc = BGMap[(BGMap_Base | ((SourceX << 3) & ~0xFFF) | ((SourceX >> 3) & 0x3F)) & 0xFFFF];
|
|
|
|
char_no = bgsc & 0x7FF;
|
|
palette_selector = bgsc >> 14;
|
|
hflip_xor = (bgsc & 0x2000) ? 7 : 0; //(((int32)bgsc << 18) >> 31) & 0x7;
|
|
vflip_xor = (bgsc & 0x1000) ? 7 : 0; //(((int32)bgsc << 19) >> 31) & 0x7;
|
|
|
|
unsigned int char_sub_y = vflip_xor ^ (SourceY & 0x7);
|
|
|
|
if(!(SourceX & 7) && (x + 7) <= final_x)
|
|
{
|
|
uint32 pixels = CHR16[char_no * 8 + char_sub_y];
|
|
|
|
#if 0
|
|
unsigned int char_sub_x;
|
|
uint8 *sub_target = target + x + 8;
|
|
|
|
for(int sub_x = -8; sub_x < 0; sub_x++)
|
|
{
|
|
if(pixels & 3) sub_target[sub_x] = GPLT_Cache[palette_selector][pixels & 3];
|
|
pixels >>= 2;
|
|
}
|
|
#endif
|
|
|
|
if(bgsc & 0x2000)
|
|
{
|
|
if((pixels >> 14) & 3) target[0 + x] = GPLT_Cache[palette_selector][(pixels >> 14) & 3];
|
|
if((pixels >> 12) & 3) target[1 + x] = GPLT_Cache[palette_selector][(pixels >> 12) & 3];
|
|
if((pixels >> 10) & 3) target[2 + x] = GPLT_Cache[palette_selector][(pixels >> 10) & 3];
|
|
if((pixels >> 8) & 3) target[3 + x] = GPLT_Cache[palette_selector][(pixels >> 8) & 3];
|
|
if((pixels >> 6) & 3) target[4 + x] = GPLT_Cache[palette_selector][(pixels >> 6) & 3];
|
|
if((pixels >> 4) & 3) target[5 + x] = GPLT_Cache[palette_selector][(pixels >> 4) & 3];
|
|
if((pixels >> 2) & 3) target[6 + x] = GPLT_Cache[palette_selector][(pixels >> 2) & 3];
|
|
if((pixels >> 0) & 3) target[7 + x] = GPLT_Cache[palette_selector][(pixels >> 0) & 3];
|
|
}
|
|
else
|
|
{
|
|
if((pixels >> 0) & 3) target[0 + x] = GPLT_Cache[palette_selector][(pixels >> 0) & 3];
|
|
if((pixels >> 2) & 3) target[1 + x] = GPLT_Cache[palette_selector][(pixels >> 2) & 3];
|
|
if((pixels >> 4) & 3) target[2 + x] = GPLT_Cache[palette_selector][(pixels >> 4) & 3];
|
|
if((pixels >> 6) & 3) target[3 + x] = GPLT_Cache[palette_selector][(pixels >> 6) & 3];
|
|
if((pixels >> 8) & 3) target[4 + x] = GPLT_Cache[palette_selector][(pixels >> 8) & 3];
|
|
if((pixels >> 10) & 3) target[5 + x] = GPLT_Cache[palette_selector][(pixels >> 10) & 3];
|
|
if((pixels >> 12) & 3) target[6 + x] = GPLT_Cache[palette_selector][(pixels >> 12) & 3];
|
|
if((pixels >> 14) & 3) target[7 + x] = GPLT_Cache[palette_selector][(pixels >> 14) & 3];
|
|
}
|
|
|
|
x += 7;
|
|
SourceX += 8;
|
|
}
|
|
else
|
|
{
|
|
unsigned int char_sub_x;
|
|
|
|
char_sub_x = hflip_xor ^ (SourceX & 0x7);
|
|
|
|
uint8 pixel = (CHR16[char_no * 8 + char_sub_y] >> (char_sub_x * 2)) & 0x3;
|
|
|
|
if(pixel)
|
|
target[x] = GPLT_Cache[palette_selector][pixel]; //target[x] = (GPLT[palette_selector] >> (pixel * 2)) & 0x3;
|
|
SourceX++;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void DrawAffine(uint8 *target, uint16 RealY, bool lr, uint32 ParamBase, uint32 BGMap_Base, bool OverplaneMode, uint16 OverplaneChar, uint32 scx, uint32 scy,
|
|
uint16 DestX, uint16 DestY, uint16 DestWidth, uint16 DestHeight)
|
|
{
|
|
const uint16 *CHR16 = CHR_RAM;
|
|
const uint16 *BGMap = DRAM;
|
|
|
|
const uint32 BGMap_XCount = 1 << scx;
|
|
const uint32 BGMap_YCount = 1 << scy;
|
|
const uint32 SourceX_Size = 512 * BGMap_XCount;
|
|
const uint32 SourceY_Size = 512 * BGMap_YCount;
|
|
|
|
const uint16 *param_ptr = &DRAM[(ParamBase + 8 * (RealY - DestY)) & 0xFFFF];
|
|
int16 mx = param_ptr[0], mp = (ParallaxDisabled ? 0 : param_ptr[1]), my = param_ptr[2], dx = param_ptr[3], dy = param_ptr[4];
|
|
|
|
uint32 SourceX, SourceY;
|
|
uint32 SourceX_Mask, SourceY_Mask;
|
|
|
|
int32 start_x, final_x;
|
|
const uint32 bgsc_overplane = DRAM[OverplaneChar];
|
|
|
|
|
|
DestX = sign_10_to_s16(DestX);
|
|
|
|
if((uint16)(RealY - DestY) > DestHeight)
|
|
return;
|
|
|
|
SourceX = (int32)mx << 6;
|
|
SourceY = (int32)my << 6;
|
|
|
|
if(DestX & 0x8000)
|
|
{
|
|
SourceX += dx * (65536 - DestX);
|
|
SourceY += dy * (65536 - DestX);
|
|
}
|
|
|
|
if(mp >= 0 && lr)
|
|
{
|
|
SourceX += dx * mp;
|
|
SourceY += dy * mp;
|
|
}
|
|
else if(mp < 0 && !lr)
|
|
{
|
|
SourceX += dx * -mp;
|
|
SourceY += dy * -mp;
|
|
}
|
|
|
|
if(OverplaneMode)
|
|
{
|
|
SourceX_Mask = 0x3FFFFFF; //(((uint32)SourceX_Size << 9) * 2) - 1;
|
|
SourceY_Mask = 0x3FFFFFF; //(((uint32)SourceY_Size << 9) * 2) - 1;
|
|
}
|
|
else
|
|
{
|
|
SourceX_Mask = ((uint32)SourceX_Size << 9) - 1;
|
|
SourceY_Mask = ((uint32)SourceY_Size << 9) - 1;
|
|
}
|
|
|
|
start_x = (int16)DestX;
|
|
final_x = (int16)DestX + DestWidth;
|
|
|
|
if(start_x < 0)
|
|
start_x = 0;
|
|
|
|
if(final_x > 383)
|
|
final_x = 383;
|
|
|
|
if(dy == 0) // Optimization for no rotation.
|
|
{
|
|
SourceY &= SourceY_Mask;
|
|
|
|
if(SourceY >= (SourceY_Size << 9))
|
|
return;
|
|
|
|
BGMap_Base |= (((SourceY >> 6) & ~0xFFF) << scx) | (((SourceY >> 12) & 0x3F) * 0x40);
|
|
for(int x = start_x; x <= final_x; x++)
|
|
{
|
|
uint32 bgsc;
|
|
uint32 hflip_xor;
|
|
uint32 vflip_xor;
|
|
uint32 pixel = 0;
|
|
|
|
SourceX &= SourceX_Mask;
|
|
|
|
bgsc = bgsc_overplane;
|
|
|
|
if(SourceX < (SourceX_Size << 9))
|
|
bgsc = BGMap[(BGMap_Base | ((SourceX >> 6) & ~0xFFF) | ((SourceX >> 12) & 0x3F)) & 0xFFFF];
|
|
|
|
//hflip_xor = bgsc & 0x2000 ? 0xE : 0;
|
|
//vflip_xor = bgsc & 0x1000 ? 0x7 : 0;
|
|
hflip_xor = ((int32)(bgsc << 18) >> 30) & 0xE;
|
|
vflip_xor = ((int32)(bgsc << 19) >> 31) & 0x7;
|
|
|
|
unsigned int char_sub_y = vflip_xor ^ ((SourceY >> 9) & 0x7);
|
|
unsigned int char_sub_x = hflip_xor ^ ((SourceX >> 8) & 0xE);
|
|
|
|
pixel = (CHR16[((bgsc & 0x7FF) * 8) | char_sub_y] >> char_sub_x) & 0x3;
|
|
|
|
if(pixel)
|
|
target[x] = GPLT_Cache[bgsc >> 14][pixel];
|
|
|
|
SourceX += dx;
|
|
}
|
|
}
|
|
else
|
|
for(int x = start_x; x <= final_x; x++)
|
|
{
|
|
uint32 bgsc;
|
|
uint32 char_no;
|
|
uint32 palette_selector;
|
|
uint32 hflip_xor;
|
|
uint32 vflip_xor;
|
|
uint8 pixel = 0;
|
|
|
|
SourceX &= SourceX_Mask;
|
|
SourceY &= SourceY_Mask;
|
|
|
|
bgsc = bgsc_overplane;
|
|
|
|
if(SourceX < (SourceX_Size << 9) && SourceY < (SourceY_Size << 9))
|
|
{
|
|
uint32 m_index = ((SourceX >> 6) & ~0xFFF) + (((SourceY >> 6) & ~0xFFF) << scx);
|
|
uint32 sub_index = ((SourceX >> 12) & 0x3F) + (((SourceY >> 12) & 0x3F) * 0x40);
|
|
|
|
bgsc = BGMap[(BGMap_Base | m_index | sub_index) & 0xFFFF];
|
|
|
|
//bgsc = BGMap[(BGMapBase + (SourceX >> 12) + (SourceY >> 12) * (SourceX_Size >> 3)) & 0xFFFF ];
|
|
}
|
|
char_no = bgsc & 0x7FF;
|
|
palette_selector = bgsc >> 14;
|
|
hflip_xor = bgsc & 0x2000 ? 7 : 0; //(((int32)bgsc << 18) >> 31) & 0x7;
|
|
vflip_xor = bgsc & 0x1000 ? 7 : 0; //(((int32)bgsc << 19) >> 31) & 0x7;
|
|
|
|
unsigned int char_sub_y = vflip_xor ^ ((SourceY >> 9) & 0x7);
|
|
unsigned int char_sub_x = hflip_xor ^ ((SourceX >> 9) & 0x7);
|
|
|
|
pixel = (CHR16[char_no * 8 + char_sub_y] >> (char_sub_x * 2)) & 0x3;
|
|
|
|
if(pixel)
|
|
target[x] = GPLT_Cache[palette_selector][pixel];
|
|
|
|
SourceX += dx;
|
|
SourceY += dy;
|
|
}
|
|
}
|
|
|
|
static int obj_search_which;
|
|
|
|
static void DrawOBJ(uint8 *fb[2], uint16 Y, bool lron[2])
|
|
{
|
|
const uint16 *CHR16 = CHR_RAM;
|
|
|
|
int32 start_oam;
|
|
int32 end_oam;
|
|
|
|
start_oam = SPT[obj_search_which];
|
|
|
|
end_oam = 1023;
|
|
if(obj_search_which)
|
|
end_oam = SPT[obj_search_which - 1];
|
|
|
|
int32 oam = start_oam;
|
|
do
|
|
{
|
|
const uint16 *oam_ptr = &DRAM[(0x1E000 + (oam * 8)) >> 1];
|
|
const uint32 jy = oam_ptr[2];
|
|
const uint32 tile_y = (Y - jy) & 0xFF; // I think this mask is right. See: http://www.planetvb.com/modules/newbb/viewtopic.php?topic_id=3797&forum=2
|
|
|
|
if(tile_y >= 8)
|
|
continue;
|
|
|
|
uint32 jx = oam_ptr[0];
|
|
uint32 jp = ParallaxDisabled ? 0 : (oam_ptr[1] & 0x3FFF);
|
|
uint32 palette_selector = oam_ptr[3] >> 14;
|
|
uint32 vflip_xor = (oam_ptr[3] & 0x1000) ? 7 : 0;
|
|
uint32 char_sub_y = vflip_xor ^ tile_y;
|
|
bool jlron[2] = { (bool)(oam_ptr[1] & 0x8000), (bool)(oam_ptr[1] & 0x4000) };
|
|
uint32 char_no = oam_ptr[3] & 0x7FF;
|
|
const uint32 pixels_save = CHR16[char_no * 8 + char_sub_y];
|
|
|
|
for(int lr = 0; lr < 2; lr++)
|
|
{
|
|
if(!(jlron[lr] & lron[lr]))
|
|
continue;
|
|
|
|
uint32 pixels = pixels_save;
|
|
int32 x = sign_x_to_s32(10, (jx + (lr ? jp : -jp))); // It may actually be 9, TODO?
|
|
|
|
if(x >= -7 && x < 384) // Make sure we always keep the pitch of our 384x8 buffer large enough(with padding before and after the visible space)
|
|
{
|
|
uint8 *target = &fb[lr][x];
|
|
|
|
if(oam_ptr[3] & 0x2000)
|
|
{
|
|
target += 7;
|
|
|
|
for(int meow = 8; meow; meow--)
|
|
{
|
|
if(pixels & 3)
|
|
*target = JPLT_Cache[palette_selector][pixels & 3];
|
|
target--;
|
|
pixels >>= 2;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for(int meow = 8; meow; meow--)
|
|
{
|
|
if(pixels & 3)
|
|
*target = JPLT_Cache[palette_selector][pixels & 3];
|
|
target++;
|
|
pixels >>= 2;
|
|
}
|
|
}
|
|
#if 0
|
|
if(oam_ptr[3] & 0x2000)
|
|
{
|
|
if((pixels >> 14) & 3) fb[lr][0 + x] = JPLT_Cache[palette_selector][(pixels >> 14) & 3];
|
|
if((pixels >> 12) & 3) fb[lr][1 + x] = JPLT_Cache[palette_selector][(pixels >> 12) & 3];
|
|
if((pixels >> 10) & 3) fb[lr][2 + x] = JPLT_Cache[palette_selector][(pixels >> 10) & 3];
|
|
if((pixels >> 8) & 3) fb[lr][3 + x] = JPLT_Cache[palette_selector][(pixels >> 8) & 3];
|
|
if((pixels >> 6) & 3) fb[lr][4 + x] = JPLT_Cache[palette_selector][(pixels >> 6) & 3];
|
|
if((pixels >> 4) & 3) fb[lr][5 + x] = JPLT_Cache[palette_selector][(pixels >> 4) & 3];
|
|
if((pixels >> 2) & 3) fb[lr][6 + x] = JPLT_Cache[palette_selector][(pixels >> 2) & 3];
|
|
if((pixels >> 0) & 3) fb[lr][7 + x] = JPLT_Cache[palette_selector][(pixels >> 0) & 3];
|
|
}
|
|
else
|
|
{
|
|
if((pixels >> 0) & 3) fb[lr][0 + x] = JPLT_Cache[palette_selector][(pixels >> 0) & 3];
|
|
if((pixels >> 2) & 3) fb[lr][1 + x] = JPLT_Cache[palette_selector][(pixels >> 2) & 3];
|
|
if((pixels >> 4) & 3) fb[lr][2 + x] = JPLT_Cache[palette_selector][(pixels >> 4) & 3];
|
|
if((pixels >> 6) & 3) fb[lr][3 + x] = JPLT_Cache[palette_selector][(pixels >> 6) & 3];
|
|
if((pixels >> 8) & 3) fb[lr][4 + x] = JPLT_Cache[palette_selector][(pixels >> 8) & 3];
|
|
if((pixels >> 10) & 3) fb[lr][5 + x] = JPLT_Cache[palette_selector][(pixels >> 10) & 3];
|
|
if((pixels >> 12) & 3) fb[lr][6 + x] = JPLT_Cache[palette_selector][(pixels >> 12) & 3];
|
|
if((pixels >> 14) & 3) fb[lr][7 + x] = JPLT_Cache[palette_selector][(pixels >> 14) & 3];
|
|
}
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
} while( (oam = (oam - 1) & 1023) != end_oam);
|
|
|
|
}
|
|
|
|
|
|
void VIP_DrawBlock(uint8 block_no, uint8 *fb_l, uint8 *fb_r)
|
|
{
|
|
for(int y = 0; y < 8; y++)
|
|
{
|
|
memset(fb_l + y * 512, BKCOL, 384);
|
|
memset(fb_r + y * 512, BKCOL, 384);
|
|
}
|
|
|
|
obj_search_which = 3;
|
|
|
|
for(int world = 31; world >= 0; world--)
|
|
{
|
|
const uint16 *world_ptr = &DRAM[(0x1D800 + world * 0x20) >> 1];
|
|
|
|
uint32 bgmap_base = world_ptr[0] & 0xF;
|
|
bool end = world_ptr[0] & 0x40;
|
|
bool over = world_ptr[0] & 0x80;
|
|
uint32 scy = (world_ptr[0] >> 8) & 3;
|
|
uint32 scx = (world_ptr[0] >> 10) & 3;
|
|
uint32 bgm = (world_ptr[0] >> 12) & 3;
|
|
bool lron[2] = { (bool)(world_ptr[0] & 0x8000), (bool)(world_ptr[0] & 0x4000) };
|
|
|
|
uint16 gx = sign_11_to_s16(world_ptr[1]);
|
|
uint16 gp = ParallaxDisabled ? 0 : sign_9_to_s16(world_ptr[2]);
|
|
uint16 gy = sign_11_to_s16(world_ptr[3]);
|
|
uint16 mx = world_ptr[4];
|
|
uint16 mp = ParallaxDisabled ? 0 : sign_9_to_s16(world_ptr[5]);
|
|
uint16 my = world_ptr[6];
|
|
uint16 window_width = sign_11_to_s16(world_ptr[7]);
|
|
uint16 window_height = (world_ptr[8] & 0x3FF);
|
|
uint32 param_base = (world_ptr[9] & 0xFFF0);
|
|
uint16 overplane_char = world_ptr[10];
|
|
|
|
if(end)
|
|
break;
|
|
|
|
if(((512 << scx) + (512 << scy)) > 4096)
|
|
{
|
|
printf("BG Size too large for world: %d(scx=%d, scy=%d)\n", world, scx, scy);
|
|
}
|
|
|
|
// if(world != 2)
|
|
// continue;
|
|
|
|
// if(block_no == 8)
|
|
// printf("World: %d; gx: %d, gp: %d, gy: %d, mx: %d, mp: %d, my: %d, window_width: %d, window_height: %d\n", world, gx, gp, gy, mx, mp, my, window_width, window_height);
|
|
|
|
for(int y = 0; y < 8; y++)
|
|
{
|
|
uint8 *fb[2] = { &fb_l[y * 512], &fb_r[y * 512] };
|
|
|
|
if(bgm == BGM_OBJ)
|
|
{
|
|
if(!lron[0] || !lron[1])
|
|
printf("Bad OBJ World? %d(%d/%d) %d~%d\n", world, lron[0], lron[1], SPT[obj_search_which], obj_search_which ? (SPT[obj_search_which - 1] + 1) : 0);
|
|
|
|
DrawOBJ(fb, (block_no * 8) + y, lron);
|
|
}
|
|
else if(bgm == BGM_AFFINE)
|
|
{
|
|
//if(((block_no * 8) + y) == 128)
|
|
// printf("Draw affine: %d %d\n", gx, gp);
|
|
for(int lr = 0; lr < 2; lr++)
|
|
{
|
|
if(lron[lr])
|
|
{
|
|
DrawAffine(fb[lr], (block_no * 8) + y, lr, param_base, bgmap_base * 4096, over, overplane_char, scx, scy,
|
|
gx + (lr ? gp : -gp), gy, window_width, window_height);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
for(int lr = 0; lr < 2; lr++)
|
|
{
|
|
uint16 srcX, srcY;
|
|
uint16 RealY = (block_no * 8) + y;
|
|
uint16 DestX;
|
|
uint16 DestY;
|
|
|
|
srcX = mx + (lr ? mp : -mp);
|
|
srcY = my + (RealY - gy);
|
|
|
|
DestX = gx + (lr ? gp : -gp);
|
|
DestY = gy;
|
|
|
|
if(lron[lr])
|
|
{
|
|
if(bgm == 1) // HBias
|
|
srcX += (int16)DRAM[(param_base + (((RealY - DestY) * 2) | lr)) & 0xFFFF];
|
|
|
|
DrawBG(fb[lr], RealY, lr, bgmap_base, over, overplane_char, (int32)(int16)srcX, (int32)(int16)srcY, scx, scy, DestX, DestY, window_width, window_height);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(bgm == BGM_OBJ)
|
|
if(obj_search_which)
|
|
obj_search_which--;
|
|
|
|
}
|
|
|
|
|
|
}
|