C4SoundEffect* C4SoundSystem::GetEffect(const char *szSndName)
{
	// Remember wildcards before adding .* extension - if there are 2 versions with different file extensions, play the last added
	bool bRandomSound = SCharCount('?',szSndName) || SCharCount('*',szSndName);
	// Evaluate sound name
	char szName[C4MaxSoundName+2+1];
	SCopy(szSndName,szName,C4MaxSoundName);
	// Any extension accepted
	DefaultExtension(szName,"*");
	// Play nth Sound. Standard: 1
	int32_t iNumber = 1;
	// Sound with a wildcard: determine number of available matches
	if (bRandomSound)
	{
		iNumber = 0;
		// Count matching sounds
		for (C4SoundEffect *pSfx=FirstSound; pSfx; pSfx=pSfx->Next)
			if (WildcardMatch(szName,pSfx->Name))
				++iNumber;
		// Nothing found? Abort
		if(iNumber == 0)
			return NULL;
		iNumber=UnsyncedRandom(iNumber)+1;
	}
	// Find requested sound effect in bank
	C4SoundEffect *pSfx;
	for (pSfx=FirstSound; pSfx; pSfx=pSfx->Next)
		if (WildcardMatch(szName,pSfx->Name))
			if(!--iNumber)
				break;
	return pSfx; // Is still NULL if nothing is found
}
Esempio n. 2
0
C4SoundEffect *C4SoundSystem::GetEffect(const char *szSndName) {
  C4SoundEffect *pSfx;
  char szName[C4MaxSoundName + 4 + 1];
  int32_t iNumber;
  // Evaluate sound name
  SCopy(szSndName, szName, C4MaxSoundName);
  // Default extension
  DefaultExtension(szName, "wav");
  // Convert old style '*' wildcard to correct '?' wildcard
  // For sound effects, '*' is supposed to match single digits only
  SReplaceChar(szName, '*', '?');
  // Sound with a wildcard: determine number of available matches
  if (SCharCount('?', szName)) {
    // Search global sound file
    if (!(iNumber = SoundFile.EntryCount(szName)))
      // Search scenario local files
      if (!(iNumber = Game.ScenarioFile.EntryCount(szName)))
        // Search bank loaded sounds
        if (!(iNumber = EffectInBank(szName)))
          // None found: failure
          return NULL;
    // Insert index to name
    iNumber = BoundBy(1 + SafeRandom(iNumber), 1, 9);
    SReplaceChar(szName, '?', '0' + iNumber);
  }
  // Find requested sound effect in bank
  for (pSfx = FirstSound; pSfx; pSfx = pSfx->Next)
    if (SEqualNoCase(szName, pSfx->Name)) break;
  // Sound not in bank, try add
  if (!pSfx)
    if (!(pSfx = AddEffect(szName))) return NULL;
  return pSfx;
}
Esempio n. 3
0
int32_t C4TextureMap::LoadMap(C4Group &hGroup, const char *szEntryName, BOOL *pOverloadMaterials, BOOL *pOverloadTextures)
  {
  char *bpMap;
  char szLine[100+1];
  int32_t cnt, iIndex, iTextures = 0;
  // Load text file into memory
  if (!hGroup.LoadEntry(szEntryName,&bpMap,NULL,1)) return 0;
  // Scan text buffer lines       
  for (cnt=0; SCopySegment(bpMap,cnt,szLine,0x0A,100); cnt++)
    if ( (szLine[0]!='#') && (SCharCount('=',szLine)==1) )
      {
      SReplaceChar(szLine,0x0D,0x00);
			if (Inside<int32_t>( iIndex = strtol(szLine,NULL,10), 0, C4M_MaxTexIndex-1 ))
				{
				const char *szMapping = szLine+SCharPos('=',szLine)+1;
				StdStrBuf Material, Texture;
				Material.CopyUntil(szMapping, '-'); Texture.Copy(SSearch(szMapping, "-"));
				if (AddEntry(iIndex, Material.getData(), Texture.getData()))
					iTextures++;
				}
      }
		else
			{
			if (SEqual2(szLine, "OverloadMaterials")) { fOverloadMaterials = TRUE; if(pOverloadMaterials) *pOverloadMaterials = TRUE; }
			if (SEqual2(szLine, "OverloadTextures")) { fOverloadTextures = TRUE;  if(pOverloadTextures) *pOverloadTextures = TRUE; }
			}
  // Delete buffer, return entry count
  delete [] bpMap;
	fEntriesAdded=false;
  return iTextures;
  }
