示例#1
0
    const AnimData* AnimResManager::loadAnimData(const char *aniFileName)
    {
        assert(aniFileName != NULL && *aniFileName != 0);
        vector< Pair >::iterator node = find(m_AnimData.begin(), m_AnimData.end(), aniFileName);
        if (node != m_AnimData.end())
        {
            return node->pAnimData;
        }

        char *s2 = strdup(aniFileName);
        if (!s2)
            return 0;

        vector<const char *> pathTokens;
        for (const char *pathToken = strtok(s2, "/\\"); pathToken; pathToken = strtok(0, "/\\"))
        {
            pathTokens.push_back(pathToken);
        }
        const char *cdot = strrchr(pathTokens.back(), '.');
        bool bXmlFile = false;
        if (cdot && 0 == strcmp(cdot, ".xml"))
            bXmlFile = true;
        free(s2);

        if (bXmlFile)
        {
            AnimData *pAnimData = new AnimData;
            if (pAnimData)
            {
                if (!pAnimData->loadFromXml(aniFileName))
                {
                    delete pAnimData;
                    pAnimData = 0;
                }
            }
            return pAnimData;
        }
        else
        {
            iByteStream *byteStream = iSystem::GetInstance()->loadStream(aniFileName);
            if (!byteStream)
                return 0;

            AnimData *pAnimData = new AnimData;
            if (pAnimData)
            {
                if (!pAnimData->loadFromByteStream(byteStream))
                {
                    delete pAnimData;
                    pAnimData = 0;
                }
            }

            iSystem::GetInstance()->release(byteStream);
            return pAnimData;
        }
    }
Animation::Animation(const AnimData& anim_data)
    : anim_data_(anim_data),
    timeline_(0),
    fps_(anim_data.fps()),
    total_frames_(anim_data_.total_frames()),
    current_frame_(0),
    playing_(false),
    hidden_(false),
    looping_(true)
{
    sprite_.SetImage(anim_data.texture());
    update_sprite_to_frame();
}
示例#3
0
/**
 * Draw one overlay
 * @param it Overlay info
 */
void FWRenderer::renderOverlay(const Common::List<overlay>::iterator &it) {
	int idx, len, width;
	ObjectStruct *obj;
	AnimData *sprite;
	byte *mask;

	switch (it->type) {
	// color sprite
	case 0:
		if (g_cine->_objectTable[it->objIdx].frame < 0) {
			return;
		}
		sprite = &g_cine->_animDataTable[g_cine->_objectTable[it->objIdx].frame];
		len = sprite->_realWidth * sprite->_height;
		mask = new byte[len];
		memcpy(mask, sprite->mask(), len);
		remaskSprite(mask, it);
		drawMaskedSprite(g_cine->_objectTable[it->objIdx], mask);
		delete[] mask;
		break;

	// game message
	case 2:
		if (it->objIdx >= g_cine->_messageTable.size()) {
			return;
		}

		_messageLen += g_cine->_messageTable[it->objIdx].size();
		drawMessage(g_cine->_messageTable[it->objIdx].c_str(), it->x, it->y, it->width, it->color);
		waitForPlayerClick = 1;
		break;

	// action failure message
	case 3:
		idx = it->objIdx * 4 + g_cine->_rnd.getRandomNumber(3);
		len = strlen(failureMessages[idx]);
		_messageLen += len;
		width = 6 * len + 20;
		width = width > 300 ? 300 : width;

		drawMessage(failureMessages[idx], (320 - width) / 2, 80, width, 4);
		waitForPlayerClick = 1;
		break;

	// bitmap
	case 4:
		assert(it->objIdx < NUM_MAX_OBJECT);
		obj = &g_cine->_objectTable[it->objIdx];

		if (obj->frame < 0) {
			return;
		}

		if (!g_cine->_animDataTable[obj->frame].data()) {
			return;
		}

		fillSprite(*obj);
		break;
	}
}
示例#4
0
/**
 * Draw one overlay
 * @param it Overlay info
 * @todo Add handling of type 22 overlays
 */
