home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mega CD-ROM 1
/
megacd_rom_1.zip
/
megacd_rom_1
/
IRIT
/
IRITS.ZIP
/
ALLOCATE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-05-05
|
10KB
|
334 lines
/*****************************************************************************
* "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;
}