home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- * "Irit" - the 3d polygonal solid modeller. *
- * *
- * Written by: Gershon Elber Ver 0.2, Mar. 1990 *
- ******************************************************************************
- * Dynamic allocation module of "Irit" - the 3d polygonal solid modeller. *
- *****************************************************************************/
-
- /* #define DEBUG Print more messages in free/allocating. */
-
- #ifdef __MSDOS__
- #include <alloc.h>
- #include <time.h>
- #include <graphics.h>
- #endif /* __MSDOS__ */
-
- #include <stdio.h>
- #include <string.h>
- #include "program.h"
- #include "ctrl-brk.h"
- #include "graphgng.h"
- #include "allocatl.h"
- #include "allocatg.h"
- #include "windowsg.h"
-
- #ifndef __MSDOS__
- #include "xgraphic.h"
- #endif /* __MSDOS__ */
-
- #ifdef __MSDOS__
- /* Used to say when to update core left on screen: */
- static time_t LastTimeAlloc = 0;
- #endif /* __MSDOS__ */
-
- /* Used for fast reallocation of most common object types: */
- static VertexStruct *VertexFreedList = NULL;
- static PolygonStruct *PolygonFreedList = NULL;
- static ObjectStruct *ObjectFreedList = NULL;
-
- /*****************************************************************************
- * My Routine to allocate dynamic memory. All program requests must call this *
- * routine (no direct call to malloc). Dies if no memory. *
- * In order to reduce the overhead of the allocation, basic objects are *
- * allocated in ALLOCATE_NUM number of objects blocks. *
- *****************************************************************************/
- char *MyMalloc(unsigned int Size, int Type)
- {
- char *p;
- int i;
-
- # ifdef __MSDOS__
- if (time(NULL) != LastTimeAlloc) {
- if (WasCtrlBrk) FatalError(NULL); /* Jump to main loop. */
- WndwStatusWindowUpdate(); /* Print free memory. */
- LastTimeAlloc = time(NULL);
- }
- # endif /* __MSDOS__ */
-
- switch (Type) {
- case VERTEX_TYPE:
- # ifdef DEBUG
- fprintf(stderr, "MyMalloc: Allocate vertex type");
- # endif /* DEBUG */
- if (VertexFreedList != NULL) {
- p = (char *) VertexFreedList;
- VertexFreedList = VertexFreedList -> Pnext;
- }
- else {
- VertexStruct *V;
-
- /* Allocate ALLOCATE_NUM objects, returns first one as new */
- /* and chain together the rest of them into the free list. */
- p = malloc(Size * ALLOCATE_NUM);
- V = (VertexStruct *) p;
- if (V != NULL) {
- for (i=1; i<ALLOCATE_NUM-1; i++) V[i].Pnext = &V[i+1];
- V[ALLOCATE_NUM-1].Pnext = NULL;
- VertexFreedList = &V[1];
- }
- }
- break;
- case POLYGON_TYPE:
- # ifdef DEBUG
- fprintf(stderr, "MyMalloc: Allocate polygon type");
- # endif /* DEBUG */
- if (PolygonFreedList != NULL) {
- p = (char *) PolygonFreedList;
- PolygonFreedList = PolygonFreedList -> Pnext;
- }
- else {
- PolygonStruct *V;
-
- /* Allocate ALLOCATE_NUM objects, returns first one as new */
- /* and chain together the rest of them into the free list. */
- p = malloc(Size * ALLOCATE_NUM);
- V = (PolygonStruct *) p;
- if (V != NULL) {
- for (i=1; i<ALLOCATE_NUM-1; i++) V[i].Pnext = &V[i+1];
- V[ALLOCATE_NUM-1].Pnext = NULL;
- PolygonFreedList = &V[1];
- }
- }
- break;
- case OBJECT_TYPE:
- # ifdef DEBUG
- fprintf(stderr, "MyMalloc: Allocate object type");
- # endif /* DEBUG */
- if (ObjectFreedList != NULL) {
- p = (char *) ObjectFreedList;
- ObjectFreedList = ObjectFreedList -> Pnext;
- }
- else {
- ObjectStruct *V;
-
- /* Allocate ALLOCATE_NUM objects, returns first one as new */
- /* and chain together the rest of them into the free list. */
- p = malloc(Size * ALLOCATE_NUM);
- V = (ObjectStruct *) p;
- if (V != NULL) {
- for (i=1; i<ALLOCATE_NUM-1; i++) V[i].Pnext = &V[i+1];
- V[ALLOCATE_NUM-1].Pnext = NULL;
- ObjectFreedList = &V[1];
- }
- }
- break;
- default:
- # ifdef DEBUG
- fprintf(stderr, "MyMalloc: Allocate undefined Type %d", Type);
- # endif /* DEBUG */
- p = malloc(Size);
- break;
- }
-
- # ifdef DEBUG
- fprintf(stderr, " (Size = %d, ptr = %p)\n", Size, p);
- # endif /* DEBUG */
-
- if (p != NULL) return p;
-
- WndwInputWindowPutStr(
- "Not enough memory - program cannt continue", RED);
- GlblFatalError = TRUE;
- /* Long jump to main intraction loop - irit.c module */
- longjmp(LongJumpBuffer, 2);
-
- return NULL; /* Only makes warnings silent... */
- }
-
- /**********************************************************************
- * Routine to free a given structure, which is not needed any more *
- * Note usually only object will be given directly to MyFree which *
- * recursively free its structure... *
- * Also, it is perfectly legal to call with NULL to MyFree... *
- **********************************************************************/
- void MyFree(char *p, int Type)
- {
- int index;
- char Line[LINE_LEN];
-
- # ifdef __MSDOS__
- if (time(NULL) != LastTimeAlloc) {
- if (WasCtrlBrk) FatalError(NULL); /* Jump to main loop. */
- WndwStatusWindowUpdate(); /* Print free memory. */
- LastTimeAlloc = time(NULL);
- }
- # endif /* __MSDOS__ */
-
- if (p == NULL) return;
-
- # ifdef DEBUG
- /* The following might fail if a record is freed without any usage! */
- if (*((long *) p) == MAGIC_FREE_NUM)
- FatalError("MyFree:Free the same record twice, dies");
- *((long *) p) = MAGIC_FREE_NUM; /* And set it for next time... */
- # endif /* DEBUG */
-
- switch (Type) {
- case VERTEX_TYPE:
- # ifdef DEBUG
- fprintf(stderr, "MyFree: free vertex type\n");
- # endif /* DEBUG */
- FreeVertexList((VertexStruct *) p);
- break;
- case POLYGON_TYPE:
- # ifdef DEBUG
- fprintf(stderr, "MyFree: free polygon type\n");
- # endif /* DEBUG */
- FreePolygonList((PolygonStruct *) p);
- break;
- case OBJECT_TYPE:
- # ifdef DEBUG
- fprintf(stderr, "MyFree: free object type\n");
- # endif /* DEBUG */
- switch (((ObjectStruct *) p)->ObjType) {
- case UNDEF_OBJ:
- break;
- case GEOMETRIC_OBJ: /* The union points on Polygon list. */
- MyFree((char *) (((ObjectStruct *) p)-> U.Pl),
- POLYGON_TYPE);
- break;
- case NUMERIC_OBJ:
- case VECTOR_OBJ:
- case MATRIX_OBJ:
- case STRING_OBJ:
- break;
- case OBJ_LIST_OBJ: /* Need to dereference elements in list. */
- index = 0;
- while (index < MAX_OBJ_LIST &&
- ((ObjectStruct *) p) -> U.PObjList[index] != NULL)
- ((ObjectStruct *) p) -> U.PObjList[index++] -> Count--;
- break;
- default: /* Kill the program - something is WRONG! */
- sprintf(Line,
- "MyFree: Attempt to free undefined Object type %d",
- ((ObjectStruct *) p)->ObjType);
- FatalError(Line);
- break;
- }
- /* Add it to global freed object list: */
- ((ObjectStruct *) p) -> Pnext = ObjectFreedList;
- ObjectFreedList = (ObjectStruct *) p;
- break;
- default:
- # ifdef DEBUG
- fprintf(stderr, "MyFree: Free undefined Type %d\n", Type);
- # endif /* DEBUG */
- free(p);
- break;
- }
- }
-
- /**********************************************************************
- * Routine to free a polygon list each consists of circular vertex *
- * list. *
- **********************************************************************/
- static void FreePolygonList(PolygonStruct *PPoly)
- {
- struct PolygonStruct *Ptemp, *PPolyHead = PPoly;
-
- # ifdef DEBUG
- fprintf(stderr, "FreePolygonList: free polygon list\n");
- # endif /* DEBUG */
-
- while (PPoly) {
- FreeVertexList(PPoly -> V);
- Ptemp = PPoly;
- PPoly = PPoly -> Pnext;
- }
-
- /* Now chain this new list to the global freed polygon list: */
- Ptemp -> Pnext = PolygonFreedList;
- PolygonFreedList = PPolyHead;
- }
-
- /**********************************************************************
- * Routine to free a circular vertex list - one polygon contour. *
- **********************************************************************/
- static void FreeVertexList(VertexStruct *VFirst)
- {
- struct VertexStruct *V = VFirst, *Vtemp;
-
- # ifdef DEBUG
- fprintf(stderr, "FreeVertexList: free vertex list\n");
- # endif /* DEBUG */
-
- if (VFirst == NULL) return;
-
- do {
- Vtemp = V;
- V = V -> Pnext;
- }
- while (V != NULL && V != VFirst); /* Both - circular or NULL terminated. */
-
- /* Now chain this new list to the global freed vertex list: */
- Vtemp -> Pnext = VertexFreedList;
- VertexFreedList = VFirst;
- }
-
- /**********************************************************************
- * Allocate one Vertex Structure: *
- **********************************************************************/
- struct VertexStruct * AllocVertex(ByteType Count, ByteType Tags,
- PolygonStruct * PAdj, VertexStruct * Pnext)
- {
- struct VertexStruct *p;
-
- p = (VertexStruct *) MyMalloc(sizeof(VertexStruct), VERTEX_TYPE);
-
- p -> Count = Count;
- p -> Tags = Tags;
- p -> Pnext = Pnext;
- p -> PAdj = PAdj;
-
- return p;
- }
-
- /**********************************************************************
- * Allocate one Polygon Structure: *
- **********************************************************************/
- struct PolygonStruct * AllocPolygon(ByteType Count, ByteType Tags,
- VertexStruct * V, PolygonStruct * Pnext)
- {
- struct PolygonStruct *p;
-
- p = (PolygonStruct *) MyMalloc(sizeof(PolygonStruct), POLYGON_TYPE);
-
- p -> Plane[0] = p -> Plane[1] = p -> Plane[2] = p -> Plane[3] = 0.0;
- p -> Count = Count;
- p -> Tags = Tags;
- p -> V = V;
- p -> Pnext = Pnext;
-
- return p;
- }
-
- /**********************************************************************
- * Allocate one Object Structure: *
- **********************************************************************/
- struct ObjectStruct * AllocObject(char *Name, ByteType ObjType,
- ObjectStruct * Pnext)
- {
- struct ObjectStruct *p;
-
- p = (ObjectStruct *) MyMalloc(sizeof(ObjectStruct), OBJECT_TYPE);
-
- strcpy(p -> Name, Name);
- p -> ObjType = ObjType;
- p -> Count = 0;
- p -> Pnext = Pnext;
- p -> U.Pl = NULL; /* To be on the safe size... */
-
- return p;
- }
-