Beispiel #1
0
/**
 * Called at the start of each scene for each actor with a code block.
 * @param as			Actor structure
 * @param bRunScript	Flag for whether to run actor's script for the scene
 */
void StartActor(const T1_ACTOR_STRUC *as, bool bRunScript) {
	SCNHANDLE hActorId = FROM_32(as->hActorId);

	// Zero-out many things
	actorInfo[hActorId - 1].bHidden = false;
	actorInfo[hActorId - 1].completed = false;
	actorInfo[hActorId - 1].x = 0;
	actorInfo[hActorId - 1].y = 0;
	actorInfo[hActorId - 1].presReel = NULL;
	actorInfo[hActorId - 1].presFilm = 0;
	actorInfo[hActorId - 1].presObj = NULL;

	// Store current scene's parameters for this actor
	actorInfo[hActorId - 1].mtype = FROM_32(as->masking);
	actorInfo[hActorId - 1].actorCode = FROM_32(as->hActorCode);

	// Run actor's script for this scene
	if (bRunScript) {
		if (bActorsOn)
			actorInfo[hActorId - 1].bAlive = true;

		if (actorInfo[hActorId - 1].bAlive && FROM_32(as->hActorCode))
			ActorEvent(hActorId, STARTUP, PLR_NOEVENT);
	}
}
Beispiel #2
0
/**
 * Poke the background palette into character 0's images.
 */
void FettleFontPal(SCNHANDLE fontPal) {
	const FONT *pFont;
	IMAGE *pImg;

	assert(fontPal);
	assert(g_hTagFont); // Tag font not declared
	assert(g_hTalkFont); // Talk font not declared

	pFont = (const FONT *)LockMem(g_hTagFont);
	pImg = (IMAGE *)LockMem(FROM_32(pFont->fontInit.hObjImg));	// get image for char 0
	if (!TinselV2)
		pImg->hImgPal = TO_32(fontPal);
	else
		pImg->hImgPal = 0;

	pFont = (const FONT *)LockMem(g_hTalkFont);
	pImg = (IMAGE *)LockMem(FROM_32(pFont->fontInit.hObjImg));	// get image for char 0
	if (!TinselV2)
		pImg->hImgPal = TO_32(fontPal);
	else
		pImg->hImgPal = 0;

	if (TinselV2 && SysVar(SV_TAGCOLOR)) {
		const COLORREF c = GetActorRGB(-1);
		SetTagColorRef(c);
		UpdateDACqueue(SysVar(SV_TAGCOLOR), c);
	}
}
Beispiel #3
0
/**
 * Returns the length of one line of a string in pixels.
 * @param szStr			String
 * @param pFont			Which font to use for dimensions
 */
int StringLengthPix(char *szStr, const FONT *pFont) {
    int strLen;	// accumulated length of string
    byte	c;
    SCNHANDLE	hImg;

    // while not end of string or end of line
    for (strLen = 0; (c = *szStr) != EOS_CHAR && c != LF_CHAR; szStr++) {
        if (g_bMultiByte) {
            if (c & 0x80)
                c = ((c & ~0x80) << 8) + *++szStr;
        }
        hImg = FROM_32(pFont->fontDef[c]);

        if (hImg) {
            // there is a IMAGE for this character
            const IMAGE *pChar = (const IMAGE *)LockMem(hImg);

            // add width of font bitmap
            strLen += FROM_16(pChar->imgWidth);
        } else
            // use width of space character
            strLen += FROM_32(pFont->spaceSize);

        // finally add the inter-character spacing
        strLen += FROM_32(pFont->xSpacing);
    }

    // return length of line in pixels - minus inter-char spacing for last character
    strLen -= FROM_32(pFont->xSpacing);
    return (strLen > 0) ? strLen : 0;
}
Beispiel #4
0
/**
 * Given the scene background film, extracts the palette handle for
 * everything else's use, then starts a display process for each reel
 * in the film.
 * @param hFilm			Scene background film
 */
