Exemplo n.º 1
0
/*
* Con_DrawInput
*
* The input line scrolls horizontally if typing goes beyond the right edge
*/
static void Con_DrawInput( int vislines )
{
    char draw_search_text[MAXCMDLINE*2+4];
    const char *text = key_lines[edit_line];
    int smallCharHeight = SCR_strHeight( cls.fontSystemSmall );
    int text_y = vislines - 14 - smallCharHeight;
    const int left_margin = 8, right_margin = 8;
    int promptwidth = SCR_strWidth( "]", cls.fontSystemSmall, 1 );
    int cursorwidth = SCR_strWidth( "_", cls.fontSystemSmall, 1 );
    int input_width = viddef.width - left_margin - right_margin;
    int prewidth;	// width of input line before cursor

    if( cls.key_dest != key_console )
        return;

    if( search_text[0] ) {
        text = draw_search_text;
        Q_snprintfz( draw_search_text, sizeof( draw_search_text ), "%s : %s", key_lines[edit_line], search_text );
    }

    prewidth = SCR_strWidth( text, cls.fontSystemSmall, key_linepos );

    // don't let the cursor go beyond the left screen edge
    clamp_high( input_prestep, prewidth - promptwidth);
    // don't let it go beyond the right screen edge
    clamp_low( input_prestep, prewidth - ( input_width - cursorwidth ) );

    SCR_DrawClampString( left_margin - input_prestep,
                         text_y, text, left_margin, text_y,
                         viddef.width - right_margin, viddef.height, cls.fontSystemSmall, colorWhite );

    if( (int)( cls.realtime>>8 )&1 )
        SCR_DrawRawChar( left_margin + prewidth - input_prestep, text_y, '_',
                         cls.fontSystemSmall, colorWhite );
}
Exemplo n.º 2
0
void Bot::CheckAlertSpots(const StaticVector<edict_t *, MAX_CLIENTS> &visibleTargets)
{
    float scores[MAX_ALERT_SPOTS];

    // First compute scores (good for instruction cache)
    for (unsigned i = 0; i < alertSpots.size(); ++i)
    {
        float score = 0.0f;
        const auto &alertSpot = alertSpots[i];
        const float squareRadius = alertSpot.radius * alertSpot.radius;
        const float invRadius = 1.0f / alertSpot.radius;
        for (const edict_t *ent: visibleTargets)
        {
            float squareDistance = DistanceSquared(ent->s.origin, alertSpot.origin.Data());
            if (squareDistance > squareRadius)
                continue;
            float distance = Q_RSqrt(squareDistance + 0.001f);
            score += 1.0f - distance * invRadius;
            // Put likely case first
            if (!(ent->s.effects & EF_CARRIER))
                score *= alertSpot.regularEnemyInfluenceScale;
            else
                score *= alertSpot.carrierEnemyInfluenceScale;
        }
        // Clamp score by a max value
        clamp_high(score, 3.0f);
        // Convert score to [0, 1] range
        score /= 3.0f;
        // Get a square root of score (values closer to 0 gets scaled more than ones closer to 1)
        score = 1.0f / Q_RSqrt(score + 0.001f);
        // Sanitize
        clamp(score, 0.0f, 1.0f);
        scores[i] = score;
    }

    // Then call callbacks
    const unsigned levelTime = level.time;
    for (unsigned i = 0; i < alertSpots.size(); ++i)
    {
        auto &alertSpot = alertSpots[i];
        unsigned nonReportedFor = levelTime - alertSpot.lastReportedAt;
        if (nonReportedFor >= 1000)
            alertSpot.lastReportedScore = 0.0f;

        // Since scores are sanitized, they are in range [0.0f, 1.0f], and abs(scoreDelta) is in range [-1.0f, 1.0f];
        float scoreDelta = scores[i] - alertSpot.lastReportedScore;
        if (scoreDelta >= 0)
        {
            if (nonReportedFor >= 1000 - scoreDelta * 500)
                alertSpot.Alert(this, scores[i]);
        }
        else
        {
            if (nonReportedFor >= 500 - scoreDelta * 500)
                alertSpot.Alert(this, scores[i]);
        }
    }
}
Exemplo n.º 3
0
/*
* IN_IME_GetCandidates
*/
unsigned int IN_IME_GetCandidates( char * const *cands, size_t candSize, unsigned int maxCands, int *selected, int *firstKey ) {
	size_t candListSize;
	CANDIDATELIST *candList = in_winime_candList;
	unsigned int i;

	if( selected ) {
		*selected = -1;
	}
	if( firstKey ) {
		*firstKey = 1;
	}

	if( !in_winime_enabled ) {
		return 0;
	}

	candListSize = qimmGetCandidateList( in_winime_context, 0, NULL, 0 );
	if( !candListSize ) {
		return 0;
	}

	if( candListSize > in_winime_candListSize ) {
		candList = Q_realloc( candList, candListSize );
		if( !candList ) {
			return 0;
		}
		in_winime_candList = candList;
		in_winime_candListSize = candListSize;
	}

	if( qimmGetCandidateList( in_winime_context, 0, candList, candListSize ) != candListSize ) {
		return 0;
	}

	clamp_high( maxCands, candList->dwPageSize );
	if( ( candList->dwPageStart + maxCands ) > candList->dwCount ) {
		maxCands = candList->dwCount - candList->dwPageStart;
	}

	if( cands && candSize ) {
		for( i = 0; i < maxCands; i++ )
			Q_WCharToUtf8String( ( const WCHAR * )( ( const char * )candList + candList->dwOffset[candList->dwPageStart + i] ), cands[i], candSize );
	}

	if( selected && ( candList->dwSelection >= candList->dwPageStart ) && ( candList->dwSelection < ( candList->dwPageStart + maxCands ) ) ) {
		*selected = ( int )candList->dwSelection - ( int )candList->dwPageStart;
	}

	if( firstKey ) {
		if( !( qimmGetProperty( GetKeyboardLayout( 0 ), IGP_PROPERTY ) & IME_PROP_CANDLIST_START_FROM_1 ) ) {
			*firstKey = 0;
		}
	}

	return maxCands;
}
Exemplo n.º 4
0
/*
* SCR_DrawClampFillRect
* 
* Fills a scissored box of pixels with a single color
*/
void SCR_DrawClampFillRect( int x, int y, int w, int h, int xmin, int ymin, int xmax, int ymax, vec4_t color )
{
	int x2 = x + w;
	int y2 = y + h;

	if( ( xmax <= xmin ) || ( ymax <= ymin ) )
		return;

	clamp_low( x, xmin );
	clamp_low( y, ymin );
	clamp_high( x2, xmax );
	clamp_high( y2, ymax );

	w = x2 - x;
	h = y2 - y;
	if( ( w <= 0 ) || ( h <= 0 ) )
		return;

	re.DrawStretchPic( x, y, w, h, 0, 0, 1, 1, color, cls.whiteShader );
}
Exemplo n.º 5
0
/*
* Con_Linefeed
*/
static void Con_Linefeed( void )
{
    // shift scrollback text up in the buffer to make room for a new line
    if (con.numlines == con.totallines )
        Q_free( con.text[con.numlines - 1] );
    memmove( con.text + 1, con.text, sizeof( con.text[0] ) * min( con.numlines, con.totallines - 1 ) );
    con.text[0] = NULL;

    // shift the timings array
    memmove( con.times + 1, con.times, sizeof( con.times[0] ) * ( NUM_CON_TIMES - 1 ) );

    con.x = 0;
    if( con.display )
    {
        // the console is scrolled up, stay in the same place if possible
        con.display++;
        clamp_high( con.display, con.totallines - 1 );
    }
    con.numlines++;
    clamp_high( con.numlines, con.totallines );
}
Exemplo n.º 6
0
void AiEntityPhysicsState::UpdateAreaNums() {
	const AiAasWorld *aasWorld = AiAasWorld::Instance();
	this->currAasAreaNum = ( decltype( this->currAasAreaNum ) )aasWorld->FindAreaNum( Origin() );
	// Use a computation shortcut when entity is on ground
	if( this->groundEntNum >= 0 ) {
		this->droppedToFloorOriginOffset = ( decltype( this->droppedToFloorOriginOffset ) )( -playerbox_stand_mins[2] );
		this->droppedToFloorOriginOffset += 4.0f;
		SetHeightOverGround( 0 );
		Vec3 droppedOrigin( Origin() );
		droppedOrigin.Z() -= this->droppedToFloorOriginOffset;
		this->droppedToFloorAasAreaNum = ( decltype( this->droppedToFloorAasAreaNum ) )aasWorld->FindAreaNum( droppedOrigin );
		return;
	}

	// Use a computation shortcut when the current area is grounded
	if( aasWorld->AreaSettings()[this->currAasAreaNum].areaflags & AREA_GROUNDED ) {
		float areaMinsZ = aasWorld->Areas()[this->currAasAreaNum].mins[2];
		float selfZ = Self()->s.origin[2];
		float heightOverGround_ = selfZ - areaMinsZ + playerbox_stand_maxs[2];
		clamp_high( heightOverGround_, GROUND_TRACE_DEPTH );
		SetHeightOverGround( heightOverGround_ );
		this->droppedToFloorOriginOffset = ( decltype( this->droppedToFloorOriginOffset ) )( heightOverGround_ - 4.0f );
		this->droppedToFloorAasAreaNum = this->currAasAreaNum;
		return;
	}

	// Try drop an origin from air to floor
	trace_t trace;
	edict_t *ent = const_cast<edict_t *>( Self() );
	Vec3 traceEnd( Origin() );
	traceEnd.Z() -= GROUND_TRACE_DEPTH;
	G_Trace( &trace, this->origin, ent->r.mins, ent->r.maxs, traceEnd.Data(), ent, MASK_PLAYERSOLID );
	// Check not only whether there is a hit but test whether is it really a ground (and not a wall or obstacle)
	if( trace.fraction != 1.0f && Origin()[2] - trace.endpos[2] > -playerbox_stand_mins[2] ) {
		float heightOverGround_ = trace.fraction * GROUND_TRACE_DEPTH + playerbox_stand_mins[2];
		this->droppedToFloorOriginOffset = ( decltype( this->droppedToFloorOriginOffset ) )( -playerbox_stand_mins[2] );
		this->droppedToFloorOriginOffset -= heightOverGround_ - 4.0f;
		SetHeightOverGround( heightOverGround_ );
		Vec3 droppedOrigin( Origin() );
		droppedOrigin.Z() -= this->droppedToFloorOriginOffset;
		this->droppedToFloorAasAreaNum = ( decltype( this->droppedToFloorAasAreaNum ) )aasWorld->FindAreaNum( droppedOrigin );
		return;
	}

	this->droppedToFloorOriginOffset = 0;
	SetHeightOverGround( std::numeric_limits<float>::infinity() );
	this->droppedToFloorAasAreaNum = this->currAasAreaNum;
}
Exemplo n.º 7
0
void UI_Main::gamepadCursorMove( void ) {
	int64_t time = trap::Milliseconds();

	static int64_t lastTime;
	if( !lastTime ) {
		lastTime = time;
		return;
	}
	if( lastTime == time ) {
		return;
	}

	int frameTimeMsec = time - lastTime;
	clamp_high( frameTimeMsec, 100 );

	gamepadStickCursorMove( frameTimeMsec );
	gamepadDpadCursorMove( frameTimeMsec );
}
Exemplo n.º 8
0
/*
* CG_StartFallKickEffect
*/
void CG_StartFallKickEffect( int bounceTime )
{
	if( !cg_viewBob->integer )
	{
		cg.fallEffectTime = 0;
		cg.fallEffectRebounceTime = 0;
		return;
	}

	if( cg.fallEffectTime > cg.time )
		cg.fallEffectRebounceTime = 0;

	bounceTime += 200;
	clamp_high( bounceTime, 400 );

	cg.fallEffectTime = cg.time + bounceTime;
	if( cg.fallEffectRebounceTime )
		cg.fallEffectRebounceTime = cg.time - ( ( cg.time - cg.fallEffectRebounceTime ) * 0.5 );
	else
		cg.fallEffectRebounceTime = cg.time;
}
Exemplo n.º 9
0
void UI_Main::gamepadDpadCursorMove( int frameTimeMsec ) {
	float frameTime = frameTimeMsec * 0.001f;
	static float holdTime;
	static float x, y;

	clamp_high( frameTime, 0.1f );

	int dx = trap::Key_IsDown( K_DPAD_RIGHT ) - trap::Key_IsDown( K_DPAD_LEFT );
	int dy = trap::Key_IsDown( K_DPAD_DOWN ) - trap::Key_IsDown( K_DPAD_UP );
	if( !dx && !dy ) {
		holdTime = x = y = 0.0f;
		return;
	}

	// Goes from half minimum screen height to double minimum screen height.
	float speed = ( 600.0f * 0.5f ) + bound( 0.0f, holdTime - 0.25f, 1.5f ) * 600.0f;
	if( dx && dy ) {
		speed *= 0.707106f;
	}
	speed *= refreshState.pixelRatio * frameTime;

	if( dx ) {
		x += ( ( dx < 0 ) ? -1.0f : 1.0f ) * speed;
	} else {
		x = 0.0f;
	}

	if( dy ) {
		y += ( ( dy < 0 ) ? -1.0f : 1.0f ) * speed;
	} else {
		y = 0.0f;
	}

	holdTime += frameTime;

	int mx = ( int )x, my = ( int )y;
	x -= ( float )mx;
	y -= ( float )my;
	mouseMove( UI_CONTEXT_MAIN, frameTimeMsec, mx, my, false, true );
}
Exemplo n.º 10
0
void UI_Main::gamepadCursorMove( void )
{
	unsigned int time = trap::Milliseconds();

	static unsigned int lastTime;
	if( !lastTime ) {
		lastTime = time;
		return;
	}

	float frameTime = ( time - lastTime ) * 0.001f;
	lastTime = time;

	if( !frameTime ) {
		return;
	}

	clamp_high( frameTime, 0.1f );

	gamepadStickCursorMove( frameTime );
	gamepadDpadCursorMove( frameTime );
}
Exemplo n.º 11
0
void W_Fire_Electrobolt_FullInstant( edict_t *self, vec3_t start, vec3_t angles, float maxdamage, float mindamage, int maxknockback, int minknockback, int stun, int range, int minDamageRange, int mod, int timeDelta )
{
	vec3_t from, end, dir;
	trace_t	tr;
	edict_t	*ignore, *event, *hit, *damaged;
	int mask;
	qboolean missed = qtrue;
	int dmgflags = 0;

#define FULL_DAMAGE_RANGE g_projectile_prestep->value

	if( GS_Instagib() )
		maxdamage = mindamage = 9999;

	AngleVectors( angles, dir, NULL, NULL );
	VectorMA( start, range, dir, end );
	VectorCopy( start, from );

	ignore = self;
	hit = damaged = NULL;

	mask = MASK_SHOT;
	if( GS_RaceGametype() )
		mask = MASK_SOLID;

	clamp_high( mindamage, maxdamage );
	clamp_high( minknockback, maxknockback );
	clamp_high( minDamageRange, range );

	if( minDamageRange <= FULL_DAMAGE_RANGE )
		minDamageRange = FULL_DAMAGE_RANGE + 1;

	if( range <= FULL_DAMAGE_RANGE + 1 )
		range = FULL_DAMAGE_RANGE + 1;

	tr.ent = -1;
	while( ignore )
	{
		G_Trace4D( &tr, from, NULL, NULL, end, ignore, mask, timeDelta );

		VectorCopy( tr.endpos, from );
		ignore = NULL;

		if( tr.ent == -1 )
			break;

		// some entity was touched
		hit = &game.edicts[tr.ent];
		if( hit == world )  // stop dead if hit the world
			break;
		if( hit->movetype == MOVETYPE_NONE || hit->movetype == MOVETYPE_PUSH )
			break;

		// allow trail to go through BBOX entities (players, gibs, etc)
		if( !ISBRUSHMODEL( hit->s.modelindex ) )
			ignore = hit;

		if( ( hit != self ) && ( hit->takedamage ) )
		{
			float frac, damage, knockback, dist;

			dist = DistanceFast( tr.endpos, start );
			if( dist <= FULL_DAMAGE_RANGE )
				frac = 0.0f;
			else
			{
				frac = ( dist - FULL_DAMAGE_RANGE ) / (float)( minDamageRange - FULL_DAMAGE_RANGE );
				clamp( frac, 0.0f, 1.0f );
			}

			damage = maxdamage - ( ( maxdamage - mindamage ) * frac );
			knockback = maxknockback - ( ( maxknockback - minknockback ) * frac );

			//G_Printf( "mindamagerange %i frac %.1f damage %i\n", minDamageRange, 1.0f - frac, (int)damage );

			G_Damage( hit, self, self, dir, dir, tr.endpos, damage, knockback, stun, dmgflags, mod );
			
			// spawn a impact event on each damaged ent
			event = G_SpawnEvent( EV_BOLT_EXPLOSION, DirToByte( tr.plane.normal ), tr.endpos );
			event->s.firemode = FIRE_MODE_STRONG;
			if( hit->r.client )
				missed = qfalse;

			damaged = hit;
		}
	}

	if( missed && self->r.client )
		G_AwardPlayerMissedElectrobolt( self, mod );

	// send the weapon fire effect
	event = G_SpawnEvent( EV_ELECTROTRAIL, ENTNUM( self ), start );
	event->r.svflags = SVF_TRANSMITORIGIN2;
	VectorScale( dir, 1024, event->s.origin2 );
	event->s.firemode = FIRE_MODE_STRONG;

#undef FULL_DAMAGE_RANGE
}
Exemplo n.º 12
0
/*
* W_Fire_Electrobolt_Combined
*/
void W_Fire_Electrobolt_Combined( edict_t *self, vec3_t start, vec3_t angles, float maxdamage, float mindamage, float maxknockback, float minknockback, int stun, int range, int mod, int timeDelta )
{
	vec3_t from, end, dir;
	trace_t	tr;
	edict_t	*ignore, *event, *hit, *damaged;
	int mask;
	qboolean missed = qtrue;
	int dmgflags = 0;
	int fireMode;

#ifdef ELECTROBOLT_TEST
	fireMode = FIRE_MODE_WEAK;
#else
	fireMode = FIRE_MODE_STRONG;
#endif

	if( GS_Instagib() )
		maxdamage = mindamage = 9999;

	AngleVectors( angles, dir, NULL, NULL );
	VectorMA( start, range, dir, end );
	VectorCopy( start, from );

	ignore = self;
	hit = damaged = NULL;

	mask = MASK_SHOT;
	if( GS_RaceGametype() )
		mask = MASK_SOLID;

	clamp_high( mindamage, maxdamage );
	clamp_high( minknockback, maxknockback );

	tr.ent = -1;
	while( ignore )
	{
		G_Trace4D( &tr, from, NULL, NULL, end, ignore, mask, timeDelta );

		VectorCopy( tr.endpos, from );
		ignore = NULL;

		if( tr.ent == -1 )
			break;

		// some entity was touched
		hit = &game.edicts[tr.ent];
		if( hit == world )  // stop dead if hit the world
			break;
		if( hit->movetype == MOVETYPE_NONE || hit->movetype == MOVETYPE_PUSH )
			break;

		// allow trail to go through BBOX entities (players, gibs, etc)
		if( !ISBRUSHMODEL( hit->s.modelindex ) )
			ignore = hit;

		if( ( hit != self ) && ( hit->takedamage ) )
		{
			float frac, damage, knockback;

			frac = DistanceFast( tr.endpos, start ) / (float)range;
			clamp( frac, 0.0f, 1.0f );

			damage = maxdamage - ( ( maxdamage - mindamage ) * frac );
			knockback = maxknockback - ( ( maxknockback - minknockback ) * frac );

			G_Damage( hit, self, self, dir, dir, tr.endpos, damage, knockback, stun, dmgflags, mod );
			
			// spawn a impact event on each damaged ent
			event = G_SpawnEvent( EV_BOLT_EXPLOSION, DirToByte( tr.plane.normal ), tr.endpos );
			event->s.firemode = fireMode;
			if( hit->r.client )
				missed = qfalse;

			damaged = hit;
		}
	}

	if( missed && self->r.client )
		G_AwardPlayerMissedElectrobolt( self, mod );

	// send the weapon fire effect
	event = G_SpawnEvent( EV_ELECTROTRAIL, ENTNUM( self ), start );
	event->r.svflags = SVF_TRANSMITORIGIN2;
	VectorScale( dir, 1024, event->s.origin2 );
	event->s.firemode = fireMode;

	if( !GS_Instagib() && tr.ent == -1 )	// didn't touch anything, not even a wall
	{
		edict_t *bolt;
		gs_weapon_definition_t *weapondef = GS_GetWeaponDef( self->s.weapon );

		// fire a weak EB from the end position
		bolt = W_Fire_Electrobolt_Weak( self, end, angles, weapondef->firedef_weak.speed, mindamage, minknockback, minknockback, stun, weapondef->firedef_weak.timeout, mod, timeDelta );
		bolt->enemy = damaged;
	}
}
Exemplo n.º 13
0
/*
* G_RadiusDamage
*/
void G_RadiusDamage( edict_t *inflictor, edict_t *attacker, cplane_t *plane, edict_t *ignore, int mod )
{
	edict_t *ent = NULL;
	float dmgFrac, kickFrac, damage, knockback, stun;
	vec3_t pushDir;
	int timeDelta;

	float maxdamage, mindamage, maxknockback, minknockback, maxstun, minstun, radius;

	assert( inflictor );

	maxdamage = inflictor->projectileInfo.maxDamage;
	mindamage = inflictor->projectileInfo.minDamage;
	maxknockback = inflictor->projectileInfo.maxKnockback;
	minknockback = inflictor->projectileInfo.minKnockback;
	maxstun = inflictor->projectileInfo.stun;
	minstun = 1;
	radius = inflictor->projectileInfo.radius;

	if( radius <= 1.0f || ( maxdamage <= 0.0f && maxknockback <= 0.0f ) )
		return;

	clamp_high( mindamage, maxdamage );
	clamp_high( minknockback, maxknockback );
	clamp_high( minstun, maxstun );

	while( ( ent = GClip_FindBoxInRadius4D( ent, inflictor->s.origin, radius, inflictor->timeDelta ) ) != NULL )
	{
		if( ent == ignore || !ent->takedamage )
			continue;

		if( ent == attacker && ent->r.client )
			timeDelta = 0;
		else
			timeDelta = inflictor->timeDelta;

		G_SplashFrac4D( ENTNUM( ent ), inflictor->s.origin, radius, pushDir, &kickFrac, &dmgFrac, timeDelta );

		damage = max( 0, mindamage + ( ( maxdamage - mindamage ) * dmgFrac ) );
		stun = max( 0, minstun + ( ( maxstun - minstun ) * dmgFrac ) );
		knockback = max( 0, minknockback + ( ( maxknockback - minknockback ) * kickFrac ) );

		// weapon jumps hack : when knockback on self, use strong weapon definition
		if( ent == attacker && ent->r.client )
		{
			gs_weapon_definition_t *weapondef = NULL;
			if( inflictor->s.type == ET_ROCKET )
				weapondef = GS_GetWeaponDef( WEAP_ROCKETLAUNCHER );
			else if( inflictor->s.type == ET_GRENADE )
				weapondef = GS_GetWeaponDef( WEAP_GRENADELAUNCHER );
			else if( inflictor->s.type == ET_PLASMA )
				weapondef = GS_GetWeaponDef( WEAP_PLASMAGUN );
			else if( inflictor->s.type == ET_BLASTER )
				weapondef = GS_GetWeaponDef( WEAP_GUNBLADE );

			if( weapondef )
			{
				G_SplashFrac4D( ENTNUM( ent ), inflictor->s.origin, radius, pushDir, &kickFrac, NULL, 0 );

				minknockback = weapondef->firedef.minknockback;
				maxknockback = weapondef->firedef.knockback;
				clamp_high( minknockback, maxknockback );
				knockback = ( minknockback + ( (float)( maxknockback - minknockback ) * kickFrac ) ) * g_self_knockback->value;
				damage *= weapondef->firedef.selfdamage;
			}
		}

		if( knockback < 1.0f )
			knockback = 0.0f;

		if( stun < 1.0f )
			stun = 0.0f;

		if( damage <= 0.0f && knockback <= 0.0f && stun <= 0.0f )
			continue;

		if( G_CanSplashDamage( ent, inflictor, plane ) )
			G_Damage( ent, inflictor, attacker, pushDir, inflictor->velocity, inflictor->s.origin, damage, knockback, stun, DAMAGE_RADIUS, mod );
	}
}
Exemplo n.º 14
0
size_t IN_IME_GetComposition( char *str, size_t strSize, size_t *cursorPos, size_t *convStart, size_t *convLen ) {
	WCHAR compStr[IN_WINIME_COMPSTR_LENGTH + 1];
	char compAttr[IN_WINIME_COMPSTR_LENGTH + 1];
	int len, attrLen, i, cursor, attr, start = -1;
	size_t cursorutf = 0, startutf = 0, convutflen = 0, ret = 0;

	if( !strSize ) {
		str = NULL;
	}

	if( str ) {
		str[0] = '\0';
	}
	if( cursorPos ) {
		*cursorPos = 0;
	}
	if( convStart ) {
		*convStart = 0;
	}
	if( convLen ) {
		*convLen = 0;
	}

	if( !in_winime_enabled ) {
		return 0;
	}

	len = qimmGetCompositionString( in_winime_context, GCS_COMPSTR, compStr, sizeof( compStr ) ) / sizeof( WCHAR );
	if( len <= 0 ) {
		return 0;
	}

	compStr[len] = 0;
	if( str ) {
		ret = Q_WCharToUtf8String( compStr, str, strSize );
	} else {
		for( i = 0; i < len; i++ )
			ret += Q_WCharUtf8Length( compStr[i] );
	}

	if( cursorPos ) {
		cursor = LOWORD( qimmGetCompositionString( in_winime_context, GCS_CURSORPOS, NULL, 0 ) );
		for( i = 0; ( i < cursor ) && ( i < len ); i++ )
			cursorutf += Q_WCharUtf8Length( compStr[i] );
		clamp_high( cursorutf, ret );
		*cursorPos = cursorutf;
	}

	if( convStart || convLen ) {
		attrLen = qimmGetCompositionString( in_winime_context, GCS_COMPATTR, compAttr, sizeof( compAttr ) );
		if( attrLen == len ) {
			for( i = 0; i < attrLen; i++ ) {
				attr = compAttr[i];
				if( ( attr == ATTR_TARGET_CONVERTED ) || ( attr == ATTR_TARGET_NOTCONVERTED ) ) {
					if( start < 0 ) {
						start = startutf;
					}
					convutflen += Q_WCharUtf8Length( compStr[i] );
				} else {
					if( start >= 0 ) {
						break;
					}
					startutf += Q_WCharUtf8Length( compStr[i] );
				}
			}

			if( start >= 0 ) {
				if( start > ( int )ret ) {
					start = ret;
				}
				if( ( start + convutflen ) > ( int )ret ) {
					convutflen = ret - start;
				}
				if( convStart ) {
					*convStart = start;
				}
				if( convLen ) {
					*convLen = convutflen;
				}
			}
		}
	}

	return ret;
}
Exemplo n.º 15
0
/*
* RFB_RegisterObject
*/
int RFB_RegisterObject( int width, int height, bool builtin, bool depthRB, bool stencilRB,
						bool colorRB, int samples, bool useFloat, bool sRGB ) {
	int i;
	int format;
	GLuint fbID;
	GLuint rbID = 0;
	r_fbo_t *fbo = NULL;

	if( !r_frambuffer_objects_initialized ) {
		return 0;
	}

#ifdef GL_ES_VERSION_2_0
	if( samples ) {
		return 0;
	}
#else
	if( samples && !glConfig.ext.framebuffer_multisample ) {
		return 0;
	}
#endif

	for( i = 0, fbo = r_framebuffer_objects; i < r_num_framebuffer_objects; i++, fbo++ ) {
		if( !fbo->objectID ) {
			// free slot
			goto found;
		}
	}

	if( i == MAX_FRAMEBUFFER_OBJECTS ) {
		Com_Printf( S_COLOR_YELLOW "RFB_RegisterObject: framebuffer objects limit exceeded\n" );
		return 0;
	}

	clamp_high( samples, glConfig.maxFramebufferSamples );

	i = r_num_framebuffer_objects++;
	fbo = r_framebuffer_objects + i;

found:
	qglGenFramebuffersEXT( 1, &fbID );
	memset( fbo, 0, sizeof( *fbo ) );
	fbo->objectID = fbID;
	if( builtin ) {
		fbo->registrationSequence = -1;
	} else {
		fbo->registrationSequence = rsh.registrationSequence;
	}
	fbo->width = width;
	fbo->height = height;
	fbo->samples = samples;
	fbo->sRGB = sRGB;

	qglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fbo->objectID );

	if( colorRB ) {
		format = glConfig.forceRGBAFramebuffers ? GL_RGBA : GL_RGB;
		if( useFloat ) {
			format = glConfig.forceRGBAFramebuffers ? GL_RGBA16F_ARB : GL_RGB16F_ARB;
		}

		qglGenRenderbuffersEXT( 1, &rbID );
		fbo->colorRenderBuffer = rbID;
		qglBindRenderbufferEXT( GL_RENDERBUFFER_EXT, rbID );

#ifndef GL_ES_VERSION_2_0
		if( samples ) {
			qglRenderbufferStorageMultisampleEXT( GL_RENDERBUFFER_EXT, samples, format, width, height );
		} else
#endif
		qglRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, format, width, height );
	}
