/* compute bitrate tracking setup, allocate circular packet size queue */ void BURGERCALL vorbis_bitrate_init(vorbis_info *vi,bitrate_manager_state *bm){ int i; codec_setup_info *ci=static_cast<codec_setup_info *>(vi->codec_setup); bitrate_manager_info *bi=&ci->bi; long maxlatency; FastMemSet(bm,0,sizeof(*bm)); if(bi){ bm->avg_sampledesired=(Word32)(bi->queue_avg_time*vi->rate); bm->avg_centerdesired=(Word32)(bi->queue_avg_time*vi->rate*bi->queue_avg_center); bm->minmax_sampledesired=(Word32)(bi->queue_minmax_time*vi->rate); /* first find the max possible needed queue size */ maxlatency=bm->avg_sampledesired-bm->avg_centerdesired; if (maxlatency<(long)bm->minmax_sampledesired) { maxlatency=bm->minmax_sampledesired; } maxlatency += bm->avg_centerdesired; if(maxlatency>0 && (bi->queue_avgmin>0 || bi->queue_avgmax>0 || bi->queue_hardmax>0 || bi->queue_hardmin>0)){ long maxpackets=maxlatency/(ci->blocksizes[0]>>1)+3; long bins=BITTRACK_DIVISOR*ci->passlimit[ci->coupling_passes-1]; bm->queue_size=maxpackets; bm->queue_bins=bins; bm->queue_binned=static_cast<Word32 *>(AllocAPointer(maxpackets*bins*sizeof(*bm->queue_binned))); bm->queue_actual=static_cast<Word32 *>(AllocAPointer(maxpackets*sizeof(*bm->queue_actual))); if((bi->queue_avgmin>0 || bi->queue_avgmax>0) && bi->queue_avg_time>0){ bm->avg_binacc=static_cast<long *>(AllocAPointer(bins*sizeof(*bm->avg_binacc))); bm->avgfloat=bi->avgfloat_initial; }else{ bm->avg_tail= -1; } if((bi->queue_hardmin>0 || bi->queue_hardmax>0) && bi->queue_minmax_time>0){ bm->minmax_binstack=static_cast<long *>(AllocAPointerClear((bins+1)*bins*2*sizeof(bm->minmax_binstack))); bm->minmax_posstack=static_cast<long *>(AllocAPointerClear((bins+1)*sizeof(bm->minmax_posstack))); bm->minmax_limitstack=static_cast<long *>(AllocAPointerClear((bins+1)*sizeof(bm->minmax_limitstack))); }else{ bm->minmax_tail= -1; } /* space for the packet queueing */ bm->queue_packet_buffers=static_cast<oggpack_buffer*>(AllocAPointerClear(maxpackets*sizeof(*bm->queue_packet_buffers))); bm->queue_packets=static_cast<ogg_packet *>(AllocAPointerClear(maxpackets*sizeof(*bm->queue_packets))); for(i=0;i<maxpackets;i++) oggpack_writeinit(bm->queue_packet_buffers+i); }else{
static void LoadSideDefs(Word lump) { Word i; mapsidedef_t *MapSide; side_t *sd; MapSide = (mapsidedef_t *)LoadAResource(lump); /* Load in the data */ numsides = ((Word *)MapSide)[0]; /* Get the side count */ MapSide = (mapsidedef_t *)&((Word *)MapSide)[1]; /* Index to the array */ i = numsides*sizeof(side_t); /* How much data do I need? */ sd = (side_t *)AllocAPointer(i); /* Allocate it */ sides=sd; /* Save the data */ i = numsides; /* Number of sides to process */ do { sd->textureoffset = MapSide->textureoffset; /* Copy the texture X offset */ sd->rowoffset = MapSide->rowoffset; /* Copy the texture Y offset */ sd->toptexture = MapSide->toptexture; /* Topmost texture */ sd->bottomtexture = MapSide->bottomtexture; /* Bottommost texture */ sd->midtexture = MapSide->midtexture; /* Center texture */ sd->sector = §ors[MapSide->sector]; /* Parent sector */ ++MapSide; /* Next indexs */ ++sd; } while (--i); /* Count down */ KillAResource(lump); /* Release the memory */ }
static void LoadSectors(Word lump) { Word i; mapsector_t *Map; sector_t *ss; Map = (mapsector_t *)LoadAResource(lump); /* Load the data in */ numsectors = ((Word *)Map)[0]; /* Get the number of entries */ Map = (mapsector_t *)&((Word*)Map)[1]; /* Index past the entry count */ i = numsectors*sizeof(sector_t); /* Get the data size */ ss = (sector_t *)AllocAPointer(i); /* Get some memory */ memset(ss,0,i); /* Clear out the memory (Extra fields present) */ sectors = ss; /* Save the sector data */ i = numsectors; /* Init the loop count */ do { ss->floorheight = Map->floorheight; /* Copy the floor height */ ss->ceilingheight = Map->ceilingheight; /* Copy the ceiling height */ ss->FloorPic = Map->floorpic; /* Copy the floor texture # */ ss->CeilingPic = Map->ceilingpic; /* Copy the ceiling texture # */ ss->lightlevel = Map->lightlevel; /* Copy the ambient light */ ss->special = Map->special; /* Copy the event number type */ ss->tag = Map->tag; /* Copy the event tag ID */ ++ss; /* Next indexs */ ++Map; } while (--i); /* All done? */ KillAResource(lump); /* Dispose of the original */ }
void BURGERCALL vorbis_comment_add_tag(vorbis_comment *vc, char *tag, char *contents){ char *comment=static_cast<char *>(AllocAPointer(strlen(tag)+strlen(contents)+2)); /* +2 for = and \0 */ strcpy(comment, tag); strcat(comment, "="); strcat(comment, contents); vorbis_comment_add(vc, comment); DeallocAPointer(comment); }
Redbook_t * BURGERCALL RedbookNew(void) { Redbook_t *Input; Input = (Redbook_t *)AllocAPointer(sizeof(Redbook_t)); /* Get the structure memory */ if (Input) { RedbookInit(Input); /* Initialize the structure */ } return Input; /* Return the pointer or nothing */ }
void BURGERCALL LinkedListAddNewEntryEnd(LinkedList_t *Input,void *Data) { LinkedListEntry_t *EntryPtr; EntryPtr = (LinkedListEntry_t *)AllocAPointer(sizeof(LinkedListEntry_t)); if (EntryPtr) { EntryPtr->Data = Data; EntryPtr->KillProc = 0; LinkedListAddEntryEnd(Input,EntryPtr); } }
void BURGERCALL LinkedListAddNewEntryMemBefore(LinkedList_t *Input,LinkedListEntry_t *EntryPtr,void *Data) { LinkedListEntry_t *NewPtr; NewPtr = (LinkedListEntry_t *)AllocAPointer(sizeof(LinkedListEntry_t)); if (NewPtr) { NewPtr->Data = Data; NewPtr->KillProc = LinkedListEntryDeallocProc; LinkedListAddEntryBefore(Input,EntryPtr,NewPtr); } }
void BURGERCALL LinkedListAddNewEntryMemBegin(LinkedList_t *Input,void *Data) { LinkedListEntry_t *EntryPtr; EntryPtr = (LinkedListEntry_t *)AllocAPointer(sizeof(LinkedListEntry_t)); if (EntryPtr) { EntryPtr->Data = Data; EntryPtr->KillProc = LinkedListEntryDeallocProc; LinkedListAddEntryBegin(Input,EntryPtr); } }
void BURGERCALL LinkedListAddNewEntryProcBefore(LinkedList_t *Input,LinkedListEntry_t *EntryPtr,void *Data,LinkedListDeleteProcPtr Kill) { LinkedListEntry_t *NewPtr; NewPtr = (LinkedListEntry_t *)AllocAPointer(sizeof(LinkedListEntry_t)); if (NewPtr) { NewPtr->Data = Data; NewPtr->KillProc = Kill; LinkedListAddEntryBefore(Input,EntryPtr,NewPtr); } }
void BURGERCALL LinkedListAddNewEntryProcBegin(LinkedList_t *Input,void *Data,LinkedListDeleteProcPtr Kill) { LinkedListEntry_t *EntryPtr; EntryPtr = (LinkedListEntry_t *)AllocAPointer(sizeof(LinkedListEntry_t)); if (EntryPtr) { EntryPtr->Data = Data; EntryPtr->KillProc = Kill; LinkedListAddEntryBegin(Input,EntryPtr); } }
void BURGERCALL vorbis_comment_add(vorbis_comment *vc,char *comment){ vc->user_comments=static_cast<char **>(ResizeAPointer(vc->user_comments, (vc->comments+2)*sizeof(*vc->user_comments))); vc->comment_lengths=static_cast<int *>(ResizeAPointer(vc->comment_lengths, (vc->comments+2)*sizeof(*vc->comment_lengths))); vc->comment_lengths[vc->comments]=strlen(comment); vc->user_comments[vc->comments]=static_cast<char *>(AllocAPointer(vc->comment_lengths[vc->comments]+1)); strcpy(vc->user_comments[vc->comments], comment); vc->comments++; vc->user_comments[vc->comments]=NULL; }
void BURGERCALL LinkedListAddNewEntryStringEnd(LinkedList_t *Input,const char *Data) { LinkedListEntry_t *EntryPtr; Word Length; Length = strlen(Data)+1; EntryPtr = (LinkedListEntry_t *)AllocAPointer(sizeof(LinkedListEntry_t)+Length); if (EntryPtr) { FastMemCpy((EntryPtr+1),Data,Length); EntryPtr->Data = EntryPtr+1; EntryPtr->KillProc = 0; LinkedListAddEntryEnd(Input,EntryPtr); } }
int BURGERCALL vorbis_comment_query_count(vorbis_comment *vc, char *tag){ int i,count=0; int taglen = strlen(tag)+1; /* +1 for the = we append */ char *fulltag = static_cast<char *>(AllocAPointer(taglen+1)); strcpy(fulltag,tag); strcat(fulltag, "="); for(i=0;i<vc->comments;i++){ if(!tagcompare(vc->user_comments[i], fulltag, taglen)) { count++; } } DeallocAPointer(fulltag); return count; }
char * BURGERCALL StrCopyPad(const char *Input,Word Padding) { Word Length; char *Result; if (Input) { /* Valid input? */ Length = strlen(Input)+1; /* Get the length */ Result = (char *)AllocAPointer(Length+Padding); /* Allocate the memory */ if (Result) { FastMemCpy(Result,Input,Length); /* Copy the string */ return Result; } } return 0; /* Return nothing */ }
void *AddThinker(void (*FuncProc)(),Word MemSize) { thinker_t *Prev; thinker_t *thinker; MemSize += sizeof(thinker_t); /* Add size for the thinker prestructure */ thinker = (thinker_t *)AllocAPointer(MemSize); /* Get memory */ memset(thinker,0,MemSize); /* Blank it out */ Prev = thinkercap.prev; /* Get the last thinker in the list */ thinker->next = &thinkercap; /* Mark as last entry in list */ thinker->prev = Prev; /* Set prev link to final entry */ thinker->function = FuncProc; Prev->next = thinker; /* Next link to the new link */ thinkercap.prev = thinker; /* Mark the reverse link */ return thinker+1; /* Index AFTER the thinker structure */ }
static void LoadBlockMap(Word lump) { Word Count; Word Entries; Byte *MyLumpPtr; void **BlockHandle; LongWord *StartIndex; BlockHandle = LoadAResourceHandle(lump); /* Load the data */ MyLumpPtr = (Byte *)LockAHandle(BlockHandle); BlockMapOrgX = ((Word *)MyLumpPtr)[0]; /* Get the orgx and y */ BlockMapOrgY = ((Word *)MyLumpPtr)[1]; BlockMapWidth = ((Word *)MyLumpPtr)[2]; /* Get the map size */ BlockMapHeight = ((Word *)MyLumpPtr)[3]; Entries = BlockMapWidth*BlockMapHeight; /* How many entries are there? */ /* Convert the loaded block map table into a huge array of block entries */ Count = Entries; /* Init the longword count */ StartIndex = &((LongWord *)MyLumpPtr)[4]; /* Index to the offsets! */ BlockMapLines = (line_t ***)StartIndex; /* Save in global */ do { StartIndex[0] = (LongWord)&MyLumpPtr[StartIndex[0]]; /* Convert to pointer */ ++StartIndex; /* Next offset entry */ } while (--Count); /* All done? */ /* Convert the lists appended to the array into pointers to lines */ Count = GetAHandleSize(BlockHandle)/4; /* How much memory is needed? (Longs) */ Count -= (Entries+4); /* Remove the header count */ do { if (StartIndex[0]!=-1) { /* End of a list? */ StartIndex[0] = (LongWord)&lines[StartIndex[0]]; /* Get the line pointer */ } else { StartIndex[0] = 0; /* Insert a null pointer */ } ++StartIndex; /* Next entry */ } while (--Count); /* Clear out mobj chains */ Count = sizeof(*BlockLinkPtr)*Entries; /* Get memory */ BlockLinkPtr = (mobj_t **)AllocAPointer(Count); /* Allocate memory */ memset(BlockLinkPtr,0,Count); /* Clear it out */ }
void G_RecordDemo (void) { Word *Dest; Dest = (Word *)AllocAPointer(0x8000); /* Get memory for demo */ DemoBuffer = Dest; /* Save the pointer */ Dest[0] = StartSkill; /* Save the skill and level */ Dest[1] = StartMap; DemoDataPtr = Dest+2; G_InitNew(StartSkill,StartMap); /* Begin a game */ DemoRecording = TRUE; /* Begin recording */ MiniLoop(P_Start,P_Stop,P_Ticker,P_Drawer); /* Play it */ DemoRecording = FALSE; /* End recording */ for (;;) { /* Stay forever */ G_PlayDemoPtr(DemoBuffer); /* Play the demo */ } }
int BURGERCALL vorbis_commentheader_out(vorbis_comment *vc, ogg_packet *op){ oggpack_buffer opb; oggpack_writeinit(&opb); if(_vorbis_pack_comment(&opb,vc)) return OV_EIMPL; op->packet = static_cast<Word8 *>(AllocAPointer(oggpack_bytes(&opb))); FastMemCpy(op->packet, opb.buffer, oggpack_bytes(&opb)); op->bytes=oggpack_bytes(&opb); op->b_o_s=0; op->e_o_s=0; op->granulepos=0; return 0; }
static void LoadSegs(Word lump) { Word i; mapseg_t *ml; seg_t *li; Word numsegs; ml = (mapseg_t *)LoadAResource(lump); /* Load in the map data */ numsegs = ((Word*)ml)[0]; /* Get the count */ i = numsegs*sizeof(seg_t); /* Get the memory size */ li = (seg_t *)AllocAPointer(i); /* Allocate it */ segs = li; /* Save pointer to global */ memset(li,0,i); /* Clear it out */ ml = (mapseg_t *)&((Word *)ml)[1]; /* Init pointer to first record */ i = 0; do { line_t *ldef; Word side; li->v1 = vertexes[ml->v1]; /* Get the line points */ li->v2 = vertexes[ml->v2]; li->angle = ml->angle; /* Set the angle of the line */ li->offset = ml->offset; /* Get the texture offset */ ldef = &lines[ml->linedef]; /* Get the line pointer */ li->linedef = ldef; side = ml->side; /* Get the side number */ li->sidedef = ldef->SidePtr[side]; /* Grab the side pointer */ li->frontsector = li->sidedef->sector; /* Get the front sector */ if (ldef->flags & ML_TWOSIDED) { /* Two sided? */ li->backsector = ldef->SidePtr[side^1]->sector; /* Mark the back sector */ } if (ldef->v1.x == li->v1.x && ldef->v1.y == li->v1.y) { /* Init the fineangle */ ldef->fineangle = li->angle>>ANGLETOFINESHIFT; /* This is a point only */ } ++li; /* Next entry */ ++ml; /* Next resource entry */ } while (++i<numsegs);
char *BURGERCALL vorbis_comment_query(vorbis_comment *vc, char *tag, int count) { long i; int found = 0; int taglen = strlen(tag)+1; /* +1 for the = we append */ char *fulltag = static_cast<char *>(AllocAPointer(taglen+ 1)); strcpy(fulltag, tag); strcat(fulltag, "="); for(i=0;i<vc->comments;i++){ if(!tagcompare(vc->user_comments[i], fulltag, taglen)){ if(count == found) { /* We return a pointer to the data, not a copy */ DeallocAPointer(fulltag); return vc->user_comments[i] + taglen; } else { found++; } } } DeallocAPointer(fulltag); return NULL; /* didn't find anything */ }
int BURGERCALL vorbis_analysis_headerout(vorbis_dsp_state *v, vorbis_comment *vc, ogg_packet *op, ogg_packet *op_comm, ogg_packet *op_code){ int ret=OV_EIMPL; vorbis_info *vi=v->vi; oggpack_buffer opb; backend_lookup_state *b=static_cast<backend_lookup_state *>(v->backend_state); if(!b){ ret=OV_EFAULT; goto err_out; } /* first header packet **********************************************/ oggpack_writeinit(&opb); if(_vorbis_pack_info(&opb,vi))goto err_out; /* build the packet */ if(b->header)DeallocAPointer(b->header); b->header=static_cast<Word8 *>(AllocAPointer(oggpack_bytes(&opb))); FastMemCpy(b->header,opb.buffer,oggpack_bytes(&opb)); op->packet=b->header; op->bytes=oggpack_bytes(&opb); op->b_o_s=1; op->e_o_s=0; op->granulepos=0; /* second header packet (comments) **********************************/ oggpack_reset(&opb); if(_vorbis_pack_comment(&opb,vc))goto err_out; if(b->header1)DeallocAPointer(b->header1); b->header1=static_cast<Word8 *>(AllocAPointer(oggpack_bytes(&opb))); FastMemCpy(b->header1,opb.buffer,oggpack_bytes(&opb)); op_comm->packet=b->header1; op_comm->bytes=oggpack_bytes(&opb); op_comm->b_o_s=0; op_comm->e_o_s=0; op_comm->granulepos=0; /* third header packet (modes/codebooks) ****************************/ oggpack_reset(&opb); if(_vorbis_pack_books(&opb,vi))goto err_out; if(b->header2)DeallocAPointer(b->header2); b->header2=static_cast<Word8 *>(AllocAPointer(oggpack_bytes(&opb))); FastMemCpy(b->header2,opb.buffer,oggpack_bytes(&opb)); op_code->packet=b->header2; op_code->bytes=oggpack_bytes(&opb); op_code->b_o_s=0; op_code->e_o_s=0; op_code->granulepos=0; oggpack_writeclear(&opb); return(0); err_out: oggpack_writeclear(&opb); FastMemSet(op,0,sizeof(*op)); FastMemSet(op_comm,0,sizeof(*op_comm)); FastMemSet(op_code,0,sizeof(*op_code)); if(b->header)DeallocAPointer(b->header); if(b->header1)DeallocAPointer(b->header1); if(b->header2)DeallocAPointer(b->header2); b->header=NULL; b->header1=NULL; b->header2=NULL; return(ret); }
static void LoadLineDefs(Word lump) { Word i; maplinedef_t *mld; line_t *ld; mld = (maplinedef_t *)LoadAResource(lump); /* Load in the data */ numlines = ((Word*)mld)[0]; /* Get the number of lines in the struct array */ i = numlines*sizeof(line_t); /* Get the size of the dest buffer */ ld = (line_t *)AllocAPointer(i); /* Get the memory for the lines array */ lines = ld; /* Save the lines */ memset(ld,0,i); /* Blank out the buffer */ mld = (maplinedef_t *)&((Word *)mld)[1]; /* Index to the first record of the struct array */ i = numlines; do { Fixed dx,dy; ld->flags = mld->flags; /* Copy the flags */ ld->special = mld->special; /* Copy the special type */ ld->tag = mld->tag; /* Copy the external tag ID trigger */ ld->v1 = vertexes[mld->v1]; /* Copy the end points to the line */ ld->v2 = vertexes[mld->v2]; dx = ld->v2.x - ld->v1.x; /* Get the delta offset (Line vector) */ dy = ld->v2.y - ld->v1.y; /* What type of line is this? */ if (!dx) { /* No x motion? */ ld->slopetype = ST_VERTICAL; /* Vertical line only */ } else if (!dy) { /* No y motion? */ ld->slopetype = ST_HORIZONTAL; /* Horizontal line only */ } else { if ((dy^dx) >= 0) { /* Is this a positive or negative slope */ ld->slopetype = ST_POSITIVE; /* Like signs, positive slope */ } else { ld->slopetype = ST_NEGATIVE; /* Unlike signs, negative slope */ } } /* Create the bounding box */ if (dx>=0) { /* V2>=V1? */ ld->bbox[BOXLEFT] = ld->v1.x; /* Leftmost x */ ld->bbox[BOXRIGHT] = ld->v2.x; /* Rightmost x */ } else { ld->bbox[BOXLEFT] = ld->v2.x; ld->bbox[BOXRIGHT] = ld->v1.x; } if (dy>=0) { ld->bbox[BOXBOTTOM] = ld->v1.y; /* Bottommost y */ ld->bbox[BOXTOP] = ld->v2.y; /* Topmost y */ } else { ld->bbox[BOXBOTTOM] = ld->v2.y; ld->bbox[BOXTOP] = ld->v1.y; } /* Copy the side numbers and sector pointers */ ld->SidePtr[0] = &sides[mld->sidenum[0]]; /* Get the side number */ ld->frontsector = ld->SidePtr[0]->sector; /* All lines have a front side */ if (mld->sidenum[1] != -1) { /* But maybe not a back side */ ld->SidePtr[1] = &sides[mld->sidenum[1]]; ld->backsector = ld->SidePtr[1]->sector; /* Get the sector pointed to */ } ++ld; /* Next indexes */ ++mld; } while (--i); KillAResource(lump); /* Release the resource */ }
void SpawnSpecials(void) { sector_t *sector; Word i; /* Init special SECTORs */ PurgeLineSpecials(); /* Make SURE they are gone */ sector = sectors; i = 0; do { switch(sector->special) { case 1: /* FLICKERING LIGHTS */ P_SpawnLightFlash(sector); break; case 2: /* STROBE FAST */ P_SpawnStrobeFlash(sector,FASTDARK,FALSE); break; case 3: /* STROBE SLOW */ P_SpawnStrobeFlash(sector,SLOWDARK,FALSE); break; case 8: /* GLOWING LIGHT */ P_SpawnGlowingLight(sector); break; case 9: /* SECRET SECTOR */ ++SecretsFoundInLevel; break; case 10: /* DOOR CLOSE IN 30 SECONDS */ P_SpawnDoorCloseIn30(sector); break; case 12: /* SYNC STROBE SLOW */ P_SpawnStrobeFlash(sector,SLOWDARK,TRUE); break; case 13: /* SYNC STROBE FAST */ P_SpawnStrobeFlash(sector,FASTDARK,TRUE); break; case 14: /* DOOR RAISE IN 5 MINUTES */ P_SpawnDoorRaiseIn5Mins(sector); } ++sector; } while (++i<numsectors); /* Init line EFFECTs, first pass, count the effects detected */ numlinespecials = 0; /* No specials found */ i = numlines; /* Get the line count */ if (i) { line_t *line; line = lines; /* Traverse the list */ do { if (line->special==48) { /* EFFECT FIRSTCOL SCROLL+ */ ++numlinespecials; /* Inc the count */ } ++line; } while (--i); /* All done? */ } if (numlinespecials) { /* Any found? */ line_t *line; line_t **linelist; /* Get memory for the list */ linelist = (line_t **)AllocAPointer(sizeof(line_t*)*numlinespecials); linespeciallist = linelist; /* Save the pointer */ i = numlines; line = lines; /* Reset the count */ do { if (line->special==48) { /* EFFECT FIRSTCOL SCROLL+ */ linelist[0] = line; /* Store the pointer */ ++linelist; } ++line; /* Next line to scan */ } while (--i); } }
Word BURGERCALL JoystickInit(void) { Word32 TempLong; Word i; MacInput_t *LocalPtr; LocalPtr = &MacInputLocals; if (!MacInputInit(LocalPtr,MACINITINPUTJOYSTICK)) { /* 1.3 or better? */ /* Discard any previous data from a previous call */ /* This will allow simple rescanning */ DeallocAPointer(LocalPtr->JoystickDescriptionsArray); DeallocAPointer(LocalPtr->JoystickDeviceArray); LocalPtr->JoystickDescriptionsArray = 0; LocalPtr->JoystickDeviceArray = 0; { Word *Boundaries; i = 0; Boundaries = &JoystickBoundaries[0][0]; /* Init pointer to struct */ do { Word j; j = 0; do { Boundaries[AXISMIN] = 0x100000; /* Init center point */ Boundaries[AXISMAX] = 0xF00000; Boundaries[AXISCENTER] = 0x800000; Boundaries+=AXISENTRIES; JoystickSetDigital(j,20,i); /* Create the digital bounds */ } while (++j<AXISCOUNT); } while (++i<MAXJOYNUM); /* All of them checked? */ } MacInputLockInputSprocket(); /* Don't allow mouse/keyboard IRQ's */ if (ISpDevices_Extract(0,&TempLong,0)) { /* How many devices are present? */ goto Abort; } i = TempLong; /* Save in register */ LocalPtr->JoystickDeviceArray = (ISpDeviceReference *)AllocAPointer(sizeof(ISpDeviceReference)*i); if (!LocalPtr->JoystickDeviceArray) { /* Memory allocation error? */ goto Abort; } if (ISpDevices_Extract(i,&TempLong,LocalPtr->JoystickDeviceArray)) { /* Get the devices */ goto Abort; } /* Now remove all devices that are not mice or keyboards */ JoystickPresent = i; /* Save the device count */ if (i) { ISpDeviceReference *ArrayPtr; ISpDeviceReference *ArrayPtr2; ArrayPtr = LocalPtr->JoystickDeviceArray; ArrayPtr2 = ArrayPtr; do { ISpDeviceDefinition ResultBuf; /* Get the device definition */ if (!ISpDevice_GetDefinition(ArrayPtr[0],sizeof(ISpDeviceDefinition),&ResultBuf)) { if (ResultBuf.theDeviceClass != kISpElementLabel_None) { if ((ResultBuf.theDeviceClass != kISpDeviceClass_Mouse) && (ResultBuf.theDeviceClass != kISpDeviceClass_Keyboard)) { ArrayPtr2[0] = ArrayPtr[0]; ++ArrayPtr2; } } } ++ArrayPtr; } while (--i); JoystickPresent = ArrayPtr2-LocalPtr->JoystickDeviceArray; } /* At this point I have all the devices I am going to use. Now */ /* I will get the actual input methods and create a map for each one */ i = JoystickPresent; if (i) { Word j; JoyDesc_t *JoyDevPtr; if (i>MAXJOYNUM) { /* I can only have 4 input devices */ i = MAXJOYNUM; JoystickPresent = MAXJOYNUM; } JoyDevPtr = (JoyDesc_t *)AllocAPointerClear(sizeof(JoyDesc_t)*i); if (!JoyDevPtr) { goto Abort; } j = 0; LocalPtr->JoystickDescriptionsArray = JoyDevPtr; do { /* For each device, scan the input elements and find a burgerlib */ /* match, assign it a button, pad or axis id */ ISpElementListReference MyElementList; if (!ISpDevice_GetElementList(LocalPtr->JoystickDeviceArray[j],&MyElementList)) { Word32 ElementCount; ISpElementReference ElementBuf[500]; if (!ISpElementList_Extract(MyElementList,500,&ElementCount,ElementBuf)) { if (ElementCount) { Word TempIndex; Word FooIndex; Word AxisIndex; Word ButtonIndex; TempIndex = 0; AxisIndex = 0; /* No axis' found */ ButtonIndex = 0; /* No buttons found */ do { ISpElementInfo ElementInfo; ISpElementReference CurrentRef; CurrentRef = ElementBuf[TempIndex]; if (!ISpElement_GetInfo(CurrentRef,&ElementInfo)) { /* I've got input, what kind of input is it? */ switch (ElementInfo.theKind) { case kISpElementKind_Button: /* Simple button */ if (ButtonIndex<20) { JoyDevPtr->Elements[ButtonIndex+ELEMENTBUTTON] = CurrentRef; ++ButtonIndex; } break; /* Hat or pad */ case kISpElementKind_DPad: /* Hat/Pad */ /* If the ID is a hat, place it in the hat slot first */ if (ElementInfo.theLabel==kISpElementLabel_Pad_POV || ElementInfo.theLabel==kISpElementLabel_Pad_POV_Horiz) { if (!JoyDevPtr->Elements[ELEMENTPAD+1]) { JoyDevPtr->Elements[ELEMENTPAD+1] = CurrentRef; break; } } FooIndex = 0; do { if (!JoyDevPtr->Elements[FooIndex+ELEMENTPAD]) { JoyDevPtr->Elements[FooIndex+ELEMENTPAD] = CurrentRef; break; } } while (++FooIndex<2); break; /* Handle joystick axis' */ case kISpElementKind_Axis: /* Joystick axis */ case kISpElementKind_Delta: if (ElementInfo.theLabel==kISpElementLabel_Axis_XAxis) { if (!JoyDevPtr->Elements[ELEMENTAXIS]) { JoyDevPtr->Elements[ELEMENTAXIS] = CurrentRef; JoyDevPtr->ElementData[ELEMENTAXIS] = 0x7FFFFFFF; break; } if (!JoyDevPtr->Elements[ELEMENTAXIS+4]) { JoyDevPtr->Elements[ELEMENTAXIS+4] = CurrentRef; JoyDevPtr->ElementData[ELEMENTAXIS+4] = 0x7FFFFFFF; break; } } else if (ElementInfo.theLabel==kISpElementLabel_Axis_YAxis) { if (!JoyDevPtr->Elements[ELEMENTAXIS+1]) { JoyDevPtr->Elements[ELEMENTAXIS+1] = CurrentRef; JoyDevPtr->ElementData[ELEMENTAXIS+1] = 0x7FFFFFFF; break; } if (!JoyDevPtr->Elements[ELEMENTAXIS+5]) { JoyDevPtr->Elements[ELEMENTAXIS+5] = CurrentRef; JoyDevPtr->ElementData[ELEMENTAXIS+5] = 0x7FFFFFFF; break; } } else if (ElementInfo.theLabel==kISpElementLabel_Axis_ZAxis) { if (!JoyDevPtr->Elements[ELEMENTAXIS+2]) { JoyDevPtr->Elements[ELEMENTAXIS+2] = CurrentRef; JoyDevPtr->ElementData[ELEMENTAXIS+2] = 0x7FFFFFFF; break; } } /* Insert in the generic list */ if (AxisIndex<AXISCOUNT) { do { if (!JoyDevPtr->Elements[AxisIndex+ELEMENTAXIS]) { JoyDevPtr->Elements[AxisIndex+ELEMENTAXIS] = CurrentRef; JoyDevPtr->ElementData[AxisIndex+ELEMENTAXIS] = 0x7FFFFFFF; break; } } while (++AxisIndex<AXISCOUNT); } break; } } } while (++TempIndex<ElementCount); } } } ++JoyDevPtr; } while (++j<i); /* All devices scanned */ } MacInputUnlockInputSprocket(); return JoystickPresent; } Abort:; MacInputUnlockInputSprocket(); JoystickDestroy(); return 0; }
void BURGERCALL LinkedListSort(LinkedList_t *Input,LinkedListSortProc Proc) { LinkedListEntry_t **ArrayPtr; LinkedListEntry_t *Internal[2000]; /* Simple sort? */ if (Input->Count>=2) { /* Should I even worry about a sort? */ /* Two entries? */ if (Input->Count==2) { /* I guess so... */ LinkedListEntry_t *First; LinkedListEntry_t *Second; First = Input->First; /* Just a two entry sort, trivial... */ Second = Input->Last; if (Proc(First->Data,Second->Data)>0) { /* Worry? */ Input->First = Second; /* Perform a swap */ Input->Last = First; Second->Next = First; /* New first entry */ Second->Prev = 0; First->Next = 0; /* New last entry */ First->Prev = Second; } return; /* I am sorted */ } /* Let's perform a merge sort */ /* First get the buffer for the sort */ if (Input->Count>1000) { ArrayPtr = (LinkedListEntry_t **)AllocAPointer(sizeof(LinkedListEntry_t *)*Input->Count*2); /* Yikes!! */ if (!ArrayPtr) { /* Memory error! */ return; /* Forget about the sort! */ } } else { ArrayPtr = Internal; /* Use my internal buffer */ } /* I need to first "flatten" the linked list */ { LinkedListEntry_t **WorkPtr1; LinkedListEntry_t *EntryPtr1; Word i1; WorkPtr1 = ArrayPtr; /* Pointer to the allocated buffer */ i1 = Input->Count; /* Number of entries to upload */ EntryPtr1 = Input->First; do { WorkPtr1[0] = EntryPtr1; /* Store the entry */ EntryPtr1 = EntryPtr1->Next; /* Next one in the chain */ ++WorkPtr1; } while (--i1); /* All done */ } /* Now, we perform the merge sort */ { LinkedListEntry_t **WorkPtr; { Word i; Word size; /* Entry size to sort with */ Word sort; /* Sort count */ LinkedListEntry_t **unsorted; i = Input->Count; /* How many entries are there? */ size = 1; /* source size (<<1 / loop)*/ sort = 1; /* iteration number (+1 / loop)*/ WorkPtr = ArrayPtr; unsorted = ArrayPtr+i; do { { Word remaining; /* Temp merge count */ LinkedListEntry_t **src1,**src2,**dest; /* Used by the sort */ remaining = i>>sort; /* How many times to try */ /* pointers incremented by the merge */ src1 = WorkPtr; /* Sorted array */ src2 = &WorkPtr[remaining<<(sort-1)]; /* Half point */ dest = unsorted; /* Dest array */ /* merge paired blocks*/ if (remaining) { /* Any to sort? */ do { LinkedListMerge(dest,src1,src2,size,size,Proc); /* All groups equal size */ dest = &dest[size+size]; src1 = &src1[size]; src2 = &src2[size]; } while (--remaining); } /* copy or merge the leftovers */ remaining = i&((size<<1)-1); /* Create mask (1 bit higher) */ if (remaining > size) { /* one complete block and one fragment */ LinkedListMerge(dest,&src2[size],src2,remaining-size,size,Proc); } else if (remaining) { /* just a single sorted fragment */ FastMemCpy(dest,src2,remaining*sizeof(LinkedListEntry_t *)); /* Copy it */ } } /* get ready to sort back to the other array */ size <<= 1; /* Double the entry size */ ++sort; /* Increase the shift size */ { LinkedListEntry_t **temp; temp = WorkPtr; /* Swap the pointers */ WorkPtr = unsorted; unsorted = temp; } } while (size<i); } /* Now that I have the sorted list, Let's create the */ /* new linked list */ { LinkedListEntry_t *EntryPtr2; LinkedListEntry_t *Prev; LinkedListEntry_t *Next; Word i3; EntryPtr2 = WorkPtr[0]; /* Get the new root pointer */ ++WorkPtr; Input->First = EntryPtr2; /* Set as the first one */ i3 = Input->Count-1; /* Traverse until the final link */ Prev = 0; /* Zap the previous link */ do { Next = WorkPtr[0]; ++WorkPtr; EntryPtr2->Next = Next; /* Store the links */ EntryPtr2->Prev = Prev; Prev = EntryPtr2; /* Follow the chains */ EntryPtr2 = Next; /* Next one */ } while (--i3); /* All done? */ EntryPtr2->Next = 0; /* The final link */ EntryPtr2->Prev = Prev; Input->Last = EntryPtr2; /* Save the ending link */ } } if (ArrayPtr!=Internal) { DeallocAPointer(ArrayPtr); /* Dispose of the linked list flattened data */ } } }