void StartupBackground(CORO_PARAM, SCNHANDLE hFilm) {
	CORO_BEGIN_CONTEXT;
	CORO_END_CONTEXT(_ctx);

	CORO_BEGIN_CODE(_ctx);

	const FILM *pfilm;
	IMAGE *pim;

	g_hBackground = hFilm;		// Save handle in case of Save_Scene()

	pim = GetImageFromFilm(hFilm, 0, NULL, NULL, &pfilm);

	SetBackPal(FROM_32(pim->hImgPal));

	// Extract the film speed
	g_BGspeed = ONE_SECOND / FROM_32(pfilm->frate);

	// Start display process for each reel in the film
	CoroScheduler.createProcess(PID_REEL, BGmainProcess, &pfilm->reels[0], sizeof(FREEL));

	if (TinselV0) {
		for (uint i = 1; i < FROM_32(pfilm->numreels); ++i)
			CoroScheduler.createProcess(PID_REEL, BGotherProcess, &pfilm->reels[i], sizeof(FREEL));
	}

	if (g_pBG[0] == NULL)
		ControlStartOff();

	if (TinselV2 && (coroParam != Common::nullContext))
		CORO_GIVE_WAY;

	CORO_END_CODE;
}
Beispiel #5
0
/**
 * LoadBasicChunks
 */
void LoadBasicChunks() {
	byte *cptr;
	int numObjects;

	// Allocate RAM for savescene data
	InitializeSaveScenes();

	// CHUNK_TOTAL_ACTORS seems to be missing in the released version, hard coding a value
	// TODO: Would be nice to just change 511 to MAX_SAVED_ALIVES
	cptr = FindChunk(MASTER_SCNHANDLE, CHUNK_TOTAL_ACTORS);
	RegisterActors((cptr != NULL) ? READ_32(cptr) : 511);

	// CHUNK_TOTAL_GLOBALS seems to be missing in some versions.
	// So if it is missing, set a reasonably high value for the number of globals.
	cptr = FindChunk(MASTER_SCNHANDLE, CHUNK_TOTAL_GLOBALS);
	RegisterGlobals((cptr != NULL) ? READ_32(cptr) : 512);

	cptr = FindChunk(INV_OBJ_SCNHANDLE, CHUNK_TOTAL_OBJECTS);
	numObjects = (cptr != NULL) ? READ_32(cptr) : 0;

	cptr = FindChunk(INV_OBJ_SCNHANDLE, CHUNK_OBJECTS);

	// Convert to native endianness
	INV_OBJECT *io = (INV_OBJECT *)cptr;
	for (int i = 0; i < numObjects; i++, io++) {
		io->id        = FROM_32(io->id);
		io->hIconFilm = FROM_32(io->hIconFilm);
		io->hScript   = FROM_32(io->hScript);
		io->attribute = FROM_32(io->attribute);
	}

	RegisterIcons(cptr, numObjects);

	cptr = FindChunk(MASTER_SCNHANDLE, CHUNK_TOTAL_POLY);
	// Max polygons are 0 in DW1 Mac (both in the demo and the full version)
	if (cptr != NULL && *cptr != 0)
		MaxPolygons(*cptr);

	if (TinselV2) {
		// Global processes
		cptr = FindChunk(MASTER_SCNHANDLE, CHUNK_NUM_PROCESSES);
		assert(cptr && (*cptr < 100));
		int num = *cptr;
		cptr = FindChunk(MASTER_SCNHANDLE, CHUNK_PROCESSES);
		assert(!num || cptr);
		GlobalProcesses(num, cptr);

		// CdPlay() stuff
		cptr = FindChunk(MASTER_SCNHANDLE, CHUNK_CDPLAY_HANDLE);
		assert(cptr);
		uint32 playHandle = READ_32(cptr);
		assert(playHandle < 512);
		SetCdPlayHandle(playHandle);
	}
}
Beispiel #6
0
static void MoverProcessHelper(int X, int Y, int id, PMOVER pMover) {
	const FILM *pfilm;
	const MULTI_INIT *pmi;
	const FRAME *pFrame;
	IMAGE *pim;


	assert(BgPal()); // Can't start actor without a background palette
	assert(pMover->walkReels[0][FORWARD]); // Starting actor process without walk reels

	InitMover(pMover);
	InitialPathChecks(pMover, X, Y);

	pfilm = (const FILM *)LockMem(pMover->walkReels[0][FORWARD]);
	pmi = (const MULTI_INIT *)LockMem(FROM_32(pfilm->reels[0].mobj));

//---
	pFrame = (const FRAME *)LockMem(FROM_32(pmi->hMulFrame));

	// get pointer to image
	pim = (IMAGE *)LockMem(READ_32(pFrame));	// handle to image
	pim->hImgPal = TO_32(BgPal());
//---
	pMover->actorObj = MultiInitObject(pmi);

/**/	assert(pMover->actorID == id);
	pMover->actorID = id;

	// add it to display list
	MultiInsertObject(GetPlayfieldList(FIELD_WORLD), pMover->actorObj);
	storeActorReel(id, NULL, 0, pMover->actorObj, 0, 0, 0);

	InitStepAnimScript(&pMover->actorAnim, pMover->actorObj, FROM_32(pfilm->reels[0].script), ONE_SECOND / FROM_32(pfilm->frate));
	pMover->stepCount = 0;

	MultiSetAniXY(pMover->actorObj, pMover->objX, pMover->objY);

	// If no path, just use first path in the scene
	if (pMover->hCpath != NOPOLY)
		SetMoverZ(pMover, pMover->objY, GetPolyZfactor(pMover->hCpath));
	else
		SetMoverZ(pMover, pMover->objY, GetPolyZfactor(FirstPathPoly()));

	// Make him the right size
	SetMoverStanding(pMover);

//**** if added 18/11/94, am
	if (X != MAGICX && Y != MAGICY) {
		HideMover(pMover, 0);		// Allows a play to come in before this appears
		pMover->bHidden = false;	// ...but don't stay hidden
	}

	pMover->bActive = true;
}
Beispiel #7
0
/**
 * Process to fade one palette.
 * A pointer to a 'FADE' structure must be passed to this process when
 * it is created.
 */