Esempio n. 4
0
void C4ObjectInfoCore::Default(C4ID n_id, 
															 C4DefList *pDefs, 
															 const char *cpNames)
  {
	
	// Def
	C4Def *pDef=NULL;
	if (pDefs) pDef = pDefs->ID2Def(n_id);
	
	// Defaults
	id=n_id;
  Participation=1; 
  Rank=0;
	Experience=0;
	Rounds=0;
	DeathCount=0;
	Birthday=0;
	TotalPlayingTime=0;	
	SCopy("Clonk",Name,C4MaxName);
	SCopy("Clonk",TypeName,C4MaxName);
	sRankName.Copy("Clonk");
	sNextRankName.Clear();
	NextRankExp=0;
	DeathMessage[0]='\0';
	*PortraitFile=0;
	Age=0;
	ExtraData.Reset();

	// Type
	if (pDef) SCopy(pDef->GetName(),TypeName,C4MaxName);

	// Name
	if (cpNames) 
		{
		// Name file reference
		if (SSearchNoCase(cpNames,C4CFN_Names))
			SCopy(GetAName(cpNames),Name,C4MaxName);
		// Name list 
		else
			{
			SCopySegment(cpNames,Random(SCharCount(0x0A,cpNames)),Name,0x0A,C4MaxName+1);
			SClearFrontBack(Name);
			SReplaceChar(Name,0x0D,0x00);
			}
		if (!Name[0]) SCopy("Clonk",Name,C4MaxName);
		}

#ifdef C4ENGINE
	if (pDefs) UpdateCustomRanks(pDefs);
#endif
  
	// Physical
	Physical.Default();
	if (pDef) Physical = pDef->Physical;
	Physical.PromotionUpdate(Rank);

	// Old format
  
	} 
Esempio n. 5
0
// helper func: Determine whether input text is good for a chat-style-layout
// dialog
bool IsSmallInputQuery(const char *szInputQuery) {
  if (!szInputQuery) return true;
  int32_t w, h;
  if (SCharCount('|', szInputQuery)) return false;
  if (!C4GUI::GetRes()->TextFont.GetTextExtent(szInputQuery, w, h, true))
    return false;  // ???
  return w < C4GUI::GetScreenWdt() / 5;
}
void C4ObjectInfoCore::Default(C4ID n_id,
                               C4DefList *pDefs,
                               const char *cpNames)
{

	// Def
	C4Def *pDef=NULL;
	if (pDefs) pDef = pDefs->ID2Def(n_id);

	// Defaults
	id=n_id;
	Participation=1;
	Rank=0;
	Experience=0;
	Rounds=0;
	DeathCount=0;
	Birthday=0;
	TotalPlayingTime=0;
	SCopy("Clonk",Name,C4MaxName);
	SCopy("Clonk",TypeName,C4MaxName);
	sRankName.Copy("Clonk");
	sNextRankName.Clear();
	NextRankExp=0;
	DeathMessage[0]='\0';
	Age=0;
	ExtraData.Reset();

	// Type
	if (pDef) SCopy(pDef->GetName(),TypeName,C4MaxName);

	// Name
	if (cpNames)
	{
		SCopySegment(cpNames,Random(SCharCount(0x0A,cpNames)),Name,0x0A,C4MaxName+1);
		SClearFrontBack(Name);
		SReplaceChar(Name,0x0D,0x00);
		if (!Name[0]) SCopy("Clonk",Name,C4MaxName);
	}

	if (pDefs) UpdateCustomRanks(pDefs);
}
Esempio n. 7
0
	ResTable(const char * table): Capacity(int(1.10 * SCharCount('\n', table))), Count(0), Entries(new Entry[Capacity]) {
		// reduce the capacity so that there is always an empty entry to mark the end of the search for an nonexistant key
		--Capacity;
		while (Count < Capacity) {
			// search '='
			const char * pos = table;
			const char * equalpos = 0;
			while (*pos && *pos != '\n' && *pos != '\r') {
				if (*pos == '=') equalpos = pos;
				++pos;
			}
			if (equalpos) {
				unsigned int h = Hash(table);
				// Get a pointer to the bucket
				Entry * e = &(Entries[h % Capacity]);
				// Search an empty spot
				int i = 0;
				while (*e) {
#ifdef _DEBUG
					if (e->Hash == h) printf("Hash Collision: %d (\"%.50s\")\nSTRINGTABLE WILL BREAK\n", h, table);
#endif
					e = &(Entries[(h + ++i) % Capacity]);
				}
				// Fill
				e->Hash = h;
				e->Data.CopyUntil(equalpos + 1, *pos);
				// Compile line feeds ("\n" -> 0D0A)
				for (i = 0; i < pos - equalpos; ++i)
				if (e->Data.getMData()[i] == '\\' && e->Data.getMData()[i + 1] == 'n')
					{ e->Data.getMData()[i] = 0x0D; e->Data.getMData()[i + 1] = 0x0A; }
				// Count!
				++Count;
			}
			while (*pos == '\n' || *pos == '\r') ++pos;
			table = pos;
			if (!*table) break;
		}
	}
