Esempio n. 1
0
void ColorBitmapText::DrawPrimitives( )
{
	Actor::SetGlobalRenderStates();	// set Actor-specified render states
	DISPLAY->SetTextureMode( TextureUnit_1, TextureMode_Modulate );

	/* Draw if we're not fully transparent or the zbuffer is enabled */
	if( m_pTempState->diffuse[0].a != 0 )
	{
		//
		// render the shadow
		//
		if( m_fShadowLengthX != 0  ||  m_fShadowLengthY != 0 )
		{
			DISPLAY->PushMatrix();
			DISPLAY->TranslateWorld( m_fShadowLengthX, m_fShadowLengthY, 0 );	// shift by 5 units
			RageColor c = m_ShadowColor;
			c.a *= m_pTempState->diffuse[0].a;
			for( unsigned i=0; i<m_aVertices.size(); i++ )
				m_aVertices[i].c = c;
			DrawChars( true );

			DISPLAY->PopMatrix();
		}

		//
		// render the diffuse pass
		//
		int loc = 0, cur = 0;
		RageColor c = m_pTempState->diffuse[0];

		for( unsigned i=0; i<m_aVertices.size(); i+=4 )
		{
			loc++;
			if( cur < (int)m_vColors.size() )
			{
				if ( loc > m_vColors[cur].l )
				{
					c = m_vColors[cur].c;
					cur++;
				}
			}
			for( unsigned j=0; j<4; j++ )
				m_aVertices[i+j].c = c;
		}

		DrawChars( false );
	}

	/* render the glow pass */
	if( m_pTempState->glow.a > 0.0001f )
	{
		DISPLAY->SetTextureMode( TextureUnit_1, TextureMode_Glow );

		for( unsigned i=0; i<m_aVertices.size(); i++ )
			m_aVertices[i].c = m_pTempState->glow;
		DrawChars( false );
	}
}
Esempio n. 2
0
void ColorBitmapText::DrawPrimitives( )
{
	Actor::SetGlobalRenderStates();	// set Actor-specified render states
	DISPLAY->SetTextureModeModulate();

	/* Draw if we're not fully transparent or the zbuffer is enabled */
	if( m_pTempState->diffuse[0].a != 0 )
	{
		//////////////////////
		// render the shadow
		//////////////////////
		if( m_fShadowLength != 0 )
		{
			DISPLAY->PushMatrix();
			DISPLAY->TranslateWorld( m_fShadowLength, m_fShadowLength, 0 );	// shift by 5 units

			RageColor dim(0,0,0,0.5f*m_pTempState->diffuse[0].a);	// semi-transparent black

			for( unsigned i=0; i<m_aVertices.size(); i++ )
				m_aVertices[i].c = dim;
			DrawChars();

			DISPLAY->PopMatrix();
		}

		//////////////////////
		// render the diffuse pass
		//////////////////////
		int loc = 0, cur = 0;
		RageColor c = m_pTempState->diffuse[0];

		for( unsigned i=0; i<m_aVertices.size(); i+=4 )
		{
			loc++;
			if ( cur < (int)m_vColors.size() )
				if ( loc > m_vColors[cur].l )
				{
					c = m_vColors[cur].c;
					cur++;
				}
			for ( unsigned j=0; j<4; j++ )
				m_aVertices[i+j].c = c;
		}

		DrawChars();
	}

	/* render the glow pass */
	if( m_pTempState->glow.a > 0.0001f )
	{
		DISPLAY->SetTextureModeGlow();

		for( unsigned i=0; i<m_aVertices.size(); i++ )
			m_aVertices[i].c = m_pTempState->glow;
		DrawChars();
	}
	Actor::DrawPrimitives();
}
Esempio n. 3
0
//-----------------------------------------------------------------------------
// Draw a vertical wire one leaf element unit high up from (cx, cy), where cx
// and cy are in charcter units.
//-----------------------------------------------------------------------------
static void VerticalWire(int cx, int cy)
{
    int j;
    for(j = 1; j < POS_HEIGHT; j++) {
        DrawChars(cx, cy + (POS_HEIGHT/2 - j), "|");
    }
    DrawChars(cx, cy + (POS_HEIGHT/2), "+");
    DrawChars(cx, cy + (POS_HEIGHT/2 - POS_HEIGHT), "+");
}
Esempio n. 4
0
//-----------------------------------------------------------------------------
// Draw the rung that signals the end of the program. Kind of useless but
// do it anyways, for convention.
//-----------------------------------------------------------------------------
void DrawEndRung(int cx, int cy)
{
    int i;
    char *str = "[END]";
    int lead = (POS_WIDTH - strlen(str))/2;
    ThisHighlighted = TRUE;
    for(i = 0; i < lead; i++) {
        DrawChars(cx + i, cy + (POS_HEIGHT/2), "-");
    }
    DrawChars(cx + i, cy + (POS_HEIGHT/2), str);
    i += strlen(str);
    for(; i < ColsAvailable*POS_WIDTH; i++) {
        DrawChars(cx + i, cy + (POS_HEIGHT/2), "-");
    }
}
Esempio n. 5
0
// *************************************************************************
// Draw an item on the screen
// *************************************************************************
static void DrawItem( char* Name, int y, long Price )
{
	int j;

	FntSetFont( stdFont );
	DrawChars( Name, 30, y );

	EraseRectangle( 110, y, 56, 9 );
	StrIToA( SBuf, Price );
	StrCat( SBuf, " cr." );
	
	j = MAXDIGITS - StrLen( SBuf );
	if (Price > 0)
		DrawChars( SBuf, 124+j*5, y );
	else
		DrawChars( "not sold", 122, y );
}
Esempio n. 6
0
//-----------------------------------------------------------------------------
// Like CenterWithWires, but for an arbitrary width position (e.g. for ADD
// and SUB, which are double-width).
//-----------------------------------------------------------------------------
static void CenterWithWiresWidth(int cx, int cy, char *str, BOOL before,
    BOOL after, int totalWidth)
{
    int extra = totalWidth - FormattedStrlen(str);

    PoweredText(after);
    DrawChars(cx + (extra/2), cy + (POS_HEIGHT/2), str);

    PoweredText(before);
    int i;
    for(i = 0; i < (extra/2); i++) {
        DrawChars(cx + i, cy + (POS_HEIGHT/2), "-");
    }
    PoweredText(after);
    for(i = FormattedStrlen(str)+(extra/2); i < totalWidth; i++) {
        DrawChars(cx + i, cy + (POS_HEIGHT/2), "-");
    }
}
Esempio n. 7
0
//-----------------------------------------------------------------------------
// Draw a string, centred in the space of a single position, with spaces on
// the left and right. Draws on the upper line of the position.
//-----------------------------------------------------------------------------
static void CenterWithSpaces(int cx, int cy, char *str, BOOL powered,
    BOOL isName)
{
    int extra = POS_WIDTH - FormattedStrlen(str);
    PoweredText(powered);
    if(isName) NameText();
    DrawChars(cx + (extra/2), cy + (POS_HEIGHT/2) - 1, str);
    if(isName) BodyText();
}
Esempio n. 8
0
// draw text at x, y using colorTop blended down to colorBottom, with size multiplied by scale
void BitmapText::DrawPrimitives()
{
	Actor::SetGlobalRenderStates();	// set Actor-specified render states
	DISPLAY->SetTextureModeModulate();

	/* Draw if we're not fully transparent or the zbuffer is enabled */
	if( m_pTempState->diffuse[0].a != 0 )
	{
		//////////////////////
		// render the shadow
		//////////////////////
		if( m_fShadowLength != 0 )
		{
			DISPLAY->PushMatrix();
			DISPLAY->TranslateWorld( m_fShadowLength, m_fShadowLength, 0 );	// shift by 5 units

			RageColor dim(0,0,0,0.5f*m_pTempState->diffuse[0].a);	// semi-transparent black

			for( unsigned i=0; i<m_aVertices.size(); i++ )
				m_aVertices[i].c = dim;
			DrawChars();

			DISPLAY->PopMatrix();
		}

		//////////////////////
		// render the diffuse pass
		//////////////////////
		if( m_bRainbow )
		{
			int color_index = int(RageTimer::GetTimeSinceStartFast() / 0.200) % NUM_RAINBOW_COLORS;
			for( unsigned i=0; i<m_aVertices.size(); i+=4 )
			{
				const RageColor color = RAINBOW_COLORS[color_index];
				for( unsigned j=i; j<i+4; j++ )
					m_aVertices[j].c = color;

				color_index = (color_index+1)%NUM_RAINBOW_COLORS;
			}
		}
		else
		{
			for( unsigned i=0; i<m_aVertices.size(); i+=4 )
			{
				m_aVertices[i+0].c = m_pTempState->diffuse[0];	// top left
				m_aVertices[i+1].c = m_pTempState->diffuse[2];	// bottom left
				m_aVertices[i+2].c = m_pTempState->diffuse[3];	// bottom right
				m_aVertices[i+3].c = m_pTempState->diffuse[1];	// top right
			}
		}

		DrawChars();
	}

	/* render the glow pass */
	if( m_pTempState->glow.a > 0.0001f )
	{
		DISPLAY->SetTextureModeGlow();

		for( unsigned i=0; i<m_aVertices.size(); i++ )
			m_aVertices[i].c = m_pTempState->glow;
		DrawChars();
	}
}
Esempio n. 9
0
// draw text at x, y using colorTop blended down to colorBottom, with size multiplied by scale
void BitmapText::DrawPrimitives()
{
	Actor::SetGlobalRenderStates(); // set Actor-specified render states
	DISPLAY->SetTextureMode( TextureUnit_1, TextureMode_Modulate );

	// Draw if we're not fully transparent or the zbuffer is enabled
	if( m_pTempState->diffuse[0].a != 0 )
	{
		// render the shadow
		if( m_fShadowLengthX != 0  ||  m_fShadowLengthY != 0 )
		{
			DISPLAY->PushMatrix();
			DISPLAY->TranslateWorld( m_fShadowLengthX, m_fShadowLengthY, 0 );

			RageColor c = m_ShadowColor;
			c.a *= m_pTempState->diffuse[0].a;
			for( unsigned i=0; i<m_aVertices.size(); i++ )
				m_aVertices[i].c = c;
			DrawChars( false );

			DISPLAY->PopMatrix();
		}

		// render the stroke
		if( m_StrokeColor.a > 0 )
		{
			RageColor c = m_StrokeColor;
			c.a *= m_pTempState->diffuse[0].a;
			for( unsigned i=0; i<m_aVertices.size(); i++ )
				m_aVertices[i].c = c;
			DrawChars( true );
		}

		// render the diffuse pass
		if( m_bRainbowScroll )
		{
			int color_index = int(RageTimer::GetTimeSinceStartFast() / 0.200) % RAINBOW_COLORS.size();
			for( unsigned i=0; i<m_aVertices.size(); i+=4 )
			{
				const RageColor color = RAINBOW_COLORS[color_index];
				for( unsigned j=i; j<i+4; j++ )
					m_aVertices[j].c = color;

				color_index = (color_index+1) % RAINBOW_COLORS.size();
			}
		}
		else
		{
			size_t i = 0;
			map<size_t,Attribute>::const_iterator iter = m_mAttributes.begin();
			while( i < m_aVertices.size() )
			{
				// Set the colors up to the next attribute.
				size_t iEnd = iter == m_mAttributes.end()? m_aVertices.size():iter->first*4;
				iEnd = min( iEnd, m_aVertices.size() );
				for( ; i < iEnd; i += 4 )
				{
					m_aVertices[i+0].c = m_pTempState->diffuse[0];	// top left
					m_aVertices[i+1].c = m_pTempState->diffuse[2];	// bottom left
					m_aVertices[i+2].c = m_pTempState->diffuse[3];	// bottom right
					m_aVertices[i+3].c = m_pTempState->diffuse[1];	// top right
				}
				if( iter == m_mAttributes.end() )
					break;
				// Set the colors according to this attribute.
				const Attribute &attr = iter->second;
				++iter;
				if( attr.length < 0 )
					iEnd = iter == m_mAttributes.end()? m_aVertices.size():iter->first*4;
				else
					iEnd = i + attr.length*4;
				iEnd = min( iEnd, m_aVertices.size() );
				for( ; i < iEnd; i += 4 )
				{
					m_aVertices[i+0].c = attr.diffuse[0];	// top left
					m_aVertices[i+1].c = attr.diffuse[2];	// bottom left
					m_aVertices[i+2].c = attr.diffuse[3];	// bottom right
					m_aVertices[i+3].c = attr.diffuse[1];	// top right
				}
			}
		}

		// apply jitter to verts
		vector<RageVector3> vGlyphJitter;
		if( m_bJitter )
		{
			int iSeed = lrintf( RageTimer::GetTimeSinceStartFast()*8 );
			RandomGen rnd( iSeed );

			for( unsigned i=0; i<m_aVertices.size(); i+=4 )
			{
				RageVector3 jitter( rnd()%2, rnd()%3, 0 );
				vGlyphJitter.push_back( jitter );

				m_aVertices[i+0].p += jitter;	// top left
				m_aVertices[i+1].p += jitter;	// bottom left
				m_aVertices[i+2].p += jitter;	// bottom right
				m_aVertices[i+3].p += jitter;	// top right
			}
		}

		DrawChars( false );

		// undo jitter to verts
		if( m_bJitter )
		{
			ASSERT( vGlyphJitter.size() == m_aVertices.size()/4 );
			for( unsigned i=0; i<m_aVertices.size(); i+=4 )
			{
				const RageVector3 &jitter = vGlyphJitter[i/4];;

				m_aVertices[i+0].p -= jitter;	// top left
				m_aVertices[i+1].p -= jitter;	// bottom left
				m_aVertices[i+2].p -= jitter;	// bottom right
				m_aVertices[i+3].p -= jitter;	// top right
			}
		}
	}

	// render the glow pass
	if( m_pTempState->glow.a > 0.0001f || m_bHasGlowAttribute )
	{
		DISPLAY->SetTextureMode( TextureUnit_1, TextureMode_Glow );

		size_t i = 0;
		map<size_t,Attribute>::const_iterator iter = m_mAttributes.begin();
		while( i < m_aVertices.size() )
		{
			// Set the glow up to the next attribute.
			size_t iEnd = iter == m_mAttributes.end()? m_aVertices.size():iter->first*4;
			iEnd = min( iEnd, m_aVertices.size() );
			for( ; i < iEnd; ++i )
				m_aVertices[i].c = m_pTempState->glow;
			if( iter == m_mAttributes.end() )
				break;
			// Set the glow according to this attribute.
			const Attribute &attr = iter->second;
			++iter;
			if( attr.length < 0 )
				iEnd = iter == m_mAttributes.end()? m_aVertices.size():iter->first*4;
			else
				iEnd = i + attr.length*4;
			iEnd = min( iEnd, m_aVertices.size() );
			for( ; i < iEnd; ++i )
				m_aVertices[i].c = attr.glow;
		}
		/* Draw glow using the base texture and the glow texture. Otherwise,
		 * glow looks too tame on BitmapText that has a stroke. - Chris Danford */
		/* This doesn't work well if the font is using an invisible stroke, as
		 * the invisible stroke will glow as well. Time for TextGlowMode.
		 * Only draw the strokes if the glow mode is not inner only. -aj */
		DrawChars(m_TextGlowMode != TextGlowMode_Inner);
	}
}
Esempio n. 10
0
static void DrawCurrentShipForm()
{
    FormPtr frmP = FrmGetActiveForm();
	int i, j, k, Line, FirstEmptySlot;
	

	RectangularShortcuts( frmP, CurrentShipBButton );

	FrmDrawForm( frmP );

	FntSetFont( boldFont );
	DrawChars( "Type:", 0, 18 );			

	DrawChars( "Equipment:", 0, 32 );			

	FntSetFont( stdFont );
	if (ScarabStatus == 3)
	{
		StrCopy( SBuf, Shiptype[Ship.Type].Name);
		StrCat ( SBuf, "/hardened hull");
		DrawChars( SBuf, 60, 18 );			
	}
	else
		DrawChars( Shiptype[Ship.Type].Name, 60, 18 );			

	Line = 32;

	for (i=0; i<MAXWEAPONTYPE+EXTRAWEAPONS; ++i)
	{
		j = 0;
		for (k=0; k<MAXWEAPON; ++k)
		{
			if (Ship.Weapon[k] == i)
				++j;
		}
		if (j > 0)
		{
			SBuf[0] = '\0';
			SBufMultiples( j, Weapontype[i].Name );
			StrToLower( SBuf2, SBuf );
			DrawChars( SBuf2, 60, Line );
			Line += 14;
		}
	}

	for (i=0; i<MAXSHIELDTYPE+EXTRASHIELDS; ++i)
	{
		j = 0;
		for (k=0; k<MAXSHIELD; ++k)
		{
			if (Ship.Shield[k] == i)
				++j;
		}
		if (j > 0)
		{
			SBuf[0] = '\0';
			SBufMultiples( j, Shieldtype[i].Name );
			StrToLower( SBuf2, SBuf );
			DrawChars( SBuf2, 60, Line );		
			Line += 14;
		}
	}
	for (i=0; i<MAXGADGETTYPE+EXTRAGADGETS; ++i)
	{
		j = 0;
		for (k=0; k<MAXGADGET; ++k)
		{
			if (Ship.Gadget[k] == i)
				++j;
		}
		if (j > 0)
		{
			if (i == EXTRABAYS)
			{
				j = j*5;
				StrIToA( SBuf, j );
				StrCat( SBuf, " extra cargo bays" );
			}
			else
			{
				StrCopy(SBuf, Gadgettype[i].Name );
			}
			StrToLower( SBuf2, SBuf );
			DrawChars( SBuf2, 60, Line );
			Line += 14;			
		}
	}

	if (EscapePod)
	{
		DrawChars( "an escape pod", 60, Line );			
		Line += 14;
	}

	if (AnyEmptySlots(&Ship))
	{			
		FntSetFont( boldFont );
		DrawChars( "Unfilled:        ", 0, Line );			

		FntSetFont( stdFont );

		FirstEmptySlot = GetFirstEmptySlot( Shiptype[Ship.Type].WeaponSlots, Ship.Weapon );
		if (FirstEmptySlot >= 0)
		{
			SBuf[0] = '\0';
			SBufMultiples( Shiptype[Ship.Type].WeaponSlots - FirstEmptySlot, "weapon slot" );
			DrawChars( SBuf, 60, Line );			
			Line += 14;
		}
		
		FirstEmptySlot = GetFirstEmptySlot( Shiptype[Ship.Type].ShieldSlots, Ship.Shield );
		if (FirstEmptySlot >= 0)
		{
			SBuf[0] = '\0';
			SBufMultiples( Shiptype[Ship.Type].ShieldSlots - FirstEmptySlot, "shield slot" );
			DrawChars( SBuf, 60, Line );			
			Line += 14;
		}
		
		FirstEmptySlot = GetFirstEmptySlot( Shiptype[Ship.Type].GadgetSlots, Ship.Gadget );
		if (FirstEmptySlot >= 0)
		{
			SBuf[0] = '\0';
			SBufMultiples( Shiptype[Ship.Type].GadgetSlots - FirstEmptySlot, "gadget slot" );
			DrawChars( SBuf, 60, Line );			
			Line += 14;
		}
	}

}
Esempio n. 11
0
//-----------------------------------------------------------------------------
// Draw a particular subcircuit with its top left corner at *cx and *cy (in
// characters). If it is a leaf element then just print it and return; else
// loop over the elements of the subcircuit and call ourselves recursively.
// At the end updates *cx and *cy.
//
// In simulation mode, returns TRUE the circuit is energized after the given
// element, else FALSE. This is needed to colour all the wires correctly,
// since the colouring indicates whether a wire is energized.
//-----------------------------------------------------------------------------
BOOL DrawElement(int which, void *elem, int *cx, int *cy, BOOL poweredBefore)
{
    BOOL poweredAfter;

    int cx0 = *cx, cy0 = *cy;
    ElemLeaf *leaf = (ElemLeaf *)elem;

    SetBkColor(Hdc, InSimulationMode ? HighlightColours.simBg :
        HighlightColours.bg);
    NormText();

    if(elem == Selected && !InSimulationMode) {
        EmphText();
        ThisHighlighted = TRUE;
    } else {
        ThisHighlighted = FALSE;
    }

    switch(which) {
        case ELEM_SERIES_SUBCKT: {
            int i;
            ElemSubcktSeries *s = (ElemSubcktSeries *)elem;
            poweredAfter = poweredBefore;
            for(i = 0; i < s->count; i++) {
                poweredAfter = DrawElement(s->contents[i].which,
                    s->contents[i].d.any, cx, cy, poweredAfter);
            }
            break;
        }
        case ELEM_PARALLEL_SUBCKT: {
            int i;
            ElemSubcktParallel *p = (ElemSubcktParallel *)elem;
            int widthMax = CountWidthOfElement(which, elem, (*cx)/POS_WIDTH);
            int heightMax = CountHeightOfElement(which, elem);

            poweredAfter = FALSE;

            int lowestPowered = -1;
            int downBy = 0;
            for(i = 0; i < p->count; i++) {
                BOOL poweredThis;

                poweredThis = DrawElement(p->contents[i].which,
                    p->contents[i].d.any, cx, cy, poweredBefore);

                if(InSimulationMode) {
                    if(poweredThis) poweredAfter = TRUE;
                    PoweredText(poweredThis);
                }

                while((*cx - cx0) < widthMax*POS_WIDTH) {
                    int gx = *cx/POS_WIDTH;
                    int gy = *cy/POS_HEIGHT;

                    if(CheckBoundsUndoIfFails(gx, gy)) return FALSE;

                    DM_BOUNDS(gx, gy);
                    DisplayMatrix[gx][gy] = PADDING_IN_DISPLAY_MATRIX;
                    DisplayMatrixWhich[gx][gy] = ELEM_PADDING;

                    char buf[256];
                    int j;
                    for(j = 0; j < POS_WIDTH; j++) {
                        buf[j] = '-';
                    }
                    buf[j] = '\0';
                    DrawChars(*cx, *cy + (POS_HEIGHT/2), buf);
                    *cx += POS_WIDTH;
                }

                *cx = cx0;
                int justDrewHeight = CountHeightOfElement(p->contents[i].which,
                    p->contents[i].d.any);
                *cy += POS_HEIGHT*justDrewHeight;

                downBy += justDrewHeight;
                if(poweredThis) {
                    lowestPowered = downBy - 1;
                }
            }
            *cx = cx0 + POS_WIDTH*widthMax;
            *cy = cy0;

            int j;
            BOOL needWire;

            if(*cx/POS_WIDTH != ColsAvailable) {
                needWire = FALSE;
                for(j = heightMax - 1; j >= 1; j--) {
                    if(j <= lowestPowered) PoweredText(poweredAfter);
                    if(DisplayMatrix[*cx/POS_WIDTH - 1][*cy/POS_HEIGHT + j]) {
                        needWire = TRUE;
                    }
                    if(needWire) VerticalWire(*cx - 1, *cy + j*POS_HEIGHT);
                }
                // stupid special case
                if(lowestPowered == 0 && InSimulationMode) {
                    EmphText();
                    DrawChars(*cx - 1, *cy + (POS_HEIGHT/2), "+");
                }
            }

            PoweredText(poweredBefore);
            needWire = FALSE;
            for(j = heightMax - 1; j >= 1; j--) {
                if(DisplayMatrix[cx0/POS_WIDTH][*cy/POS_HEIGHT + j]) {
                    needWire = TRUE;
                }
                if(needWire) VerticalWire(cx0 - 1, *cy + j*POS_HEIGHT);
            }

            break;
        }
        default:
            poweredAfter = DrawLeaf(which, leaf, cx, cy, poweredBefore);
            break;
    }


    NormText();
    return poweredAfter;
}
Esempio n. 12
0
//-----------------------------------------------------------------------------
// Draw a leaf element. Special things about a leaf: no need to recurse
// further, and we must put it into the display matrix.
//-----------------------------------------------------------------------------
static BOOL DrawLeaf(int which, ElemLeaf *leaf, int *cx, int *cy,
    BOOL poweredBefore)
{
    int cx0 = *cx, cy0 = *cy;
    BOOL poweredAfter = leaf->poweredAfter;

    switch(which) {
        case ELEM_COMMENT: {
            char tbuf[MAX_COMMENT_LEN];
            char tlbuf[MAX_COMMENT_LEN+8];

            strcpy(tbuf, leaf->d.comment.str);
            char *b = strchr(tbuf, '\n');

            if(b) {
                if(b[-1] == '\r') b[-1] = '\0';
                *b = '\0';
                sprintf(tlbuf, "\x03 ; %s\x02", tbuf);
                DrawChars(*cx, *cy + (POS_HEIGHT/2) - 1, tlbuf);
                sprintf(tlbuf, "\x03 ; %s\x02", b+1);
                DrawChars(*cx, *cy + (POS_HEIGHT/2), tlbuf);
            } else {
                sprintf(tlbuf, "\x03 ; %s\x02", tbuf);
                DrawChars(*cx, *cy + (POS_HEIGHT/2) - 1, tlbuf);
            }

            *cx += ColsAvailable*POS_WIDTH;
            break;
        }
        case ELEM_PLACEHOLDER: {
            NormText();
            CenterWithWiresWidth(*cx, *cy, "--", FALSE, FALSE, 2);
            *cx += POS_WIDTH;
            break;
        }
        case ELEM_CONTACTS: {
            char buf[4];
            ElemContacts *c = &leaf->d.contacts;

            buf[0] = ']';
            buf[1] = c->negated ? '/' : ' ';
            buf[2] = '[';
            buf[3] = '\0';

            CenterWithSpaces(*cx, *cy, c->name, poweredAfter, TRUE);
            CenterWithWires(*cx, *cy, buf, poweredBefore, poweredAfter);

            *cx += POS_WIDTH;
            break;
        }
        {
            char *s;
            case ELEM_EQU:
                s = "=="; goto cmp;
            case ELEM_NEQ:
                s = "/="; goto cmp;
            case ELEM_GRT:
                s = ">"; goto cmp;
            case ELEM_GEQ:
                s = ">="; goto cmp;
            case ELEM_LES:
                s = "<"; goto cmp;
            case ELEM_LEQ:
                s = "<="; goto cmp;
cmp:
                char s1[POS_WIDTH+10], s2[POS_WIDTH+10];
                int l1, l2, lmax;

                l1 = 2 + 1 + strlen(s) + strlen(leaf->d.cmp.op1);
                l2 = 2 + 1 + strlen(leaf->d.cmp.op2);
                lmax = max(l1, l2);

                memset(s1, ' ', sizeof(s1));
                s1[0] = '[';
                int lcmp = lmax < POS_WIDTH ? lmax : POS_WIDTH;
                s1[lcmp - 1] = ']';
                s1[lcmp] = '\0';
                strcpy(s2, s1);

                if(l1 >= POS_WIDTH) {
                    memcpy(s1 + 1, leaf->d.cmp.op1, 3);
                    memset(s1 + 4, '.', 3);
                    memcpy(s1 + 7, leaf->d.cmp.op1 + strlen(leaf->d.cmp.op1) - 3, 3);
                    memcpy(s1 + 9 + 2, s, strlen(s));
                } else {
                    memcpy(s1 + 1, leaf->d.cmp.op1, strlen(leaf->d.cmp.op1));
                    memcpy(s1 + strlen(leaf->d.cmp.op1) + 2, s, strlen(s));
                }
                if(l2 >= POS_WIDTH) {
                    memcpy(s2 + 1, leaf->d.cmp.op2, 3);
                    memset(s2 + 4, '.', 3);
                    memcpy(s2 + 7, leaf->d.cmp.op2 + strlen(leaf->d.cmp.op2) - 3, 3);
                } else {
                    memcpy(s2 + 2, leaf->d.cmp.op2, strlen(leaf->d.cmp.op2));
                }

                CenterWithSpaces(*cx, *cy, s1, poweredAfter, FALSE);
                CenterWithWires(*cx, *cy, s2, poweredBefore, poweredAfter);

                *cx += POS_WIDTH;
                break;
        }
        case ELEM_OPEN:
            CenterWithWires(*cx, *cy, "+      +", poweredBefore, poweredAfter);
            *cx += POS_WIDTH;
            break;

        case ELEM_SHORT:
            CenterWithWires(*cx, *cy, "+------+", poweredBefore, poweredAfter);
            *cx += POS_WIDTH;
            break;

        case ELEM_ONE_SHOT_RISING:
        case ELEM_ONE_SHOT_FALLING: {
            char *s1, *s2;
            if(which == ELEM_ONE_SHOT_RISING) {
                s1 = "      _ ";
                s2 = "[\x01OSR\x02_/ ]";
            } else if(which == ELEM_ONE_SHOT_FALLING) {
                s1 = "    _   ";
                s2 = "[\x01OSF\x02 \\_]";
            } else oops();

            CenterWithSpaces(*cx, *cy, s1, poweredAfter, FALSE);
            CenterWithWires(*cx, *cy, s2, poweredBefore, poweredAfter);

            *cx += POS_WIDTH;
            break;
        }
        case ELEM_CTU:
        case ELEM_CTD: {
            char *s;
            if(which == ELEM_CTU)
                s = "\x01""CTU\x02";
            else if(which == ELEM_CTD)
                s = "\x01""CTD\x02";
            else oops();

            char buf[256];
            ElemCounter *c = &leaf->d.counter;
            sprintf(buf, "[%s >=%d]", s, c->max);

            CenterWithSpaces(*cx, *cy, c->name, poweredAfter, TRUE);
            CenterWithWires(*cx, *cy, buf, poweredBefore, poweredAfter);

            *cx += POS_WIDTH;
            break;
        }
        case ELEM_RTO:
        case ELEM_TON:
        case ELEM_TOF: {
            char *s;
            if(which == ELEM_TON)
                s = "\x01TON\x02";
            else if(which == ELEM_TOF)
                s = "\x01TOF\x02";
            else if(which == ELEM_RTO)
                s = "\x01RTO\x02";
            else oops();

            char buf[256];
            ElemTimer *t = &leaf->d.timer;
            if(t->delay >= 1000*1000) {
                sprintf(buf, "[%s %.3f s]", s, t->delay/1000000.0);
            } else if(t->delay >= 100*1000) {
                sprintf(buf, "[%s %.1f ms]", s, t->delay/1000.0);
            } else {
                sprintf(buf, "[%s %.2f ms]", s, t->delay/1000.0);
            }

            CenterWithSpaces(*cx, *cy, t->name, poweredAfter, TRUE);
            CenterWithWires(*cx, *cy, buf, poweredBefore, poweredAfter);

            *cx += POS_WIDTH;
            break;
        }
        case ELEM_FORMATTED_STRING: {
            // Careful, string could be longer than fits in our space.
            char str[POS_WIDTH*2];
            memset(str, 0, sizeof(str));
            char *srcStr = leaf->d.fmtdStr.string;
            memcpy(str, srcStr, min(strlen(srcStr), POS_WIDTH*2 - 7));

            char bot[100];
            sprintf(bot, "{\"%s\"}", str);

            int extra = 2*POS_WIDTH - strlen(leaf->d.fmtdStr.var);
            PoweredText(poweredAfter);
            NameText();
            DrawChars(*cx + (extra/2), *cy + (POS_HEIGHT/2) - 1,
                leaf->d.fmtdStr.var);
            BodyText();

            CenterWithWiresWidth(*cx, *cy, bot, poweredBefore, poweredAfter,
                2*POS_WIDTH);
            *cx += 2*POS_WIDTH;
            break;
        }
        case ELEM_UART_RECV:
        case ELEM_UART_SEND:
            CenterWithWires(*cx, *cy,
                (char *)((which == ELEM_UART_RECV) ? "{UART RECV}" : "{UART SEND}"),
                poweredBefore, poweredAfter);
            CenterWithSpaces(*cx, *cy, leaf->d.uart.name, poweredAfter, TRUE);
            *cx += POS_WIDTH;
            break;

        default:
            poweredAfter = DrawEndOfLine(which, leaf, cx, cy, poweredBefore);
            break;
    }

    // And now we can enter the element into the display matrix so that the
    // UI routines know what element is at position (gx, gy) when the user
    // clicks there, and so that we know where to put the cursor if this
    // element is selected.

    // Don't use original cx0, as an end of line element might be further
    // along than that.
    cx0 = *cx - POS_WIDTH;

    int gx = cx0/POS_WIDTH;
    int gy = cy0/POS_HEIGHT;
    if(CheckBoundsUndoIfFails(gx, gy)) return FALSE;
    DM_BOUNDS(gx, gy);

    DisplayMatrix[gx][gy] = leaf;
    DisplayMatrixWhich[gx][gy] = which;

    int xadj = 0;
    switch(which) {
        case ELEM_ADD:
        case ELEM_SUB:
        case ELEM_MUL:
        case ELEM_DIV:
        case ELEM_FORMATTED_STRING:
            DM_BOUNDS(gx-1, gy);
            DisplayMatrix[gx-1][gy] = leaf;
            DisplayMatrixWhich[gx-1][gy] = which;
            xadj = POS_WIDTH*FONT_WIDTH;
            break;
    }

    if(which == ELEM_COMMENT) {
        int i;
        for(i = 0; i < ColsAvailable; i++) {
            DisplayMatrix[i][gy] = leaf;
            DisplayMatrixWhich[i][gy] = ELEM_COMMENT;
        }
        xadj = (ColsAvailable-1)*POS_WIDTH*FONT_WIDTH;
    }

    int x0 = X_PADDING + cx0*FONT_WIDTH;
    int y0 = Y_PADDING + cy0*FONT_HEIGHT;

    if(leaf->selectedState != SELECTED_NONE && leaf == Selected) {
        SelectionActive = TRUE;
    }
    switch(leaf->selectedState) {
        case SELECTED_LEFT:
            Cursor.left = x0 + FONT_WIDTH - 4 - xadj;
            Cursor.top = y0 - FONT_HEIGHT/2;
            Cursor.width = 2;
            Cursor.height = POS_HEIGHT*FONT_HEIGHT;
            break;

        case SELECTED_RIGHT:
            Cursor.left = x0 + (POS_WIDTH-1)*FONT_WIDTH - 5;
            Cursor.top = y0 - FONT_HEIGHT/2;
            Cursor.width = 2;
            Cursor.height = POS_HEIGHT*FONT_HEIGHT;
            break;

        case SELECTED_ABOVE:
            Cursor.left = x0 + FONT_WIDTH/2 - xadj;
            Cursor.top = y0 - 2;
            Cursor.width = (POS_WIDTH-2)*FONT_WIDTH + xadj;
            Cursor.height = 2;
            break;

        case SELECTED_BELOW:
            Cursor.left = x0 + FONT_WIDTH/2 - xadj;
            Cursor.top = y0 + (POS_HEIGHT-1)*FONT_HEIGHT +
                FONT_HEIGHT/2 - 2;
            Cursor.width = (POS_WIDTH-2)*(FONT_WIDTH) + xadj;
            Cursor.height = 2;
            break;

        default:
            break;
    }

    return poweredAfter;
}
Esempio n. 13
0
//-----------------------------------------------------------------------------
// Draw an end of line element (coil, RES, MOV, etc.). Special things about
// an end of line element: we must right-justify it.
//-----------------------------------------------------------------------------
static BOOL DrawEndOfLine(int which, ElemLeaf *leaf, int *cx, int *cy,
    BOOL poweredBefore)
{
    int cx0 = *cx, cy0 = *cy;

    BOOL poweredAfter = leaf->poweredAfter;

    int thisWidth;
    switch(which) {
        case ELEM_ADD:
        case ELEM_SUB:
        case ELEM_MUL:
        case ELEM_DIV:
            thisWidth = 2;
            break;

        default:
            thisWidth = 1;
            break;
    }

    NormText();
    PoweredText(poweredBefore);
    while(*cx < (ColsAvailable-thisWidth)*POS_WIDTH) {
        int gx = *cx/POS_WIDTH;
        int gy = *cy/POS_HEIGHT;

        if(CheckBoundsUndoIfFails(gx, gy)) return FALSE;

        if(gx >= DISPLAY_MATRIX_X_SIZE) oops();
        DM_BOUNDS(gx, gy);
        DisplayMatrix[gx][gy] = PADDING_IN_DISPLAY_MATRIX;
        DisplayMatrixWhich[gx][gy] = ELEM_PADDING;

        int i;
        for(i = 0; i < POS_WIDTH; i++) {
            DrawChars(*cx + i, *cy + (POS_HEIGHT/2), "-");
        }
        *cx += POS_WIDTH;
        cx0 += POS_WIDTH;
    }

    if(leaf == Selected && !InSimulationMode) {
        EmphText();
        ThisHighlighted = TRUE;
    } else {
        ThisHighlighted = FALSE;
    }

    switch(which) {
        case ELEM_CTC: {
            char buf[256];
            ElemCounter *c = &leaf->d.counter;
            sprintf(buf, "{\x01""CTC\x02 0:%d}", c->max);

            CenterWithSpaces(*cx, *cy, c->name, poweredAfter, TRUE);
            CenterWithWires(*cx, *cy, buf, poweredBefore, poweredAfter);
            break;
        }
        case ELEM_RES: {
            ElemReset *r = &leaf->d.reset;
            CenterWithSpaces(*cx, *cy, r->name, poweredAfter, TRUE);
            CenterWithWires(*cx, *cy, "{RES}", poweredBefore, poweredAfter);
            break;
        }
        case ELEM_READ_ADC: {
            ElemReadAdc *r = &leaf->d.readAdc;
            CenterWithSpaces(*cx, *cy, r->name, poweredAfter, TRUE);
            CenterWithWires(*cx, *cy, "{READ ADC}", poweredBefore,
                poweredAfter);
            break;
        }
        case ELEM_SET_PWM: {
            ElemSetPwm *s = &leaf->d.setPwm;
            CenterWithSpaces(*cx, *cy, s->name, poweredAfter, TRUE);
            char l[50];
            if(s->targetFreq >= 100000) {
                sprintf(l, "{PWM %d kHz}", (s->targetFreq+500)/1000);
            } else if(s->targetFreq >= 10000) {
                sprintf(l, "{PWM %.1f kHz}", s->targetFreq/1000.0);
            } else if(s->targetFreq >= 1000) {
                sprintf(l, "{PWM %.2f kHz}", s->targetFreq/1000.0);
            } else {
                sprintf(l, "{PWM %d Hz}", s->targetFreq);
            }
            CenterWithWires(*cx, *cy, l, poweredBefore,
                poweredAfter);
            break;
        }
        case ELEM_PERSIST:
            CenterWithSpaces(*cx, *cy, leaf->d.persist.var, poweredAfter, TRUE);
            CenterWithWires(*cx, *cy, "{PERSIST}", poweredBefore, poweredAfter);
            break;

        case ELEM_MOVE: {
            char top[256];
            char bot[256];
            ElemMove *m = &leaf->d.move;

            strcpy(top, "{            }");
            if((strlen(m->dest) >= (POS_WIDTH - 9))) {
                memcpy(top + 1, m->dest, 3);
                memset(top + 4, '.', 3);
                memcpy(top + 7, m->dest + strlen(m->dest) - 3, 3);
                top[9 + 2] = ':';
                top[9 + 3] = '=';
            } else {
                memcpy(top + 1, m->dest, strlen(m->dest));
                top[strlen(m->dest) + 3] = ':';
                top[strlen(m->dest) + 4] = '=';
            }

            strcpy(bot, "{         \x01MOV\x02}");
            if (strlen(m->src) >= (POS_WIDTH - 9)) {
                memcpy(bot + 1, m->src, 3);
                memset(bot + 4, '.', 3);
                memcpy(bot + 7, m->src + strlen(m->src) - 2, 2);
            } else {
                memcpy(bot + 2, m->src, strlen(m->src));
            }

            CenterWithSpaces(*cx, *cy, top, poweredAfter, FALSE);
            CenterWithWires(*cx, *cy, bot, poweredBefore, poweredAfter);
            break;
        }
        case ELEM_MASTER_RELAY:
            CenterWithWires(*cx, *cy, "{MASTER RLY}", poweredBefore,
                poweredAfter);
            break;

        case ELEM_SHIFT_REGISTER: {
            char bot[MAX_NAME_LEN+20];
            memset(bot, ' ', sizeof(bot));
            bot[0] = '{';
            sprintf(bot+2, "%s0..%d", leaf->d.shiftRegister.name,
                leaf->d.shiftRegister.stages-1);
            bot[strlen(bot)] = ' ';
            bot[13] = '}';
            bot[14] = '\0';
            CenterWithSpaces(*cx, *cy, "{\x01SHIFT REG\x02   }",
                poweredAfter, FALSE);
            CenterWithWires(*cx, *cy, bot, poweredBefore, poweredAfter);
            break;
        }
        case ELEM_PIECEWISE_LINEAR:
        case ELEM_LOOK_UP_TABLE: {
            char top[MAX_NAME_LEN+20], bot[MAX_NAME_LEN+20];
            char *dest, *index, *str;
            if(which == ELEM_PIECEWISE_LINEAR) {
                dest = leaf->d.piecewiseLinear.dest;
                index = leaf->d.piecewiseLinear.index;
                str = "PWL";
            } else {
                dest = leaf->d.lookUpTable.dest;
                index = leaf->d.lookUpTable.index;
                str = "LUT";
            }
            memset(top, ' ', sizeof(top));
            top[0] = '{';
            sprintf(top+2, "%s :=", dest);
            top[strlen(top)] = ' ';
            top[13] = '}';
            top[14] = '\0';
            CenterWithSpaces(*cx, *cy, top, poweredAfter, FALSE);
            memset(bot, ' ', sizeof(bot));
            bot[0] = '{';
            sprintf(bot+2, " %s[%s]", str, index);
            bot[strlen(bot)] = ' ';
            bot[13] = '}';
            bot[14] = '\0';
            CenterWithWires(*cx, *cy, bot, poweredBefore, poweredAfter);
            break;
        }
        case ELEM_COIL: {
            char buf[4];
            ElemCoil *c = &leaf->d.coil;

            buf[0] = '(';
            if(c->negated) {
                buf[1] = '/';
            } else if(c->setOnly) {
                buf[1] = 'S';
            } else if(c->resetOnly) {
                buf[1] = 'R';
            } else {
                buf[1] = ' ';
            }
            buf[2] = ')';
            buf[3] = '\0';

            CenterWithSpaces(*cx, *cy, c->name, poweredAfter, TRUE);
            CenterWithWires(*cx, *cy, buf, poweredBefore, poweredAfter);
            break;
        }
        case ELEM_DIV:
        case ELEM_MUL:
        case ELEM_SUB:
        case ELEM_ADD: {
            char top[POS_WIDTH*2-3+2];
            char bot[POS_WIDTH*2-3];

            memset(top, ' ', sizeof(top)-1);
            top[0] = '{';

            memset(bot, ' ', sizeof(bot)-1);
            bot[0] = '{';

            int lt = 1;
            if(which == ELEM_ADD) {
                memcpy(top+lt, "\x01""ADD\x02", 5);
            } else if(which == ELEM_SUB) {
                memcpy(top+lt, "\x01SUB\x02", 5);
            } else if(which == ELEM_MUL) {
                memcpy(top+lt, "\x01MUL\x02", 5);
            } else if(which == ELEM_DIV) {
                memcpy(top+lt, "\x01""DIV\x02", 5);
            } else oops();

            lt += 7;
            memcpy(top+lt, leaf->d.math.dest, strlen(leaf->d.math.dest));
            lt += strlen(leaf->d.math.dest) + 2;
            top[lt++] = ':';
            top[lt++] = '=';

            int lb = 2;
            memcpy(bot+lb, leaf->d.math.op1, strlen(leaf->d.math.op1));
            lb += strlen(leaf->d.math.op1) + 1;
            if(which == ELEM_ADD) {
                bot[lb++] = '+';
            } else if(which == ELEM_SUB) {
                bot[lb++] = '-';
            } else if(which == ELEM_MUL) {
                bot[lb++] = '*';
            } else if(which == ELEM_DIV) {
                bot[lb++] = '/';
            } else oops();
            lb++;
            memcpy(bot+lb, leaf->d.math.op2, strlen(leaf->d.math.op2));
            lb += strlen(leaf->d.math.op2);

            int l = max(lb, lt - 2);
            top[l+2] = '}'; top[l+3] = '\0';
            bot[l] = '}'; bot[l+1] = '\0';

            int extra = 2*POS_WIDTH - FormattedStrlen(top);
            PoweredText(poweredAfter);
            DrawChars(*cx + (extra/2), *cy + (POS_HEIGHT/2) - 1, top);
            CenterWithWiresWidth(*cx, *cy, bot, poweredBefore, poweredAfter,
                2*POS_WIDTH);

            *cx += POS_WIDTH;

            break;
        }
        default:
            oops();
            break;
    }

    *cx += POS_WIDTH;

    return poweredAfter;
}