static void FadeProcess(CORO_PARAM, const void *param) {
	// COROUTINE
	CORO_BEGIN_CONTEXT;
		COLORREF fadeRGB[MAX_COLORS];	// local copy of palette
		const long *pColMult;			// pointer to color multiplier table
		PALETTE *pPalette;		// pointer to palette
	CORO_END_CONTEXT(_ctx);

	// get the fade data structure - copied to process when it was created
	const FADE *pFade = (const FADE *)param;

	CORO_BEGIN_CODE(_ctx);

	if (TinselV2)
		// Note that this palette is being faded
		FadingPalette(pFade->pPalQ, true);

	// get pointer to palette - reduce pointer indirection a bit
	_ctx->pPalette = (PALETTE *)LockMem(FROM_32(pFade->pPalQ->hPal));

	for (_ctx->pColMult = pFade->pColorMultTable; *_ctx->pColMult >= 0; _ctx->pColMult++) {
		// go through all multipliers in table - until a negative entry

		// fade palette using next multiplier
		if (TinselV2)
			FadePalette(_ctx->fadeRGB, pFade->pPalQ->palRGB,
				pFade->pPalQ->numColors, (uint32) *_ctx->pColMult);
		else
			FadePalette(_ctx->fadeRGB, _ctx->pPalette->palRGB,
				FROM_32(_ctx->pPalette->numColors), (uint32) *_ctx->pColMult);

		// send new palette to video DAC
		UpdateDACqueue(pFade->pPalQ->posInDAC, FROM_32(_ctx->pPalette->numColors), _ctx->fadeRGB);

		// allow time for video DAC to be updated
		CORO_SLEEP(1);
	}

	if (TinselV2)
		// Note that this palette is being faded
		FadingPalette(pFade->pPalQ, false);

	CORO_END_CODE;
}
Beispiel #8
0
/**
 * Change which reel is playing for a moving actor.
 */
