/** * Give a object a new image and new orientation flags. * @param pAniObj Object to be updated * @param newflags Objects new flags * @param hNewImg Objects new image */ void AnimateObjectFlags(OBJECT *pAniObj, int newflags, SCNHANDLE hNewImg) { // validate object pointer assert(isValidObject(pAniObj)); if (pAniObj->hImg != hNewImg || (pAniObj->flags & DMA_HARDFLAGS) != (newflags & DMA_HARDFLAGS)) { // something has changed int oldAniX, oldAniY; // objects old animation offsets int newAniX, newAniY; // objects new animation offsets // get objects old animation offsets GetAniOffset(pAniObj->hImg, pAniObj->flags, &oldAniX, &oldAniY); // get objects new animation offsets GetAniOffset(hNewImg, newflags, &newAniX, &newAniY); if (hNewImg) { // get pointer to image const IMAGE *pNewImg = (IMAGE *)LockMem(hNewImg); // setup new shape pAniObj->width = FROM_LE_16(pNewImg->imgWidth); pAniObj->height = FROM_LE_16(pNewImg->imgHeight) & ~C16_FLAG_MASK; newflags &= ~C16_FLAG_MASK; newflags |= FROM_LE_16(pNewImg->imgHeight) & C16_FLAG_MASK; // set objects bitmap definition pAniObj->hBits = FROM_LE_32(pNewImg->hImgBits); } else { // null image pAniObj->width = 0; pAniObj->height = 0; pAniObj->hBits = 0; } // set objects flags and signal a change pAniObj->flags = newflags | DMA_CHANGED; // set objects image pAniObj->hImg = hNewImg; // adjust objects position - subtract new from old for difference pAniObj->xPos += intToFrac(oldAniX - newAniX); pAniObj->yPos += intToFrac(oldAniY - newAniY); } }
/** * Returns the x,y position of an objects animation point. * @param pObj Pointer to object * @param pPosX Gets set to objects X animation position * @param pPosY Gets set to objects Y animation position */ void GetAniPosition(OBJECT *pObj, int *pPosX, int *pPosY) { // validate object pointer assert(isValidObject(pObj)); // get the animation offset of the object GetAniOffset(pObj->hImg, pObj->flags, pPosX, pPosY); // from animation offset and objects position - determine objects animation point *pPosX += fracToInt(pObj->xPos); *pPosY += fracToInt(pObj->yPos); }
/** * Initialise a object using a OBJ_INIT structure to supply parameters. * @param pInitTbl Pointer to object initialisation table */ OBJECT *InitObject(const OBJ_INIT *pInitTbl) { // allocate a new object OBJECT *pObj = AllocObject(); // make sure object created assert(pObj != NULL); // set objects shape pObj->hImg = pInitTbl->hObjImg; // set objects ID pObj->oid = pInitTbl->objID; // set objects flags pObj->flags = DMA_CHANGED | pInitTbl->objFlags; // set objects Z position pObj->zPos = pInitTbl->objZ; // get pointer to image if (pInitTbl->hObjImg) { int aniX, aniY; // objects animation offsets PALQ *pPalQ = NULL; // palette queue pointer const IMAGE *pImg = (const IMAGE *)LockMem(pInitTbl->hObjImg); // handle to image if (pImg->hImgPal) { // allocate a palette for this object pPalQ = AllocPalette(FROM_LE_32(pImg->hImgPal)); // make sure palette allocated assert(pPalQ != NULL); } // assign palette to object pObj->pPal = pPalQ; // set objects size pObj->width = FROM_LE_16(pImg->imgWidth); pObj->height = FROM_LE_16(pImg->imgHeight) & ~C16_FLAG_MASK; pObj->flags &= ~C16_FLAG_MASK; pObj->flags |= FROM_LE_16(pImg->imgHeight) & C16_FLAG_MASK; // set objects bitmap definition pObj->hBits = FROM_LE_32(pImg->hImgBits); // get animation offset of object GetAniOffset(pObj->hImg, pInitTbl->objFlags, &aniX, &aniY); // set objects X position - subtract ani offset pObj->xPos = intToFrac(pInitTbl->objX - aniX); // set objects Y position - subtract ani offset pObj->yPos = intToFrac(pInitTbl->objY - aniY); } else { // no image handle - null image // set objects X position pObj->xPos = intToFrac(pInitTbl->objX); // set objects Y position pObj->yPos = intToFrac(pInitTbl->objY); } // return new object return pObj; }
/** * 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; }