// reallocate a block... // This acts like the standard realloc GENESISAPI void *geRam_Realloc ( void *ptr, uint32 newsize ) { char *p; char * NewPtr; if (ptr == NULL) { return geRam_Allocate (newsize); } // if newsize is NULL, then it's a free and return NULL if (newsize == 0) { geRam_Free (ptr); return NULL; } p = ptr; do { NewPtr = (char *)realloc (p, newsize); } while ((NewPtr == NULL) && (geRam_DoCriticalCallback ())); return NewPtr; }
LogType *Log_Open(Log_DestinationType dest,char *filename,Log_OpenType mode) { LogType *log; log = geRam_Allocate(sizeof(LogType)); assert(log); assert(filename!=NULL); assert(strlen(filename)<LOG_MAX_FILENAME_LENGTH); assert(strlen(filename)>0); strcpy(log->filename,filename); log->dest=dest; log->mode=mode; switch (dest) { case (LOG_TO_FILE): { Log_FileReset(log); break; } case (LOG_TO_NOTEPAD): case (LOG_TO_OPEN_NOTEPAD): { Log_NotepadReset(log); break; } } if (log->dest==LOG_TO_OPEN_NOTEPAD) log->dest = LOG_TO_NOTEPAD; //collapse to notepad destination return log; }
Group *Group_Create ( int id, char const *pName ) { Group *pGroup; assert (pName != NULL); pGroup = (Group *)geRam_Allocate (sizeof (Group)); if (pGroup != NULL) { pGroup->Visible = TRUE; pGroup->Locked = FALSE ; pGroup->GroupId = id; pGroup->GroupName = Util_Strdup (pName); pGroup->Color.r = 255.0 ; pGroup->Color.g = 255.0 ; pGroup->Color.b = 255.0 ; pGroup->Color.a = 255.0 ; pGroup->Next = NULL; } return pGroup; }
//static BOOL CreateChannel( char* Name, DSBUFFERDESC* dsBD, Channel** chanelPtr) static BOOL CreateChannel(DSBUFFERDESC* dsBD, Channel** chanelPtr) { Channel* channel; // channel = malloc( sizeof( Channel ) ); channel = geRam_Allocate( sizeof( Channel ) ); if ( channel == NULL ) { geErrorLog_Add(GE_ERR_OUT_OF_MEMORY, NULL); return( FALSE ); } if(DS_OK != IDirectSound_CreateSoundBuffer(lpDirectSound, dsBD, &channel->buffer, NULL)) { geErrorLog_Add(GE_ERR_CREATE_SOUND_BUFFER_FAILED, NULL); return FALSE; } if(DS_OK != IDirectSoundBuffer_GetFrequency(channel->buffer, &channel->BaseFreq) ) { geErrorLog_Add(GE_ERR_DS_ERROR, NULL); return FALSE; } channel->next = NULL; channel->nextDup = NULL; channel->ID = 0; channel->cfg.Volume = 1.0f; channel->cfg.Pan = 0.0f; channel->cfg.Frequency = 0.0f; // channel->name = Name; *chanelPtr = channel; return( TRUE ); }
static BOOL DupChannel( SoundManager *sm, Channel* channel, Channel** dupChannelPtr ) { Channel* dupChannel; HRESULT Error; *dupChannelPtr = NULL; // dupChannel = malloc( sizeof(Channel ) ); dupChannel = geRam_Allocate( sizeof(Channel ) ); if( dupChannel == NULL ) { geErrorLog_Add(GE_ERR_OUT_OF_MEMORY, NULL ); return FALSE; } Error = IDirectSound_DuplicateSoundBuffer( lpDirectSound, channel->buffer, &dupChannel->buffer ); if( Error != DS_OK ) { geRam_Free(dupChannel); // free( dupChannel ); dupChannel = ReloadData( channel->Data ); if( dupChannel == NULL ) { geErrorLog_Add(GE_ERR_DS_ERROR, NULL); return FALSE; } } dupChannel->ID = sm->smNextChannelID++; dupChannel->next = NULL; dupChannel->nextDup = channel->nextDup; dupChannel->cfg = channel->cfg; // dupChannel->name = NULL; dupChannel->Data = channel->Data; channel->nextDup = dupChannel; *dupChannelPtr = dupChannel; return( TRUE ); }
Parse3dt *Parse3dt_Create (const char *Filename) { int i; int j; Parse3dt *Parser; assert (Filename != NULL); // initialize the tables for (i = 0; i < NumInitializers; i++) { Scanner_CharMap * cm; cm = StateInitializers[i].siMap; for (j = 0; j < 256; j++) { cm[j].cmNextState = SNull; cm[j].cmAction = IllegalChar; } for (j = 0; j < StateInitializers[i].siInitializerCount; j++) { Scanner_CharMapInitializer * cmi; int k; cmi = &(StateInitializers[i].siMapInitializer[j]); for (k = cmi->cmiStartChar; k < cmi->cmiEndChar; k++) { cm[k].cmNextState = cmi->cmiNextState; cm[k].cmAction = cmi->cmiAction; cm[k].cmFlags = cmi->cmiFlags; } } } Parser = geRam_Allocate (sizeof (Parse3dt)); if (Parser != NULL) { geBoolean NoErrors; Parser->HashTable = NULL; Parser->Scanner = Scanner_Create (StateInitializers, NumInitializers, SNull); // Create the hash table Parser->HashTable = Iden_CreateHashTable(); NoErrors = ((Parser->Scanner != NULL) && (Parser->HashTable != NULL)); if (NoErrors) { NoErrors = Scanner_InitFile (Parser->Scanner, Filename, SCANNER_FILE_TEXT, Parser->HashTable); } if (!NoErrors) { Parse3dt_Destroy (&Parser); } } return Parser; }
log_type *log_open(const char *filename) { log_type *log; log = geRam_Allocate(sizeof(log_type)); assert(log); strcpy(log->filename, filename); log_file_reset(log); return log; }
GENESISAPI void * geRam_AllocateClear(uint32 size) { void * mem; size = (size + 3)&(~(uint32)3); mem = geRam_Allocate(size); if ( mem ) { memset(mem,0,size); } return mem; }
char *Util_Strdup (const char *s) { char *rslt; assert (s != NULL); rslt = geRam_Allocate (strlen (s) + 1); if (rslt != NULL) { strcpy (rslt, s); } return rslt; }
GENESISAPI void * geRam_Realloc (void *ptr, uint32 newsize) { char *p; char * NewPtr; uint32 size; // if realloc is called with NULL, just treat it like an alloc if (ptr == NULL) { return geRam_Allocate (newsize); } // verify the block p = ram_verify_block (ptr); if (p == NULL) { return NULL; } // if newsize is NULL, then it's a free and return NULL if (newsize == 0) { geRam_Free (ptr); return NULL; } // gotta get the size before I realloc it... size = *((uint32 *)p); do { NewPtr = (char *)realloc (p, newsize+EXTRA_SIZE); } while ((NewPtr == NULL) && geRam_DoCriticalCallback ()); // if allocation failed, return NULL... if (NewPtr == NULL) { return NULL; } geRam_SetupBlock (NewPtr, newsize, DONT_INITIALIZE); geRam_CurrentlyUsed += (newsize - size); if (geRam_CurrentlyUsed > geRam_MaximumUsed) { geRam_MaximumUsed = geRam_CurrentlyUsed; } assert ((geRam_CurrentlyUsed >= 0) && "free()d more ram than you allocated!"); return NewPtr + HEADER_SIZE; }
void Type_AddTypeField(Type *tp, SymTab_Symbol *fieldName, unsigned short flags) { TypeField * tf; TypeField * newField; SymTab_Symbol * before; before = 0; assert(tp->tpTopType == T_STRUCT); newField = (TypeField *)geRam_Allocate(sizeof(*newField)); if (!newField) { #pragma message("Type_AddTypeField can't propagate memory allocation errors") assert(0); return; } memset(newField, 0, sizeof(*newField)); newField->tfSymbol = fieldName; newField->tfFlags = flags; tf = tp->t.s.tpFields; while (tf) { if (tf->tfSymbol == before) { if (tf->tfPrev) tf->tfPrev->tfNext = newField; newField->tfPrev = tf->tfPrev; tf->tfPrev = newField; newField->tfNext = tf; if (tf == tp->t.s.tpFields) tp->t.s.tpFields = newField; return; } if (!tf->tfNext) { tf->tfNext = newField; newField->tfPrev = tf; return; } tf = tf->tfNext; } assert(!tp->t.s.tpFields); tp->t.s.tpFields = newField; newField->tfNext = newField->tfPrev = NULL; }
GroupListType *Group_CreateList ( void ) { GroupListType *pList; pList = (GroupListType *)geRam_Allocate (sizeof (GroupListType)); if (pList != NULL) { pList->First = NULL; } return pList; }
geBoolean DirTree_SetFileHints(DirTree *Tree, const geVFile_Hints *Hints) { if (Tree->Hints.HintData) geRam_Free(Tree->Hints.HintData); if (Hints->HintData) { Tree->Hints.HintData = geRam_Allocate(Hints->HintDataLength); if (!Tree->Hints.HintData) return GE_FALSE; memcpy(Tree->Hints.HintData, Hints->HintData, Hints->HintDataLength); } Tree->Hints.HintDataLength = Hints->HintDataLength; return GE_TRUE; }
//static BOOL GetSoundData( char* Name, unsigned char** dataPtr) static BOOL GetSoundData( geVFile *File, unsigned char** dataPtr) { // FILE * f; int32 Size; uint8 *data; // int32 CurPos; #if 0 f = fopen(Name, "rb"); if (!f) { geErrorLog_Add(GE_ERR_FILE_OPEN_ERROR, NULL); return FALSE; } #endif #if 0 CurPos = ftell (f); // Save the startinf pos into this function fseek (f, 0, SEEK_END); // Seek to end Size = ftell (f); // Get End (this will be the size) fseek (f, CurPos, SEEK_SET); // Restore file position #endif if (geVFile_Size(File, &Size) == GE_FALSE) return FALSE; data = geRam_Allocate(Size); if (!data) { geErrorLog_Add(GE_ERR_OUT_OF_MEMORY, NULL); return FALSE; } if (geVFile_Read(File, data, Size) == GE_FALSE) { geRam_Free(data); return FALSE; } // fread(data, Size, 1, f); // fclose(f); *dataPtr = data; return( TRUE ); }
DirTree_Finder * DirTree_CreateFinder(DirTree *Tree, const char *Path) { DirTree_Finder * Finder; DirTree * SubTree; char Directory[_MAX_PATH]; char Name[_MAX_FNAME]; char Ext[_MAX_EXT]; assert(Tree); assert(Path); _splitpath(Path, NULL, Directory, Name, Ext); SubTree = DirTree_FindExact(Tree, Directory); if (!SubTree) return NULL; Finder = geRam_Allocate(sizeof(*Finder)); if (!Finder) return Finder; Finder->MatchName = DuplicateString(Name); if (!Finder->MatchName) { geRam_Free(Finder); return NULL; } // The RTL leaves the '.' on there. That won't do. if (*Ext == '.') Finder->MatchExt = DuplicateString(&Ext[1]); else Finder->MatchExt = DuplicateString(&Ext[0]); if (!Finder->MatchExt) { geRam_Free(Finder->MatchName); geRam_Free(Finder); return NULL; } Finder->Current = SubTree->Children; return Finder; }
void GroupList_Collapse (GroupListType *Groups, int StartingId, BrushList *Brushes, CEntityArray *Entities) { int nEntries; assert (Groups != NULL); assert (StartingId > 0); assert (Brushes != NULL); assert (Entities != NULL); nEntries = Group_GetCount (Groups); if (nEntries > 1) { Group_MapEntry *Mappings; Mappings = (Group_MapEntry *)geRam_Allocate (nEntries * sizeof (Group_MapEntry)); if (Mappings != NULL) { int i; Group *pGroup; pGroup = Groups->First; assert (pGroup->GroupId == 0); pGroup = pGroup->Next; i = 0; while (pGroup != NULL) { assert (pGroup->GroupId != 0); Mappings[i].OldId = pGroup->GroupId; Mappings[i].NewId = i+StartingId; pGroup->GroupId = Mappings[i].NewId; ++i; pGroup = pGroup->Next; } Mappings[i].OldId = 0; // stop sentinel Mappings[i].NewId = 0; BrushList_Enum (Brushes, Mappings, Group_RenumBrush); EntityList_Enum (*Entities, Mappings, Group_RenumEntity); geRam_Free (Mappings); } } }
Type * Type_CreatePtrType(Type **tl, Type *tp) { Type * ptrTp; ptrTp = geRam_Allocate(sizeof(*ptrTp)); if (!ptrTp) return ptrTp; memset(ptrTp, 0, sizeof(*ptrTp)); ptrTp->tpTopType = T_PTR; ptrTp->t.p.tpPtrType = tp; ptrTp->tpNext = *tl; *tl = ptrTp; return ptrTp; }
DirTree * DirTree_AddFile(DirTree *Tree, const char *Path, geBoolean IsDirectory) { DirTree * NewEntry; const char * LeftOvers; assert(Tree); assert(Path); assert(IsDirectory == GE_TRUE || IsDirectory == GE_FALSE); assert(strlen(Path) > 0); if (PathHasDir(Path)) { Tree = DirTree_FindPartial(Tree, Path, &LeftOvers); if (!Tree) return NULL; if (PathHasDir(LeftOvers)) return NULL; Path = LeftOvers; } NewEntry = geRam_Allocate(sizeof(*NewEntry)); if (!NewEntry) return NULL; memset(NewEntry, 0, sizeof(*NewEntry)); NewEntry->Name = DuplicateString(Path); if (!NewEntry->Name) { geRam_Free(NewEntry->Name); geRam_Free(NewEntry); return NULL; } NewEntry->Siblings = Tree->Children; Tree->Children = NewEntry; if (IsDirectory == GE_TRUE) NewEntry->AttributeFlags |= GE_VFILE_ATTRIB_DIRECTORY; return NewEntry; }
DirTree *DirTree_Create(void) { DirTree * Tree; Tree = geRam_Allocate(sizeof(*Tree)); if (!Tree) return Tree; memset(Tree, 0, sizeof(*Tree)); Tree->Name = DuplicateString(""); if (!Tree->Name) { geRam_Free(Tree); return NULL; } Tree->AttributeFlags |= GE_VFILE_ATTRIB_DIRECTORY; return Tree; }
Type * Type_CreateType(Type **tl, Iden *name, unsigned short flags) { Type * tp; tp = geRam_Allocate(sizeof(*tp)); memset(tp, 0, sizeof(*tp)); if (!tp) return tp; tp->tpName = name; tp->tpTopType = T_STRUCT; tp->tpFlags = flags; tp->tpNext = *tl; *tl = tp; return tp; }
void GroupList_FillCombobox( const GroupListType *pList, CComboBox * pCombo, int GroupId ) { Group * g; PCompare pSortArray ; int i ; int Count ; int Index ; pCombo->ResetContent() ; Count = Group_GetCount( pList ) ; assert( Count ) ; pSortArray = (PCompare)geRam_Allocate ( sizeof(SCompare) * Count ) ; if( pSortArray == NULL ) return ; g = pList->First; i = 0 ; while (g != NULL) { pSortArray[i].pGroup = g ; i++ ; g = g->Next; } qsort( pSortArray, Count, sizeof( SCompare ), compare ) ; for( i=0; i < Count; i++ ) { Index = pCombo->AddString( pSortArray[i].pGroup->GroupName ); pCombo->SetItemData( Index, pSortArray[i].pGroup->GroupId ); if( pSortArray[i].pGroup->GroupId == GroupId ) { pCombo->SetCurSel( Index ); } }// Fill the list geRam_Free ( pSortArray ) ; }/* GroupList_FillCombobox */
static void * GENESISCC FSDos_FinderCreate( geVFile * FS, void * Handle, const char * FileSpec) { DosFinder * Finder; DosFile * File; char * NamePtr; char Buff[_MAX_PATH]; assert(FileSpec != NULL); File = Handle; CHECK_HANDLE(File); Finder = geRam_Allocate(sizeof(*Finder)); if (!Finder) return NULL; memset(Finder, 0, sizeof(*Finder)); if (BuildFileName(File, FileSpec, Buff, &NamePtr, sizeof(Buff)) == GE_FALSE) { geRam_Free(Finder); return NULL; } Finder->OffsetToName = NamePtr - Buff; Finder->FindHandle = FindFirstFile(Buff, &Finder->FindData); Finder->FirstStillCached = GE_TRUE; Finder->Signature = DOSFINDER_SIGNATURE; return (void *)Finder; }
Brush *BrushTemplate_CreateCone (const BrushTemplate_Cone *pTemplate) { int index, BottomCount; geVec3d StartPoint, CurPoint, OldPoint, OuterFocus; geVec3d FaceVerts[3], *BottomVerts; FaceList *fl; Face *f; Brush *b; double CurAngle; double AngleDeltaDegrees = 360.0f/(float)pTemplate->VerticalStrips; double AngleDelta = UNITS_DEGREES_TO_RADIANS (AngleDeltaDegrees); fl =FaceList_Create(pTemplate->VerticalStrips + 1); geVec3d_Set (&OuterFocus, 0, (float)(pTemplate->Height/2), 0); geVec3d_Set (&StartPoint, (float)(pTemplate->Width/2), (float)-(pTemplate->Height/2), 0); CurPoint =OldPoint =StartPoint; BottomVerts =(geVec3d *)geRam_Allocate (sizeof(geVec3d) * pTemplate->VerticalStrips); BottomVerts[0] =CurPoint; CurAngle =BottomCount =0; for( index = 1; index < pTemplate->VerticalStrips; index++ ) { // Rotate around to create our successive points... CurAngle += AngleDelta; geVec3d_Set ( &CurPoint, (float)(( StartPoint.X * cos( CurAngle ) ) +( StartPoint.Z * sin( CurAngle ) )), StartPoint.Y, (float)(( StartPoint.Z * cos( CurAngle ) ) -( StartPoint.X * sin( CurAngle ) )) ); FaceVerts[2] =OuterFocus; FaceVerts[1] =OldPoint; FaceVerts[0] =CurPoint; f =Face_Create(3, FaceVerts, 0); FaceList_AddFace(fl, f); OldPoint =CurPoint; // Assign the current point to bottom plane... BottomVerts[++BottomCount] =CurPoint; } // Create the final polygon... CurAngle += AngleDelta; geVec3d_Set ( &CurPoint, (float)(( StartPoint.X * cos( CurAngle ) ) + ( StartPoint.Z * sin( CurAngle ) )), StartPoint.Y, (float)(( StartPoint.Z * cos( CurAngle ) ) - ( StartPoint.X * sin( CurAngle ) )) ); FaceVerts[2] =OuterFocus; FaceVerts[1] =OldPoint; FaceVerts[0] =CurPoint; f =Face_Create(3, FaceVerts, 0); if(f) { FaceList_AddFace(fl, f); } f =Face_Create(pTemplate->VerticalStrips, BottomVerts, 0); if(f) { if(pTemplate->Style > 1) //default to hollow (if they make hollow later) { Face_SetFixedHull(f, GE_TRUE); } FaceList_AddFace(fl, f); } geRam_Free(BottomVerts); if(!pTemplate->Style) { b =Brush_Create(BRUSH_LEAF, fl, NULL); if(b) { Brush_SetSubtract(b, pTemplate->TCut); } return b; } else { BrushList *bl =BrushList_Create(); Brush *bh, *bm; b =Brush_Create(BRUSH_LEAF, fl, NULL); if(b) { Brush_SetHollow(b, GE_TRUE); Brush_SetHullSize(b, (float)pTemplate->Thickness); bh =Brush_CreateHollowFromBrush(b); if(bh) { Brush_SetHollowCut(bh, GE_TRUE); BrushList_Append(bl, b); BrushList_Append(bl, bh); bm =Brush_Create(BRUSH_MULTI, NULL, bl); if(bm) { Brush_SetHollow(bm, GE_TRUE); Brush_SetSubtract(bm, pTemplate->TCut); Brush_SetHullSize(bm, (float)pTemplate->Thickness); return bm; } } else { Brush_Destroy(&b); BrushList_Destroy(&bl); } } else { BrushList_Destroy(&bl); } } return NULL; }
static SoundManager * CreateSoundManager(HWND hWnd ) { typedef HRESULT (WINAPI *DS_CREATE_FUNC)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN); PCMWAVEFORMAT pcmwf; DSBUFFERDESC dsbdesc; HRESULT hres; SoundManager * sm; DS_CREATE_FUNC pDirectSoundCreate; // load the DirectSound DLL hmodDirectSound = LoadLibrary ("DSOUND.DLL"); if (hmodDirectSound == NULL) { // Couldn't load DSOUND.DLL return NULL; } pDirectSoundCreate = (DS_CREATE_FUNC)GetProcAddress (hmodDirectSound, "DirectSoundCreate"); if (pDirectSoundCreate == NULL) { // couldn't find the DirectSoundCreate function FreeLibrary (hmodDirectSound); return NULL; } hres = pDirectSoundCreate(NULL, &lpDirectSound, NULL); if (hres != DS_OK) { // failed somehow FreeLibrary (hmodDirectSound); return NULL; } // sm = malloc(sizeof(*sm)); sm = geRam_Allocate(sizeof(*sm)); if (!sm) { IDirectSound_Release(lpDirectSound); FreeLibrary (hmodDirectSound); return NULL; } sm->smChannelCount = 0; sm->smNextChannelID = 1; sm->smChannels = NULL; memset(&pcmwf, 0, sizeof(PCMWAVEFORMAT)); pcmwf.wf.wFormatTag = WAVE_FORMAT_PCM; //pcmwf.wf.nChannels = 1; //pcmwf.wf.nSamplesPerSec = 44050; //pcmwf.wf.nBlockAlign = 2; #if 1 pcmwf.wf.nChannels = 2; pcmwf.wf.nSamplesPerSec = 44100; pcmwf.wf.nBlockAlign = 4; pcmwf.wBitsPerSample = 16; pcmwf.wf.nAvgBytesPerSec = pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign; #else pcmwf.wf.nChannels = 1; pcmwf.wf.nSamplesPerSec = 22050; pcmwf.wf.nBlockAlign = 1; pcmwf.wBitsPerSample = 8; pcmwf.wf.nAvgBytesPerSec = pcmwf.wf.nSamplesPerSec * 2; #endif memset(&dsbdesc, 0, sizeof(DSBUFFERDESC)); dsbdesc.dwSize = sizeof(DSBUFFERDESC); dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER;// | DSBCAPS_CTRLDEFAULT;// | DSBCAPS_CTRL3D; dsbdesc.dwBufferBytes = 0; //dwBufferBytes and lpwfxFormat must be set this way. dsbdesc.lpwfxFormat = NULL; #if 1 if (DS_OK== IDirectSound_SetCooperativeLevel(lpDirectSound, hWnd,DSSCL_NORMAL)) #else if (DS_OK== IDirectSound_SetCooperativeLevel(lpDirectSound, hWnd,DSSCL_EXCLUSIVE)) #endif { if (DS_OK== IDirectSound_CreateSoundBuffer(lpDirectSound, &dsbdesc, &sm->smPrimaryChannel, NULL)) { return sm; } IDirectSound_Release(lpDirectSound); FreeLibrary (hmodDirectSound); } // free( sm ); geRam_Free(sm); return NULL; }
static void * GENESISCC FSDos_Open( geVFile * FS, void * Handle, const char * Name, void * Context, unsigned int OpenModeFlags) { DosFile * DosFS; DosFile * NewFile; char Buff[_MAX_PATH]; int Length; char * NamePtr; DosFS = Handle; if (DosFS && DosFS->IsDirectory != GE_TRUE) return NULL; NewFile = geRam_Allocate(sizeof(*NewFile)); if (!NewFile) return NewFile; memset(NewFile, 0, sizeof(*NewFile)); if (BuildFileName(DosFS, Name, Buff, &NamePtr, sizeof(Buff)) == GE_FALSE) goto fail; Length = strlen(Buff); NewFile->FullPath = geRam_Allocate(Length + 1); if (!NewFile->FullPath) goto fail; NewFile->Name = NewFile->FullPath + (NamePtr - &Buff[0]); memcpy(NewFile->FullPath, Buff, Length + 1); if (OpenModeFlags & GE_VFILE_OPEN_DIRECTORY) { WIN32_FIND_DATA FileInfo; HANDLE FindHandle; geBoolean IsDirectory; assert(!DosFS || DosFS->IsDirectory == GE_TRUE); memset(&FileInfo, 0, sizeof(FileInfo)); FindHandle = FindFirstFile(NewFile->FullPath, &FileInfo); if (FindHandle != INVALID_HANDLE_VALUE && FileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { IsDirectory = GE_TRUE; } else { IsDirectory = IsRootDirectory(NewFile->FullPath); } FindClose (FindHandle); if (OpenModeFlags & GE_VFILE_OPEN_CREATE) { if (IsDirectory == GE_TRUE) goto fail; if (CreateDirectory(NewFile->FullPath, NULL) == FALSE) goto fail; } else { if (IsDirectory != GE_TRUE) goto fail; } NewFile->IsDirectory = GE_TRUE; NewFile->FileHandle = INVALID_HANDLE_VALUE; } else { DWORD ShareMode=0; DWORD CreationMode; DWORD Access=0; DWORD LastError; CreationMode = OPEN_EXISTING; switch (OpenModeFlags & (GE_VFILE_OPEN_READONLY | GE_VFILE_OPEN_UPDATE | GE_VFILE_OPEN_CREATE)) { case GE_VFILE_OPEN_READONLY: Access = GENERIC_READ; ShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; break; case GE_VFILE_OPEN_CREATE: CreationMode = CREATE_ALWAYS; // Fall through case GE_VFILE_OPEN_UPDATE: Access = GENERIC_READ | GENERIC_WRITE; ShareMode = FILE_SHARE_READ; break; default: assert(!"Illegal open mode flags"); break; } NewFile->FileHandle = CreateFile(NewFile->FullPath, Access, ShareMode, NULL, CreationMode, 0, NULL); if (NewFile->FileHandle == INVALID_HANDLE_VALUE) { LastError = GetLastError(); goto fail; } } NewFile->Signature = DOSFILE_SIGNATURE; return (void *)NewFile; fail: if (NewFile->FullPath) geRam_Free(NewFile->FullPath); geRam_Free(NewFile); return NULL; }
static geBoolean ReadTree(geVFile *File, DirTree **TreePtr) { int Terminator; int Length; DirTree * Tree; if (geVFile_Read(File, &Terminator, sizeof(Terminator)) == GE_FALSE) return GE_FALSE; if (Terminator == DIRTREE_LIST_TERMINATED) { *TreePtr = NULL; return GE_TRUE; } Tree = geRam_Allocate(sizeof(*Tree)); if (!Tree) return GE_FALSE; memset(Tree, 0, sizeof(*Tree)); // Read the name if (geVFile_Read(File, &Length, sizeof(Length)) == GE_FALSE) goto fail; assert(Length > 0); Tree->Name = geRam_Allocate(Length); if (!Tree->Name) { geRam_Free(Tree); return GE_FALSE; } if (geVFile_Read(File, Tree->Name, Length) == GE_FALSE) goto fail; //printf("Reading '%s'\n", Tree->Name); // Read out the attribute information if (geVFile_Read(File, &Tree->Time, sizeof(Tree->Time)) == GE_FALSE) goto fail; if (geVFile_Read(File, &Tree->AttributeFlags, sizeof(Tree->AttributeFlags)) == GE_FALSE) goto fail; if (geVFile_Read(File, &Tree->Size, sizeof(Tree->Size)) == GE_FALSE) goto fail; if (geVFile_Read(File, &Tree->Offset, sizeof(Tree->Offset)) == GE_FALSE) goto fail; if (geVFile_Read(File, &Tree->Hints.HintDataLength, sizeof(Tree->Hints.HintDataLength)) == GE_FALSE) goto fail; if (Tree->Hints.HintDataLength != 0) { Tree->Hints.HintData = geRam_Allocate(Tree->Hints.HintDataLength); if (!Tree->Hints.HintData) goto fail; //bug fix. someone got copy happy and forgot to remove the & from Tree->Hints.HintData if (geVFile_Read(File, Tree->Hints.HintData, Tree->Hints.HintDataLength) == GE_FALSE) goto fail; } //printf("Reading children of '%s'\n", Tree->Name); // Read the children if (ReadTree(File, &Tree->Children) == GE_FALSE) goto fail; //printf("Reading siblings of '%s'\n", Tree->Name); // Read the Siblings if (ReadTree(File, &Tree->Siblings) == GE_FALSE) goto fail; //DirTree_Dump(Tree); *TreePtr = Tree; return GE_TRUE; fail: DirTree_Destroy(Tree); return GE_FALSE; }
geBoolean CWadFile::Setup(const char *Filename) { geVFile * Library; geBoolean NoErrors = GE_FALSE; Library = geVFile_OpenNewSystem (NULL, GE_VFILE_TYPE_VIRTUAL, Filename, NULL, GE_VFILE_OPEN_READONLY | GE_VFILE_OPEN_DIRECTORY); if (Library != NULL) { NoErrors = GE_TRUE; DestroyBitmapArray (); int nFiles = wadCountFiles (Library, "*.*"); if (nFiles > 0) { // make new array and fill it with loaded bitmaps mBitmaps = (WadFileEntry *)geRam_Allocate (nFiles * sizeof (WadFileEntry)); // and fill array with filenames NoErrors = GE_FALSE; geVFile_Finder *Finder = geVFile_CreateFinder (Library, "*.*"); if (Finder != NULL) { NoErrors = GE_TRUE; geVFile_Properties Props; while (geVFile_FinderGetNextFile (Finder) != GE_FALSE) { geVFile_FinderGetProperties (Finder, &Props); // load the file and create a DibBitmap from it geVFile *BmpFile = geVFile_Open (Library, Props.Name, GE_VFILE_OPEN_READONLY); geBitmap *TheBitmap; if (BmpFile == NULL) { NoErrors = GE_FALSE; } else { TheBitmap = geBitmap_CreateFromFile (BmpFile); geVFile_Close (BmpFile); if (TheBitmap == NULL) { NoErrors = GE_FALSE; } else { if (geBitmap_SetFormat (TheBitmap, GE_PIXELFORMAT_16BIT_555_RGB, GE_FALSE, 0, NULL) != GE_FALSE) { WadFileEntry *pe; geBitmap_Info info, info2; geBitmap_GetInfo (TheBitmap, &info, &info2); pe = &mBitmaps[mBitmapCount]; pe->bmp = TheBitmap; pe->Height = info.Height; pe->Width = info.Width; pe->Name = Util_Strdup (Props.Name); geBitmap_LockForReadNative (pe->bmp, &pe->LockedBitmap, 0, 0); pe->BitsPtr = geBitmap_GetBits (pe->LockedBitmap); ++mBitmapCount; } else { geBitmap_Destroy (&TheBitmap); NoErrors = GE_FALSE; } } } } geVFile_DestroyFinder (Finder); } } geVFile_Close (Library); } return GE_TRUE; }
//======================================================================================== // ReadChunk //======================================================================================== static geBoolean ReadChunk(GBSP_BSPData *BSP, GBSP_Chunk *Chunk, geVFile *f) { int i; if (geVFile_Read(f, Chunk, sizeof(GBSP_Chunk)) == GE_FALSE) { return GE_FALSE; } switch(Chunk->Type) { case GBSP_CHUNK_HEADER: { // printf("GBSP_CHUNK_HEADER\n"); if (sizeof(GBSP_Header) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } if (!ReadChunkData(Chunk, (void*)&BSP->GBSPHeader, f)) return GE_FALSE; if (strcmp(BSP->GBSPHeader.TAG, "GBSP")) { geErrorLog_Add(GE_ERR_INVALID_BSP_TAG, NULL); return GE_FALSE; } if (BSP->GBSPHeader.Version != GBSP_VERSION) { geErrorLog_Add(GE_ERR_INVALID_BSP_VERSION, NULL); return GE_FALSE; } break; } case GBSP_CHUNK_MODELS: { // printf("GBSP_CHUNK_MODELS\n"); if (sizeof(GFX_Model) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXModels = Chunk->Elements; BSP->GFXModels = GE_RAM_ALLOCATE_ARRAY(GFX_Model, BSP->NumGFXModels); if (!ReadChunkData(Chunk, (void*)BSP->GFXModels, f)) return GE_FALSE; // Walk the models and zero out the motion pointers for (i = 0; i < BSP->NumGFXModels; i++) BSP->GFXModels[i].Motion = NULL; break; } case GBSP_CHUNK_NODES: { // printf("GBSP_CHUNK_NODES\n"); if (sizeof(GFX_Node) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXNodes = Chunk->Elements; BSP->GFXNodes = (GFX_Node*)geRam_Allocate(sizeof(GFX_Node)*BSP->NumGFXNodes); if (!ReadChunkData(Chunk, (void*)BSP->GFXNodes, f)) return GE_FALSE; break; } case GBSP_CHUNK_BNODES: { // printf("GBSP_CHUNK_BNODES\n"); if (sizeof(GFX_BNode) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXBNodes = Chunk->Elements; if (BSP->NumGFXBNodes) { BSP->GFXBNodes = (GFX_BNode*)geRam_Allocate(sizeof(GFX_BNode)*BSP->NumGFXBNodes); if (!ReadChunkData(Chunk, (void*)BSP->GFXBNodes, f)) return GE_FALSE; } break; } case GBSP_CHUNK_LEAFS: { // printf("GBSP_CHUNK_LEAFS\n"); if (sizeof(GFX_Leaf) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXLeafs = Chunk->Elements; BSP->GFXLeafs = (GFX_Leaf*)geRam_Allocate(sizeof(GFX_Leaf)*BSP->NumGFXLeafs); if (!ReadChunkData(Chunk, (void*)BSP->GFXLeafs, f)) return GE_FALSE; break; } case GBSP_CHUNK_CLUSTERS: { // printf("GBSP_CHUNK_CLUSTERS\n"); if (sizeof(GFX_Cluster) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXClusters = Chunk->Elements; //BSP->GFXClusters = GE_RAM_ALLOCATE_ARRAY(GFX_Cluster, BSP->NumGFXClusters); BSP->GFXClusters = (GFX_Cluster*)geRam_Allocate(sizeof(GFX_Cluster)*BSP->NumGFXClusters); if (!ReadChunkData(Chunk, (void*)BSP->GFXClusters, f)) return GE_FALSE; break; } case GBSP_CHUNK_AREAS: { // printf("GBSP_CHUNK_AREAS\n"); if (sizeof(GFX_Area) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXAreas = Chunk->Elements; BSP->GFXAreas = GE_RAM_ALLOCATE_ARRAY(GFX_Area, BSP->NumGFXAreas); if (!ReadChunkData(Chunk, BSP->GFXAreas, f)) return GE_FALSE; break; } case GBSP_CHUNK_AREA_PORTALS: { // printf("GBSP_CHUNK_AREA_PORTALS\n"); if (sizeof(GFX_AreaPortal) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXAreaPortals = Chunk->Elements; BSP->GFXAreaPortals = GE_RAM_ALLOCATE_ARRAY(GFX_AreaPortal, BSP->NumGFXAreaPortals); if (!ReadChunkData(Chunk, BSP->GFXAreaPortals, f)) return GE_FALSE; break; } case GBSP_CHUNK_PORTALS: { // printf("GBSP_CHUNK_PORTALS\n"); if (sizeof(GFX_Portal) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXPortals = Chunk->Elements; BSP->GFXPortals = (GFX_Portal*)geRam_Allocate(sizeof(GFX_Portal)*BSP->NumGFXPortals); if (!ReadChunkData(Chunk, (void*)BSP->GFXPortals, f)) return GE_FALSE; break; } case GBSP_CHUNK_PLANES: { // printf("GBSP_CHUNK_PLANES\n"); if (sizeof(GFX_Plane) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXPlanes = Chunk->Elements; BSP->GFXPlanes = (GFX_Plane*)geRam_Allocate(sizeof(GFX_Plane)*BSP->NumGFXPlanes); if (!ReadChunkData(Chunk, (void*)BSP->GFXPlanes, f)) return GE_FALSE; break; } case GBSP_CHUNK_FACES: { // printf("GBSP_CHUNK_FACES\n"); if (sizeof(GFX_Face) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXFaces = Chunk->Elements; BSP->GFXFaces = (GFX_Face*)geRam_Allocate(sizeof(GFX_Face)*BSP->NumGFXFaces); if (!ReadChunkData(Chunk, (void*)BSP->GFXFaces, f)) return GE_FALSE; break; } case GBSP_CHUNK_LEAF_FACES: { // printf("GBSP_CHUNK_LEAF_FACES\n"); if (sizeof(int32) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXLeafFaces = Chunk->Elements; BSP->GFXLeafFaces = (int32*)geRam_Allocate(sizeof(int32)*BSP->NumGFXLeafFaces); if (!ReadChunkData(Chunk, (void*)BSP->GFXLeafFaces, f)) return GE_FALSE; break; } case GBSP_CHUNK_LEAF_SIDES: { // printf("GBSP_CHUNK_LEAF_SIDES\n"); if (sizeof(GFX_LeafSide) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXLeafSides = Chunk->Elements; BSP->GFXLeafSides = (GFX_LeafSide*)geRam_Allocate(sizeof(GFX_LeafSide)*BSP->NumGFXLeafSides); if (!ReadChunkData(Chunk, (void*)BSP->GFXLeafSides, f)) return GE_FALSE; break; } case GBSP_CHUNK_VERTS: { // printf("GBSP_CHUNK_VERTS\n"); if (sizeof(geVec3d) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXVerts = Chunk->Elements; BSP->GFXVerts = (geVec3d*)geRam_Allocate(sizeof(geVec3d)*BSP->NumGFXVerts); if (!ReadChunkData(Chunk, (void*)BSP->GFXVerts, f)) return GE_FALSE; break; } case GBSP_CHUNK_VERT_INDEX: { // printf("GBSP_CHUNK_VERT_INDEX\n"); if (sizeof(int32) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXVertIndexList = Chunk->Elements; BSP->GFXVertIndexList = (int32*)geRam_Allocate(sizeof(int32)*BSP->NumGFXVertIndexList); if (!ReadChunkData(Chunk, (void*)BSP->GFXVertIndexList, f)) return GE_FALSE; break; } case GBSP_CHUNK_RGB_VERTS: { // printf("GBSP_CHUNK_RGB_VERTS\n"); if (sizeof(geVec3d) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXRGBVerts = Chunk->Elements; BSP->GFXRGBVerts = (geVec3d*)geRam_Allocate(sizeof(geVec3d)*BSP->NumGFXRGBVerts); if (!ReadChunkData(Chunk, (void*)BSP->GFXRGBVerts, f)) return GE_FALSE; break; } case GBSP_CHUNK_TEXINFO: { // printf("GBSP_CHUNK_TEXINFO\n"); if (sizeof(GFX_TexInfo) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXTexInfo = Chunk->Elements; BSP->GFXTexInfo = (GFX_TexInfo*)geRam_Allocate(sizeof(GFX_TexInfo)*BSP->NumGFXTexInfo); if (!ReadChunkData(Chunk, (void*)BSP->GFXTexInfo, f)) return GE_FALSE; break; } case GBSP_CHUNK_TEXTURES: { // printf("GBSP_CHUNK_TEXTURES\n"); if (sizeof(GFX_Texture) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXTextures = Chunk->Elements; BSP->GFXTextures = (GFX_Texture*)geRam_Allocate(sizeof(GFX_Texture)*BSP->NumGFXTextures); if (!ReadChunkData(Chunk, (void*)BSP->GFXTextures, f)) return GE_FALSE; break; } case GBSP_CHUNK_TEXDATA: { // printf("GBSP_CHUNK_TEXDATA\n"); if (sizeof(uint8) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXTexData = Chunk->Elements; BSP->GFXTexData = (uint8*)geRam_Allocate(sizeof(uint8)*BSP->NumGFXTexData); if (!ReadChunkData(Chunk, (void*)BSP->GFXTexData, f)) return GE_FALSE; break; } case GBSP_CHUNK_ENTDATA: { // printf("GBSP_CHUNK_ENTDATA\n"); if (sizeof(uint8) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXEntData = Chunk->Elements; BSP->GFXEntData = (uint8*)geRam_Allocate(sizeof(uint8)*BSP->NumGFXEntData); if (!ReadChunkData(Chunk, (void*)BSP->GFXEntData, f)) return GE_FALSE; break; } case GBSP_CHUNK_LIGHTDATA: { // printf("GBSP_CHUNK_LIGHTDATA\n"); if (sizeof(uint8) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXLightData = Chunk->Elements; BSP->GFXLightData = (uint8*)geRam_Allocate(sizeof(uint8)*BSP->NumGFXLightData); if (!ReadChunkData(Chunk, (void*)BSP->GFXLightData, f)) return GE_FALSE; break; } case GBSP_CHUNK_VISDATA: { // printf("GBSP_CHUNK_VISDATA\n"); if (sizeof(uint8) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXVisData = Chunk->Elements; BSP->GFXVisData = (uint8*)geRam_Allocate(sizeof(uint8)*BSP->NumGFXVisData); if (!ReadChunkData(Chunk, (void*)BSP->GFXVisData, f)) return GE_FALSE; break; } case GBSP_CHUNK_SKYDATA: { // printf("GBSP_CHUNK_SKYDATA\n"); if (sizeof(GFX_SkyData) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } if (!ReadChunkData(Chunk, (void*)&BSP->GFXSkyData, f)) return GE_FALSE; break; } case GBSP_CHUNK_PALETTES: { // printf("GBSP_CHUNK_PALETTES\n"); if (sizeof(DRV_Palette) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXPalettes = Chunk->Elements; BSP->GFXPalettes = (DRV_Palette*)geRam_Allocate(sizeof(DRV_Palette)*BSP->NumGFXPalettes); if (BSP->GFXPalettes == NULL) return GE_FALSE; if (!ReadChunkData(Chunk, (void*)BSP->GFXPalettes, f)) return GE_FALSE; break; } case GBSP_CHUNK_MOTIONS: { // printf("GBSP_CHUNK_MOTIONS\n"); return LoadMotions(BSP, f); } case GBSP_CHUNK_END: { // printf("GBSP_CHUNK_END\n"); break; } default: // printf("Don't know what this chunk is\n"); return GE_FALSE; } return TRUE; }
Brush *BrushTemplate_CreateSpheroid (const BrushTemplate_Spheroid *pTemplate) { double z, ring_radius, r, dz, t, dt; int vcnt, HBand, VBand; geVec3d *sv, FaceVerts[4]; FaceList *fl; Face *f; Brush *b; if((pTemplate->HorizontalBands < 2) || (pTemplate->VerticalBands < 3)) { return GE_FALSE ; } fl =FaceList_Create((pTemplate->HorizontalBands)* pTemplate->VerticalBands); sv =(geVec3d *)geRam_Allocate(sizeof(geVec3d) * (((pTemplate->HorizontalBands-1) * pTemplate->VerticalBands)+2)); r =pTemplate->YSize; vcnt =0; geVec3d_Set (&sv[vcnt], 0.0f, pTemplate->YSize, 0.0f); vcnt++; dz =2.0*r/(double)(pTemplate->HorizontalBands-1); for(z=(-r)+dz/2.0; z<(r-dz/2.0+dz/4.0); z+=dz) { ring_radius =sqrt(r*r - z*z); dt =PI2 /(double)(pTemplate->VerticalBands); for(t=0.0;t < PI2-(dt*0.5);t+=dt) { sv[vcnt].X =(float)(sin(t) * ring_radius); sv[vcnt].Z =(float)(cos(t) * ring_radius); sv[vcnt++].Y=(float)(-z); } } sv[vcnt].X =0.0f; sv[vcnt].Y =(float)(-pTemplate->YSize); sv[vcnt++].Z=0.0f; for(VBand=0;VBand < pTemplate->VerticalBands;VBand++) { FaceVerts[0] =sv[0]; FaceVerts[1] =sv[(((1 + VBand) % pTemplate->VerticalBands) + 1)]; FaceVerts[2] =sv[(VBand % pTemplate->VerticalBands)+1]; f =Face_Create(3, FaceVerts, 0); if(f) { FaceList_AddFace(fl, f); } } for(HBand=1;HBand < (pTemplate->HorizontalBands-1);HBand++) { for(VBand=0;VBand < pTemplate->VerticalBands;VBand++) { FaceVerts[0] =sv[(((HBand-1)*pTemplate->VerticalBands)+1)+VBand]; FaceVerts[1] =sv[(((HBand-1)*pTemplate->VerticalBands)+1)+((VBand+1)%pTemplate->VerticalBands)]; FaceVerts[2] =sv[((HBand*pTemplate->VerticalBands)+1)+((VBand+1)%pTemplate->VerticalBands)]; FaceVerts[3] =sv[((HBand*pTemplate->VerticalBands)+1)+VBand]; f =Face_Create(4, FaceVerts, 0); if(f) { FaceList_AddFace(fl, f); } } } for(VBand=0;VBand < pTemplate->VerticalBands;VBand++) { FaceVerts[0] =sv[1+((pTemplate->HorizontalBands-2)*pTemplate->VerticalBands)+VBand]; FaceVerts[1] =sv[1+((pTemplate->HorizontalBands-2)*pTemplate->VerticalBands)+((VBand+1)%pTemplate->VerticalBands)]; FaceVerts[2] =sv[((pTemplate->HorizontalBands-1)*pTemplate->VerticalBands)+1]; f =Face_Create(3, FaceVerts, 0); if(f) { FaceList_AddFace(fl, f); } } geRam_Free(sv); if(!pTemplate->Solid) { b =Brush_Create(BRUSH_LEAF, fl, NULL); if(b) { Brush_SetSubtract(b, pTemplate->TCut); } return b; } else { BrushList *bl =BrushList_Create(); Brush *bh, *bm; b =Brush_Create(BRUSH_LEAF, fl, NULL); if(b) { Brush_SetHollow(b, GE_TRUE); Brush_SetHullSize(b, (float)pTemplate->Thickness); bh =Brush_CreateHollowFromBrush(b); if(bh) { Brush_SetHollowCut(bh, GE_TRUE); BrushList_Append(bl, b); BrushList_Append(bl, bh); bm =Brush_Create(BRUSH_MULTI, NULL, bl); if(bm) { Brush_SetHollow(bm, GE_TRUE); Brush_SetSubtract(bm, pTemplate->TCut); Brush_SetHullSize(bm, (float)pTemplate->Thickness); return bm; } } else { Brush_Destroy(&b); BrushList_Destroy(&bl); } } else { BrushList_Destroy(&bl); } } return NULL; }
Brush *BrushTemplate_CreateCylinder (const BrushTemplate_Cylinder *pTemplate) { double CurrentXDiameter, CurrentZDiameter; double DeltaXDiameter, DeltaZDiameter; double CurrentXOffset, CurrentZOffset; double DeltaXOffset, DeltaZOffset, sqrcheck; double EllipseZ; int NumVerticalBands, HBand, VBand; int VertexCount=0; geVec3d *Verts, *TopPoints; geVec3d Current, Final, Delta; geXForm3d YRotation; FaceList *fl; Face *f; Brush *b; NumVerticalBands = (int)(pTemplate->VerticalStripes); if (NumVerticalBands < 3) { return NULL; } Verts =(geVec3d *)geRam_Allocate(sizeof(geVec3d)*NumVerticalBands * 2); TopPoints =(geVec3d *)geRam_Allocate(sizeof(geVec3d)*NumVerticalBands); fl =FaceList_Create(NumVerticalBands + 2); if(!Verts || !TopPoints ||!fl) { return NULL; } geXForm3d_SetIdentity(&YRotation); geXForm3d_SetYRotation(&YRotation, (M_PI * 2.0f)/(geFloat)NumVerticalBands); // Start with the top of cylinder CurrentXDiameter =pTemplate->TopXSize; CurrentZDiameter =pTemplate->TopZSize; DeltaXDiameter =(pTemplate->BotXSize - pTemplate->TopXSize); DeltaZDiameter =(pTemplate->BotZSize - pTemplate->TopZSize); // Get the offset amounts CurrentXOffset =pTemplate->TopXOffset; CurrentZOffset =pTemplate->TopZOffset; DeltaXOffset =(pTemplate->BotXOffset - pTemplate->TopXOffset); DeltaZOffset =(pTemplate->BotZOffset - pTemplate->TopZOffset); // Get the band positions and deltas geVec3d_Set(&Current, (float)(pTemplate->TopXSize / 2), (float)(pTemplate->YSize / 2), 0.0); geVec3d_Set(&Delta, (float)((pTemplate->BotXSize / 2) - Current.X), (float)(-(pTemplate->YSize/2) - Current.Y), 0.0); for(HBand = 0;HBand <= 1;HBand++) { Final = Current; for(VBand = 0;VBand < NumVerticalBands;VBand++) { // Get the elliptical Z value // (x^2/a^2) + (z^2/b^2) = 1 // z = sqrt(b^2(1 - x^2/a^2)) sqrcheck=( ((CurrentZDiameter/2)*(CurrentZDiameter/2)) * (1.0 - (Final.X*Final.X) / ( (CurrentXDiameter/2)*(CurrentXDiameter/2) )) ); if(sqrcheck <0.0) sqrcheck=0.0; EllipseZ = sqrt(sqrcheck); // Check if we need to negate this thing if(VBand > (NumVerticalBands/2)) EllipseZ = -EllipseZ; geVec3d_Set ( &Verts[VertexCount], (float)(Final.X + CurrentXOffset), Final.Y, (float)(EllipseZ + CurrentZOffset) ); VertexCount++; // Rotate the point around the Y to get the next vertical band geXForm3d_Rotate(&YRotation, &Final, &Final); } CurrentXDiameter +=DeltaXDiameter; CurrentZDiameter +=DeltaZDiameter; CurrentXOffset +=DeltaXOffset; CurrentZOffset +=DeltaZOffset; geVec3d_Add(&Current, &Delta, &Current); } for(VBand=0;VBand < NumVerticalBands;VBand++) { TopPoints[VBand] =Verts[VBand]; } f =Face_Create(NumVerticalBands, TopPoints, 0); if(f) { if(pTemplate->Solid > 1) { Face_SetFixedHull(f, GE_TRUE); } FaceList_AddFace(fl, f); } for(VBand=NumVerticalBands-1, HBand=0;VBand >=0;VBand--, HBand++) { TopPoints[HBand] =Verts[VBand + NumVerticalBands]; } f =Face_Create(NumVerticalBands, TopPoints, 0); if(f) { if(pTemplate->Solid > 1) { Face_SetFixedHull(f, GE_TRUE); } FaceList_AddFace(fl, f); } // Generate the polygons for(HBand = 0;HBand < 1;HBand++) { for(VBand = 0;VBand < NumVerticalBands;VBand++) { TopPoints[3] =Verts[(HBand * NumVerticalBands) + VBand]; TopPoints[2] =Verts[(HBand * NumVerticalBands) + ((VBand + 1) % NumVerticalBands)]; TopPoints[1] =Verts[((HBand + 1) * NumVerticalBands) + ((VBand + 1) % NumVerticalBands)]; TopPoints[0] =Verts[((HBand + 1) * NumVerticalBands) + VBand]; f =Face_Create(4, TopPoints, 0); if(f) { FaceList_AddFace(fl, f); } } } geRam_Free(Verts); geRam_Free(TopPoints); if(!pTemplate->Solid) { b =Brush_Create(BRUSH_LEAF, fl, NULL); if(b) { Brush_SetSubtract(b, pTemplate->TCut); } return b; } else { BrushList *bl =BrushList_Create(); Brush *bh, *bm; b =Brush_Create(BRUSH_LEAF, fl, NULL); if(b) { Brush_SetHollow(b, GE_TRUE); Brush_SetHullSize(b, (float)pTemplate->Thickness); bh =Brush_CreateHollowFromBrush(b); if(bh) { Brush_SetHollowCut(bh, GE_TRUE); BrushList_Append(bl, b); BrushList_Append(bl, bh); bm =Brush_Create(BRUSH_MULTI, NULL, bl); if(bm) { Brush_SetHollow(bm, GE_TRUE); Brush_SetSubtract(bm, pTemplate->TCut); Brush_SetHullSize(bm, (float)pTemplate->Thickness); return bm; } } else { Brush_Destroy(&b); BrushList_Destroy(&bl); } } else { BrushList_Destroy(&bl); } } return NULL; }