void AlterMover(PMOVER pMover, SCNHANDLE film, AR_FUNCTION fn) {
	const FILM *pfilm;

	assert(pMover->actorObj); // Altering null moving actor's animation script

	if (fn == AR_POPREEL) {
		// Use the saved film
		film = pMover->hPushedFilm;
	}
	if (fn == AR_PUSHREEL) {
		// Save the one we're replacing
		pMover->hPushedFilm = (pMover->bSpecReel) ? pMover->hLastFilm : 0;
	}

	if (film == 0) {
		if (pMover->bSpecReel) {
			// Revert to 'normal' actor
			SetMoverWalkReel(pMover, pMover->direction, pMover->scale, true);
			pMover->bSpecReel = false;
		}
	} else {
		// Remember this one in case the actor talks
		pMover->hLastFilm = film;

		pfilm = (const FILM *)LockMem(film);
		assert(pfilm != NULL);

		InitStepAnimScript(&pMover->actorAnim, pMover->actorObj, FROM_32(pfilm->reels[0].script), ONE_SECOND / FROM_32(pfilm->frate));
		if (!TinselV2)
			pMover->stepCount = 0;

		// If no path, just use first path in the scene
		if (pMover->hCpath != NOPOLY)
			SetMoverZ(pMover, pMover->objY, GetPolyZfactor(pMover->hCpath));
		else
			SetMoverZ(pMover, pMover->objY, GetPolyZfactor(FirstPathPoly()));

		if (fn == AR_WALKREEL) {
			pMover->bSpecReel = false;
			pMover->bWalkReel = true;
		} else {
			pMover->bSpecReel = true;
			pMover->bWalkReel = false;

#ifdef DEBUG
			assert(StepAnimScript(&pMover->actorAnim) != ScriptFinished); // Actor reel has finished!
#else
			StepAnimScript(&pMover->actorAnim);	// 04/01/95
#endif
		}

		// Hang on, we may not want him yet! 04/01/95
		if (pMover->bHidden)
			MultiSetZPosition(pMover->actorObj, -1);
	}
}
Beispiel #9
0
/**
 * Called at the start of each scene. Start each actor with a code block.
 * @param ah			Scene handle
 * @param numActors		Number of actors
 * @param bRunScript	Flag for whether to run actor scene scripts
 */
void StartTaggedActors(SCNHANDLE ah, int numActors, bool bRunScript) {
	int	i;

	if (TinselV2) {
		// Clear it all out for a fresh start
		memset(taggedActors, 0, sizeof(taggedActors));
		numTaggedActors = numActors;
	} else {
		// Only actors with code blocks got (x, y) re-initialized, so...
		for (i = 0; i < NumActors; i++) {
			actorInfo[i].x = actorInfo[i].y = 0;
			actorInfo[i].mtype = 0;
		}
	}

	if (!TinselV2) {
		// Tinsel 1 load variation
		const T1_ACTOR_STRUC *as = (const T1_ACTOR_STRUC *)LockMem(ah);
		for (i = 0; i < numActors; i++, as++) {
			StartActor(as, bRunScript);
		}
	} else if (numActors > 0) {
		// Tinsel 2 load variation
		const T2_ACTOR_STRUC *as = (T2_ACTOR_STRUC *)LockMem(ah);
		for (i = 0; i < numActors; i++, as++) {
			assert(as->hActorCode);

			// Store current scene's parameters for this tagged actor
			taggedActors[i].id			= FROM_32(as->hActorId);
			taggedActors[i].hTagText	= FROM_32(as->hTagText);
			taggedActors[i].tagPortionV	= FROM_32(as->tagPortionV);
			taggedActors[i].tagPortionH	= FROM_32(as->tagPortionH);
			taggedActors[i].hActorCode	= FROM_32(as->hActorCode);

			// Run actor's script for this scene
			if (bRunScript) {
				// Send in reverse order - they get swapped round in the scheduler
				ActorEvent(Common::nullContext, taggedActors[i].id, SHOWEVENT, false, 0);
				ActorEvent(Common::nullContext, taggedActors[i].id, STARTUP, false, 0);
			}
		}
	}
}
Beispiel #10
0
/**
 * Runs secondary reels for a scene background
 */
static void BGotherProcess(CORO_PARAM, const void *param) {
	// COROUTINE
	CORO_BEGIN_CONTEXT;
		OBJECT *pObj;
		ANIM anim;
	CORO_END_CONTEXT(_ctx);

	const FREEL *pReel = (const FREEL *)param;
	const MULTI_INIT *pmi = (const MULTI_INIT *)LockMem(FROM_32(pReel->mobj));

	CORO_BEGIN_CODE(_ctx);

	// Initialize and insert the object, and initialize its script.
	_ctx->pObj = MultiInitObject(pmi);
	MultiInsertObject(GetPlayfieldList(FIELD_WORLD), _ctx->pObj);

	InitStepAnimScript(&_ctx->anim, g_pBG[0], FROM_32(pReel->script), g_BGspeed);

	while (StepAnimScript(&_ctx->anim) != ScriptFinished)
		CORO_SLEEP(1);

	CORO_END_CODE;
}
Beispiel #11
0
/**
 * Get actor to adopt its appropriate walking reel.
 */
