예제 #1
0
파일: anims.cpp 프로젝트: AReim1982/scummvm
void Router::setSpriteShading(byte *ob_graph, uint32 type) {
	ObjectGraphic obGraph(ob_graph);

	// Remove the previous shading, but don't affect the status lower-word.
	// Note that mega frames may still be shaded automatically, even when
	// not sent 'RDSPR_SHADOW'.
	obGraph.setType((obGraph.getType() & 0x0000ffff) | type);
}
예제 #2
0
void Screen::registerFrame(byte *ob_mouse, byte *ob_graph, byte *ob_mega) {
	ObjectGraphic obGraph(ob_graph);

	// check low word for sprite type
	switch (obGraph.getType() & 0x0000ffff) {
	case BGP0_SPRITE:
		assert(_curBgp0 < MAX_bgp0_sprites);
		registerFrame(ob_mouse, ob_graph, ob_mega, &_bgp0List[_curBgp0]);
		_curBgp0++;
		break;
	case BGP1_SPRITE:
		assert(_curBgp1 < MAX_bgp1_sprites);
		registerFrame(ob_mouse, ob_graph, ob_mega, &_bgp1List[_curBgp1]);
		_curBgp1++;
		break;
	case BACK_SPRITE:
		assert(_curBack < MAX_back_sprites);
		registerFrame(ob_mouse, ob_graph, ob_mega, &_backList[_curBack]);
		_curBack++;
		break;
	case SORT_SPRITE:
		assert(_curSort < MAX_sort_sprites);
		_sortOrder[_curSort] = _curSort;
		registerFrame(ob_mouse, ob_graph, ob_mega, &_sortList[_curSort]);
		_curSort++;
		break;
	case FORE_SPRITE:
		assert(_curFore < MAX_fore_sprites);
		registerFrame(ob_mouse, ob_graph, ob_mega, &_foreList[_curFore]);
		_curFore++;
		break;
	case FGP0_SPRITE:
		assert(_curFgp0 < MAX_fgp0_sprites);
		registerFrame(ob_mouse, ob_graph, ob_mega, &_fgp0List[_curFgp0]);
		_curFgp0++;
		break;
	case FGP1_SPRITE:
		assert(_curFgp1 < MAX_fgp1_sprites);
		registerFrame(ob_mouse, ob_graph, ob_mega, &_fgp1List[_curFgp1]);
		_curFgp1++;
		break;
	default:
		// NO_SPRITE no registering!
		break;
	}
}
예제 #3
0
void Router::standAt(byte *ob_graph, byte *ob_mega, int32 x, int32 y, int32 dir) {
	assert(dir >= 0 && dir <= 7);

	ObjectGraphic obGraph(ob_graph);
	ObjectMega obMega(ob_mega);

	// Set up the stand frame & set the mega's new direction

	obMega.setFeetX(x);
	obMega.setFeetY(y);
	obMega.setCurDir(dir);

	// Mega-set animation file
	obGraph.setAnimResource(obMega.getMegasetRes());

	// Dir + first stand frame (always frame 96)
	obGraph.setAnimPc(dir + 96);
}
예제 #4
0
void Screen::registerFrame(byte *ob_mouse, byte *ob_graph, byte *ob_mega, BuildUnit *build_unit) {
	ObjectGraphic obGraph(ob_graph);
	ObjectMega obMega(ob_mega);

	assert(obGraph.getAnimResource());

	byte *file = _vm->_resman->openResource(obGraph.getAnimResource());

	AnimHeader anim_head;
	CdtEntry cdt_entry;
	FrameHeader frame_head;

	anim_head.read(_vm->fetchAnimHeader(file));
	cdt_entry.read(_vm->fetchCdtEntry(file, obGraph.getAnimPc()));
	frame_head.read(_vm->fetchFrameHeader(file, obGraph.getAnimPc()));

	// update player graphic details for on-screen debug info
	if (_vm->_logic->readVar(ID) == CUR_PLAYER_ID) {
		_vm->_debugger->_graphType = obGraph.getType();
		_vm->_debugger->_graphAnimRes = obGraph.getAnimResource();
		// counting 1st frame as 'frame 1'
		_vm->_debugger->_graphAnimPc = obGraph.getAnimPc() + 1;
		_vm->_debugger->_graphNoFrames = anim_head.noAnimFrames;
	}

	// fill in the BuildUnit structure for this frame

	build_unit->anim_resource = obGraph.getAnimResource();
	build_unit->anim_pc = obGraph.getAnimPc();
	build_unit->layer_number = 0;

	// Affected by shading mask?
	if (obGraph.getType() & SHADED_SPRITE)
		build_unit->shadingFlag = true;
	else
		build_unit->shadingFlag = false;

	// Check if this frame has offsets ie. this is a scalable mega frame

	int scale = 0;

	if (cdt_entry.frameType & FRAME_OFFSET) {
		scale = obMega.calcScale();

		// calc final render coordinates (top-left of sprite), based
		// on feet coords & scaled offsets

		// add scaled offsets to feet coords
		build_unit->x = obMega.getFeetX() + (cdt_entry.x * scale) / 256;
		build_unit->y = obMega.getFeetY() + (cdt_entry.y * scale) / 256;

		// Work out new width and height. Always divide by 256 after
		// everything else, to maintain accurary
		build_unit->scaled_width = ((scale * frame_head.width) / 256);
		build_unit->scaled_height = ((scale * frame_head.height) / 256);
	} else {
		// It's a non-scaling anim. Get render coords for sprite, from cdt
		build_unit->x = cdt_entry.x;
		build_unit->y = cdt_entry.y;

		// Get width and height
		build_unit->scaled_width = frame_head.width;
		build_unit->scaled_height = frame_head.height;
	}

	// either 0 or required scale, depending on whether 'scale' computed
	build_unit->scale = scale;

	// calc the bottom y-coord for sorting purposes
	build_unit->sort_y = build_unit->y + build_unit->scaled_height - 1;

	if (ob_mouse) {
		// passed a mouse structure, so add to the _mouseList
		_vm->_mouse->registerMouse(ob_mouse, build_unit);

	}

	_vm->_resman->closeResource(obGraph.getAnimResource());
}
예제 #5
0
int Router::doWalk(byte *ob_logic, byte *ob_graph, byte *ob_mega, byte *ob_walkdata, int16 target_x, int16 target_y, uint8 target_dir) {
	ObjectLogic obLogic(ob_logic);
	ObjectGraphic obGraph(ob_graph);
	ObjectMega obMega(ob_mega);

	// If this is the start of the walk, calculate the route.

	if (obLogic.getLooping() == 0) {
		// If we're already there, don't even bother allocating
		// memory and calling the router, just quit back & continue
		// the script! This avoids an embarassing mega stand frame
		// appearing for one cycle when we're already in position for
		// an anim eg. repeatedly clicking on same object to repeat
		// an anim - no mega frame will appear in between runs of the
		// anim.

		if (obMega.getFeetX() == target_x && obMega.getFeetY() == target_y && obMega.getCurDir() == target_dir) {
			_vm->_logic->writeVar(RESULT, 0);
			return IR_CONT;
		}

		assert(target_dir <= 8);

		obMega.setWalkPc(0);

		// Set up mem for _walkData in route_slots[] & set mega's
		// 'route_slot_id' accordingly
		allocateRouteMem();

		int32 route = routeFinder(ob_mega, ob_walkdata, target_x, target_y, target_dir);

		// 0 = can't make route to target
		// 1 = created route
		// 2 = zero route but may need to turn

		if (route != 1 && route != 2) {
			freeRouteMem();
			_vm->_logic->writeVar(RESULT, 1);
			return IR_CONT;
		}

		// Walk is about to start

		obMega.setIsWalking(1);
		obLogic.setLooping(1);
		obGraph.setAnimResource(obMega.getMegasetRes());
	} else if (_vm->_logic->readVar(EXIT_FADING) && _vm->_screen->getFadeStatus() == RDFADE_BLACK) {
		// Double clicked an exit, and the screen has faded down to
		// black. Ok, that's it. Back to script and change screen.

		// We have to clear te EXIT_CLICK_ID variable in case there's a
		// walk instruction on the new screen, or it'd be cut short.

		freeRouteMem();

		obLogic.setLooping(0);
		obMega.setIsWalking(0);
		_vm->_logic->writeVar(EXIT_CLICK_ID, 0);
		_vm->_logic->writeVar(RESULT, 0);

		return IR_CONT;
	}

	// Get pointer to walkanim & current frame position

	WalkData *walkAnim = getRouteMem();
	int32 walk_pc = obMega.getWalkPc();

	// If stopping the walk early, overwrite the next step with a
	// slow-out, then finish

	if (_vm->_logic->checkEventWaiting() && walkAnim[walk_pc].step == 0 && walkAnim[walk_pc + 1].step == 1) {
		// At the beginning of a step
		earlySlowOut(ob_mega, ob_walkdata);
	}

	// Get new frame of walk

	obGraph.setAnimPc(walkAnim[walk_pc].frame);
	obMega.setCurDir(walkAnim[walk_pc].dir);
	obMega.setFeetX(walkAnim[walk_pc].x);
	obMega.setFeetY(walkAnim[walk_pc].y);

	// Is the NEXT frame is the end-marker (512) of the walk sequence?

	if (walkAnim[walk_pc + 1].frame != 512) {
		// No, it wasn't. Increment the walk-anim frame number and
		// come back next cycle.
		obMega.setWalkPc(obMega.getWalkPc() + 1);
		return IR_REPEAT;
	}

	// We have reached the end-marker, which means we can return to the
	// script just as the final (stand) frame of the walk is set.

	freeRouteMem();
	obLogic.setLooping(0);
	obMega.setIsWalking(0);

	// If George's walk has been interrupted to run a new action script for
	// instance or Nico's walk has been interrupted by player clicking on
	// her to talk

	// There used to be code here for checking if two megas were colliding,
	// but it had been commented out, and it was only run if a function
	// that always returned zero returned non-zero.

	if (_vm->_logic->checkEventWaiting()) {
		_vm->_logic->startEvent();
		_vm->_logic->writeVar(RESULT, 1);
		return IR_TERMINATE;
	}

	_vm->_logic->writeVar(RESULT, 0);

	// CONTINUE the script so that RESULT can be checked! Also, if an anim
	// command follows the fnWalk command, the 1st frame of the anim (which
	// is always a stand frame itself) can replace the final stand frame of
	// the walk, to hide the slight difference between the shrinking on the
	// mega frames and the pre-shrunk anim start-frame.

	return IR_CONT;
}
예제 #6
0
파일: anims.cpp 프로젝트: AReim1982/scummvm
int Router::doAnimate(byte *ob_logic, byte *ob_graph, int32 animRes, bool reverse) {
	AnimHeader anim_head;
	byte *anim_file;

	ObjectLogic obLogic(ob_logic);
	ObjectGraphic obGraph(ob_graph);

	if (obLogic.getLooping() == 0) {
		// This is the start of the anim - set up the first frame

		// For testing all anims!
		// A script loop can send every resource number to the anim
		// function & it will only run the valid ones. See
		// 'testing_routines' object in George's Player Character
		// section of linc

		if (_vm->_logic->readVar(SYSTEM_TESTING_ANIMS)) {
			if (!_vm->_resman->checkValid(animRes)) {
				// Not a valid resource number. Switch off
				// the sprite. Don't animate - just continue
				// script next cycle.
				setSpriteStatus(ob_graph, NO_SPRITE);
				return IR_STOP;
			}

			// if it's not an animation file
			if (_vm->_resman->fetchType(animRes) != ANIMATION_FILE) {
				// switch off the sprite
				// don't animate - just continue
				// script next cycle
				setSpriteStatus(ob_graph, NO_SPRITE);
				return IR_STOP;
			}

			// switch on the sprite
			setSpriteStatus(ob_graph, SORT_SPRITE);
		}

		assert(animRes);

		// open anim file
		anim_file = _vm->_resman->openResource(animRes);

		assert(_vm->_resman->fetchType(animRes) == ANIMATION_FILE);

		// point to anim header
		anim_head.read(_vm->fetchAnimHeader(anim_file));

		// now running an anim, looping back to this call again
		obLogic.setLooping(1);
		obGraph.setAnimResource(animRes);

		if (reverse)
			obGraph.setAnimPc(anim_head.noAnimFrames - 1);
		else
			obGraph.setAnimPc(0);
	} else if (_vm->_logic->getSync() != -1) {
		// We've received a sync - return to script immediately
		debug(5, "**sync stopped %d**", _vm->_logic->readVar(ID));

		// If sync received, anim finishes right now (remaining on
		// last frame). Quit animation, but continue script.
		obLogic.setLooping(0);
		return IR_CONT;
	} else {
		// Not first frame, and no sync received - set up the next
		// frame of the anim.

		// open anim file and point to anim header
		anim_file = _vm->_resman->openResource(obGraph.getAnimResource());
		anim_head.read(_vm->fetchAnimHeader(anim_file));

		if (reverse)
			obGraph.setAnimPc(obGraph.getAnimPc() - 1);
		else
			obGraph.setAnimPc(obGraph.getAnimPc() + 1);
	}

	// check for end of anim

	if (reverse) {
		if (obGraph.getAnimPc() == 0)
			obLogic.setLooping(0);
	} else {
		if (obGraph.getAnimPc() == anim_head.noAnimFrames - 1)
			obLogic.setLooping(0);
	}

	// close the anim file
	_vm->_resman->closeResource(obGraph.getAnimResource());

	// check if we want the script to loop back & call this function again
	return obLogic.getLooping() ? IR_REPEAT : IR_STOP;
}
예제 #7
0
파일: anims.cpp 프로젝트: AReim1982/scummvm
void Router::setSpriteStatus(byte *ob_graph, uint32 type) {
	ObjectGraphic obGraph(ob_graph);

	// Remove the previous status, but don't affect the shading upper-word
	obGraph.setType((obGraph.getType() & 0xffff0000) | type);
}