void OSRenderer::renderOverlay(const Common::List<overlay>::iterator &it) {
	int len, idx, width, height;
	ObjectStruct *obj;
	AnimData *sprite;
	byte *mask;
	byte color;

	switch (it->type) {
	// color sprite
	case 0:
		if (g_cine->_objectTable[it->objIdx].frame < 0) {
			break;
		}
		sprite = &g_cine->_animDataTable[g_cine->_objectTable[it->objIdx].frame];
		len = sprite->_realWidth * sprite->_height;
		mask = new byte[len];
		generateMask(sprite->data(), mask, len, g_cine->_objectTable[it->objIdx].part);
		remaskSprite(mask, it);
		drawMaskedSprite(g_cine->_objectTable[it->objIdx], mask);
		delete[] mask;
		break;

	// game message
	case 2:
		if (it->objIdx >= g_cine->_messageTable.size()) {
			return;
		}

		_messageLen += g_cine->_messageTable[it->objIdx].size();
		drawMessage(g_cine->_messageTable[it->objIdx].c_str(), it->x, it->y, it->width, it->color);
		if (it->color >= 0) { // This test isn't in Future Wars's implementation
			waitForPlayerClick = 1;
		}
		break;

	// action failure message
	case 3:
		idx = it->objIdx * 4 + g_cine->_rnd.getRandomNumber(3);
		len = strlen(failureMessages[idx]);
		_messageLen += len;
		width = 6 * len + 20;
		width = width > 300 ? 300 : width;

		// The used color here differs from Future Wars
		drawMessage(failureMessages[idx], (320 - width) / 2, 80, width, _messageBg);
		waitForPlayerClick = 1;
		break;

	// bitmap
	case 4:
		if (g_cine->_objectTable[it->objIdx].frame >= 0) {
			FWRenderer::renderOverlay(it);
		}
		break;

	// masked background
	case 20:
		assert(it->objIdx < NUM_MAX_OBJECT);
		var5 = it->x; // A global variable updated here!
		obj = &g_cine->_objectTable[it->objIdx];
		sprite = &g_cine->_animDataTable[obj->frame];

		if (obj->frame < 0 || it->x < 0 || it->x > 8 || !_bgTable[it->x].bg || sprite->_bpp != 1) {
			break;
		}

		maskBgOverlay(_bgTable[it->x].bg, sprite->data(), sprite->_realWidth, sprite->_height, _backBuffer, obj->x, obj->y);
		break;

	// FIXME: Implement correct drawing of type 21 overlays.
	// Type 21 overlays aren't just filled rectangles, I found their drawing routine
	// from Operation Stealth's drawSprite routine. So they're likely some kind of sprites
	// and it's just a coincidence that the oxygen meter during the first arcade sequence
	// works even somehow currently. I tried the original under DOSBox and the oxygen gauge
	// is a long red bar that gets shorter as the air runs out.
	case 21:
	// A filled rectangle:
	case 22:
		// TODO: Check it this implementation really works correctly (Some things might be wrong, needs testing).
		assert(it->objIdx < NUM_MAX_OBJECT);
		obj = &g_cine->_objectTable[it->objIdx];
		color = obj->part & 0x0F;
		width = obj->frame;
		height = obj->costume;
		drawPlainBox(obj->x, obj->y, width, height, color);
		debug(5, "renderOverlay: type=%d, x=%d, y=%d, width=%d, height=%d, color=%d",
			it->type, obj->x, obj->y, width, height, color);
		break;

	// something else
	default:
		FWRenderer::renderOverlay(it);
		break;
	}
}
示例#5
0
文件: gfx.cpp 项目: andrew889/scummvm
/**
 * Draw one overlay
 * @param it Overlay info
 * @todo Add handling of type 22 overlays
 */
void OSRenderer::renderOverlay(const Common::List<overlay>::iterator &it) {
	int len, idx, width, height;
	ObjectStruct *obj;
	AnimData *sprite;
	byte color;

	switch (it->type) {
	// color sprite
	case 0:
		if (g_cine->_objectTable[it->objIdx].frame < 0) {
			break;
		}
		sprite = &g_cine->_animDataTable[g_cine->_objectTable[it->objIdx].frame];
		drawSprite(&(*it), sprite->data(), sprite->_realWidth, sprite->_height, _backBuffer, g_cine->_objectTable[it->objIdx].x, g_cine->_objectTable[it->objIdx].y, g_cine->_objectTable[it->objIdx].part, sprite->_bpp);
		break;

	// game message
	case 2:
		if (it->objIdx >= g_cine->_messageTable.size()) {
			return;
		}

		_messageLen += g_cine->_messageTable[it->objIdx].size();
		drawMessage(g_cine->_messageTable[it->objIdx].c_str(), it->x, it->y, it->width, it->color);
		if (it->color >= 0) { // This test isn't in Future Wars's implementation
			waitForPlayerClick = 1;
		}
		break;

	// action failure message
	case 3:
		idx = it->objIdx * 4 + g_cine->_rnd.getRandomNumber(3);
		len = strlen(failureMessages[idx]);
		_messageLen += len;
		width = 6 * len + 20;
		width = width > 300 ? 300 : width;

		// The used color here differs from Future Wars
		drawMessage(failureMessages[idx], (320 - width) / 2, 80, width, _messageBg);
		waitForPlayerClick = 1;
		break;

	// bitmap
	case 4:
		if (g_cine->_objectTable[it->objIdx].frame >= 0) {
			FWRenderer::renderOverlay(it);
		}
		break;

	// masked background
	case 20:
		assert(it->objIdx < NUM_MAX_OBJECT);
		var5 = it->x; // A global variable updated here!
		obj = &g_cine->_objectTable[it->objIdx];
		sprite = &g_cine->_animDataTable[obj->frame];

		if (obj->frame < 0 || it->x < 0 || it->x > 8 || !_bgTable[it->x].bg || sprite->_bpp != 1) {
			break;
		}

		maskBgOverlay(_bgTable[it->x].bg, sprite->data(), sprite->_realWidth, sprite->_height, _backBuffer, obj->x, obj->y);
		break;

	case 22:
		// TODO: Check it this implementation really works correctly (Some things might be wrong, needs testing).
		assert(it->objIdx < NUM_MAX_OBJECT);
		obj = &g_cine->_objectTable[it->objIdx];
		color = obj->part & 0x0F;
		width = obj->frame;
		height = obj->costume;
		drawPlainBox(obj->x, obj->y, width, height, color);
		debug(5, "renderOverlay: type=%d, x=%d, y=%d, width=%d, height=%d, color=%d",
			  it->type, obj->x, obj->y, width, height, color);
		break;

	// something else
	default:
		FWRenderer::renderOverlay(it);
		break;
	}
}