void ConfigureCheat (void) { if (!cartOpen) return; OSStatus err; IBNibRef nibRef; err = CreateNibReference(kMacS9XCFString, &nibRef); if (err == noErr) { err = CreateWindowFromNib(nibRef, CFSTR("CheatEntry"), &wRef); if (err == noErr) { DataBrowserCallbacks callbacks; EventHandlerRef eref; EventHandlerUPP eUPP; EventTypeSpec events[] = { { kEventClassCommand, kEventCommandProcess }, { kEventClassCommand, kEventCommandUpdateStatus }, { kEventClassWindow, kEventWindowClose } }; HIViewRef ctl, root; HIViewID cid; root = HIViewGetRoot(wRef); cid.id = 0; cid.signature = kDataBrowser; HIViewFindByID(root, cid, &dbRef); #ifdef MAC_PANTHER_SUPPORT if (systemVersion < 0x1040) { HISize minSize; Rect rct; GetWindowBounds(wRef, kWindowContentRgn, &rct); minSize.width = (float) (rct.right - rct.left); minSize.height = (float) (rct.bottom - rct.top ); err = SetWindowResizeLimits(wRef, &minSize, NULL); } #endif callbacks.version = kDataBrowserLatestCallbacks; err = InitDataBrowserCallbacks(&callbacks); callbacks.u.v1.itemDataCallback = NewDataBrowserItemDataUPP(DBClientDataCallback); callbacks.u.v1.itemCompareCallback = NewDataBrowserItemCompareUPP(DBCompareCallBack); callbacks.u.v1.itemNotificationCallback = NewDataBrowserItemNotificationUPP(DBItemNotificationCallBack); err = SetDataBrowserCallbacks(dbRef, &callbacks); if (systemVersion >= 0x1040) err = DataBrowserChangeAttributes(dbRef, kDataBrowserAttributeListViewAlternatingRowColors, kDataBrowserAttributeNone); InitCheatItems(); ImportCheatItems(); DataBrowserItemID *id; id = new DataBrowserItemID[MAC_MAX_CHEATS]; if (!id) QuitWithFatalError(0, "cheat 01"); numofcheats = 0; for (unsigned int i = 0; i < MAC_MAX_CHEATS; i++) { if (citem[i].valid) { id[numofcheats] = citem[i].id; numofcheats++; } } if (numofcheats) err = AddDataBrowserItems(dbRef, kDataBrowserNoItem, numofcheats, id, kDataBrowserItemNoProperty); delete [] id; cid.signature = kNewButton; HIViewFindByID(root, cid, &ctl); if (numofcheats == MAC_MAX_CHEATS) err = DeactivateControl(ctl); else err = ActivateControl(ctl); cid.signature = kAllButton; HIViewFindByID(root, cid, &ctl); if (numofcheats == 0) err = DeactivateControl(ctl); else err = ActivateControl(ctl); cid.signature = kDelButton; HIViewFindByID(root, cid, &ctl); err = DeactivateControl(ctl); eUPP = NewEventHandlerUPP(CheatEventHandler); err = InstallWindowEventHandler(wRef, eUPP, GetEventTypeCount(events), events, (void *) wRef, &eref); err = SetKeyboardFocus(wRef, dbRef, kControlFocusNextPart); MoveWindowPosition(wRef, kWindowCheatEntry, true); ShowWindow(wRef); err = RunAppModalLoopForWindow(wRef); HideWindow(wRef); SaveWindowPosition(wRef, kWindowCheatEntry); err = RemoveEventHandler(eref); DisposeEventHandlerUPP(eUPP); DisposeDataBrowserItemNotificationUPP(callbacks.u.v1.itemNotificationCallback); DisposeDataBrowserItemCompareUPP(callbacks.u.v1.itemCompareCallback); DisposeDataBrowserItemDataUPP(callbacks.u.v1.itemDataCallback); CFRelease(wRef); DetachCheatItems(); } DisposeNibReference(nibRef); } }
// -------------------------------------------------------------------------------------- void ReleaseIconDataBrowserItemData(ControlRef iconDataBrowser) { Handle itemsHandle; DataBrowserItemID *items; int itemNumber; IconDBItemDataRec *itemsData[kNumberOfRows]; UInt16 referenceCount; Boolean needRelease = false; itemsHandle = NewHandle(0); // GetDataBrowserItems will resize this for us GetDataBrowserItems(iconDataBrowser, kDataBrowserNoItem, false, kDataBrowserItemAnyState, itemsHandle); /* At this point we have the following: Handle -> Pointer -> DataBrowserItemID[] In our icon data browser, DataBrowserItemID = IconDBItemDataRec pointer So that means we have: Handle -> Pointer -> IconDBItemDataRec pointer -> IconDBItemDataRec */ HLockHi(itemsHandle); // since we're about to dereference this, we need it to stay put items = (DataBrowserItemID *)*itemsHandle; /* While this is technically unnecessary, it will save us a lot of awkward multiple dereferencings and generally make things much easier to read. */ for (itemNumber = 0; itemNumber < kNumberOfRows; itemNumber++) itemsData[itemNumber] = (IconDBItemDataRec *)*(items + itemNumber); GetIconRefOwners((itemsData[0])->icon, &referenceCount); // first, unregister and/or release the icons if (referenceCount == 1) // if this is the last instance of the { // IconRefs we should unregister them OSType iconType; /* UnregisterIconRef doesn't decrement the reference count on some versions of Mac OS X (it does on 10.1.5, doesn't on 10.2.8, and does on 10.3.4). To account for this we will retain/acquire the icon, unregister it, then check the reference/owner count. If it's the same then we will also release the icons. We can't release the icons first or UnregisterIconRef will return noSuchIconErr (because the icons will already be disposed). Likewise we can't just release the icons afterwards because they may get disposed of when they're unregistered. */ AcquireIconRef((itemsData[0])->icon); for (iconType = 'Cat0'; iconType <= 'Cat9'; iconType++) UnregisterIconRef(kAppSignature, iconType); gIconsRegistered = false; GetIconRefOwners((itemsData[0])->icon, &referenceCount); if (referenceCount > 1) needRelease = true; ReleaseIconRef((itemsData[0])->icon); } else // otherwise simply release the icons needRelease = true; if (needRelease) { for (itemNumber = 0; itemNumber < kNumberOfRows; itemNumber++) ReleaseIconRef((itemsData[itemNumber])->icon); } // second, release the strings for (itemNumber = 0; itemNumber < kNumberOfRows; itemNumber++) CFRelease((itemsData[itemNumber])->name); DisposeHandle(itemsHandle); // finally, release our callbacks gCallbackRefCount--; if (gCallbackRefCount == 0) { DisposeDataBrowserItemNotificationUPP(gIconDBCallbacks.u.v1.itemNotificationCallback); DisposeDataBrowserDrawItemUPP(gIconDBCustomCallbacks.u.v1.drawItemCallback); } }
bool dialog_animation_settings_run(int animate_idx) { int i,pose_move_idx; ControlRef ctrl; ControlID ctrl_id; DataBrowserItemID itemID; DataBrowserCallbacks dbcall; DataBrowserItemDataUPP pose_list_item_upp,particle_list_item_upp,ring_list_item_upp; DataBrowserItemNotificationUPP pose_list_notify_upp,particle_list_notify_upp,ring_list_notify_upp; EventHandlerUPP event_upp,tab_event_upp; EventLoopTimerRef timer_event; EventLoopTimerUPP timer_upp; EventTypeSpec event_list[]={{kEventClassCommand,kEventProcessCommand}}, tab_event_list[]={{kEventClassCommand,kEventProcessCommand}, {kEventClassControl,kEventControlHit}}; // backup animation for cancel memmove(&animate_backup,&model.animates[animate_idx],sizeof(model_animate_type)); // if there is no pose moves or new animation, // then we need to add a default pose pose_move_idx=0; if (model.animates[animate_idx].npose_move==0) { pose_move_idx=model_animate_pose_insert(&model,animate_idx,-1,0); } // open the dialog dialog_open(&dialog_animation_settings_wind,"AnimationSettings"); // tab dialog_set_tab(dialog_animation_settings_wind,kAnimationPoseTab,0,0,kAnimationPoseTabCount); ctrl_id.signature=kAnimationPoseTab; ctrl_id.id=0; GetControlByID(dialog_animation_settings_wind,&ctrl_id,&ctrl); tab_event_upp=NewEventHandlerUPP(pose_move_setting_tab_proc); InstallControlEventHandler(ctrl,tab_event_upp,GetEventTypeCount(tab_event_list),tab_event_list,dialog_animation_settings_wind,NULL); // set pose list dialog_animate_idx=animate_idx; dialog_pose_move_idx=pose_move_idx; ctrl_id.signature=kAnimationPoseList; ctrl_id.id=0; GetControlByID(dialog_animation_settings_wind,&ctrl_id,&dialog_pose_move_list); dbcall.version=kDataBrowserLatestCallbacks; InitDataBrowserCallbacks(&dbcall); pose_list_item_upp=NewDataBrowserItemDataUPP(&pose_list_item_proc); dbcall.u.v1.itemDataCallback=pose_list_item_upp; pose_list_notify_upp=NewDataBrowserItemNotificationUPP(&pose_list_notify_proc); dbcall.u.v1.itemNotificationCallback=pose_list_notify_upp; SetDataBrowserCallbacks(dialog_pose_move_list,&dbcall); AddDataBrowserItems(dialog_pose_move_list,kDataBrowserNoItem,model.animates[dialog_animate_idx].npose_move,NULL,kDataBrowserItemNoProperty); dialog_pose_move_change_ok=FALSE; itemID=pose_move_idx+1; SetDataBrowserSelectedItems(dialog_pose_move_list,1,&itemID,kDataBrowserItemsAssign); dialog_pose_move_change_ok=TRUE; // setup particle list ctrl_id.signature=kAnimationParticleList; ctrl_id.id=0; GetControlByID(dialog_animation_settings_wind,&ctrl_id,&dialog_particle_list); dbcall.version=kDataBrowserLatestCallbacks; InitDataBrowserCallbacks(&dbcall); particle_list_item_upp=NewDataBrowserItemDataUPP(&particle_list_item_proc); dbcall.u.v1.itemDataCallback=particle_list_item_upp; particle_list_notify_upp=NewDataBrowserItemNotificationUPP(&particle_list_notify_proc); dbcall.u.v1.itemNotificationCallback=particle_list_notify_upp; SetDataBrowserCallbacks(dialog_particle_list,&dbcall); // setup ring list ctrl_id.signature=kAnimationRingList; ctrl_id.id=0; GetControlByID(dialog_animation_settings_wind,&ctrl_id,&dialog_ring_list); dbcall.version=kDataBrowserLatestCallbacks; InitDataBrowserCallbacks(&dbcall); ring_list_item_upp=NewDataBrowserItemDataUPP(&ring_list_item_proc); dbcall.u.v1.itemDataCallback=ring_list_item_upp; ring_list_notify_upp=NewDataBrowserItemNotificationUPP(&ring_list_notify_proc); dbcall.u.v1.itemNotificationCallback=ring_list_notify_upp; SetDataBrowserCallbacks(dialog_ring_list,&dbcall); // fill pose combo dialog_clear_combo(dialog_animation_settings_wind,kAnimationPosePose,0); for (i=0;i!=model.npose;i++) { dialog_add_combo_item(dialog_animation_settings_wind,kAnimationPosePose,0,model.poses[i].name,FOUR_CHAR_CODE('\?\?\?\?')); } // fill mesh combo (leave none in list) for (i=0;i!=model.nmesh;i++) { dialog_add_combo_item(dialog_animation_settings_wind,kAnimationMeshName,0,model.meshes[i].name,FOUR_CHAR_CODE('\?\?\?\?')); } // load setting data dialog_set_text(dialog_animation_settings_wind,kAnimationName,0,model.animates[animate_idx].name); dialog_set_boolean(dialog_animation_settings_wind,kAnimationLoop,0,model.animates[animate_idx].loop); dialog_set_focus(dialog_animation_settings_wind,kAnimationName,0); // load pose move data dialog_pose_move_settings_load(); dialog_animation_settings_cancel=FALSE; // show window ShowWindow(dialog_animation_settings_wind); // install event handler event_upp=NewEventHandlerUPP(animation_settings_event_proc); InstallWindowEventHandler(dialog_animation_settings_wind,event_upp,GetEventTypeCount(event_list),event_list,NULL,NULL); // modal window and timer timer_upp=NewEventLoopTimerUPP(pose_move_timer); InstallEventLoopTimer(GetCurrentEventLoop(),0,0.01,timer_upp,NULL,&timer_event); RunAppModalLoopForWindow(dialog_animation_settings_wind); RemoveEventLoopTimer(timer_event); DisposeEventLoopTimerUPP(timer_upp); // dialog to data dialog_get_text(dialog_animation_settings_wind,kAnimationName,0,model.animates[animate_idx].name,name_str_len); model.animates[animate_idx].loop=dialog_get_boolean(dialog_animation_settings_wind,kAnimationLoop,0); dialog_pose_move_settings_save(); // close window DisposeDataBrowserItemDataUPP(pose_list_item_upp); DisposeDataBrowserItemNotificationUPP(pose_list_notify_upp); DisposeDataBrowserItemDataUPP(particle_list_item_upp); DisposeDataBrowserItemNotificationUPP(particle_list_notify_upp); DisposeDataBrowserItemDataUPP(ring_list_item_upp); DisposeDataBrowserItemNotificationUPP(ring_list_notify_upp); DisposeWindow(dialog_animation_settings_wind); // if cancel, reset animation if (dialog_animation_settings_cancel) { memmove(&model.animates[animate_idx],&animate_backup,sizeof(model_animate_type)); } reset_animate_list(); return(!dialog_animation_settings_cancel); }