void SetMoverWalkReel(PMOVER pMover, DIRECTION reel, int scale, bool force) {
	SCNHANDLE	whichReel;
	const FILM *pfilm;

	// Kill off any play that may be going on for this actor
	// and restore the real actor
	storeActorReel(pMover->actorID, NULL, 0, NULL, 0, 0, 0);
	UnHideMover(pMover);

	// Don't do it if using a special walk reel
	if (pMover->bWalkReel)
		return;

	if (force || pMover->scale != scale || pMover->direction != reel) {
		assert(reel >= 0 && reel <= 3 && scale > 0 && scale <= TOTAL_SCALES); // out of range scale or reel

		// If scale change and both are regular scales
		// and there's a scaling reel in the right direction
		if (pMover->scale != scale
				&& scale <= NUM_MAINSCALES && pMover->scale <= NUM_MAINSCALES
				&& (whichReel = ScalingReel(pMover->actorID, pMover->scale, scale, reel)) != 0) {
//			error("Cripes");
			;	// Use what is now in 'whichReel'
		} else {
			whichReel = pMover->walkReels[scale-1][reel];
			assert(whichReel); // no reel
		}

		pfilm = (const FILM *)LockMem(whichReel);
		assert(pfilm != NULL); // no film

		InitStepAnimScript(&pMover->actorAnim, pMover->actorObj, FROM_32(pfilm->reels[0].script), 1);

		// Synchronised walking reels
		assert(pMover->stepCount >= 0);
		SkipFrames(&pMover->actorAnim, pMover->stepCount);

		pMover->scale = scale;
		pMover->direction = reel;
	}
}
Beispiel #12
0
/**
 * Main text outputting routine. If a object list is specified a
 * multi-object is created for the whole text and a pointer to the head
 * of the list is returned.
 * @param pList			Object list to add text to
 * @param szStr			String to output
 * @param color		Color for monochrome text
 * @param xPos			X position of string
 * @param yPos			Y position of string
 * @param hFont			Which font to use
 * @param mode			Mode flags for the string
 * @param sleepTime		Sleep time between each character (if non-zero)
 */