#ifndef GL_ES_VERSION_2_0
	else {
		// until a color texture is attached, don't enable drawing to the buffer
		qglDrawBuffer( GL_NONE );
		qglReadBuffer( GL_NONE );
	}
#endif

	if( depthRB ) {
		qglGenRenderbuffersEXT( 1, &rbID );
		fbo->depthRenderBuffer = rbID;
		qglBindRenderbufferEXT( GL_RENDERBUFFER_EXT, rbID );

		if( stencilRB ) {
			format = GL_DEPTH24_STENCIL8_EXT;
		} else if( glConfig.ext.depth24 ) {
			format = GL_DEPTH_COMPONENT24;
		} else if( glConfig.ext.depth_nonlinear ) {
			format = GL_DEPTH_COMPONENT16_NONLINEAR_NV;
		} else {
			format = GL_DEPTH_COMPONENT16;
		}

#ifndef GL_ES_VERSION_2_0
		if( samples ) {
			qglRenderbufferStorageMultisampleEXT( GL_RENDERBUFFER_EXT, samples, format, width, height );
		} else
#endif
		qglRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, format, width, height );

		if( stencilRB ) {
			fbo->stencilRenderBuffer = rbID;
		}
	}

	if( rbID ) {
		qglBindRenderbufferEXT( GL_RENDERBUFFER_EXT, 0 );
	}

	if( fbo->colorRenderBuffer ) {
		qglFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, fbo->colorRenderBuffer );
	}
	if( fbo->depthRenderBuffer ) {
		qglFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fbo->depthRenderBuffer );
	}
	if( fbo->stencilRenderBuffer ) {
		qglFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fbo->stencilRenderBuffer );
	}

	if( colorRB && depthRB ) {
		if( !RFB_CheckObjectStatus() ) {
			goto fail;
		}
	}

	if( r_bound_framebuffer_objectID ) {
		qglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, r_bound_framebuffer_object->objectID );
	} else {
		qglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
	}

	return i + 1;