Esempio n. 8
0
void C4MapScriptMatTexMask::UnmaskSpec(C4String *spec)
{
	// Mask all indices of material-texture definitions
	// Possible definitions:
	// Material-Texture - Given material-texture combination (both sky and tunnel background)
	// Material         - All defined default textures of given material
	// *                - All materials including sky
	// Sky              - Index C4M_MaxTexIndex
	// Transparent      - Index 0
	// Background       - All tunnel materials plus sky
	// Liquid           - All liquid materials
	// Solid            - All solid materials
	// Possible modifiers:
	// ^Material        - Given material only with sky background
	// &Material        - Given material only with tunnel background
	// ~Material        - Inverse of given definition; i.e. everything except Material
	if (!spec || !spec->GetCStr()) return;
	const char *cspec = spec->GetCStr();
	bool invert=false, bgsky=false, bgtunnel=false, prefix_done=false;
	while (*cspec)
	{
		switch (*cspec)
		{
		case '~': invert=!invert; break;
		case '^': bgsky=true; break;
		case '&': bgtunnel=true; break;
		default: prefix_done=true; break;
		}
		if (prefix_done) break;
		++cspec;
	}
	std::vector<bool> mat_mask(C4M_MaxTexIndex+1, false);
	if (SEqual(cspec, DrawFn_Transparent_Name))
	{
		// "Transparent" is zero index. Force to non-IFT
		mat_mask[0] = true;
	}
	else if (SEqual(cspec, DrawFn_Sky_Name))
	{
		// Sky material
		mat_mask[C4M_MaxTexIndex] = true;
	}
	else if (SEqual(cspec, DrawFn_Background_Name))
	{
		// All background materials
		for (int32_t i=1; i<C4M_MaxTexIndex; ++i) if (!DensitySemiSolid(Landscape.GetPixDensity(i))) mat_mask[i] = true;
		// Background includes sky
		mat_mask[C4M_MaxTexIndex] = true;
	}
	else if (SEqual(cspec, DrawFn_Liquid_Name))
	{
		// All liquid materials
		for (int32_t i=1; i<C4M_MaxTexIndex; ++i) if (DensityLiquid(Landscape.GetPixDensity(i))) mat_mask[i] = true;
	}
	else if (SEqual(cspec, DrawFn_Solid_Name))
	{
		// All solid materials
		for (int32_t i=1; i<C4M_MaxTexIndex; ++i) if (DensitySolid(Landscape.GetPixDensity(i))) mat_mask[i] = true;
	}
	else if (SEqual(cspec, "*"))
	{
		// All materials
		for (int32_t i=1; i<C4M_MaxTexIndex; ++i) mat_mask[i] = true;
		// Including sky
		mat_mask[C4M_MaxTexIndex] = true;
	}
	else
	{
		// Specified material
		if (SCharCount('-', cspec))
		{
			// Material+Texture
			int32_t col = ::MapScript.pTexMap->GetIndexMatTex(cspec, NULL, false);
			if (col) mat_mask[col] = true;
		}
		else
		{
			// Only material: Mask all textures of this material
			int32_t mat = ::MapScript.pMatMap->Get(cspec);
			if (mat!=MNone)
			{
				const char *tex_name;
				int32_t col;
				for (int32_t itex=0; (tex_name=::MapScript.pTexMap->GetTexture(itex)); itex++)
					if ((col = ::MapScript.pTexMap->GetIndex(cspec,tex_name,false)))
						mat_mask[col] = true;
			}
		}
	}

	// 'OR' spec onto this->sky_mask and this->tunnel_mask. Apply bgsky, bgtunnel and invert.
	for (int32_t i=0; i<C4M_MaxTexIndex + 1; ++i)
	{
		if ((mat_mask[i] && (bgsky || !bgtunnel)) != invert)
			sky_mask[i] = true;
		if ((mat_mask[i] && (!bgsky || bgtunnel)) != invert)
			tunnel_mask[i] = true;
	}
}
Esempio n. 9
0
bool C4Sky::Init(bool fSavegame)
{
	int32_t skylistn;

	// reset scrolling pos+speed
	// not in savegame, because it will have been loaded from game data there
	if (!fSavegame)
	{
		x=y=xdir=ydir=0; ParX=ParY=10; ParallaxMode=0;
	}

	// Check for sky bitmap in scenario file
	Surface = new C4Surface();
	bool loaded = !!Surface->LoadAny(Game.ScenarioFile,C4CFN_Sky,true,true, C4SF_Tileable | C4SF_MipMap);

	// Else, evaluate scenario core landscape sky default list
	if (!loaded)
	{
		// Scan list sections
		SReplaceChar(Game.C4S.Landscape.SkyDef,',',';'); // modifying the C4S here...!
		skylistn=SCharCount(';',Game.C4S.Landscape.SkyDef)+1;
		char str[402];
		SCopySegment(Game.C4S.Landscape.SkyDef,SeededRandom(Game.RandomSeed,skylistn),str,';');
		SClearFrontBack(str);
		// Sky tile specified, try load
		if (*str && !SEqual(str,"Default"))
		{
			// Check for sky tile in scenario file
			loaded = !!Surface->LoadAny(Game.ScenarioFile,str,true,true, C4SF_Tileable | C4SF_MipMap);
			if (!loaded)
			{
				loaded = !!Surface->LoadAny(::GraphicsResource.Files, str, true, false, C4SF_Tileable | C4SF_MipMap);
			}
		}
	}

	if (loaded)
	{
		// surface loaded, store first color index
		FadeClr1=FadeClr2=0xffffffff;

		// set parallax scroll mode
		switch (Game.C4S.Landscape.SkyScrollMode)
		{
		case 0: // default: no scrolling
			break;
		case 1: // go with the wind in xdir, and do some parallax scrolling in ydir
			ParallaxMode=C4SkyPM_Wind;
			ParY=20;
			break;
		case 2: // parallax in both directions
			ParX=ParY=20;
			break;
		}

	}


	// Else, try creating default Surface
	if (!loaded)
	{
		SetFadePalette(Game.C4S.Landscape.SkyDefFade);
		delete Surface;
		Surface = 0;
	}

	// Load sky shaders: regular sprite shaders with OC_SKY define
	const char* const SkyDefines[] = { "OC_SKY", NULL };
	if (!pDraw->PrepareSpriteShader(Shader, "Sky", Surface ? C4SSC_BASE : 0, &::GraphicsResource.Files, SkyDefines, NULL))
		return false;
	if (!pDraw->PrepareSpriteShader(ShaderLight, "SkyLight", (Surface ? C4SSC_BASE : 0) | C4SSC_LIGHT, &::GraphicsResource.Files, SkyDefines, NULL))
		return false;

	// no sky - using fade in newgfx
	if (!Surface)
		return true;

	// Store size
	if (Surface)
	{
		int iWdt,iHgt;
		if (Surface->GetSurfaceSize(iWdt, iHgt))
		{
			Width = iWdt; Height = iHgt;
		}
	}

	// Success
	return true;
}