OBJECT *ObjectTextOut(OBJECT **pList, char *szStr, int color,
                      int xPos, int yPos, SCNHANDLE hFont, int mode, int sleepTime) {
    int xJustify;	// x position of text after justification
    int yOffset;	// offset to next line of text
    OBJECT *pFirst;	// head of multi-object text list
    OBJECT *pChar = 0;	// object ptr for the character
    byte c;
    SCNHANDLE hImg;
    const IMAGE *pImg;

    // make sure there is a linked list to add text to
    assert(pList);

    // get font pointer
    const FONT *pFont = (const FONT *)LockMem(hFont);

    // init head of text list
    pFirst = NULL;

    // get image for capital W
    assert(pFont->fontDef[(int)'W']);
    pImg = (const IMAGE *)LockMem(FROM_32(pFont->fontDef[(int)'W']));

    // get height of capital W for offset to next line
    yOffset = FROM_16(pImg->imgHeight) & ~C16_FLAG_MASK;

    while (*szStr) {
        // x justify the text according to the mode flags
        xJustify = JustifyText(szStr, xPos, pFont, mode);

        // repeat until end of string or end of line
        while ((c = *szStr) != EOS_CHAR && c != LF_CHAR) {
            if (g_bMultiByte) {
                if (c & 0x80)
                    c = ((c & ~0x80) << 8) + *++szStr;
            }
            hImg = FROM_32(pFont->fontDef[c]);

            if (hImg == 0) {
                // no image for this character

                // add font spacing for a space character
                xJustify += FROM_32(pFont->spaceSize);
            } else {	// printable character

                int aniX, aniY;		// char image animation offsets

                OBJ_INIT oi;
                oi.hObjImg  = FROM_32(pFont->fontInit.hObjImg);
                oi.objFlags = FROM_32(pFont->fontInit.objFlags);
                oi.objID    = FROM_32(pFont->fontInit.objID);
                oi.objX     = FROM_32(pFont->fontInit.objX);
                oi.objY     = FROM_32(pFont->fontInit.objY);
                oi.objZ     = FROM_32(pFont->fontInit.objZ);

                // allocate and init a character object
                if (pFirst == NULL)
                    // first time - init head of list
                    pFirst = pChar = InitObject(&oi);	// FIXME: endian issue using fontInit!!!
                else
                    // chain to multi-char list
                    pChar = pChar->pSlave = InitObject(&oi);	// FIXME: endian issue using fontInit!!!

                // convert image handle to pointer
                pImg = (const IMAGE *)LockMem(hImg);

                // fill in character object
                pChar->hImg   = hImg;			// image def
                pChar->width  = FROM_16(pImg->imgWidth);		// width of chars bitmap
                pChar->height = FROM_16(pImg->imgHeight) & ~C16_FLAG_MASK;	// height of chars bitmap
                pChar->hBits  = FROM_32(pImg->hImgBits);		// bitmap

                // check for absolute positioning
                if (mode & TXT_ABSOLUTE)
                    pChar->flags |= DMA_ABS;

                // set characters color - only effective for mono fonts
                pChar->constant = color;

                // get Y animation offset
                GetAniOffset(hImg, pChar->flags, &aniX, &aniY);

                // set x position - ignore animation point
                pChar->xPos = intToFrac(xJustify);

                // set y position - adjust for animation point
                pChar->yPos = intToFrac(yPos - aniY);

                if (mode & TXT_SHADOW) {
                    // we want to shadow the character
                    OBJECT *pShad;

                    // allocate a object for the shadow and chain to multi-char list
                    pShad = pChar->pSlave = AllocObject();

                    // copy the character for a shadow
                    CopyObject(pShad, pChar);

                    // add shadow offsets to characters position
                    pShad->xPos += intToFrac(FROM_32(pFont->xShadow));
                    pShad->yPos += intToFrac(FROM_32(pFont->yShadow));

                    // shadow is behind the character
                    pShad->zPos--;

                    // shadow is always mono
                    pShad->flags = DMA_CNZ | DMA_CHANGED;

                    // check for absolute positioning
                    if (mode & TXT_ABSOLUTE)
                        pShad->flags |= DMA_ABS;

                    // shadow always uses first palette entry
                    // should really alloc a palette here also ????
                    pShad->constant = 1;

                    // add shadow to object list
                    InsertObject(pList, pShad);
                }

                // add character to object list
                InsertObject(pList, pChar);

                // move to end of list
                if (pChar->pSlave)
                    pChar = pChar->pSlave;

                // add character spacing
                xJustify += FROM_16(pImg->imgWidth);
            }

            // finally add the inter-character spacing
            xJustify += FROM_32(pFont->xSpacing);

            // next character in string
            ++szStr;
        }

        // adjust the text y position and add the inter-line spacing
        yPos += yOffset + FROM_32(pFont->ySpacing);

        // check for newline
        if (c == LF_CHAR)
            // next character in string
            ++szStr;
    }

    // return head of list
    return pFirst;
}
Beispiel #13
0
/**
 * Tinsel 2 Moving actor process
 * - 1 per moving actor in current scene.
 */
