void PriorityQueueAdd(struct VMGlobals *g, PyrObject* queueobj, PyrSlot* item, double time) { PyrObject *schedq, *newschedq; int size, maxsize; PyrSlot *schedqSlot = queueobj->slots; if (!IsObj(schedqSlot)) { size = 16; schedq = newPyrArray(g->gc, size, 0, true); SetObject(schedqSlot, schedq); g->gc->GCWrite(queueobj, schedq); } else { schedq = schedqSlot->uo; maxsize = ARRAYMAXINDEXSIZE(schedq); size = schedq->size; if (size+2 > maxsize) { PyrSlot *pslot, *qslot; newschedq = newPyrArray(g->gc, maxsize*2, 0, true); newschedq->size = size; pslot = schedq->slots - 1; qslot = newschedq->slots - 1; for (int i=0; i<size; ++i) slotCopy(++qslot, ++pslot); SetObject(schedqSlot, newschedq); g->gc->GCWrite(queueobj, newschedq); schedq = newschedq; } } addheap(g, schedq, time, item); }
void PriorityQueueAdd(struct VMGlobals *g, PyrObject* queueobj, PyrSlot* item, double time) { PyrObject *schedq, *newschedq; int size, maxsize; PyrSlot *schedqSlot = queueobj->slots; if (!IsObj(schedqSlot)) { size = 32; schedq = newPyrArray(g->gc, size, 0, true); schedq->size = 1; SetInt(schedq->slots + 0, 0); // stability count SetObject(schedqSlot, schedq); g->gc->GCWriteNew(queueobj, schedq); // we know schedq is white so we can use GCWriteNew } else { schedq = slotRawObject(schedqSlot); maxsize = ARRAYMAXINDEXSIZE(schedq); size = schedq->size; if (size+3 > maxsize) { newschedq = newPyrArray(g->gc, maxsize*2, 0, true); newschedq->size = size; slotCopy(newschedq->slots, schedq->slots, size); assert(IsInt(newschedq->slots)); SetObject(schedqSlot, newschedq); g->gc->GCWriteNew(queueobj, newschedq); // we know newschedq is white so we can use GCWriteNew schedq = newschedq; } } addheap(g, schedq, time, item); }
int prArrayMultiChanExpand(struct VMGlobals *g, int numArgsPushed) { PyrSlot *a, *slot, *slots1, *slots2, *slots3, *slots4; PyrObject *obj1, *obj2, *obj3, *obj4; int i, j, size, len, maxlen; a = g->sp; obj1 = slotRawObject(a); size = obj1->size; slots1 = obj1->slots; maxlen = 1; for (j=0; j<size; ++j) { slot = slots1 + j; if (IsObj(slot)) { if (slotRawObject(slot)->classptr == class_array) { len = slotRawObject(slot)->size; maxlen = len > maxlen ? len : maxlen; } else if (isKindOf(slotRawObject(slot), class_sequenceable_collection) && (slotRawObject(slot)->classptr != class_string)) { return errFailed; // this primitive only handles Arrays. } } } obj2 = newPyrArray(g->gc, maxlen, 0, true); SetObject(a, obj2); slots2 = obj2->slots; for (i=0; i<maxlen; ++i) { obj3 = newPyrArray(g->gc, size, 0, true); obj3->size = size; SetObject(slots2 + i, obj3); g->gc->GCWriteNew(obj2, obj3); // we know obj3 is white so we can use GCWriteNew obj2->size++; slots1 = obj1->slots; slots3 = obj3->slots; for (j=0; j<size; ++j) { slot = slots1 + j; if (IsObj(slot)) { if (slotRawObject(slot)->classptr == class_array && slotRawObject(slot)->size > 0) { PyrSlot *slotToCopy; obj4 = slotRawObject(slot); slots4 = obj4->slots; slotToCopy = &slots4[i % obj4->size]; slotCopy(&slots3[j],slotToCopy); g->gc->GCWrite(obj3, slotToCopy); } else { slotCopy(&slots3[j],slot); g->gc->GCWrite(obj3, slot); } } else { slotCopy(&slots3[j],slot); // we don't need GCWrite here, as slot is not an object } } } return errNone; }
int prArrayMultiChanExpand(struct VMGlobals *g, int numArgsPushed) { PyrSlot *a, *slot, *slots1, *slots2, *slots3, *slots4; PyrObject *obj1, *obj2, *obj3, *obj4; int i, j, size, len, maxlen; a = g->sp; obj1 = a->uo; size = obj1->size; slots1 = obj1->slots; maxlen = 1; for (j=0; j<size; ++j) { slot = slots1 + j; if (IsObj(slot)) { if (slot->uo->classptr == class_array) { len = slot->uo->size; maxlen = len > maxlen ? len : maxlen; } else if (isKindOf(slot->uo, class_sequenceable_collection) && (slot->uo->classptr != class_string)) { return errFailed; // this primitive only handles Arrays. } } } obj2 = newPyrArray(g->gc, maxlen, 0, true); obj2->size = maxlen; slots2 = obj2->slots; for (i=0; i<maxlen; ++i) { obj3 = newPyrArray(g->gc, size, 0, false); obj3->size = size; SetObject(slots2 + i, obj3); slots1 = obj1->slots; slots3 = obj3->slots; for (j=0; j<size; ++j) { slot = slots1 + j; if (IsObj(slot)) { if (slot->uo->classptr == class_array && slot->uo->size > 0) { obj4 = slot->uo; slots4 = obj4->slots; slotCopy(&slots3[j],&slots4[i % obj4->size]); } else { slotCopy(&slots3[j],slot); } } else { slotCopy(&slots3[j],slot); } } } SetObject(a, obj2); return errNone; }
static void _doc_traverse(struct VMGlobals* g, DocNode *n, PyrObject *parent, PyrSlot *slot) { PyrObject *result = instantiateObject( g->gc, s_scdoc_node->u.classobj, 0, false, false ); result->size = 0; SetObject(slot, result); if(parent) g->gc->GCWrite(parent, result); PyrSymbol *id = getsym(n->id); SetSymbol(result->slots+result->size++, id); if(n->text) { PyrObject *str = (PyrObject*) newPyrString(g->gc, n->text, 0, true); SetObject(result->slots+result->size++, str); g->gc->GCWrite(result, str); } else { SetNil(result->slots+result->size++); } if(n->n_childs) { PyrObject *array = newPyrArray(g->gc, n->n_childs, 0, true); array->size = 0; SetObject(result->slots+result->size++, array); g->gc->GCWrite(result, array); for(int i=0; i<n->n_childs; i++) { array->size++; _doc_traverse(g, n->children[i], array, array->slots+i); } } else { SetNil(result->slots+result->size++); } result->size += 3; // makeDiv, notPrivOnly, sort }
int prHIDBuildElementList(VMGlobals *g, int numArgsPushed) { PyrSlot *a = g->sp - 2; //class PyrSlot *b = g->sp - 1; //locID device PyrSlot *c = g->sp; //array int locID; int err = slotIntVal(b, &locID); if (err) return err; //look for the right device: pRecDevice pCurrentHIDDevice = HIDGetFirstDevice (); while (pCurrentHIDDevice && (pCurrentHIDDevice->locID !=locID)) pCurrentHIDDevice = HIDGetNextDevice (pCurrentHIDDevice); if(!pCurrentHIDDevice) return errFailed; pRecElement devElement = HIDGetFirstDeviceElement (pCurrentHIDDevice, kHIDElementTypeAll ); UInt32 numElements = HIDCountDeviceElements (pCurrentHIDDevice, kHIDElementTypeAll ); // PyrObject* devAllElementsArray = newPyrArray(g->gc, numElements * sizeof(PyrObject), 0 , true); PyrObject *devAllElementsArray = c->uo; // post("numElements: %d\n", numElements); numElements = sc_clip(numElements, 0, devAllElementsArray->size); for(uint i=0; i<numElements; i++){ if(devElement){ char cstrElementName [256]; PyrObject* devElementArray = newPyrArray(g->gc, 8 * sizeof(PyrObject), 0 , true); // type name (1) HIDGetTypeName((IOHIDElementType) devElement->type, cstrElementName); PyrString *devstring = newPyrString(g->gc, cstrElementName, 0, true); SetObject(devElementArray->slots+devElementArray->size++, devstring); //g->gc->GCWrite(devElementArray, (PyrObject*) devstring); //usage (2) HIDGetUsageName (devElement->usagePage, devElement->usage, cstrElementName); PyrString *usestring = newPyrString(g->gc, cstrElementName, 0, true); SetObject(devElementArray->slots+devElementArray->size++, usestring); //g->gc->GCWrite(devElementArray, (PyrObject*) usestring); //cookie (3) SetInt(devElementArray->slots+devElementArray->size++, (long) devElement->cookie); // min (4) SetInt(devElementArray->slots+devElementArray->size++, (long) devElement->min); // max (5) SetInt(devElementArray->slots+devElementArray->size++, (long) devElement->max); // IO type as int: (6) SetInt(devElementArray->slots+devElementArray->size++, (int) devElement->type); // Usage page as int: (7) SetInt(devElementArray->slots+devElementArray->size++, (long) devElement->usagePage); // Usage type as int: (8) SetInt(devElementArray->slots+devElementArray->size++, (long) devElement->usage); SetObject(devAllElementsArray->slots+i, devElementArray); //g->gc->GCWrite(devAllElementsArray, (PyrObject*) devElementArray); } devElement = HIDGetNextDeviceElement (devElement, kHIDElementTypeAll); } SetObject(a, devAllElementsArray); return errNone; }
PyrObject* ConvertOSCMessage(int inSize, char *inData) { char *cmdName = inData; int cmdNameLen = OSCstrlen(cmdName); sc_msg_iter msg(inSize - cmdNameLen, inData + cmdNameLen); int numElems; if (inSize == cmdNameLen) { numElems = 0; } else { if (!msg.tags) { numElems = 0; error("OSC messages must have type tags. %s\n", cmdName); } else { numElems = strlen(msg.tags); } } //post("tags %s %d\n", msg.tags, numElems); VMGlobals *g = gMainVMGlobals; PyrObject *obj = newPyrArray(g->gc, numElems + 1, 0, false); PyrSlot *slots = obj->slots; SetSymbol(slots+0, getsym(cmdName)); for (int i=0; i<numElems; ++i) { char tag = msg.nextTag(); //post("%d %c\n", i, tag); switch (tag) { case 'i' : SetInt(slots+i+1, msg.geti()); break; case 'f' : SetFloat(slots+i+1, msg.getf()); break; case 'd' : SetFloat(slots+i+1, msg.getd()); break; case 's' : SetSymbol(slots+i+1, getsym(msg.gets())); //post("sym '%s'\n", slots[i+1].us->name); break; case 'b' : SetObject(slots+i+1, (PyrObject*)MsgToInt8Array(msg)); break; case 'c': SetChar(slots+i+1, (char)msg.geti()); break; // else add the type tag as a char (jrhb 2009) default: SetChar(slots+i+1, tag); msg.gets(); } } obj->size = numElems + 1; return obj; }
int identDictPut(struct VMGlobals *g, PyrObject *dict, PyrSlot *key, PyrSlot *value) { PyrSlot *slot, *newslot; int i, index, size; PyrObject *array; bool knows = IsTrue(dict->slots + ivxIdentDict_know); if (knows && IsSym(key)) { if (slotRawSymbol(key) == s_parent) { slotCopy(&dict->slots[ivxIdentDict_parent],value); g->gc->GCWrite(dict, value); return errNone; } if (slotRawSymbol(key) == s_proto) { slotCopy(&dict->slots[ivxIdentDict_proto],value); g->gc->GCWrite(dict, value); return errNone; } } array = slotRawObject(&dict->slots[ivxIdentDict_array]); if (array->IsImmutable()) return errImmutableObject; if (!isKindOf((PyrObject*)array, class_array)) return errFailed; index = arrayAtIdentityHashInPairs(array, key); slot = array->slots + index; slotCopy(&slot[1],value); g->gc->GCWrite(array, value); if (IsNil(slot)) { slotCopy(slot,key); g->gc->GCWrite(array, key); size = slotRawInt(&dict->slots[ivxIdentDict_size]) + 1; SetRaw(&dict->slots[ivxIdentDict_size], size); if (array->size < size*3) { PyrObject *newarray; newarray = newPyrArray(g->gc, size*3, 0, false); newarray->size = ARRAYMAXINDEXSIZE(newarray); nilSlots(newarray->slots, newarray->size); slot = array->slots; for (i=0; i<array->size; i+=2, slot+=2) { if (NotNil(slot)) { index = arrayAtIdentityHashInPairs(newarray, slot); newslot = newarray->slots + index; slotCopy(&newslot[0],&slot[0]); slotCopy(&newslot[1],&slot[1]); } } SetRaw(&dict->slots[ivxIdentDict_array], newarray); g->gc->GCWriteNew(dict, newarray); // we know newarray is white so we can use GCWriteNew } } return errNone; }
int prIdentDict_PutGet(struct VMGlobals *g, int numArgsPushed) { PyrSlot *a, *b, *c, *d, *slot, *newslot; int i, index, size; PyrObject *dict; PyrObject *array; a = g->sp - 2; // dict b = g->sp - 1; // key c = g->sp; // value d = ++g->sp; // push the stack to save the receiver slotCopy(d,a); dict = slotRawObject(d); array = slotRawObject(&dict->slots[ivxIdentDict_array]); if (!isKindOf((PyrObject*)array, class_array)) { SetNil(a); --g->sp; return errFailed; } index = arrayAtIdentityHashInPairs(array, b); slot = array->slots + index; slotCopy(a,&slot[1]); slotCopy(&slot[1],c); g->gc->GCWrite(array, c); if (IsNil(slot)) { slotCopy(slot,b); g->gc->GCWrite(array, b); size = slotRawInt(&dict->slots[ivxIdentDict_size]) + 1; SetRaw(&dict->slots[ivxIdentDict_size], size); if (array->size < size*3) { PyrObject *newarray; newarray = newPyrArray(g->gc, size*3, 0, true); newarray->size = ARRAYMAXINDEXSIZE(newarray); nilSlots(newarray->slots, newarray->size); slot = array->slots; for (i=0; i<array->size; i+=2, slot+=2) { if (NotNil(slot)) { index = arrayAtIdentityHashInPairs(newarray, slot); newslot = newarray->slots + index; slotCopy(&newslot[0],&slot[0]); slotCopy(&newslot[1],&slot[1]); } } SetRaw(&dict->slots[ivxIdentDict_array], newarray); g->gc->GCWriteNew(dict, newarray); // we know newarray is white so we can use GCWriteNew } } --g->sp; return errNone; }
int identDictPut(struct VMGlobals *g, PyrObject *dict, PyrSlot *key, PyrSlot *value) { PyrSlot *slot, *newslot; int i, index, size; PyrObject *array; bool knows = IsTrue(dict->slots + ivxIdentDict_know); if (knows && IsSym(key)) { if (key->us == s_parent) { slotCopy(&dict->slots[ivxIdentDict_parent],value); g->gc->GCWrite(dict, value); return errNone; } if (key->us == s_proto) { slotCopy(&dict->slots[ivxIdentDict_proto],value); g->gc->GCWrite(dict, value); return errNone; } } array = dict->slots[ivxIdentDict_array].uo; if (!isKindOf((PyrObject*)array, class_array)) return errFailed; index = arrayAtIdentityHashInPairs(array, key); slot = array->slots + index; slotCopy(&slot[1],value); g->gc->GCWrite(array, value); if (IsNil(slot)) { slotCopy(slot,key); g->gc->GCWrite(array, key); size = ++dict->slots[ivxIdentDict_size].ui; if (array->size < size*3) { PyrObject *newarray; newarray = newPyrArray(g->gc, size*3, 0, false); newarray->size = ARRAYMAXINDEXSIZE(newarray); nilSlots(newarray->slots, newarray->size); slot = array->slots; for (i=0; i<array->size; i+=2, slot+=2) { if (NotNil(slot)) { index = arrayAtIdentityHashInPairs(newarray, slot); newslot = newarray->slots + index; slotCopy(&newslot[0],&slot[0]); slotCopy(&newslot[1],&slot[1]); } } dict->slots[ivxIdentDict_array].uo = newarray; g->gc->GCWrite(dict, newarray); } } return errNone; }
int SC_TerminalClient::prArgv(struct VMGlobals* g, int) { int argc = ((SC_TerminalClient*)SC_TerminalClient::instance())->options().mArgc; char** argv = ((SC_TerminalClient*)SC_TerminalClient::instance())->options().mArgv; PyrSlot* argvSlot = g->sp; PyrObject* argvObj = newPyrArray(g->gc, argc * sizeof(PyrObject), 0, true); SetObject(argvSlot, argvObj); for (int i=0; i < argc; i++) { PyrString* str = newPyrString(g->gc, argv[i], 0, true); SetObject(argvObj->slots+i, str); argvObj->size++; g->gc->GCWriteNew(argvObj, (PyrObject*)str); // we know str is white so we can use GCWriteNew } return errNone; }
int prGetControlBusValues(VMGlobals *g, int numArgsPushed) { PyrSlot *a = g->sp - 2; PyrSlot *b = g->sp - 1; PyrSlot *c = g->sp; assert(IsObj(a)); PyrObject * self = slotRawObject(a); int ptrIndex = 0; PyrSlot * ptrSlot = self->slots + ptrIndex; if (NotPtr(ptrSlot)) return errFailed; if (!IsInt(b)) return errFailed; int busIndex = slotRawInt(b); if (!IsInt(c)) return errFailed; int numberOfChannels = slotRawInt(c); server_shared_memory_client * client = (server_shared_memory_client*)slotRawPtr(ptrSlot); PyrObject * ret = newPyrArray(g->gc, numberOfChannels, 0, 1); ret->size = numberOfChannels; for (int i = 0; i != numberOfChannels; ++i) { float value = client->get_control_busses()[busIndex + i]; SetFloat(ret->slots+i, value); } SetObject(a, ret); return errNone; }
int prHID_API_GetInfo( VMGlobals* g, int numArgsPushed ){ PyrSlot *args = g->sp - numArgsPushed + 1; PyrSlot* self = args + 0; PyrSlot* arg = args + 1; int err; int joyid; err = slotIntVal( arg, &joyid ); if ( err != errNone ) return err; const char emptyString[] = ""; struct hid_dev_desc * devdesc = SC_HID_APIManager::instance().get_device( joyid ); struct hid_device_info * cur_dev = devdesc->info; if ( cur_dev != NULL ){ PyrObject* devInfo = newPyrArray(g->gc, 9 * sizeof(PyrObject), 0 , true); SetObject( self, devInfo ); SetInt(devInfo->slots+devInfo->size++, cur_dev->vendor_id); SetInt(devInfo->slots+devInfo->size++, cur_dev->product_id); PyrString *dev_path_name = newPyrString(g->gc, cur_dev->path, 0, true ); SetObject(devInfo->slots+devInfo->size++, dev_path_name); g->gc->GCWrite(devInfo, dev_path_name); const char * mystring; if ( cur_dev->serial_number != NULL ){ mystring = wchar_to_char( cur_dev->serial_number ); } else { mystring = emptyString; } PyrString *dev_serial = newPyrString(g->gc, mystring, 0, true ); SetObject(devInfo->slots+devInfo->size++, dev_serial); g->gc->GCWrite(devInfo, dev_serial); if (mystring != emptyString) free((void*)mystring); if ( cur_dev->manufacturer_string != NULL ){ mystring = wchar_to_char( cur_dev->manufacturer_string ); } else { mystring = emptyString; } PyrString *dev_man_name = newPyrString(g->gc, mystring, 0, true ); SetObject(devInfo->slots+devInfo->size++, dev_man_name); g->gc->GCWrite(devInfo, dev_man_name); if (mystring != emptyString) free((void*)mystring); if ( cur_dev->product_string != NULL ){ mystring = wchar_to_char( cur_dev->product_string ); } else { mystring = emptyString; } PyrString *dev_prod_name = newPyrString(g->gc, mystring, 0, true ); SetObject(devInfo->slots+devInfo->size++, dev_prod_name); g->gc->GCWrite(devInfo, dev_prod_name); if (mystring != emptyString) free((void*)mystring); SetInt(devInfo->slots+devInfo->size++, cur_dev->release_number); SetInt(devInfo->slots+devInfo->size++, cur_dev->interface_number); } else { SetInt( self, 0 ); } return errNone; }
int prHID_API_BuildDeviceList(VMGlobals* g, int numArgsPushed){ PyrSlot *args = g->sp - numArgsPushed + 1; PyrSlot *self = args + 0; // no arguments int err; const char emptyString[] = ""; // iterate over available devices and return info to language to populate the list there int result = SC_HID_APIManager::instance().build_devicelist(); if ( result > 0 ){ PyrObject* allDevsArray = newPyrArray(g->gc, result * sizeof(PyrObject), 0 , true); SetObject( self, allDevsArray ); struct hid_device_info *cur_dev = SC_HID_APIManager::instance().devinfos; while( cur_dev ){ PyrObject* devInfo = newPyrArray(g->gc, 11 * sizeof(PyrObject), 0 , true); SetInt(devInfo->slots+devInfo->size++, cur_dev->vendor_id); SetInt(devInfo->slots+devInfo->size++, cur_dev->product_id); PyrString *dev_path_name = newPyrString(g->gc, cur_dev->path, 0, true ); SetObject(devInfo->slots+devInfo->size++, dev_path_name); g->gc->GCWrite(devInfo, dev_path_name); const char * mystring; if ( cur_dev->serial_number != NULL ) mystring = wchar_to_char( cur_dev->serial_number ); else mystring = emptyString; PyrString *dev_serial = newPyrString(g->gc, mystring, 0, true ); SetObject(devInfo->slots+devInfo->size++, dev_serial); g->gc->GCWrite(devInfo, dev_serial); if (mystring != emptyString) free((void*)mystring); if ( cur_dev->manufacturer_string != NULL ) mystring = wchar_to_char( cur_dev->manufacturer_string ); else mystring = emptyString; PyrString *dev_man_name = newPyrString(g->gc, mystring, 0, true ); SetObject(devInfo->slots+devInfo->size++, dev_man_name); g->gc->GCWrite(devInfo, dev_man_name); if (mystring != emptyString) free((void*)mystring); if ( cur_dev->product_string != NULL ) mystring = wchar_to_char( cur_dev->product_string ); else mystring = emptyString; PyrString *dev_prod_name = newPyrString(g->gc, mystring, 0, true ); SetObject(devInfo->slots+devInfo->size++, dev_prod_name); g->gc->GCWrite(devInfo, dev_prod_name); if (mystring != emptyString) free((void*)mystring); SetInt(devInfo->slots+devInfo->size++, cur_dev->release_number); SetInt(devInfo->slots+devInfo->size++, cur_dev->interface_number); SetInt(devInfo->slots+devInfo->size++, cur_dev->usage_page); SetInt(devInfo->slots+devInfo->size++, cur_dev->usage); SetObject(allDevsArray->slots+allDevsArray->size++, devInfo ); g->gc->GCWrite(allDevsArray, devInfo); cur_dev = cur_dev->next; } SC_HID_APIManager::instance().free_devicelist(); } else { // send back info that no devices were found, or empty array SetInt( self, 0 ); } return errNone; }
HOT void executeMethod(VMGlobals *g, PyrMethod *meth, long numArgsPushed) { PyrMethodRaw *methraw; PyrFrame *frame; PyrFrame *caller; PyrSlot *pslot, *qslot; PyrSlot *rslot; PyrSlot *vars; PyrObject *proto; long i, m, mmax, numtemps, numargs; #ifdef GC_SANITYCHECK g->gc->SanityCheck(); CallStackSanity(g, "executeMethod"); #endif #if DEBUGMETHODS if (gTraceInterpreter) { if (g->method) { postfl(" %s:%s -> %s:%s\n", slotRawSymbol(&slotRawClass(&g->method->ownerclass)->name)->name, slotRawSymbol(&g->method->name)->name, slotRawSymbol(&slotRawClass(&meth->ownerclass)->name)->name, slotRawSymbol(&meth->name)->name); } else { postfl(" top -> %s:%s\n", slotRawSymbol(&slotRawClass(&meth->ownerclass)->name)->name, slotRawSymbol(&meth->name)->name); } } #endif #if METHODMETER if (gTraceInterpreter) { slotRawInt(&meth->callMeter)++; } #endif #if TAILCALLOPTIMIZE int tailCall = g->tailCall; if (tailCall) { if (tailCall == 1) { returnFromMethod(g); } else { returnFromBlock(g); } } #endif g->execMethod = 20; proto = slotRawObject(&meth->prototypeFrame); methraw = METHRAW(meth); numtemps = methraw->numtemps; numargs = methraw->numargs; caller = g->frame; //postfl("executeMethod allArgsPushed %d numKeyArgsPushed %d\n", allArgsPushed, numKeyArgsPushed); frame = (PyrFrame*)g->gc->NewFrame(methraw->frameSize, 0, obj_slot, methraw->needsHeapContext); vars = frame->vars - 1; frame->classptr = class_frame; frame->size = FRAMESIZE + proto->size; SetObject(&frame->method, meth); SetObject(&frame->homeContext, frame); SetObject(&frame->context, frame); if (caller) { SetPtr(&caller->ip, g->ip); SetObject(&frame->caller, caller); } else { SetInt(&frame->caller, 0); } SetPtr(&frame->ip, 0); g->method = meth; g->ip = slotRawInt8Array(&meth->code)->b - 1; g->frame = frame; g->block = (PyrBlock*)meth; g->sp -= numArgsPushed; qslot = g->sp; pslot = vars; if (numArgsPushed <= numargs) { /* not enough args pushed */ /* push all args to frame */ for (m=0,mmax=numArgsPushed; m<mmax; ++m) slotCopy(++pslot, ++qslot); /* push default arg & var values */ pslot = vars + numArgsPushed; qslot = proto->slots + numArgsPushed - 1; for (m=0, mmax=numtemps - numArgsPushed; m<mmax; ++m) slotCopy(++pslot, ++qslot); } else if (methraw->varargs) { PyrObject *list; PyrSlot *lslot; /* push all normal args to frame */ for (m=0,mmax=numargs; m<mmax; ++m) slotCopy(++pslot, ++qslot); /* push list */ i = numArgsPushed - numargs; list = newPyrArray(g->gc, (int)i, 0, false); list->size = (int)i; rslot = pslot+1; SetObject(rslot, list); //SetObject(vars + numargs + 1, list); /* put extra args into list */ lslot = (list->slots - 1); // fixed and raw sizes are zero for (m=0,mmax=i; m<mmax; ++m) slotCopy(++lslot, ++qslot); if (methraw->numvars) { /* push default keyword and var values */ pslot = vars + numargs + 1; qslot = proto->slots + numargs; for (m=0,mmax=methraw->numvars; m<mmax; ++m) slotCopy(++pslot, ++qslot); } } else { /* push all args to frame */ for (m=0,mmax=numargs; m<mmax; ++m) slotCopy(++pslot, ++qslot); if (methraw->numvars) { /* push default keyword and var values */ pslot = vars + numargs; qslot = proto->slots + numargs - 1; for (m=0,mmax=methraw->numvars; m<mmax; ++m) slotCopy(++pslot, ++qslot); } } slotCopy(&g->receiver, &vars[1]); #ifdef GC_SANITYCHECK g->gc->SanityCheck(); CallStackSanity(g, "<executeMethod"); #endif }
/* ------------------------------------------------------------- */ int prListMIDIEndpoints(struct VMGlobals *g, int numArgsPushed) { PyrSlot *a = g->sp; int numSrc = gNumMIDIInPorts; int numDst = gNumMIDIOutPorts; PyrObject* idarray = newPyrArray(g->gc, 6 * sizeof(PyrObject), 0 , true); SetObject(a, idarray); // 0 PyrObject* idarraySo = newPyrArray(g->gc, numSrc * sizeof(__int32), 0 , true); SetObject(idarray->slots+idarray->size++, idarraySo); g->gc->GCWrite(idarray, idarraySo); // 1 PyrObject* devarraySo = newPyrArray(g->gc, numSrc * sizeof(PyrObject), 0 , true); SetObject(idarray->slots+idarray->size++, devarraySo); g->gc->GCWrite(idarray, devarraySo); // 2 PyrObject* namearraySo = newPyrArray(g->gc, numSrc * sizeof(PyrObject), 0 , true); SetObject(idarray->slots+idarray->size++, namearraySo); g->gc->GCWrite(idarray, namearraySo); // 3 PyrObject* idarrayDe = newPyrArray(g->gc, numDst * sizeof(__int32), 0 , true); SetObject(idarray->slots+idarray->size++, idarrayDe); g->gc->GCWrite(idarray, idarrayDe); // 4 PyrObject* namearrayDe = newPyrArray(g->gc, numDst * sizeof(PyrObject), 0 , true); SetObject(idarray->slots+idarray->size++, namearrayDe); g->gc->GCWrite(idarray, namearrayDe); // 5 PyrObject* devarrayDe = newPyrArray(g->gc, numDst * sizeof(PyrObject), 0 , true); SetObject(idarray->slots+idarray->size++, devarrayDe); g->gc->GCWrite(idarray, devarrayDe); for (int i=0; i<numSrc; ++i) { const PmDeviceInfo* devInfo = Pm_GetDeviceInfo(gMidiInputIndexToPmDevIndex[i]); char cendname[1024], cdevname[1024]; // currently, copy both name strings in endpoint name and dev name strncpy(cendname,devInfo->name,1023); cendname[1023] = 0; strncpy(cdevname,devInfo->name,1023); cdevname[1023] = 0; PyrString *string = newPyrString(g->gc, cendname, 0, true); SetObject(namearraySo->slots+i, string); namearraySo->size++; g->gc->GCWrite(namearraySo, (PyrObject*)string); PyrString *devstring = newPyrString(g->gc, cdevname, 0, true); SetObject(devarraySo->slots+i, devstring); devarraySo->size++; g->gc->GCWrite(devarraySo, (PyrObject*)devstring); SetInt(idarraySo->slots+i, i); idarraySo->size++; } // post("numDst %d\n", numDst); for (int i=0; i<numDst; ++i) { const PmDeviceInfo* devInfo = Pm_GetDeviceInfo(gMidiOutputIndexToPmDevIndex[i]); char cendname[1024], cdevname[1024]; // currently, copy both name strings in endpoint name and dev name strncpy(cendname,devInfo->name,1023); cendname[1023] = 0; strncpy(cdevname,devInfo->name,1023); cdevname[1023] = 0; PyrString *string = newPyrString(g->gc, cendname, 0, true); SetObject(namearrayDe->slots+namearrayDe->size++, string); g->gc->GCWrite(namearrayDe, (PyrObject*)string); PyrString *devstring = newPyrString(g->gc, cdevname, 0, true); SetObject(devarrayDe->slots+devarrayDe->size++, devstring); g->gc->GCWrite(devarrayDe, (PyrObject*)devstring); SetInt(idarrayDe->slots+idarrayDe->size++, i); } return errNone; }
int prSimpleNumberSeries(struct VMGlobals *g, int numArgsPushed) { PyrSlot *a = g->sp - 2; PyrSlot *b = g->sp - 1; PyrSlot *c = g->sp; int err, size; if (IsInt(a) && (IsInt(b) || IsNil(b)) && IsInt(c)) { int first, second, last, step; first = slotRawInt(a); last = slotRawInt(c); second = IsInt(b) ? slotRawInt(b) : (first < last ? first + 1 : first - 1); step = second - first; if ( step == 0 ) size = 1; else size = ((last - first) / step) + 1; if(size<1 || size > INT_MAX_BY_PyrSlot){ post("prSimpleNumberSeries: array size %i exceeds limit (%i)\n", size, INT_MAX_BY_PyrSlot); return errFailed; } PyrObject *obj = newPyrArray(g->gc, size, 0, true); obj->size = size; PyrSlot *slots = obj->slots; if(step==1){ // Faster iteration for common case if(first==0){ for (int i=0; i<size; ++i) { SetInt(slots+i, i); } }else{ for (int i=0; i<size; ++i) { SetInt(slots+i, first++); } } }else{ int val = first; for (int i=0; i<size; ++i) { SetInt(slots+i, val); val += step; } } SetObject(a, obj); } else { double first, second, last, step; err = slotDoubleVal(a, &first); if (err) return err; err = slotDoubleVal(c, &last); if (err) return err; err = slotDoubleVal(b, &second); if (err) { if (first < last) second = first + 1.; else second = first - 1.; } step = second - first; size = (int)floor((last - first) / step + 0.001) + 1; if(size<1 || size > INT_MAX_BY_PyrSlot){ post("prSimpleNumberSeries: array size %i exceeds limit (%i)\n", size, INT_MAX_BY_PyrSlot); return errFailed; } PyrObject *obj = newPyrArray(g->gc, size, 0, true); obj->size = size; PyrSlot *slots = obj->slots; if(first==0. && step==1.){ // Faster iteration for common case for (long i=0; i<size; ++i) { SetFloat(slots+i, i); } }else{ double val = first; for (long i=0; i<size; ++i) { val = first + step * i; SetFloat(slots+i, val); } } SetObject(a, obj); } return errNone; }
int prListMIDIEndpoints(struct VMGlobals *g, int numArgsPushed) { OSStatus error; PyrSlot *a = g->sp; int numSrc = (int)MIDIGetNumberOfSources(); int numDst = (int)MIDIGetNumberOfDestinations(); PyrObject* idarray = newPyrArray(g->gc, 6 * sizeof(PyrObject), 0 , true); SetObject(a, idarray); PyrObject* idarraySo = newPyrArray(g->gc, numSrc * sizeof(SInt32), 0 , true); SetObject(idarray->slots+idarray->size++, idarraySo); g->gc->GCWrite(idarray, idarraySo); PyrObject* devarraySo = newPyrArray(g->gc, numSrc * sizeof(PyrObject), 0 , true); SetObject(idarray->slots+idarray->size++, devarraySo); g->gc->GCWrite(idarray, devarraySo); PyrObject* namearraySo = newPyrArray(g->gc, numSrc * sizeof(PyrObject), 0 , true); SetObject(idarray->slots+idarray->size++, namearraySo); g->gc->GCWrite(idarray, namearraySo); PyrObject* idarrayDe = newPyrArray(g->gc, numDst * sizeof(SInt32), 0 , true); SetObject(idarray->slots+idarray->size++, idarrayDe); g->gc->GCWrite(idarray, idarrayDe); PyrObject* namearrayDe = newPyrArray(g->gc, numDst * sizeof(PyrObject), 0 , true); SetObject(idarray->slots+idarray->size++, namearrayDe); g->gc->GCWrite(idarray, namearrayDe); PyrObject* devarrayDe = newPyrArray(g->gc, numDst * sizeof(PyrObject), 0 , true); SetObject(idarray->slots+idarray->size++, devarrayDe); g->gc->GCWrite(idarray, devarrayDe); for (int i=0; i<numSrc; ++i) { MIDIEndpointRef src = MIDIGetSource(i); SInt32 id; MIDIObjectGetIntegerProperty(src, kMIDIPropertyUniqueID, &id); MIDIEntityRef ent; error = MIDIEndpointGetEntity(src, &ent); CFStringRef devname, endname; char cendname[1024], cdevname[1024]; // Virtual sources don't have entities if(error) { MIDIObjectGetStringProperty(src, kMIDIPropertyName, &devname); MIDIObjectGetStringProperty(src, kMIDIPropertyName, &endname); CFStringGetCString(devname, cdevname, 1024, kCFStringEncodingUTF8); CFStringGetCString(endname, cendname, 1024, kCFStringEncodingUTF8); } else { MIDIDeviceRef dev; MIDIEntityGetDevice(ent, &dev); MIDIObjectGetStringProperty(dev, kMIDIPropertyName, &devname); MIDIObjectGetStringProperty(src, kMIDIPropertyName, &endname); CFStringGetCString(devname, cdevname, 1024, kCFStringEncodingUTF8); CFStringGetCString(endname, cendname, 1024, kCFStringEncodingUTF8); } PyrString *string = newPyrString(g->gc, cendname, 0, true); SetObject(namearraySo->slots+i, string); namearraySo->size++; g->gc->GCWrite(namearraySo, (PyrObject*)string); PyrString *devstring = newPyrString(g->gc, cdevname, 0, true); SetObject(devarraySo->slots+i, devstring); devarraySo->size++; g->gc->GCWrite(devarraySo, (PyrObject*)devstring); SetInt(idarraySo->slots+i, id); idarraySo->size++; CFRelease(devname); CFRelease(endname); } // post("numDst %d\n", numDst); for (int i=0; i<numDst; ++i) { MIDIEndpointRef dst = MIDIGetDestination(i); SInt32 id; MIDIObjectGetIntegerProperty(dst, kMIDIPropertyUniqueID, &id); MIDIEntityRef ent; error = MIDIEndpointGetEntity(dst, &ent); CFStringRef devname, endname; char cendname[1024], cdevname[1024]; // Virtual destinations don't have entities either if(error) { MIDIObjectGetStringProperty(dst, kMIDIPropertyName, &devname); MIDIObjectGetStringProperty(dst, kMIDIPropertyName, &endname); CFStringGetCString(devname, cdevname, 1024, kCFStringEncodingUTF8); CFStringGetCString(endname, cendname, 1024, kCFStringEncodingUTF8); } else { MIDIDeviceRef dev; MIDIEntityGetDevice(ent, &dev); MIDIObjectGetStringProperty(dev, kMIDIPropertyName, &devname); MIDIObjectGetStringProperty(dst, kMIDIPropertyName, &endname); CFStringGetCString(devname, cdevname, 1024, kCFStringEncodingUTF8); CFStringGetCString(endname, cendname, 1024, kCFStringEncodingUTF8); } PyrString *string = newPyrString(g->gc, cendname, 0, true); SetObject(namearrayDe->slots+namearrayDe->size++, string); g->gc->GCWrite(namearrayDe, (PyrObject*)string); PyrString *devstring = newPyrString(g->gc, cdevname, 0, true); SetObject(devarrayDe->slots+devarrayDe->size++, devstring); g->gc->GCWrite(devarrayDe, (PyrObject*)devstring); SetInt(idarrayDe->slots+idarrayDe->size++, id); CFRelease(devname); CFRelease(endname); } return errNone; }
int prHID_API_GetCollectionInfo( VMGlobals* g, int numArgsPushed ){ PyrSlot *args = g->sp - numArgsPushed + 1; PyrSlot* self = args + 0; PyrSlot* arg1 = args + 1; PyrSlot* arg2 = args + 2; int err; int joyid; int collectionid; err = slotIntVal( arg1, &joyid ); if ( err != errNone ) return err; err = slotIntVal( arg2, &collectionid ); if ( err != errNone ) return err; struct hid_dev_desc * devdesc = SC_HID_APIManager::instance().get_device( joyid ); struct hid_device_collection * curdev = devdesc->device_collection; struct hid_device_collection * curcollection = curdev->first_collection; struct hid_device_collection * thiscollection = NULL; bool found = curcollection->index == collectionid; if ( found ){ thiscollection = curcollection; } while( curcollection != NULL && !found ){ found = curcollection->index == collectionid; if ( found ){ thiscollection = curcollection; } curcollection = curcollection->next_collection; } if ( thiscollection != NULL ){ PyrObject* elInfo = newPyrArray(g->gc, 9 * sizeof(PyrObject), 0 , true); SetObject( self, elInfo ); SetInt(elInfo->slots+elInfo->size++, thiscollection->index ); SetInt(elInfo->slots+elInfo->size++, thiscollection->type ); SetInt(elInfo->slots+elInfo->size++, thiscollection->usage_page ); SetInt(elInfo->slots+elInfo->size++, thiscollection->usage_index ); if ( thiscollection->parent_collection != NULL ){ SetInt(elInfo->slots+elInfo->size++, thiscollection->parent_collection->index ); } else { SetInt(elInfo->slots+elInfo->size++, -2 ); } SetInt(elInfo->slots+elInfo->size++, thiscollection->num_collections ); if ( thiscollection->first_collection != NULL ){ SetInt(elInfo->slots+elInfo->size++, thiscollection->first_collection->index ); } else { SetInt(elInfo->slots+elInfo->size++, -1 ); } SetInt(elInfo->slots+elInfo->size++, thiscollection->num_elements ); if ( thiscollection->first_element != NULL ){ SetInt(elInfo->slots+elInfo->size++, thiscollection->first_element->index ); } else { SetInt(elInfo->slots+elInfo->size++, -1 ); } } else { SetInt( self, 0 ); } return errNone; }
int prHID_API_GetElementInfo( VMGlobals* g, int numArgsPushed ){ PyrSlot *args = g->sp - numArgsPushed + 1; PyrSlot* self = args + 0; PyrSlot* arg1 = args + 1; PyrSlot* arg2 = args + 2; int err; int joyid; int elementid; err = slotIntVal( arg1, &joyid ); if ( err != errNone ) return err; err = slotIntVal( arg2, &elementid ); if ( err != errNone ) return err; struct hid_dev_desc * devdesc = SC_HID_APIManager::instance().get_device( joyid ); struct hid_device_collection * curdev = devdesc->device_collection; struct hid_device_element * curelement = curdev->first_element; struct hid_device_element * thiselement = NULL; bool found = curelement->index == elementid; if ( found ){ thiselement = curelement; } while( curelement != NULL && !found ){ found = curelement->index == elementid; if ( found ){ thiselement = curelement; } curelement = curelement->next; } if ( thiselement != NULL ){ PyrObject* elInfo = newPyrArray(g->gc, 18 * sizeof(PyrObject), 0 , true); SetObject( self, elInfo ); SetInt(elInfo->slots+elInfo->size++, thiselement->index ); SetInt(elInfo->slots+elInfo->size++, thiselement->io_type ); SetInt(elInfo->slots+elInfo->size++, thiselement->type ); SetInt(elInfo->slots+elInfo->size++, thiselement->usage_page ); SetInt(elInfo->slots+elInfo->size++, thiselement->usage ); SetInt(elInfo->slots+elInfo->size++, thiselement->usage_min ); SetInt(elInfo->slots+elInfo->size++, thiselement->usage_max ); SetInt(elInfo->slots+elInfo->size++, thiselement->logical_min ); SetInt(elInfo->slots+elInfo->size++, thiselement->logical_max ); SetInt(elInfo->slots+elInfo->size++, thiselement->phys_min ); SetInt(elInfo->slots+elInfo->size++, thiselement->phys_max ); SetInt(elInfo->slots+elInfo->size++, thiselement->unit_exponent ); SetInt(elInfo->slots+elInfo->size++, thiselement->unit ); SetInt(elInfo->slots+elInfo->size++, thiselement->report_size ); SetInt(elInfo->slots+elInfo->size++, thiselement->report_id ); SetInt(elInfo->slots+elInfo->size++, thiselement->report_index ); SetInt(elInfo->slots+elInfo->size++, thiselement->value ); SetInt(elInfo->slots+elInfo->size++, thiselement->parent_collection->index ); } else { SetInt( self, 0 ); } return errNone; }
int prString_FindRegexp(struct VMGlobals *g, int numArgsPushed) { int err; PyrSlot *a = g->sp - 2; // source string PyrSlot *b = g->sp - 1; // pattern PyrSlot *c = g->sp; // offset if (!isKindOfSlot(b, class_string) || (NotInt(c))) return errWrongType; // post("prString_FindRegexp\n"); int maxfind = MAXREGEXFIND; int offset = slotRawInt(c); int stringsize = slotRawObject(a)->size + 1; int patternsize = slotRawObject(b)->size + 1; char *string = (char*)malloc(slotRawObject(a)->size + 1); err = slotStrVal(a, string, slotRawObject(a)->size + 1); if (err){ free(string); return err; } char *pattern = (char*)malloc(slotRawObject(b)->size + 1); err = slotStrVal(b, pattern, slotRawObject(b)->size + 1); if (err) return err; UParseError uerr; UErrorCode status = (UErrorCode)0; UChar *regexStr; UChar *ustring; regexStr = (UChar*)malloc((patternsize)*sizeof(UChar)); u_charsToUChars (pattern, regexStr, patternsize); ustring = (UChar*)malloc((stringsize)*sizeof(UChar)); u_charsToUChars (string+offset, ustring, stringsize-offset); unsigned flags = UREGEX_MULTILINE; int groupNumber = 0; SCRegExRegion * what; int indx = 0; int size = 0; URegularExpression *expression = uregex_open(regexStr, -1, flags, &uerr, &status); if(U_FAILURE(status)) goto nilout; if(!U_FAILURE(status)) { uregex_setText(expression, ustring, -1, &status); what = (SCRegExRegion*)malloc((maxfind)*sizeof(SCRegExRegion)); for(int i=0; i< maxfind; i++) { SCRegExRegion range; range.matched = false; what[i] = range; } int32_t groups = uregex_groupCount(expression, &status) + 1; if(U_FAILURE(status)) goto nilout; // post("groups: %i\n", groups); while (uregex_findNext(expression, &status) && size<maxfind) { if(U_FAILURE(status)) return errNone; for(int i=0; i< groups; ++i){ what[size].group = i; what[size].start = sc_clip(uregex_start(expression, i, &status), 0, stringsize) ; if(U_FAILURE(status)) goto nilout; what[size].end = sc_clip(uregex_end(expression, i, &status), 0, stringsize); what[size].matched = true; // post("index:%i, size:%i, start %i, end %i\n", i, size, what[i].start, what[i].end); size = indx++ + 1; if(U_FAILURE(status)) goto nilout; } } PyrObject *result_array = newPyrArray(g->gc, size, 0, true); result_array->size = 0; if (size>0) //(matched) { for (int i = 0; i < size; i++) { if (what[0].matched == false) { result_array->size++; SetNil(result_array->slots+i); } else { result_array->size++; int match_start = what[i].start; int match_length = what[i].end - what[i].start; // post("for i:%i, start %i, end %i\n", i, what[i].start, what[i].end); // char *match = (char*)malloc(match_length); char match[match_length]; strncpy(match, string + offset + match_start, match_length); match[match_length] = 0; PyrObject *array = newPyrArray(g->gc, 2, 0, true); array->size = 2; SetInt(array->slots, match_start + offset); PyrObject *matched_string = (PyrObject*)newPyrString(g->gc, match, 0, true); SetObject(array->slots+1, matched_string); g->gc->GCWrite(matched_string, array->slots + 1); SetObject(result_array->slots + i, array); g->gc->GCWrite(array, result_array->slots + i); } } } else { SetNil(a); } free(what); free(pattern); free(regexStr); free(ustring); free(string); SetObject(a, result_array); g->gc->GCWrite(result_array,a); //uregex_close(expression); return errNone; } nilout: free(string); free(what); free(pattern); free(regexStr); free(ustring); SetNil(a); return errNone; }
int prAsFraction(struct VMGlobals *g, int numArgsPushed) { PyrSlot *a = g->sp - 2; PyrSlot *b = g->sp - 1; PyrSlot *c = g->sp; double mediant_num, lower_num, upper_num, temp_num; double mediant_den, lower_den, upper_den, temp_den; double x, d; int k, k1; int maxDenominator; int err; bool neg = false; err = slotDoubleVal(a, &x); if (err) return err; err = slotIntVal(b, &maxDenominator); if (err) return err; bool faster = IsTrue(c); PyrObject *obj = newPyrArray(g->gc, 2, 0, true); obj->size = 2; PyrSlot *slots = obj->slots; SetObject(a, obj); if (x < 0.0) { x = -x; neg = true; } if (x < 1.0) { upper_num = 1.0; upper_den = floor(1./x); lower_num = 1.0; lower_den = upper_den + 1.; } else { lower_num = floor(x); lower_den = 1.0; upper_num = lower_num + 1.; upper_den = 1.0; } while (true) { mediant_num = lower_num + upper_num; mediant_den = lower_den + upper_den; //post(" md %g %g %g %g %g %g\n", mediant_num, mediant_den, lower_num, lower_den, upper_num, upper_den); if (x * mediant_den > mediant_num) { d = upper_num - (x * upper_den); if (maxDenominator < mediant_den || fabs(d) < 1e-5) { if (neg) upper_num = -upper_num; SetInt(slots+0, (int)upper_num); SetInt(slots+1, (int)upper_den); return errNone; } lower_num = mediant_num; lower_den = mediant_den; if (faster) { k = (int)floor(((x * lower_den) - lower_num) / d); if (k < 10000) { k1 = k + 1; temp_num = lower_num + (k1 * upper_num); temp_den = lower_den + (k1 * upper_den); lower_num = lower_num + (k * upper_num); lower_den = lower_den + (k * upper_den); upper_num = temp_num; upper_den = temp_den; } } } else if (x * mediant_den == mediant_num) { if (maxDenominator >= mediant_den) { if (neg) mediant_num = -mediant_num; SetInt(slots+0, (int)mediant_num); SetInt(slots+1, (int)mediant_den); return errNone; } else if (lower_den < upper_den) { if (neg) lower_num = -lower_num; SetInt(slots+0, (int)lower_num); SetInt(slots+1, (int)lower_den); return errNone; } else { if (neg) upper_num = -upper_num; SetInt(slots+0, (int)upper_num); SetInt(slots+1, (int)upper_den); return errNone; } } else { d = lower_num - (x * lower_den); if (maxDenominator < mediant_den || fabs(d) < 1e-5) { if (neg) lower_num = -lower_num; SetInt(slots+0, (int)lower_num); SetInt(slots+1, (int)lower_den); return errNone; } upper_num = mediant_num; upper_den = mediant_den; if (faster) { k = (int)floor(((x * upper_den) - upper_num) / d); if (k < 10000) { k1 = k + 1; temp_num = (k1 * lower_num) + upper_num; temp_den = (k1 * lower_den) + upper_den; upper_num = (k * lower_num) + upper_num; upper_den = (k * lower_den) + upper_den; lower_num = temp_num; lower_den = temp_den; } } } } }
int prHIDBuildDeviceList(VMGlobals *g, int numArgsPushed) { //build a device list PyrSlot *a = g->sp - 2; PyrSlot *b = g->sp - 1; //usagePage PyrSlot *c = g->sp; //usage int usagePage, usage, err; if(IsNil(b)) usagePage = 0; else { err = slotIntVal(b, &usagePage); if (err) return err; } if(IsNil(c)) usage = 0; else { err = slotIntVal(c, &usage); if (err) return err; } //pass in usage & usagepage //kHIDUsage_GD_Joystick kHIDUsage_GD_GamePad //UInt32 usagePage = kHIDPage_GenericDesktop; //UInt32 usage = NULL; Boolean result = HIDBuildDeviceList (usagePage, usage); // returns false if no device found (ignored in this case) - returns always false ? if(result) post("no HID devices found\n"); int numdevs = HIDCountDevices(); gNumberOfHIDDevices = numdevs; if(!numdevs){ SetNil(a); return errNone; } //post("number of devices: %d", numdevs); char cstrDeviceName [256]; pRecDevice pCurrentHIDDevice = HIDGetFirstDevice (); PyrObject* allDevsArray = newPyrArray(g->gc, numdevs * sizeof(PyrObject), 0 , true); for(int i=0; i<numdevs; i++){ //device: PyrObject* devNameArray = newPyrArray(g->gc, 8 * sizeof(PyrObject), 0 , true); //manufacturer: PyrString *devstring = newPyrString(g->gc, pCurrentHIDDevice->manufacturer, 0, true); SetObject(devNameArray->slots+devNameArray->size++, devstring); g->gc->GCWrite(devNameArray, (PyrObject*) devstring); //product name: devstring = newPyrString(g->gc, pCurrentHIDDevice->product, 0, true); SetObject(devNameArray->slots+devNameArray->size++, devstring); g->gc->GCWrite(devNameArray, (PyrObject*) devstring); //usage HIDGetUsageName (pCurrentHIDDevice->usagePage, pCurrentHIDDevice->usage, cstrDeviceName); devstring = newPyrString(g->gc, cstrDeviceName, 0, true); SetObject(devNameArray->slots+devNameArray->size++, devstring); g->gc->GCWrite(devNameArray, (PyrObject*) devstring); //vendor id SetInt(devNameArray->slots+devNameArray->size++, pCurrentHIDDevice->vendorID); //product id SetInt(devNameArray->slots+devNameArray->size++, pCurrentHIDDevice->productID); //locID SetInt(devNameArray->slots+devNameArray->size++, pCurrentHIDDevice->locID); //version SetInt(devNameArray->slots+devNameArray->size++, pCurrentHIDDevice->version); //serial devstring = newPyrString(g->gc, pCurrentHIDDevice->serial, 0, true); SetObject(devNameArray->slots+devNameArray->size++, devstring); g->gc->GCWrite(devNameArray, (PyrObject*) devstring); SetObject(allDevsArray->slots+allDevsArray->size++, devNameArray); g->gc->GCWrite(allDevsArray, (PyrObject*) devNameArray); pCurrentHIDDevice = HIDGetNextDevice (pCurrentHIDDevice); } //UInt32 outnum = HIDCountDeviceElements (pCurrentHIDDevice, kHIDElementTypeOutput); //post("number of outputs: %d \n", outnum); SetObject(a, allDevsArray); return errNone; }