fail:
	RFB_DeleteObject( fbo );
	qglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
	return 0;
}
Exemplo n.º 16
0
/*
* Con_DrawNotify
*
* Draws the last few lines of output transparently over the game top
*/
void Con_DrawNotify( void )
{
    int v;
    char *text;
    const char *say;
    const char *translated;
    int i;
    int time;
    char *s;

    v = 0;
    if( con_drawNotify->integer )
    {
        for( i = min( NUM_CON_TIMES, con.numlines ) - 1; i >= 0; i-- )
        {
            time = con.times[i];
            if( time == 0 )
                continue;
            time = cls.realtime - time;
            if( time > con_notifytime->value*1000 )
                continue;
            text = con.text[i] ? con.text[i] : "";

            SCR_DrawString( 8, v, ALIGN_LEFT_TOP, text, cls.fontSystemSmall, colorWhite );

            v += SCR_strHeight( cls.fontSystemSmall );
        }
    }

    if( cls.key_dest == key_message )
    {
        int x, y;
        int width, prewidth;
        int promptwidth, cursorwidth;
        struct qfontface_s *font = NULL;

        if( con_chatCGame->integer )
        {
            width = con_chatWidth->integer;

            if( *con_chatFontFamily->string && con_chatFontSize->integer ) {
                font = SCR_RegisterFont( con_chatFontFamily->string, con_chatFontStyle->integer, con_chatFontSize->integer );
            }
            if( !font )
                font = cls.fontSystemSmall;

            x = con_chatX->integer;
            y = con_chatY->integer;
        }
        else
        {
            width = viddef.width;
            x = 8;
            y = v;
            font = cls.fontSystemSmall;
        }

        // 48 is an arbitrary offset for not overlapping the FPS and clock prints
        width -= 48;
        cursorwidth = SCR_strWidth( "_", font, 0 );

        if( chat_team )
        {
            say = "say_team:";
        }
        else
        {
            say = "say:";
        }

        translated = L10n_TranslateString( "common", say );
        if( !translated ) {
            translated = say;
        }
        SCR_DrawString( x, y, ALIGN_LEFT_TOP, translated, font, colorWhite );
        promptwidth = SCR_strWidth( translated, font, 0 ) + SCR_strWidth( " ", font, 0 );

        s = chat_buffer;
        prewidth = chat_linepos ? SCR_strWidth( s, font, chat_linepos ) : 0;

        // don't let the cursor go beyond the left screen edge
        clamp_high( chat_prestep, prewidth );

        // don't let it go beyond the right screen edge
        clamp_low( chat_prestep, prewidth - ( width - promptwidth - cursorwidth ) );

        // FIXME: we double the font height to compensate for alignment issues
        SCR_DrawClampString( x + promptwidth - chat_prestep,
                             y, s, x + promptwidth, y,
                             x + width, y + SCR_strHeight( font ) * 2, font, colorWhite );

        if( (int)( cls.realtime>>8 )&1 )
            SCR_DrawRawChar( x + promptwidth + prewidth - chat_prestep, y, '_',
                             font, colorWhite );
    }