Пример #1
0
SpritePtr CreateStatsSpriteClone(
    SpritePtr masterSpriteP,
    short numDigits,
    JustifyType justification,
    int fillWithZeros)
{
    StatsStructPtr  spriteStructP;
    SpritePtr       newSpriteP;
    SWError         err = kNoError;
    
    SW_ASSERT(masterSpriteP != NULL);
    SW_ASSERT(masterSpriteP->maxFrames >= 10);
    
        // Allocate memory for the StatsStruct
    spriteStructP = (StatsStructPtr)calloc(1,sizeof(StatsStruct));
    if (!spriteStructP)
    {
            err = kMemoryAllocationError;
        }
        
    if (err == kNoError)
    {
        err = SWCloneSprite(masterSpriteP, &newSpriteP, spriteStructP);
    }
    
    if (err == kNoError)
    {
            // Set the Sprite's DrawProc to our special digit-drawing DrawProc.
        newSpriteP->frameDrawProc = StatsItemDrawProc;
        
            // Adjust the Sprite's width to match the width of all the digits put together.
        newSpriteP->drawData->scaledWidth = SW_RECT_WIDTH(newSpriteP->destFrameRect) * numDigits;
        newSpriteP->drawData->scaledHeight = SW_RECT_HEIGHT(newSpriteP->destFrameRect);
        SWSetCurrentFrameIndex(newSpriteP, newSpriteP->curFrameIndex);
        
        spriteStructP->numDigits = numDigits;
        spriteStructP->theNum = -1;
        spriteStructP->justification = justification;
        spriteStructP->fillWithZeros = fillWithZeros;
        spriteStructP->drawProc = SWStdSpriteDrawProc;
    }
    else
    {
        newSpriteP = NULL;
    }
    
    return newSpriteP;
}
Пример #2
0
SWError blitStringToFrame(
	char *string,
	TTF_Font *font,
	int align,
	int rendering,
	SDL_Color *textColor,
	SDL_Color *backColor,
	FramePtr frameP )
{
	SWError err = kNoError;
	char *lineStart, *lineEnd;
	SDL_Surface *textSurface = NULL, *convertedTextSurface = NULL;
	int lineSkipHeight = TTF_FontLineSkip( font );
	SDL_Rect destRect;
	int lineWidth;
	
		// draw the background. Transparent for solid or blended,
		// solid bkgnd color for smooth.
	if( rendering == STRendering_Smooth )
		SDL_FillRect( frameP->frameSurfaceP, NULL,
			SDL_MapRGBA( frameP->frameSurfaceP->format, backColor->r, backColor->g, backColor->b, 0xFF ) );
	else
		SDL_FillRect( frameP->frameSurfaceP, NULL,
			SDL_MapRGBA( frameP->frameSurfaceP->format, backColor->r, backColor->g, backColor->b, 0x00 ) );
	
	destRect.x = frameP->frameRect.left;
	destRect.y = frameP->frameRect.top;
	destRect.w = SW_RECT_WIDTH( frameP->frameRect );
	
	lineStart = string;
	
		// render each line, one at a time, and blit them over to our frame
		// one after another. We have to start at the last line and work
		// our way to the first, since some characters hang over to the
		// line below, and we don't want those bits cut off.
	while(
		lineStart != NULL &&
		*lineStart != '\0' &&
		destRect.y < frameP->frameRect.bottom &&
		err == kNoError )
	{
		lineEnd = strchr( lineStart, '\n' );
		if( lineEnd != NULL )
		{
				// we need to insert a null char temporarily at the end of
				// this line, so that we can render just this text.
			*lineEnd = '\0';
		}
		
		TTF_SizeText( font, lineStart, &lineWidth, NULL );
		
		switch( rendering )
		{
			case STRendering_Solid:
				textSurface = TTF_RenderText_Solid( font, lineStart, *textColor );
				break;
			case STRendering_Smooth:
				textSurface = TTF_RenderText_Shaded( font, lineStart, *textColor, *backColor );
				break;
			case STRendering_Blended:
				textSurface = TTF_RenderText_Blended( font, lineStart, *textColor );
				break;
		}
				
		if( textSurface == NULL )
			err = kSTTextRenderingError;
			
		if( err == kNoError )
		{
				// put things back the way we found them, now that
				// the text has been rendered
			if( lineEnd != NULL )
				*lineEnd = '\n';
	
				// convert the text surface to the display format, so we can
				// blit it safely onto frameSurfaceP
			convertedTextSurface = SDL_ConvertSurface(
				textSurface,
				frameP->frameSurfaceP->format,
				SDL_SWSURFACE );
			
			if( convertedTextSurface == NULL )
				err = kSTTextRenderingError;
		}
		
		if( err == kNoError )
		{
			switch( align )
			{
				case STAlign_Left:
					destRect.x = 0;
					break;
				case STAlign_Center:
					destRect.x = (frameP->frameRect.right / 2) - (lineWidth / 2);
					break;
				case STAlign_Right:
					destRect.x = frameP->frameRect.right - lineWidth;
					break;
			}
					
				// if we don't unset the SRCALPHA flag, then the dest
				// surface alpha will remain untouched, and our text
				// wont show up using a std blit. This is the way SDL
				// is designed, although it is aknowledged to be
				// counterintuitive in the docs.
			if( SDL_SetAlpha( convertedTextSurface, 0, 0xFF ) < 0 )
				err = kSTTextRenderingError;
			
			if( SDL_SetColorKey( convertedTextSurface, SDL_SRCCOLORKEY, 
				SDL_MapRGBA( convertedTextSurface->format, 0xFF, 0xFF, 0xFF, 0x00 ) ) < 0 )
				err = kSTTextRenderingError;
		}
		
			// we use our own function for alpha bending since for
			// a RGBA to RGBA blit, SDL either leaves the dest alpha
			// untouched (if SRCALPHA is set), or replaces it completely
			// with the source alpha (if SRCALPHA is not set). In the first
			// option the text doesnt show up at all, and in the second hanging
			// characters such as 'g' and 'j' have their bottoms cut off
			// when the next line is blit. So we do our own blit pixel-by-pixel,
			// 'alpha-bending' (taking the max of src/dest alphas) as we go.
			// FWIK, this is rediculously slow on HW surfaces, but until
			// somebody comesup with a better solution...
		if( err == kNoError )
		{
			if( rendering == STRendering_Blended || rendering == STRendering_Solid )
				alphaBlendTextSurfaceToFrame( convertedTextSurface, frameP->frameSurfaceP, &destRect );
			else
			{
				if( err == kNoError )
					if( SDL_BlitSurface( convertedTextSurface, NULL, frameP->frameSurfaceP, &destRect ) < 0 )
						err = kSTTextRenderingError;
			}
		}
		
		if( err == kNoError )
		{	
			if( lineEnd == NULL )
				lineStart = NULL;
			else
				lineStart = lineEnd + 1;
			
			destRect.y += lineSkipHeight;
			
		}

		if( textSurface ) SDL_FreeSurface( textSurface );
		if( convertedTextSurface ) SDL_FreeSurface( convertedTextSurface );
	}
	
	return err;
}
Пример #3
0
SWError st_CreateStaticText(
	const char* string,
	const char* fontPath,
	int fontSize,
	SWRect* bounds,
	int wrap,
	StaticTextPtr* newStaticTextPP )
{
	SWError err = kNoError;
	FramePtr frameP = NULL;
	StaticTextPtr tempStaticTextP = NULL;
	
	*newStaticTextPP = 0;
	
	if( ! gSTHasBeenInitialized )
		err = kSTHasNotBeenInitedError;
	
	if( err == kNoError )
		if( strlen( string ) > kMaxStringLength - 1 )
			err = kSTStringTooLongError;

	if( err == kNoError )
		if( strlen( fontPath ) > kMaxPathLength - 1 )
			err = kSTPathTooLongError;
	
	if( err == kNoError )
	{
		tempStaticTextP = malloc( sizeof( StaticTextRec ) );
		if( ! tempStaticTextP ) err = kMemoryAllocationError;
	}
	
	if( err == kNoError )
		err = SWCreateSprite( (SpritePtr*)&tempStaticTextP, tempStaticTextP, 1 );		

	if( err == kNoError )
	{
		SWSetSpriteMoveProc( (SpritePtr)tempStaticTextP, handleStaticText );
		
			// make the frame to which we will be copying each line of text
		err = SWCreateBlankFrame(
			&frameP,
			SW_RECT_WIDTH( *bounds ),
			SW_RECT_HEIGHT( *bounds ),
			SDL_GetVideoInfo()->vfmt->BitsPerPixel,
			true );
	}
				
	if( err == kNoError )
	{
		SWSetSpriteLocation( (SpritePtr)tempStaticTextP, bounds->left, bounds->top );
		err = SWAddFrame( (SpritePtr)tempStaticTextP, frameP );
	}
	
	if( err == kNoError )
	{
		strcpy( tempStaticTextP->string, string );
		strcpy( tempStaticTextP->fontPath, fontPath );
		tempStaticTextP->fontSize = fontSize;
		tempStaticTextP->fontStyle = gDefaultStyle;
		tempStaticTextP->wrap = wrap;
		tempStaticTextP->bounds = *bounds;
		tempStaticTextP->align = gDefaultAlign;
		tempStaticTextP->rendering = gDefaultRendering;
		tempStaticTextP->textColor = gDefaultTextColor;
		tempStaticTextP->backColor = gDefaultBackColor;
		
		err = SWSetCurrentFrameIndex( (SpritePtr)tempStaticTextP, 0 );
	}
		
	if( err == kNoError )
		err = renderStaticText( tempStaticTextP );

	if( err == kNoError )
	{
		SWLockSprite( (SpritePtr)tempStaticTextP );
		*newStaticTextPP = tempStaticTextP;
	}
	
	if( err != kNoError )
	{
			// clean up what we can
		if( tempStaticTextP ) st_DisposeStaticText( &tempStaticTextP );
		if( frameP ) SWDisposeFrame( &frameP );
	}
	
	SWSetStickyIfError( err );
	return err;
}
Пример #4
0
void StatsItemDrawProc(
    FramePtr srcFrameP,
    FramePtr dstFrameP,
    SWRect* srcRectP,
    SWRect* dstRectP)
{
    short           n, theDigit, width, index, fillValue;
    long            theNum;
    char            digitArray[10];         // Enough digits for a long
    StatsStructPtr      statsStructP;
    FramePtr        *srcFrameArray;
    SWRect          destRect, srcRect, frameRect, clippedDstRect;
                
    SW_ASSERT(gSWCurrentElementDrawData != NULL);
    
    statsStructP = (StatsStructPtr)gSWCurrentElementDrawData->parentSpriteP;
    srcFrameArray = gSWCurrentElementDrawData->parentSpriteP->frameArray;
    theNum = statsStructP->theNum;

    if (statsStructP->fillWithZeros)
        fillValue = 0;
    else
        fillValue = -1;

        // Fill the unused part of the display with either nothing or 0s.
    for (n=0; n < statsStructP->numDigits; n++)
        digitArray[n] = fillValue;
    
        // Put the number into the digitArray
    if (theNum >= 0)
    {
        if (statsStructP->justification == kLeftJustify)
            index = GetNumberLength(theNum)-1;
        else
            index = statsStructP->numDigits-1;

        do
        {       // Fill digitArray with the digits from the new number
            digitArray[index] = theNum%10;      // Get the right-most digit
            index--;
            theNum /= 10;                       // Remove the right-most digit
        } while (theNum > 0 && index >= 0);
    }
    
    destRect = *dstRectP;
    frameRect = srcFrameArray[0]->frameRect;
    width = SW_RECT_WIDTH(frameRect);
    
        // Expand destRect's left and top to its original size before it was clipped
    if (srcRectP->top > frameRect.top)
        destRect.top += frameRect.top - srcRectP->top;
    if (srcRectP->left > frameRect.left)
        destRect.left += frameRect.left - srcRectP->left;
    
        // The destRect's width and height should be the size of one digit.
    destRect.bottom = destRect.top + SW_RECT_HEIGHT(frameRect);
    destRect.right = destRect.left + width;

    
        // Draw the number
    for (index = 0; index < statsStructP->numDigits; index++)
    {
        theDigit = digitArray[index];
        
        if (theDigit >= 0)
        {
            srcFrameP = srcFrameArray[theDigit];
            srcRect = srcFrameP->frameRect;
            
                // Clip each digit with the dstRect passed to this drawProc.
            clippedDstRect = destRect;
            SW_CLIP_DST_AND_SRC_RECT(clippedDstRect, srcRect, (*dstRectP));

                // Set the sprite's location (used by hardware drawprocs)
            gSWCurrentElementDrawData->horizLoc = clippedDstRect.left;
            gSWCurrentElementDrawData->vertLoc = clippedDstRect.top;

            if (gSWCurrentSpriteWorld != NULL)
            {
                gSWCurrentElementDrawData->horizLoc += gSWCurrentSpriteWorld->visScrollRect.left;
                gSWCurrentElementDrawData->vertLoc += gSWCurrentSpriteWorld->visScrollRect.top;
            }
            
                // Draw the digit
            (*statsStructP->drawProc)(srcFrameP, dstFrameP, &srcRect, &clippedDstRect);
        }
        
        destRect.left += width;
        destRect.right += width;
    }
}