void T2MoverProcess(CORO_PARAM, const void *param) {
	CORO_BEGIN_CONTEXT;
	CORO_END_CONTEXT(_ctx);

	// Get the co-ordinates - copied to process when it was created
	const MAINIT *rpos = (const MAINIT *)param;
	PMOVER pMover = rpos->pMover;
	int i;
	FILM *pFilm;
	PMULTI_INIT pmi;

	CORO_BEGIN_CODE(_ctx);

	for (i = 0; i < TOTAL_SCALES; i++) {
		if (pMover->walkReels[i][FORWARD])
			break;
	}
	assert(i < TOTAL_SCALES);

	InitMover(pMover);
	InitialPathChecks(pMover, rpos->X, rpos->Y);

	pFilm = (FILM *)LockMem(pMover->walkReels[i][FORWARD]);	// Any old reel
	pmi = (PMULTI_INIT)LockMem(FROM_32(pFilm->reels[0].mobj));

	// Poke in the background palette
	PokeInPalette(pmi);

	pMover->actorObj = MultiInitObject(pmi);
	// FIXME: This is what the original did. A bug, perhaps?
	// pMover->actorID = pMover->actorID;
	pMover->bActive = true;

	// add it to display list
	MultiInsertObject( GetPlayfieldList(FIELD_WORLD), pMover->actorObj );

	InitStepAnimScript(&pMover->actorAnim, pMover->actorObj, pFilm->reels[0].script, ONE_SECOND/pFilm->frate);
	pMover->stepCount = 0;

	MultiSetAniXY(pMover->actorObj, pMover->objX, pMover->objY);

	// If no path, just use first path in the scene
	if (pMover->hCpath != NOPOLY)
		SetMoverZ(pMover, pMover->objY, GetPolyZfactor(pMover->hCpath));
	else
		SetMoverZ(pMover, pMover->objY, GetPolyZfactor(FirstPathPoly()));

	// Make him the right size
	SetMoverStanding(pMover);

	HideMover(pMover);		// Allows a play to come in before this appears
	pMover->bHidden = false;	// ...but don't stay hidden

	for (;;) {
		if (pMover->bSpecReel) {
			if (!pMover->bHidden)
				StepAnimScript(&pMover->actorAnim);
		} else
			DoMoveActor(pMover);

		CheckBrightness(pMover);

		CORO_SLEEP(1);
	}

	CORO_END_CODE;
}
Beispiel #14
0
bool PCMMusicPlayer::getNextChunk() {
	MusicSegment *musicSegments;
	int32 *script, *scriptBuffer;
	int id;
	int snum;
	uint32 sampleOffset, sampleLength, sampleCLength;
	Common::File file;
	byte *buffer;
	Common::SeekableReadStream *sampleStream;

	switch (_state) {
	case S_NEW:
	case S_NEXT:
		_forcePlay = false;

		script = scriptBuffer = (int32 *)LockMem(_hScript);

		// Set parameters for this chunk of music
		id = _scriptNum;
		while (id--)
			script = scriptBuffer + READ_32(script);
		snum = FROM_32(script[_scriptIndex++]);

		if (snum == MUSIC_JUMP || snum == MUSIC_END) {
			// Let usual code sort it out!
			_scriptIndex--;    // Undo increment
			_forcePlay = true; // Force a Play
			_state = S_END1;   // 'Goto' S_END1
			break;
		}

		musicSegments = (MusicSegment *) LockMem(_hSegment);

		assert(FROM_32(musicSegments[snum].numChannels) == 1);
		assert(FROM_32(musicSegments[snum].bitsPerSample) == 16);

		sampleOffset = FROM_32(musicSegments[snum].sampleOffset);
		sampleLength = FROM_32(musicSegments[snum].sampleLength);
		sampleCLength = (((sampleLength + 63) & ~63)*33)/64;

		if (!file.open(_filename))
			error(CANNOT_FIND_FILE, _filename.c_str());

		file.seek(sampleOffset);
		if (file.eos() || file.err() || (uint32)file.pos() != sampleOffset)
			error(FILE_IS_CORRUPT, _filename.c_str());

		buffer = (byte *) malloc(sampleCLength);
		assert(buffer);

		// read all of the sample
		if (file.read(buffer, sampleCLength) != sampleCLength)
			error(FILE_IS_CORRUPT, _filename.c_str());

		debugC(DEBUG_DETAILED, kTinselDebugMusic, "Creating ADPCM music chunk with size %d, "
				"offset %d (script %d.%d)", sampleCLength, sampleOffset,
				_scriptNum, _scriptIndex - 1);

		sampleStream = new Common::MemoryReadStream(buffer, sampleCLength, DisposeAfterUse::YES);

		delete _curChunk;
		_curChunk = new Tinsel8_ADPCMStream(sampleStream, DisposeAfterUse::YES, sampleCLength,
				22050, 1, 32);

		_state = S_MID;
		return true;

	case S_END1:
		debugC(DEBUG_DETAILED, kTinselDebugMusic, "Music reached state S_END1 (script %d.%d)",
				_scriptNum, _scriptIndex);

		script = scriptBuffer = (int32 *) LockMem(_hScript);

		id = _scriptNum;
		while (id--)
			script = scriptBuffer + READ_32(script);
		snum = FROM_32(script[_scriptIndex]);

		if (snum == MUSIC_END) {
			_state = S_END2;
		} else {
			if (snum == MUSIC_JUMP)
				_scriptIndex = FROM_32(script[_scriptIndex+1]);

			_state = _forcePlay ? S_NEW : S_NEXT;
			_forcePlay = false;
		}

		return true;

	case S_END2:
		debugC(DEBUG_DETAILED, kTinselDebugMusic, "Music reached state S_END2 (script %d.%d)",
				_scriptNum, _scriptIndex);

		_silenceSamples = 11025; // Half a second of silence
		return true;

	case S_END3:
		debugC(DEBUG_DETAILED, kTinselDebugMusic, "Music reached state S_END3 (script %d.%d)",
				_scriptNum, _scriptIndex);

		stop();
		_state = S_IDLE;
		return false;

	case S_IDLE:
		return false;

	default:
		break;
	}

	return true;
}
Beispiel #15
0
/**
 * Run main animation that comprises the scene background.
 */
