summaryrefslogtreecommitdiff
path: root/dxr3spudecoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'dxr3spudecoder.c')
-rw-r--r--dxr3spudecoder.c608
1 files changed, 309 insertions, 299 deletions
diff --git a/dxr3spudecoder.c b/dxr3spudecoder.c
index 239c97f..8b09524 100644
--- a/dxr3spudecoder.c
+++ b/dxr3spudecoder.c
@@ -22,11 +22,6 @@
*
*/
-/*
-ToDo:
- - Line 175
-*/
-
#include <assert.h>
#include <string.h>
#include <inttypes.h>
@@ -48,7 +43,7 @@ ToDo:
#define CMD_SPU_CHG_COLCON 0x07
#define CMD_SPU_EOF 0xff
-#define spuU32(i) ((spu[i] << 8) + spu[i+1])
+#define spuU32(i) ((spu[i] << 8) + spu[i+1])
/*
@@ -60,36 +55,36 @@ ToDo:
* Inputs:
* - a SPU rle encoded image on creation, which will be decoded into
* the full screen indexed bitmap
- *
+ *
* Output:
* - a minimal sized cDxr3SpuBitmap a given palette, the indexed bitmap
* will be scanned to get the smallest possible resulting bitmap considering
* transparencies
*/
-
// ==================================
void cDxr3SpuPalette::setPalette(const uint32_t * pal)
{
for (int i = 0; i < 16; i++)
- palette[i] = Tools::YUV2Rgb(pal[i]);
+ palette[i] = Tools::YUV2Rgb(pal[i]);
}
// ==================================
#define setMin(a, b) if (a > b) a = b
#define setMax(a, b) if (a < b) a = b
-#define spuXres 720
-#define spuYres 576
+#define spuXres 720
+#define spuYres 576
#define revRect(r1, r2) { r1.x1 = r2.x2; r1.y1 = r2.y2; r1.x2 = r2.x1; r1.y2 = r2.y1; }
// ==================================
-cDxr3SpuBitmap::cDxr3SpuBitmap(sDxr3SpuRect size, uint8_t * fodd, uint8_t * eodd, uint8_t * feven, uint8_t * eeven)
+cDxr3SpuBitmap::cDxr3SpuBitmap(sDxr3SpuRect size, uint8_t * fodd,
+ uint8_t * eodd, uint8_t * feven,
+ uint8_t * eeven)
{
- if (size.x1 < 0 || size.y1 < 0 || size.x2 >= spuXres
- || size.y2 >= spuYres)
- throw;
+ if (size.x1 < 0 || size.y1 < 0 || size.x2 >= spuXres || size.y2 >= spuYres)
+ throw;
bmpsize = size;
revRect(minsize[0], size);
@@ -98,7 +93,7 @@ cDxr3SpuBitmap::cDxr3SpuBitmap(sDxr3SpuRect size, uint8_t * fodd, uint8_t * eodd
revRect(minsize[3], size);
if (!(bmp = new uint8_t[spuXres * spuYres * sizeof(uint8_t)]))
- throw;
+ throw;
memset(bmp, 0, spuXres * spuYres * sizeof(uint8_t));
putFieldData(0, fodd, eodd);
@@ -112,75 +107,80 @@ cDxr3SpuBitmap::~cDxr3SpuBitmap()
}
// ==================================
-cBitmap *cDxr3SpuBitmap::getBitmap(const aDxr3SpuPalDescr paldescr, const cDxr3SpuPalette & pal, sDxr3SpuRect & size) const
+cBitmap *cDxr3SpuBitmap::getBitmap(const aDxr3SpuPalDescr paldescr,
+ const cDxr3SpuPalette & pal,
+ sDxr3SpuRect & size) const
{
int h = size.height();
int w = size.width();
if (size.y1 + h >= spuYres)
- {
- h = spuYres - size.y1 - 1;
- }
+ {
+ h = spuYres - size.y1 - 1;
+ }
if (size.x1 + w >= spuXres)
- {
- w = spuXres - size.x1 - 1;
- }
+ {
+ w = spuXres - size.x1 - 1;
+ }
if (w & 0x03)
- {
- w += 4 - (w & 0x03);
- }
+ {
+ w += 4 - (w & 0x03);
+ }
cBitmap *ret = new cBitmap(w, h, 2);
// set the palette
- for (int i = 0; i < 4; i++)
- {
- uint32_t color = pal.getColor(paldescr[i].index, paldescr[i].trans);
- ret->SetColor(i, (tColor) color);
+ for (int i = 0; i < 4; i++)
+ {
+ uint32_t color = pal.getColor(paldescr[i].index, paldescr[i].trans);
+ ret->SetColor(i, (tColor) color);
}
// set the content
- for (int yp = 0; yp < h; yp++)
+ for (int yp = 0; yp < h; yp++)
+ {
+ for (int xp = 0; xp < w; xp++)
{
- for (int xp = 0; xp < w; xp++)
- {
- uint8_t idx = bmp[(size.y1 + yp) * spuXres + size.x1 + xp];
- ret->SetIndex(xp, yp, idx);
- }
+ uint8_t idx = bmp[(size.y1 + yp) * spuXres + size.x1 + xp];
+ ret->SetIndex(xp, yp, idx);
+ }
}
return ret;
}
// ==================================
// find the minimum non-transparent area
-bool cDxr3SpuBitmap::getMinSize(const aDxr3SpuPalDescr paldescr, sDxr3SpuRect & size) const
+bool cDxr3SpuBitmap::getMinSize(const aDxr3SpuPalDescr paldescr,
+ sDxr3SpuRect & size) const
{
bool ret = false;
- for (int i = 0; i < 4; i++)
- {
- if (paldescr[i].trans != 0)
- {
- if (!ret)
- {
- size = minsize[i];
- }
- else
- {
- setMin(size.x1, minsize[i].x1);
- setMin(size.y1, minsize[i].y1);
- setMax(size.x2, minsize[i].x2);
- setMax(size.y2, minsize[i].y2);
- }
- ret = true;
- }
- }
-/*
- if (ret && cDxr3ConfigData::Instance().GetDebug())
+ for (int i = 0; i < 4; i++)
+ {
+ if (paldescr[i].trans != 0)
{
- cLog::Instance() << "cDxr3SpuBitmap::getMinSize: (" << size.x1 ", " << size.y1 << ") x (" << size.x2 << ", " << size.y2 << ")\n";
+ if (!ret)
+ {
+ size = minsize[i];
+ }
+ else
+ {
+ setMin(size.x1, minsize[i].x1);
+ setMin(size.y1, minsize[i].y1);
+ setMax(size.x2, minsize[i].x2);
+ setMax(size.y2, minsize[i].y2);
+ }
+ ret = true;
}
-*/
+ }
+ /*
+ if (ret && cDxr3ConfigData::Instance().GetDebug())
+ {
+ cLog::Instance() << "cDxr3SpuBitmap::getMinSize: ("
+ << size.x1 ", " << size.y1 << ") x ("
+ << size.x2 << ", " << size.y2 << ")\n";
+ }
+ */
return ret;
}
@@ -199,13 +199,13 @@ static uint8_t getBits(uint8_t * &data, uint8_t & bitf)
{
uint8_t ret = *data;
if (bitf)
- {
- ret >>= 4;
- }
+ {
+ ret >>= 4;
+ }
else
- {
- data++;
- }
+ {
+ data++;
+ }
bitf ^= 1;
@@ -219,41 +219,41 @@ void cDxr3SpuBitmap::putFieldData(int field, uint8_t * data, uint8_t * endp)
int yp = bmpsize.y1 + field;
uint8_t bitf = 1;
- while (data < endp)
+ while (data < endp)
+ {
+ uint16_t vlc = getBits(data, bitf);
+ if (vlc < 0x0004)
{
- uint16_t vlc = getBits(data, bitf);
- if (vlc < 0x0004)
- {
- vlc = (vlc << 4) | getBits(data, bitf);
- if (vlc < 0x0010)
- {
- vlc = (vlc << 4) | getBits(data, bitf);
- if (vlc < 0x0040)
- {
- vlc = (vlc << 4) | getBits(data, bitf);
- }
- }
- }
-
- uint8_t color = vlc & 0x03;
- int len = vlc >> 2;
-
- // if len == 0 -> end sequence - fill to end of line
- len = len ? len : bmpsize.x2 - xp + 1;
- putPixel(xp, yp, len, color);
- xp += len;
-
- if (xp > bmpsize.x2)
+ vlc = (vlc << 4) | getBits(data, bitf);
+ if (vlc < 0x0010)
+ {
+ vlc = (vlc << 4) | getBits(data, bitf);
+ if (vlc < 0x0040)
{
- // nextLine
- if (!bitf)
- data++;
- bitf = 1;
- xp = bmpsize.x1;
- yp += 2;
- if (yp > bmpsize.y2)
- return;
- }
+ vlc = (vlc << 4) | getBits(data, bitf);
+ }
+ }
+ }
+
+ uint8_t color = vlc & 0x03;
+ int len = vlc >> 2;
+
+ // if len == 0 -> end sequence - fill to end of line
+ len = len ? len : bmpsize.x2 - xp + 1;
+ putPixel(xp, yp, len, color);
+ xp += len;
+
+ if (xp > bmpsize.x2)
+ {
+ // nextLine
+ if (!bitf)
+ data++;
+ bitf = 1;
+ xp = bmpsize.x1;
+ yp += 2;
+ if (yp > bmpsize.y2)
+ return;
+ }
}
}
@@ -286,10 +286,11 @@ void cDxr3SpuDecoder::processSPU(uint32_t pts, uint8_t * buf)
{
setTime(pts);
- if (cDxr3ConfigData::Instance().GetDebug())
- {
- cLog::Instance() << "cDxr3SpuDecoder::processSPU: SPU pushData: pts: " << pts << "\n";
- }
+ if (cDxr3ConfigData::Instance().GetDebug())
+ {
+ cLog::Instance() << "cDxr3SpuDecoder::processSPU: SPU pushData: pts: "
+ << pts << "\n";
+ }
delete spubmp;
spubmp = NULL;
@@ -329,31 +330,32 @@ void cDxr3SpuDecoder::setPalette(uint32_t * pal)
void cDxr3SpuDecoder::setHighlight(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint32_t palette)
{
aDxr3SpuPalDescr pld;
- for (int i = 0; i < 4; i++)
- {
- pld[i].index = 0xf & (palette >> (16 + 4 * i));
- pld[i].trans = 0xf & (palette >> (4 * i));
+ for (int i = 0; i < 4; i++)
+ {
+ pld[i].index = 0xf & (palette >> (16 + 4 * i));
+ pld[i].trans = 0xf & (palette >> (4 * i));
}
bool ne = hlpsize.x1 != sx || hlpsize.y1 != sy ||
- hlpsize.x2 != ex || hlpsize.y2 != ey ||
- pld[0] != hlpDescr[0] || pld[1] != hlpDescr[1] ||
- pld[2] != hlpDescr[2] || pld[3] != hlpDescr[3];
+ hlpsize.x2 != ex || hlpsize.y2 != ey ||
+ pld[0] != hlpDescr[0] || pld[1] != hlpDescr[1] ||
+ pld[2] != hlpDescr[2] || pld[3] != hlpDescr[3];
- if (ne)
+ if (ne)
+ {
+ if (cDxr3ConfigData::Instance().GetDebug())
{
- if (cDxr3ConfigData::Instance().GetDebug())
- {
- cLog::Instance() << "cDxr3SpuDecoder::setHighlight: " << sx << ", " << sy << ", " << ex << ", " << ey << "\n";
- }
+ cLog::Instance() << "cDxr3SpuDecoder::setHighlight: " << sx
+ << ", " << sy << ", " << ex << ", " << ey << "\n";
+ }
- hlpsize.x1 = sx;
- hlpsize.y1 = sy;
- hlpsize.x2 = ex;
- hlpsize.y2 = ey;
- memcpy(hlpDescr, pld, sizeof(aDxr3SpuPalDescr));
- highlight = true;
- clean = false;
+ hlpsize.x1 = sx;
+ hlpsize.y1 = sy;
+ hlpsize.x2 = ex;
+ hlpsize.y2 = ey;
+ memcpy(hlpDescr, pld, sizeof(aDxr3SpuPalDescr));
+ highlight = true;
+ clean = false;
}
}
@@ -372,22 +374,23 @@ void cDxr3SpuDecoder::clearHighlight()
// ==================================
int cDxr3SpuDecoder::ScaleYcoord(int value)
{
- if (scaleMode == eSpuLetterBox)
- {
- int offset = cDevice::PrimaryDevice()->GetVideoSystem() == vsPAL ? 72 : 60;
- return lround((value * 3.0) / 4.0) + offset;
+ if (scaleMode == eSpuLetterBox)
+ {
+ int offset =
+ cDevice::PrimaryDevice()->GetVideoSystem() == vsPAL ? 72 : 60;
+ return lround((value * 3.0) / 4.0) + offset;
}
- return value;
+ return value;
}
// ==================================
int cDxr3SpuDecoder::ScaleYres(int value)
{
if (scaleMode == eSpuLetterBox)
- {
- return lround((value * 3.0) / 4.0);
- }
- return value;
+ {
+ return lround((value * 3.0) / 4.0);
+ }
+ return value;
}
// ==================================
@@ -395,11 +398,11 @@ void cDxr3SpuDecoder::DrawBmp(sDxr3SpuRect & size, cBitmap * bmp)
{
int x2 = size.x2;
while ((x2 - size.x1 + 1) & 0x03)
- x2++;
+ x2++;
tArea Area = { size.x1, size.y1, x2, size.y2, 2 };
osd->SetAreas(&Area, 1);
if (x2 > size.x2)
- osd->DrawRectangle(size.x2 + 1, size.y1, x2, size.y2, clrTransparent);
+ osd->DrawRectangle(size.x2 + 1, size.y1, x2, size.y2, clrTransparent);
osd->DrawBitmap(size.x1, size.y1, *bmp);
delete bmp;
}
@@ -411,9 +414,9 @@ void cDxr3SpuDecoder::Draw()
Hide();
if (!spubmp)
- {
- return;
- }
+ {
+ return;
+ }
cBitmap *fg = NULL;
cBitmap *bg = NULL;
@@ -426,46 +429,46 @@ void cDxr3SpuDecoder::Draw()
hlsize.y2 = ScaleYcoord(hlpsize.y2);
if (highlight)
- {
- fg = spubmp->getBitmap(hlpDescr, palette, hlsize);
- }
+ {
+ fg = spubmp->getBitmap(hlpDescr, palette, hlsize);
+ }
- if (spubmp->getMinSize(palDescr, bgsize))
+ if (spubmp->getMinSize(palDescr, bgsize))
+ {
+ bg = spubmp->getBitmap(palDescr, palette, bgsize);
+ if (scaleMode == eSpuLetterBox)
{
- bg = spubmp->getBitmap(palDescr, palette, bgsize);
- if (scaleMode == eSpuLetterBox)
- {
- // the coordinates have to be modified for letterbox
- int y1 = ScaleYres(bgsize.y1) + bgsize.height();
- bgsize.y2 = y1 + bgsize.height();
- bgsize.y1 = y1;
- }
+ // the coordinates have to be modified for letterbox
+ int y1 = ScaleYres(bgsize.y1) + bgsize.height();
+ bgsize.y2 = y1 + bgsize.height();
+ bgsize.y1 = y1;
+ }
}
- if (bg || fg)
- {
- if (osd == NULL)
- if ((osd = cOsdProvider::NewOsd(0, 0)) == NULL)
- {
- if (cDxr3ConfigData::Instance().GetDebug())
- {
- cLog::Instance() << "cDxr3SpuDecoder::Draw: New OSD faild!\n";
- }
- dsyslog("NewOsd failed\n");
- return;
- }
-
- if (fg)
+ if (bg || fg)
+ {
+ if (osd == NULL)
+ if ((osd = cOsdProvider::NewOsd(0, 0)) == NULL)
+ {
+ if (cDxr3ConfigData::Instance().GetDebug())
{
- DrawBmp(hlsize, fg);
+ cLog::Instance() << "cDxr3SpuDecoder::Draw: New OSD faild!\n";
}
+ dsyslog("NewOsd failed\n");
+ return;
+ }
- if (bg)
- {
- DrawBmp(bgsize, bg);
- }
+ if (fg)
+ {
+ DrawBmp(hlsize, fg);
+ }
+
+ if (bg)
+ {
+ DrawBmp(bgsize, bg);
+ }
- osd->Flush();
+ osd->Flush();
}
clean = true;
@@ -500,157 +503,164 @@ void cDxr3SpuDecoder::Empty()
int cDxr3SpuDecoder::setTime(uint32_t pts)
{
if (!spu)
- {
- return 0;
- }
+ {
+ return 0;
+ }
if (spu && !clean)
+ {
+ Draw();
+ }
+
+ while (DCSQ_offset != prev_DCSQ_offset)
+ {
+ // Display Control Sequences
+ int i = DCSQ_offset;
+ state = spNONE;
+
+ uint32_t exec_time = spupts + spuU32(i) * 1024;
+ if ((pts != 0) && (exec_time > pts))
{
- Draw();
+ return 0;
}
- while (DCSQ_offset != prev_DCSQ_offset)
- {
- // Display Control Sequences
- int i = DCSQ_offset;
- state = spNONE;
+ if (pts != 0)
+ {
+ uint16_t feven = 0;
+ uint16_t fodd = 0;
+
+ i += 2;
- uint32_t exec_time = spupts + spuU32(i) * 1024;
- if ((pts != 0) && (exec_time > pts))
- {
- return 0;
- }
+ prev_DCSQ_offset = DCSQ_offset;
+ DCSQ_offset = spuU32(i);
+ i += 2;
- if (pts != 0)
+ while (spu[i] != CMD_SPU_EOF)
+ {
+ // Command Sequence
+ switch (spu[i])
{
- uint16_t feven = 0;
- uint16_t fodd = 0;
-
- i += 2;
-
- prev_DCSQ_offset = DCSQ_offset;
- DCSQ_offset = spuU32(i);
- i += 2;
-
- while (spu[i] != CMD_SPU_EOF)
- {
- // Command Sequence
- switch (spu[i])
- {
- case CMD_SPU_SHOW:
- // show subpicture
- if (cDxr3ConfigData::Instance().GetDebug())
- {
- cLog::Instance() << "cDxr3SpuDecoder::setTime: show subpicture\n";
- }
- state = spSHOW;
- i++;
- break;
-
- case CMD_SPU_HIDE:
- // hide subpicture
- if (cDxr3ConfigData::Instance().GetDebug())
- {
- cLog::Instance() << "cDxr3SpuDecoder::setTime: hide subpicture\n";
- }
- state = spHIDE;
- i++;
- break;
-
- case CMD_SPU_SET_PALETTE:
- // CLUT
- palDescr[0].index = spu[i + 2] & 0xf;
- palDescr[1].index = spu[i + 2] >> 4;
- palDescr[2].index = spu[i + 1] & 0xf;
- palDescr[3].index = spu[i + 1] >> 4;
- i += 3;
- break;
-
- case CMD_SPU_SET_ALPHA:
- // transparency palette
- palDescr[0].trans = spu[i + 2] & 0xf;
- palDescr[1].trans = spu[i + 2] >> 4;
- palDescr[2].trans = spu[i + 1] & 0xf;
- palDescr[3].trans = spu[i + 1] >> 4;
- i += 3;
- break;
-
- case CMD_SPU_SET_SIZE:
- // image coordinates
- size.x1 = (spu[i + 1] << 4) | (spu[i + 2] >> 4);
- size.x2 = ((spu[i + 2] & 0x0f) << 8) | spu[i + 3];
-
- size.y1 = (spu[i + 4] << 4) | (spu[i + 5] >> 4);
- size.y2 = ((spu[i + 5] & 0x0f) << 8) | spu[i + 6];
-
- if (cDxr3ConfigData::Instance().GetDebug())
- {
- cLog::Instance() << "cDxr3SpuDecoder::setTime: (" << size.x1 << ", " << size.y1 <<") x (" << size.x2 << ", " << size.y2 <<")\n";
- }
- i += 7;
- break;
-
- case CMD_SPU_SET_PXD_OFFSET:
- // image 1 / image 2 offsets
- fodd = spuU32(i + 1);
- feven = spuU32(i + 3);
-
- if (cDxr3ConfigData::Instance().GetDebug())
- {
- cLog::Instance() << "cDxr3SpuDecoder::setTime: odd = " << fodd << " even = " << feven << "\n";
- }
- i += 5;
- break;
+ case CMD_SPU_SHOW:
+ // show subpicture
+ if (cDxr3ConfigData::Instance().GetDebug())
+ {
+ cLog::Instance() << "cDxr3SpuDecoder::setTime: show subpicture\n";
+ }
+ state = spSHOW;
+ i++;
+ break;
- case CMD_SPU_CHG_COLCON:
+ case CMD_SPU_HIDE:
+ // hide subpicture
+ if (cDxr3ConfigData::Instance().GetDebug())
{
- int size = spuU32(i + 1);
- i += 1 + size;
+ cLog::Instance() << "cDxr3SpuDecoder::setTime: hide subpicture\n";
}
+ state = spHIDE;
+ i++;
break;
- case CMD_SPU_MENU:
- if (cDxr3ConfigData::Instance().GetDebug())
- {
- cLog::Instance() << "cDxr3SpuDecoder::setTime: spu menu\n";
- }
- state = spMENU;
-
- i++;
- break;
-
- default:
- esyslog("invalid sequence in control header (%.2x)\n", spu[i]);
- assert(0);
- i++;
- break;
- }
- }
- if (fodd != 0 && feven != 0)
- {
- delete spubmp;
- spubmp = new cDxr3SpuBitmap(size, spu + fodd, spu + feven, spu + feven, spu + cmdOffs());
- }
- }
- else if (!clean)
- {
- state = spSHOW;
- }
+ case CMD_SPU_SET_PALETTE:
+ // CLUT
+ palDescr[0].index = spu[i + 2] & 0xf;
+ palDescr[1].index = spu[i + 2] >> 4;
+ palDescr[2].index = spu[i + 1] & 0xf;
+ palDescr[3].index = spu[i + 1] >> 4;
+ i += 3;
+ break;
- if (state == spSHOW || state == spMENU)
- {
- Draw();
- }
+ case CMD_SPU_SET_ALPHA:
+ // transparency palette
+ palDescr[0].trans = spu[i + 2] & 0xf;
+ palDescr[1].trans = spu[i + 2] >> 4;
+ palDescr[2].trans = spu[i + 1] & 0xf;
+ palDescr[3].trans = spu[i + 1] >> 4;
+ i += 3;
+ break;
+
+ case CMD_SPU_SET_SIZE:
+ // image coordinates
+ size.x1 = (spu[i + 1] << 4) | (spu[i + 2] >> 4);
+ size.x2 = ((spu[i + 2] & 0x0f) << 8) | spu[i + 3];
+
+ size.y1 = (spu[i + 4] << 4) | (spu[i + 5] >> 4);
+ size.y2 = ((spu[i + 5] & 0x0f) << 8) | spu[i + 6];
- if (state == spHIDE)
+ if (cDxr3ConfigData::Instance().GetDebug())
+ {
+ cLog::Instance() << "cDxr3SpuDecoder::setTime: ("
+ << size.x1 << ", " << size.y1
+ << ") x (" << size.x2 << ", "
+ << size.y2 <<")\n";
+ }
+ i += 7;
+ break;
+
+ case CMD_SPU_SET_PXD_OFFSET:
+ // image 1 / image 2 offsets
+ fodd = spuU32(i + 1);
+ feven = spuU32(i + 3);
+
+ if (cDxr3ConfigData::Instance().GetDebug())
+ {
+ cLog::Instance() << "cDxr3SpuDecoder::setTime: odd = "
+ << fodd << " even = " << feven
+ << "\n";
+ }
+ i += 5;
+ break;
+
+ case CMD_SPU_CHG_COLCON:
{
- Hide();
+ int size = spuU32(i + 1);
+ i += 1 + size;
}
+ break;
- if (pts == 0)
- {
- return 0;
+ case CMD_SPU_MENU:
+ if (cDxr3ConfigData::Instance().GetDebug())
+ {
+ cLog::Instance() << "cDxr3SpuDecoder::setTime: spu menu\n";
+ }
+ state = spMENU;
+
+ i++;
+ break;
+
+ default:
+ esyslog("invalid sequence in control header (%.2x)\n",
+ spu[i]);
+ assert(0);
+ i++;
+ break;
}
+ }
+ if (fodd != 0 && feven != 0)
+ {
+ delete spubmp;
+ spubmp = new cDxr3SpuBitmap(size, spu + fodd, spu + feven,
+ spu + feven, spu + cmdOffs());
+ }
+ }
+ else if (!clean)
+ {
+ state = spSHOW;
+ }
+
+ if (state == spSHOW || state == spMENU)
+ {
+ Draw();
+ }
+
+ if (state == spHIDE)
+ {
+ Hide();
+ }
+
+ if (pts == 0)
+ {
+ return 0;
+ }
}
return 1;