示例#1
0
bool FlifHandler::read( QImage *img_pointer ) {
    //Read data on first frame
    if( !loaded() ) {
        auto data = device()->readAll();
        if( !decoder.decodeMemory( data.constData(), data.size() ) )
            return false;
    }

    frame++;
    if( imageCount() <= frame )
        return false;

    auto img = decoder.getImage( frame );
    QImage out( img.getWidth(), img.getHeight(), QImage::Format_ARGB32 );

    auto buffer = std::make_unique<uint8_t[]>( out.width() * 4 );
    for( int iy=0; iy<out.height(); iy++ ) {
        img.readRowRgba8( iy, buffer.get(), out.width() * 4 );
        auto line = (QRgb*)out.scanLine( iy );

        for( int ix=0; ix<out.width(); ix++ )
            line[ix] = qRgba( buffer[ix*4+0], buffer[ix*4+1], buffer[ix*4+2], buffer[ix*4+3] );
    }

    lastImageDelay = img.getFrameDelay();
    *img_pointer = out;
    return true;
}
示例#2
0
uint32 VideoDecoder::getFrameWaitTime() {
	int32 waitTime = (getFrameDelay() + getAudioLag()) / 100;

	if (waitTime < 0)
		return 0;

	return waitTime;
}
示例#3
0
void Goblin::senseDistance(int wallX, int level){
	// +50 lets it overlap castle a bit, for some depth
	float distance = spriteData.x + 50 - wallX;
	float maxDistance = GAME_WIDTH - wallX + 50;

	// change speed based on distance from wall and framedelay
	// if at tower do not execute large if else if
	if(distance > 0){
		if(distance/maxDistance < .1) {
			velocity.x = -goblinNS::SPEED - 45;
			setFrameDelay(goblinNS::GOBLIN_ANIMATION_DELAY_9);
		}
		else if(distance/maxDistance < .2) {
			velocity.x = -goblinNS::SPEED - 40;
			setFrameDelay(goblinNS::GOBLIN_ANIMATION_DELAY_8);
		}
		else if(distance/maxDistance < .3) {
			velocity.x = -goblinNS::SPEED - 35;
			setFrameDelay(goblinNS::GOBLIN_ANIMATION_DELAY_7);
		}
		else if(distance/maxDistance < .4) {
			velocity.x = -goblinNS::SPEED - 30;
			setFrameDelay(goblinNS::GOBLIN_ANIMATION_DELAY_6);
		}
		else if(distance/maxDistance < .5){
			velocity.x = -goblinNS::SPEED - 25;
			setFrameDelay(goblinNS::GOBLIN_ANIMATION_DELAY_5);
		}
		else if(distance/maxDistance < .6) {
			velocity.x = -goblinNS::SPEED - 20;
			setFrameDelay(goblinNS::GOBLIN_ANIMATION_DELAY_4);
		}
		else if(distance/maxDistance < .7) {
			velocity.x = -goblinNS::SPEED - 15;
			setFrameDelay(goblinNS::GOBLIN_ANIMATION_DELAY_3);
		}
		else if(distance/maxDistance < .8) {
			velocity.x = -goblinNS::SPEED - 10;
			setFrameDelay(goblinNS::GOBLIN_ANIMATION_DELAY_2);
		}
		else {
			velocity.x = -goblinNS::SPEED - 5;
			setFrameDelay(goblinNS::GOBLIN_ANIMATION_DELAY_1);
		}
	}
	else {
		velocity.x = 0;
		setFrames(goblinNS::ATTACK_START_FRAME, goblinNS::ATTACK_END_FRAME);		
		setFrameDelay(goblinNS::GOBLIN_ANIMATION_DELAY);
	}
	velocity.x *= level * 0.85;
	//velocity.x *= .15;
	setFrameDelay(getFrameDelay() / level);
}
示例#4
0
 // Loads the animation using data from a JSON structure
 void Animation::deserialize(Json::Value &configData)
 {
     std::string frame       = DataManager::getString(configData, "frame",   getFrameName());
     std::string extension   = DataManager::getString(configData, "ext",     getFrameExtension());
     int count               = DataManager::getInt   (configData, "frames",  getFrameCount());
     float delay             = DataManager::getFloat (configData, "delay",   getFrameDelay());
     init(frame, extension, count, delay);
     
     setName             (DataManager::getString (configData, "name",    getName()));
     setLooping          (DataManager::getBool   (configData, "loop",    isLooping()));
     allowEventGeneration(DataManager::getBool   (configData, "alert",   isGeneratingEvents()));
 }