static void BGmainProcess(CORO_PARAM, const void *param) {
	// COROUTINE
	CORO_BEGIN_CONTEXT;
	CORO_END_CONTEXT(_ctx);

	CORO_BEGIN_CODE(_ctx);

	const FILM *pFilm;
	const FREEL *pReel;
	const MULTI_INIT *pmi;

	// get the stuff copied to process when it was created
	if (g_pBG[0] == NULL) {
		/*** At start of scene ***/

		if (!TinselV2) {
			pReel = (const FREEL *)param;

			// Get the MULTI_INIT structure
			pmi = (const MULTI_INIT *)LockMem(FROM_32(pReel->mobj));

			// Initialize and insert the object, and initialize its script.
			g_pBG[0] = MultiInitObject(pmi);
			MultiInsertObject(GetPlayfieldList(FIELD_WORLD), g_pBG[0]);
			InitStepAnimScript(&g_thisAnim[0], g_pBG[0], FROM_32(pReel->script), g_BGspeed);
			g_bgReels = 1;
		} else {
			/*** At start of scene ***/
			pFilm = (const FILM *)LockMem(g_hBackground);
			g_bgReels = FROM_32(pFilm->numreels);

			int i;
			for (i = 0; i < g_bgReels; i++) {
				// Get the MULTI_INIT structure
				pmi = (PMULTI_INIT) LockMem(FROM_32(pFilm->reels[i].mobj));

				// Initialize and insert the object, and initialize its script.
				g_pBG[i] = MultiInitObject(pmi);
				MultiInsertObject(GetPlayfieldList(FIELD_WORLD), g_pBG[i]);
				MultiSetZPosition(g_pBG[i], 0);
				InitStepAnimScript(&g_thisAnim[i], g_pBG[i], FROM_32(pFilm->reels[i].script), g_BGspeed);

				if (i > 0)
					g_pBG[i-1]->pSlave = g_pBG[i];
			}
		}

		if (g_bDoFadeIn) {
			FadeInFast(NULL);
			g_bDoFadeIn = false;
		} else if (TinselV2)
			PokeInTagColor();

		for (;;) {
			for (int i = 0; i < g_bgReels; i++) {
				if (StepAnimScript(&g_thisAnim[i]) == ScriptFinished)
					error("Background animation has finished");
			}

			CORO_SLEEP(1);
		}
	} else {
		// New background during scene
		if (!TinselV2) {
			pReel = (const FREEL *)param;
			InitStepAnimScript(&g_thisAnim[0], g_pBG[0], FROM_32(pReel->script), g_BGspeed);
			StepAnimScript(&g_thisAnim[0]);
		} else {
			pFilm = (const FILM *)LockMem(g_hBackground);
			assert(g_bgReels == (int32)FROM_32(pFilm->numreels));

			// Just re-initialize the scripts.
			for (int i = 0; i < g_bgReels; i++) {
				InitStepAnimScript(&g_thisAnim[i], g_pBG[i], pFilm->reels[i].script, g_BGspeed);
				StepAnimScript(&g_thisAnim[i]);
			}
		}
	}

	CORO_END_CODE;
}