示例#5
0
void cMobile::draw(int cellx, int celly, int leftClip, int topClip, int rightClip, int bottomClip) {
	//return; // Don't draw yet

	// See if the current action expired
	if (currentActionEnd_ != 0 && currentActionEnd_ < Utilities::getTicks()) {
		freeSequence(); // Free current surface
		currentActionEnd_ = 0; // Reset end time
		currentAction_ = getIdleAction();
	}

	// Refresh the sequence
	if (!sequence_) {
		refreshSequence();
	}

	// Modify cellx/celly based on the smooth move settings
	// Smooth move handling. 
	if (smoothMoveEnd != 0) {
		int moveProgress = smoothMoveTime - (smoothMoveEnd - Utilities::getTicks());
		if (moveProgress < 0 || moveProgress >= (int)smoothMoveTime) {
			smoothMoveEnd = 0;
		} else {
			if (moveProgress <= 0) {
				cellx += drawxoffset;
				celly += drawyoffset;
				frame = 0;
			} else {
				float factor = 1.0f - (float)moveProgress / (float)smoothMoveTime;
				cellx += (int)(factor * (float)drawxoffset);
				celly += (int)(factor * (float)drawyoffset);
				if (sequence_) {
					frame = (int)(sequence_->frameCount() * factor);
				}
			}
		}
	}

	// Draw
	if (sequence_) {
		// Skip to next frame
		if (smoothMoveEnd == 0 && nextFrame < Utilities::getTicks()) {
			if (++frame >= sequence_->frameCount()) {
				frame = 0;
			}
			nextFrame = Utilities::getTicks() + getFrameDelay();
		}
		
		// The anims facing right are generated by flipping the ones facing left
		bool flip = (direction_ > 0 && direction_ < 4);
		sequence_->draw(frame, cellx, celly, flip);
	}
}
示例#6
0
void cMobile::refreshSequence() {
	if (sequence_) {
		sequence_->decref();
	}

	sequence_ = Animations->readSequence(body_, currentAction_, direction_, hue_, partialHue_);	
	
	// Try to maintain the flow of the animation
	if (sequence_ && frame >= sequence_->frameCount()) {
		frame = 0;
		nextFrame = Utilities::getTicks() + getFrameDelay();
	}
}
示例#7
0
int32 VideoDecoder::getAudioLag() {
	if (!_fileStream)
		return 0;

	/* No audio.
	   Calculate the lag by how much time has gone by since the first frame
	   and how much time *should* have passed.
	*/
	int32 audioTime = (g_system->getMillis() - _videoInfo.startTime) * 100;
	int32 videoTime = _videoInfo.currentFrame * getFrameDelay();

	return videoTime - audioTime;
}
示例#8
0
int32 DXADecoderWithSound::getAudioLag() {
    if (!_fileStream)
        return 0;

    if (!_mixer->isSoundHandleActive(*_bgSoundHandle))
        return 0;

    int32 frameDelay = getFrameDelay();
    int32 videoTime = _videoInfo.currentFrame * frameDelay;
    int32 audioTime;

    audioTime = (((int32) _mixer->getSoundElapsedTime(*_bgSoundHandle)) * 100);

    return videoTime - audioTime;
}
示例#9
0
void cMobile::draw(int cellx, int celly, int leftClip, int topClip, int rightClip, int bottomClip) {
	// Save the original cellx, celly for the greyed out stuff
	int orgCellX = cellx;
	int orgCellY = celly;
	static int cellXOffset = 0;
	static int cellYOffset = 0;

	if (Config->gameHideMobiles()) {
		return;
	}

	// Test for smoother player movement
	if (this == Player) {
		cellx = WorldView->x() + WorldView->width() / 2;
		celly = WorldView->y() + WorldView->height() / 2;
	}

	cellx += cellXOffset;
	celly += cellYOffset;

	// See if the current action expired
	if (currentActionEnd_ != 0 && currentActionEnd_ < Utilities::getTicks()) {
		// Don't cancel the movement action while we're still moving -or- have movement requests left
		if (this != Player || ((!WorldView->isMoving() || WorldView->isMovementBlocked()) && (!UoSocket || UoSocket->sequenceQueueLength() == 0))) {
			freeSequence(); // Free current surface
			currentActionEnd_ = 0; // Reset end time
			currentAction_ = getIdleAction();
		}
	}

	// Refresh the sequence
	if (!sequence_) {
		refreshSequence();
	}

	float alpha = 1.0f;

	// Modify cellx/celly based on the smooth move settings
	// Smooth move handling.
	if (smoothMoveEnd != 0) {
		int moveProgress = smoothMoveTime - (smoothMoveEnd - Utilities::getTicks());
		if (moveProgress < 0 || moveProgress >= (int)smoothMoveTime) {
			smoothMoveEnd = 0;
			World->removeEntity(this);
			World->addEntity(this);
		} else if (this != Player) {
			if (moveProgress <= 0) {
				cellx += drawxoffset;
				celly += drawyoffset;
			} else {
				float factor = 1.0f - (float)moveProgress / (float)smoothMoveTime;
				cellx += (int)(factor * (float)drawxoffset);
				celly += (int)(factor * (float)drawyoffset);
			}
		}
	}

	static bool inGreyDraw = false;
	static bool inBlurDraw = false;

	if (isHidden()) {
		glPushAttrib(GL_ENABLE_BIT);

		glEnable(GL_ALPHA_TEST); // Make sure that transparent pixels wont touch our stencil buffer
		glAlphaFunc(GL_GREATER, 0.0f);

		glEnable(GL_STENCIL_TEST); // Enable per-pixel stencil testing
		glStencilFunc(GL_EQUAL, 1, 1); // Draw if stencil buffer is not zero
		glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO);

		if (!inGreyDraw) {
			glClearStencil(1);
			glClear(GL_STENCIL_BUFFER_BIT);
		}

		static uint nextPeak = 0;
		static uint lastPeak = 0;
		static bool peakDirection = false;

		uint time = Utilities::getTicks();

		if (time >= nextPeak) {
			lastPeak = Utilities::getTicks();
			nextPeak = lastPeak + 1500 + Random->randInt(1000);				
			peakDirection = !peakDirection;
		}

		alpha = (nextPeak - Utilities::getTicks()) / (float)(nextPeak - lastPeak);
		if (peakDirection) {
			alpha = 1.0f - alpha;
		}

		if (inGreyDraw) {			
			if (inBlurDraw) {
				alpha *= 0.5f;
			} else {
				alpha *= 0.8f;
			}
		} else {
			GLWidget->enableGrayShader();
			alpha = 0.8 * (1.0f - alpha); // Invert alpha value
		}
	}

	// Draw
	if (sequence_) {
		// Only advance to the next frame if we're not beyond the end of this action
		if (currentActionEnd_ != 0 && currentActionEnd_ >= Utilities::getTicks()) {
			// Skip to next frame
			if (nextFrame < Utilities::getTicks()) {
				if (++frame >= sequence_->frameCount()) {
					frame = 0;
				}
				nextFrame = Utilities::getTicks() + getFrameDelay();
			}
		}

		// The anims facing right are generated by flipping the ones facing left
		bool flip = (direction_ >= 0 && direction_ < 4);

		// Mounts come always first
		if (!isHidden()) {
			if ((bodyType() == HUMAN || bodyType() == EQUIPMENT) && equipment[LAYER_MOUNT] && equipmentSequences[LAYER_MOUNT]) {
				// Only advance to the next frame if we're not beyond the end of this action
				if (currentActionEnd_ != 0 && currentActionEnd_ >= Utilities::getTicks()) {
					// Skip to next frame
					if (nextMountFrame < Utilities::getTicks()) {
						if (++mountFrame >= equipmentSequences[LAYER_MOUNT]->frameCount()) {
							mountFrame = 0;
						}
						nextMountFrame = Utilities::getTicks() + getMountFrameDelay();
					}
				}
				
				mountFrame = frame; // Until something better is found
				equipmentSequences[LAYER_MOUNT]->draw(mountFrame, cellx, celly, flip, alpha);            
			}

			sequence_->draw(frame, cellx, celly, flip, alpha);
		}

		// Draw the equipment
		if (bodyType() == HUMAN || bodyType() == EQUIPMENT) {
			// Reverse the draw order if hidden
			if (isHidden()) {
				uint count = 0;
				const int *order = drawOrder[direction_ % 8];
				while (order[count] != -1) {
					count++;
				}

				for (int i = count - 1; i >= 0; --i) {
					enLayer layer = (enLayer)order[i];

					if (layer < LAYER_VISIBLECOUNT && equipmentSequences[layer]) {
						// Oh great OSI... Another exception from the rule *sigh*
						// Don't draw Hair if we're wearing a gm robe
						if (layer != LAYER_HAIR || !equipmentSequences[LAYER_OUTERTORSO] || equipmentSequences[LAYER_OUTERTORSO]->body() != 0x3db) {					
							equipmentSequences[layer]->draw(frame, cellx, celly, flip, alpha);
						}
					}
				}
			} else {
				const int *order = drawOrder[direction_ % 8];
				while (*order != -1) {
					enLayer layer = (enLayer)*order;
		
					if (layer < LAYER_VISIBLECOUNT && equipmentSequences[layer]) {
						// Oh great OSI... Another exception from the rule *sigh*
						// Don't draw Hair if we're wearing a gm robe
						if (layer != LAYER_HAIR || !equipmentSequences[LAYER_OUTERTORSO] || equipmentSequences[LAYER_OUTERTORSO]->body() != 0x3db) {					
							equipmentSequences[layer]->draw(frame, cellx, celly, flip, alpha);
						}				
					}
		
					++order; // Next layer
				}
			}
		}

		// If we're hidden, mount+body come last
		if (isHidden()) {
			sequence_->draw(frame, cellx, celly, flip, alpha);

			if ((bodyType() == HUMAN || bodyType() == EQUIPMENT) && equipment[LAYER_MOUNT] && equipmentSequences[LAYER_MOUNT]) {
				// Only advance to the next frame if we're not beyond the end of this action
				if (currentActionEnd_ != 0 && currentActionEnd_ >= Utilities::getTicks()) {
					// Skip to next frame
					if (nextMountFrame < Utilities::getTicks()) {
						if (++mountFrame >= equipmentSequences[LAYER_MOUNT]->frameCount()) {
							mountFrame = 0;
						}
						nextMountFrame = Utilities::getTicks() + getMountFrameDelay();
					}
				}
				
				mountFrame = frame; // Until something better is found
				equipmentSequences[LAYER_MOUNT]->draw(mountFrame, cellx, celly, flip, alpha);            
			}
		}
	}

	if (isHidden()) {
		glPopAttrib();
		if (!inGreyDraw) {
			GLWidget->disableGrayShader();
		}
	}

	drawx_ = cellx;
	drawy_ = celly;

	if (isHidden() && !inGreyDraw) {
		glClearStencil(1);
		glClear(GL_STENCIL_BUFFER_BIT);

		inGreyDraw = true;	
		inBlurDraw = true;
		cellXOffset = 1;
		draw(orgCellX, orgCellY, leftClip, topClip, rightClip, bottomClip);
		cellXOffset = -1;
		draw(orgCellX, orgCellY, leftClip, topClip, rightClip, bottomClip);
		cellXOffset = 0;
		cellYOffset = 1;
		draw(orgCellX, orgCellY, leftClip, topClip, rightClip, bottomClip);
		cellYOffset = -1;
		draw(orgCellX, orgCellY, leftClip, topClip, rightClip, bottomClip);
		cellYOffset = 0;
		inBlurDraw = false;
		draw(orgCellX, orgCellY, leftClip, topClip, rightClip, bottomClip);
		inGreyDraw = false;
	}
}