HayBox عبارة عن برنامج ثابت معياري عبر الأنظمة الأساسية لوحدات التحكم التناظرية/الرقمية الرقمية أو المختلطة، يستهدف بشكل أساسي وحدات التحكم ذات النمط B0XX.
تشمل الميزات:
إذا كنت تريد ببساطة استخدام برنامج ثابت تم إنشاؤه مسبقًا مع تعيينات وتكوينات الدبوس الافتراضية، فارجع إلى قسم الثنائيات المعدة مسبقًا. إذا كنت تريد إجراء أي تغييرات على الكود، فارجع إلى قسم المبنى من المصدر.
.uf2
)، فما عليك سوى وضعه في وضع التمهيد أثناء توصيله بجهاز الكمبيوتر الخاص بك، ثم سحب وإفلات ملف .uf2
على محرك RPI-RP2 الذي يظهر.hex
)، فيمكنك استخدام برنامج مثل QMK Toolbox لتحديث الملف .hex
إليهتوجد حاليًا ثلاث طرق رئيسية لإنشاء HayBox:
يتطلب كل من GitHub Actions وGitHub Codespaces منك إنشاء حساب GitHub، لكن لا يتطلبان منك تثبيت أي تبعيات على جهازك المحلي.
التبعيات التالية مطلوبة عند البناء محليًا:
بعد تثبيت جميع المتطلبات، قم بتنزيل واستخراج أحدث إصدار من HayBox، أو انسخ المستودع إذا كان لديك git مثبتًا (مما يسهل عليك سحب التحديثات).
بعد ذلك:
git config --global core.longpaths true
في أي محطة طرفية (داخل VS Code أو cmd/PowerShell العادي كلها جيدة)config/<environment>/config.cpp
). يمكن ببساطة حذف أي أزرار لا تحتوي عليها وحدة التحكم الخاصة بك من القائمة.HayBox/.pio/build/<environment>/firmware.uf2
على RPI محرك -RP2 الذي يأتي.ربما تكون هذه هي الطريقة الأكثر ملاءمة لتعديل وإعادة بناء HayBox، ولكن ضع في اعتبارك أن الطبقة المجانية لـ GitHub تضع بعض القيود على مقدار استخدام Codespaces كل شهر. ولهذا السبب، ستحتاج إلى التأكد من إغلاق Codespaces الخاصة بك عندما لا تستخدمها، من أجل تعظيم ما يمكنك الحصول عليه من حصتك.
أولاً، قم بإنشاء حساب GitHub أو قم فقط بتسجيل الدخول إذا كان لديك حساب بالفعل، ثم قم بتقسيم هذا المستودع وافتح تفرعك في Codespace جديد عن طريق النقر فوق زر Code الأخضر -> Codespaces -> إنشاء codespace على الملف الرئيسي. يجب أن يؤدي هذا إلى فتح VS Code في متصفحك مع تثبيت جميع الملحقات والتبعيات الضرورية مسبقًا. من هنا، تشبه العملية إلى حد كبير عملية البناء محليًا، باستثناء أنه لا يمكنك استخدام زر التحميل لتحديث البرنامج الثابت. سيتعين عليك بدلاً من ذلك تنزيل الملف الثنائي المترجم من HayBox/.pio/build/<environment>/
وتفليشه يدويًا (انظر هنا لمزيد من المعلومات حول ذلك).
يحتوي هذا المستودع على تعريف سير عمل GitHub Actions الذي يبني كل بيئة PlatformIO محددة في المصفوفة في كل دفعة، ويقوم بتحميل ثنائيات البرامج الثابتة كعناصر فنية يمكنك تنزيلها بالنقر فوق سير عمل محدد يتم تشغيله من السجل. يمكنك إنشاء فرع لهذا المستودع وتمكين الإجراءات من خلال النقر على الإعدادات -> الإجراءات -> عام -> تحديد "السماح بجميع الإجراءات ومهام سير العمل القابلة لإعادة الاستخدام" -> حفظ.
أسرع طريقة لإجراء التغييرات إذا كنت تريد الإنشاء عبر GitHub Actions فقط هي استخدام github.dev. يمكنك القيام بذلك بمجرد الضغط على .
على لوحة المفاتيح أثناء فتح شوكة هذا المستودع، وسيفتح محرر VS Code في متصفحك. لا يمنحك هذا نفس إمكانات التطوير التي ستحصل عليها في Codespace، ولكنه يسمح لك بإجراء التغييرات وتنفيذها مباشرةً من متصفحك. قم بتغيير ما تريد، ثم استخدم علامة التبويب "التحكم في المصدر" الموجودة على اليسار لإضافة التغييرات وتنفيذها ودفعها. أخيرًا، ارجع إلى المستودع وانقر فوق علامة التبويب "إجراءات"، وانقر فوق "تشغيل سير العمل"، وانتظر حتى يتم إنشاء القطعة الأثرية.
إذا كنت تضيف بيئة تكوين/PlatformIO لجهاز جديد، فسيتعين عليك إضافة البيئة إلى المصفوفة حتى يتم إنشاؤها بواسطة سير عمل GitHub Actions. يمكنك أيضًا إزالة أي بيئات من المصفوفة لا تهتم بها لتقليل استخدام الموارد وربما تسريع عمليات الإنشاء الخاصة بك.
لإعادة تشغيل وحدات التحكم المستندة إلى Pico في وضع التمهيد، اضغط مع الاستمرار على زر البدء في البرنامج الإضافي.
للتبديل إلى وضع لوحة Brook علىGCPCB2، أوGCMX، أوB0XX R2، أو LBX، اضغط باستمرار على B في المكون الإضافي.
يتم تحديد الواجهات الخلفية للاتصالات بشكل مختلف قليلاً اعتمادًا على نوع وحدة التحكم الدقيقة المستخدمة في وحدة التحكم.
في Pico/RP2040، يتم اكتشاف USB vs GameCube vs Nintendo 64 تلقائيًا. إذا لم يتم توصيله بوحدة التحكم، فإن الإعداد الافتراضي هو XInput ، والذي يجب أن يعمل بنظام التوصيل والتشغيل مع معظم ألعاب الكمبيوتر. يتم تحديد الواجهات الخلفية الأخرى بالضغط على أحد الأزرار التالية في البرنامج المساعد:
في Arduino/AVR، يتم تحديد الواجهة الخلفية DInput إذا تم اكتشاف اتصال USB. بخلاف ذلك، يتم تعيينه افتراضيًا على الواجهة الخلفية لـ GameCube، ما لم يتم تحديد واجهة خلفية أخرى يدويًا بالضغط على أحد الأزرار التالية في المكون الإضافي:
على عكس البرامج الثابتة الأخرى المشابهة، يسمح لك HayBox افتراضيًا بتبديل الأوضاع بسرعة دون فصل وحدة التحكم الخاصة بك. يعد هذا مفيدًا بشكل أساسي على جهاز الكمبيوتر، على عكس وحدة التحكم حيث يتعين عليك عادةً إعادة تشغيل وحدة التحكم لتبديل اللعبة على أي حال. كما أنه يخدم غرض تقليل عدد الأزرار التي يجب عليك الإمساك بها بيد واحدة أثناء التوصيل.
مجموعات أزرار وضع وحدة التحكم الافتراضية هي:
مجموعات أزرار وضع لوحة المفاتيح الافتراضية (متوفرة فقط عند استخدام الواجهة الخلفية DInput، وليس مع XInput):
يحتاج HayBox إلى ملف تعريف وحدة تحكم Dolphin مختلف عن البرنامج الثابت B0XX الرسمي، لأنه يستخدم تعيينات DInput مختلفة أكثر منطقية للاستخدام عبر ألعاب متعددة. يمكن العثور عليها في مجلد dolphin
في HayBox repo. تتم تسمية ملفات التعريف للإشارة إلى الواجهة الخلفية للاتصالات ونظام التشغيل المخصص لها:
لتثبيت الملف الشخصي:
dolphin
داخل HayBox إلى المجلد <YourDolphinInstallation>UserConfigProfilesGCPad
(قم بإنشائه إذا لم يكن موجودًا)%appdata%Slippi LaunchernetplayUserConfigProfilesGCPad
~/.config/SlippiOnline/Config/Profiles/GCPad/
Cmd + Shift + G
وأدخل المسار /Users/<USER>/Library/Application Support/Slippi Launcher/netplay/Slippi Dolphin.app/Contents/Resources/Sys/Config/Profiles/GCPad
%userprofile%DocumentsDolphin EmulatorConfigProfilesGCPad
~/.config/dolphin-emu/Profiles/GCPad/
* يدعم نظام التشغيل macOS DInput فقط (وليس بشكل جيد جدًا)، لذا إذا كنت تستخدم وحدة تحكم تعتمد على Pico/RP2040، فسيتعين عليك فرض وضع DInput بالضغط على Z على المكون الإضافي، وحتى ذلك الحين قد لا يعمل. لا يمكنني حقًا فعل أي شيء بشأن دعم وحدة التحكم الضعيف من Apple (والذي يبدو أنه ينقطع مع كل تحديث آخر) وأنا لا أملك أي أجهزة Apple، لذلك سيعتبر هذا أيضًا استخدامًا غير مدعوم لـ HayBox.
يتم تحديد الواجهة الخلفية للاتصال (مثل DInput أو GameCube أو N64) جزئيًا من خلال الاكتشاف التلقائي ويعتمد جزئيًا على الأزرار الموجودة في البرنامج الإضافي. تتم معالجة ذلك في config/<environment>/config.cpp
في الدالة setup()
. المنطق بسيط إلى حد ما، وحتى إذا لم تكن لديك خبرة في البرمجة، فلن يكون من الصعب جدًا رؤية ما يحدث وتغيير الأشياء إذا كنت ترغب في ذلك.
مجلدات التكوين المقابلة لبيئات Arduino هي:
config/arduino_nativeusb/
لـ Arduino مع دعم USB الأصلي (مثل Leonardo وMicro)config/arduino/
لـ Arduino بدون دعم USB الأصلي (مثل Uno وNano وMega 2560) بالنسبة لتكوينات جهاز Arduino، قد تلاحظ أنه تم تمرير الرقم 125 إلى GamecubeBackend()
. يتيح لك هذا تغيير معدل الاستقصاء، على سبيل المثال، إذا كان جهاز DIY الخاص بك لا يدعم USB الأصلي وتريد استخدامه مع محول وحدة تحكم GameCube مع زيادة سرعة التشغيل. في هذا المثال، يمكنك تمرير 1000 للمزامنة حتى معدل الاستقصاء 1000 هرتز، أو 0 لتعطيل إصلاح التأخر هذا تمامًا. يمكن تمرير معدل الاستقصاء إلى مُنشئ N64Backend بنفس الطريقة.
قد تلاحظ أن معدل الاستقصاء 1000 هرتز يعمل على وحدة التحكم أيضًا. كن على علم أنه أثناء نجاح ذلك، فإنه سيؤدي إلى مزيد من تأخر الإدخال. الهدف من تحديد معدل الاقتراع هنا هو أن الواجهة الخلفية لـ GameCube يمكن أن تتأخر حتى قبل الاقتراع التالي مباشرة قبل قراءة المدخلات، بحيث تكون المدخلات جديدة وليست قديمة.
بالنسبة إلى Pico/RP2040، ليس من الضروري اجتياز معدل استقصاء وحدة التحكم، لأن Pico لديه قوة معالجة كافية لقراءة/معالجة المدخلات بعد تلقي استقصاء وحدة التحكم، لذلك ليست هناك حاجة للتنبؤ بموعد وصول الاستقصاء وإعداد الأشياء مقدماً.
لتكوين عمليات تعليق الزر لأوضاع الإدخال (أوضاع وحدة التحكم/لوحة المفاتيح)، قم بتحرير وظيفة select_mode()
في config/mode_selection.hpp
. كل عبارة if
عبارة عن مجموعة أزرار لتحديد وضع الإدخال.
تدعم معظم أوضاع الإدخال المرور في وضع تنظيف SOCD، على سبيل المثال socd::2IP_NO_REAC
. انظر هنا للتعرف على الأوضاع الأخرى المتاحة.
لإنشاء أوضاع إدخال جديدة، من المفيد أن تعرف بعض لغة C++، أو على الأقل لديك بعض الخبرة في البرمجة. ومع ذلك، يجب أن تكون قادرًا على تدبر الأمر حتى بدون خبرة سابقة إذا قمت فقط ببناء وضعك الجديد على الأوضاع الحالية والإشارة إليها كأمثلة.
هناك نوعان من أوضاع الإدخال: وضع التحكم ووضع لوحة المفاتيح
تعد أوضاع لوحة المفاتيح أبسط قليلاً، لذا فلنبدأ بها.
يعمل وضع لوحة المفاتيح بمثابة لوحة مفاتيح قياسية ويجب أن يعمل مع أي جهاز يدعم لوحات المفاتيح.
أنت حر في استخدام أي حيل منطقية وبرمجية تريدها في وظيفة UpdateKeys()
لتحديد المخرجات بناءً على حالة الإدخال. يمكنك إنشاء طبقات إدخال (مثل طبقة D-Pad في وضع Melee الذي يتم تنشيطه عند الضغط على Mod X وMod Y)، أو أنواع أخرى من المدخلات الشرطية.
يمكن العثور على قائمة رموز المفاتيح المتاحة هنا.
تذكر أنه لا يمكن تنشيط أوضاع لوحة المفاتيح إلا عند استخدام الواجهة الخلفية لاتصال DInput ( وليس XInput).
يأخذ وضع التحكم حالة إدخال الزر الرقمي ويحولها إلى حالة إخراج تتوافق مع لوحة الألعاب القياسية. سيعمل أي وضع تحكم مع أي وضع CommunicationBackend. يقوم CommunicationBackend ببساطة بقراءة المدخلات من مصدر إدخال واحد أو أكثر، ويستخدم وضع التحكم الحالي لتحديث المخرجات بناءً على تلك المدخلات، ويتعامل مع إرسال المخرجات إلى وحدة التحكم أو الكمبيوتر الشخصي.
لإنشاء ControllerMode، تحتاج فقط إلى تنفيذ الوظائف UpdateDigitalOutputs()
و UpdateAnalogOutputs()
.
UpdateDigitalOutputs()
يشبه إلى حد كبير وظيفة UpdateKeys()
في أوضاع لوحة المفاتيح، مع اختلاف أنه بدلاً من استدعاء وظيفة Press()
لإرسال المدخلات على الفور، نقوم ببساطة بتعيين حالة الإخراج لهذا التكرار. كما يشير الاسم، سنتعامل فقط مع المخرجات الرقمية في هذه الوظيفة.
UpdateAnalogOutputs()
أكثر تعقيدًا بعض الشيء. أولاً، عليه استدعاء UpdateDirections()
قبل القيام بأي شيء آخر. تأخذ هذه الوظيفة قيمًا تشير إلى ما إذا كانت العصا اليسرى واليمنى تشير إلى اليسار/اليمين/لأعلى/لأسفل. يمكنك أيضًا تمرير القيم التناظرية الدنيا والمحايدة (المركزية) والحد الأقصى، بحيث يمكنك تكوينها على أساس كل وضع. يتم استخدام كل هذه المعلومات لتعيين القيم التناظرية للعصا تلقائيًا بناءً على المدخلات التي قمت بتمريرها. وهذا هو كل ما عليك فعله إلا إذا كنت ترغب في تنفيذ المعدلات.
يقوم UpdateDirections()
أيضًا بملء directions
المتغيرة بقيم تشير إلى اتجاه العصا الحالي، والذي يمكن أن يكون 1 أو 0 أو -1 للمحورين X وY لكلا العصاتين. تسهل هذه القيم كتابة منطق التعديل.
بعد استدعاء UpdateDirections()
، قم بإضافة أي منطق معالجة للمعدل تريده. تذكر أن UpdateDirections()
قام بالفعل بتعيين قيم العصا التناظرية الافتراضية، لذلك عند التعامل مع المعدلات، تحتاج فقط إلى تعيين قيم المحاور التي يتم تعديلها فعليًا يدويًا. بخلاف ذلك، لا يمكنني تعليم كيفية كتابة منطق التعديل الخاص بك، لذا انظر فقط إلى الأمثلة وجربها.
وأخيرًا، قم بتعيين أي قيم تشغيل تمثيلية تحتاجها.
ملاحظة: يمكن أيضًا التعامل مع مخرجات المشغل التناظرية في UpdateDigitalOutputs()
، لكنني أعتقد أنه عادةً ما يبدو الأمر أكثر نظافة للاحتفاظ بها جنبًا إلى جنب مع المخرجات التناظرية الأخرى.
لاحظ أيضًا: لا داعي للقلق بشأن إعادة تعيين حالة الإخراج أو مسح أي شيء منها. ويتم ذلك تلقائيًا في بداية كل تكرار.
في مُنشئ كل وضع (لأوضاع وحدة التحكم وأوضاع لوحة المفاتيح)، يمكنك تكوين أزواج من مدخلات الاتجاه المتعارضة لتطبيق تنظيف SOCD عليها.
على سبيل المثال، في src/modes/Melee20Button.cpp
:
_socd_pair_count = 4;
_socd_pairs = new socd::SocdPair[_socd_pair_count]{
socd::SocdPair{&InputState::left, &InputState::right, socd_type},
socd::SocdPair{ &InputState::down, &InputState::up, socd_type},
socd::SocdPair{ &InputState::c_left, &InputState::c_right, socd_type},
socd::SocdPair{ &InputState::c_down, &InputState::c_up, socd_type},
};
يؤدي هذا إلى إعداد اليسار/اليمين، والأسفل/لأعلى، وC-Left/C-Right، وC-Down/C-Up كأزواج من الاتجاهات الأساسية المتعارضة التي سيتم تطبيق تنظيف SOCD لها. يتم تنظيف SOCD تلقائيًا قبل UpdateDigitalOutputs()
و UpdateAnalogOutputs()
، ولا داعي للقلق بشأن ذلك أكثر من ذلك.
لكل SocdPair
يمكنك تمرير SocdType
من اختيارك. افتراضيًا، بالنسبة لمعظم الأوضاع، يتم تمرير هذا كمعلمة منشئة واحدة، ولكن من الممكن تمرير معلمات متعددة، أو ببساطة استخدام قيمة مضمنة. يتم تمثيل كلا الأسلوبين في src/modes/FgcMode.cpp
.
SocdType | وصف |
---|---|
SOCD_NEUTRAL | يسار + يمين = محايد - الافتراضي في حالة عدم تحديد SocdType في SocdPair |
SOCD_2IP | أولوية الإدخال الثانية - يسار -> يسار + يمين = يمين، والعكس صحيح. تحرير الاتجاه الثاني يعطي الاتجاه الأصلي |
SOCD_2IP_NO_REAC | أولوية الإدخال الثانية دون إعادة التنشيط - كما هو مذكور أعلاه، باستثناء أن تحرير الاتجاه الثاني يؤدي إلى الحياد. يجب إعادة تنشيط الاتجاه الأصلي فعليًا. |
SOCD_DIR1_PRIORITY | دائمًا ما يكون للزر الأول في SocdPair الأولوية على الزر الثاني |
SOCD_DIR2_PRIORITY | الزر الثاني في SocdPair دائمًا ما يكون له الأولوية على الأول |
SOCD_NONE | لا يوجد قرار SOCD - اللعبة تقرر |
لاحظ أنه ليس عليك تنفيذ دالة HandleSocd()
كما هو الحال في وضعي Melee20Button وMelee18Button. يتم تجاوزه فقط في هذه الأوضاع حتى نتمكن من التحقق مما إذا كان كل من اليسار واليمين مثبتين قبل تنظيف SOCD، لأنه عندما يتم تثبيتهما (بدون تثبيت الاتجاه الرأسي) نحتاج إلى تجاوز جميع المعدلات.
إذا كانت وحدة التحكم الخاصة بك لا تحتوي على أزرار درع الضوء، فقد ترغب في استخدام Mod X لدرع الضوء ووضع إمالة الدرع على R بدلاً من ذلك. يمكنك القيام بذلك عن طريق استخدام وضع Melee18Button بدلاً من Melee20Button.
يوفر الوضعان Melee20Button وMelee18Button اختيار الإحداثيات التي سيتم استخدامها عند الضغط لأسفل + لليمين. افتراضيًا، يتيح لك الضغط باستمرار على زر + الرجوع إمكانية إلغاء الضربات تلقائيًا، وهو أسلوب مفيد لبعض الشخصيات.
أسلوب شائع آخر يستخدم القطر لأسفل + لليمين هو ما يسمى بتحديد خيار الانحناء/المشي. تتضمن هذه التقنية الضغط باستمرار + للأمام بزاوية معينة أثناء الانحناء، بحيث بعد إلغاء الهجوم، ستبدأ تلقائيًا في المشي نحو خصمك بدلاً من العودة إلى الانحناء. يمكن أن يكون هذا مفيدًا جدًا لمطاردة التكنولوجيا، لكن الإحداثيات المستخدمة في هذه التقنية لا تسمح لك بإلغاء الضربات تلقائيًا.
يمكن تكوين هذا كما هو موضح في config/mode_selection.hpp
عن طريق ضبط خيار crouch_walk_os
على true:
new Melee20Button(socd::SOCD_2IP_NO_REAC, { .crouch_walk_os = false })
سيتعين عليك أيضًا تغيير هذا في config/<environment>/config.cpp
حتى يتم تطبيقه على المكون الإضافي، حيث يتحكم mode_selection.hpp
فقط في ما يحدث عند تبديل الوضع.
يحتوي وضع ProjectM على بعض الخيارات الإضافية لتكوين سلوكيات معينة. كما رأينا في config/mode_selection.hpp
:
new ProjectM(
socd::SOCD_2IP_NO_REAC,
{ .true_z_press = false, .ledgedash_max_jump_traj = true }
)
أولاً، يتيح لك خيار ledgedash_max_jump_traj
تمكين أو تعطيل السلوك المستعار من وضع المشاجرة حيث يؤدي الضغط على اليسار واليمين (بدون اتجاهات رأسية) إلى إعطاء قيمة 1.0 بغض النظر عن الاحتفاظ بالمعدلات.
إذا قمت بتغيير وضع SOCD إلى 2IP (مع إعادة التنشيط)، فيجب عليك أيضًا تغيير هذا الخيار إلى false إذا كنت تريد تجربة لعب سلسة.
ثانيًا، خيار true_z_press
موجود لأن Project M/Project+ لا يتعامل مع ضغطات Z بنفس الطريقة التي يتعامل بها Melee. يفسر Melee الضغط على Z على أنه lightshield + A، وبالتالي يمكن استخدامه لإلغاء L دون إبعادك عن التقنيات. في PM/P+، سيؤدي الضغط على Z إلى تشغيل تقنية وبالتالي يتسبب في إغلاق التكنولوجيا غير المرغوب فيه إذا تم استخدامه لإلغاء L. افتراضيًا في HayBox، يتم تعيين وضع ProjectM لاستخدام ماكرو من lightshield + A للحفاظ على السلوك المتوقع من Melee. ومع ذلك، لا يمكّنك هذا الماكرو من استخدام هجمات الربط/الكلاّب أو الاستيلاء على العناصر. للتغلب على هذه المشكلة، يمكنك الضغط على Mod X + Z لإرسال إدخال Z حقيقي.
إذا كان هذا يزعجك، وتريد فقط إرسال إدخال Z حقيقي بشكل افتراضي عند الضغط على Z، فيمكنك ضبط خيار true_z_press
على true.
يدعم HayBox العديد من مصادر الإدخال التي يمكن القراءة منها لتحديث حالة الإدخال:
GpioButtonInput
- الأكثر استخدامًا لقراءة المفاتيح/الأزرار المتصلة مباشرةً بمنافذ GPIO. يتم تعريف تعيينات الإدخال بواسطة مجموعة من GpioButtonMapping
كما يمكن رؤيته في جميع التكوينات الموجودة تقريبًا.SwitchMatrixInput
- مشابه لما ورد أعلاه، ولكنه يقوم بمسح مصفوفة تبديل نمط لوحة المفاتيح بدلاً من المفاتيح الفردية. تم تضمين التكوين الخاص بـ Crane's Model C<=53 في config/c53/config.cpp
والذي يعد بمثابة مثال لكيفية تحديد مصدر إدخال مصفوفة التبديل واستخدامه.NunchukInput
- يقرأ المدخلات من جهاز Wii Nunchuk باستخدام i2c. يمكن استخدام هذا لوحدات التحكم في الإدخال المختلط (على سبيل المثال، تستخدم اليد اليسرى الننشوك للحركة، وتستخدم اليد اليمنى الأزرار لعناصر التحكم الأخرى)GamecubeControllerInput
- يشبه ما ورد أعلاه، ولكنه يقرأ من وحدة تحكم GameCube. يمكن إنشاء مثيل له بشكل مشابه لـ GamecubeBackend. يتم تنفيذه حاليًا فقط لـ Pico، ويجب عليك إما تشغيله على مثيل pio مختلف (pio0 أو pio1) عن أي مثيل لـ GamecubeBackend، أو التأكد من أن كلاهما يستخدم نفس إزاحة ذاكرة تعليمات PIO. يحتوي كل مصدر إدخال على قيمة "سرعة المسح" التي تشير تقريبًا إلى الوقت الذي يستغرقه قراءة المدخلات. تتم دائمًا قراءة مصادر الإدخال السريع في آخر لحظة ممكنة (على الأقل في Pico)، مما يؤدي إلى زمن وصول منخفض جدًا. على العكس من ذلك، عادةً ما تتم قراءة مصادر الإدخال البطيئة قبل فترة طويلة من الحاجة إليها، حيث إنها بطيئة جدًا بحيث لا يمكن قراءتها استجابةً للاستقصاء. ولهذا السبب، من الأفضل أن تتم قراءة تلك المدخلات باستمرار على مركز منفصل. هذا غير ممكن على وحدات AVR MCU لأنها كلها ذات نواة واحدة، ولكنه ممكن (وسهل) على Pico/RP2040. يوضح الجزء السفلي من تكوين Pico config/pico/config.cpp
الافتراضي ذلك باستخدام core1 لقراءة مدخلات Nunchuk بينما يتعامل core0 مع كل شيء آخر. راجع القسم التالي لمزيد من المعلومات حول استخدام core1.
في وظيفة setup()
لكل تكوين، نقوم ببناء مصفوفة من مصادر الإدخال، ثم نقوم بتمريرها إلى الواجهة الخلفية للاتصال. تقرر الواجهة الخلفية للاتصالات متى تقرأ مصادر الإدخال، لأن المدخلات تحتاج إلى القراءة في نقاط زمنية مختلفة للواجهات الخلفية المختلفة. نقوم أيضًا ببناء مجموعة من الواجهات الخلفية للاتصالات، مما يسمح باستخدام أكثر من واجهة خلفية واحدة في وقت واحد. على سبيل المثال، في معظم التكوينات، يتم استخدام الواجهة الخلفية لعارض الإدخال B0XX كواجهة خلفية ثانوية عند استخدام الواجهة الخلفية DInput. في كل تكرار، تخبر الحلقة الرئيسية كلًا من الواجهات الخلفية بإرسال التقارير الخاصة به. في المستقبل، قد يكون هناك المزيد من الواجهات الخلفية لأشياء مثل كتابة المعلومات على شاشة OLED.
في كل تكوين، توجد الوظيفتان setup()
و loop()
، حيث يتم تشغيل setup()
أولاً، ثم يتم تشغيل loop()
بشكل متكرر حتى يتم إيقاف تشغيل الجهاز.
في Pico/RP2040، يتم تنفيذ وظائف setup()
و loop()
على core0، ويمكنك إضافة الوظائف setup1()
و loop1()
لتشغيل المهام على core1.
على سبيل المثال، لقراءة مدخلات وحدة تحكم GameCube على core1:
GamecubeControllerInput *gcc = nullptr;
void setup1() {
while (backends == nullptr) {
tight_loop_contents();
}
gcc = new GamecubeControllerInput(gcc_pin, 2500, pio1);
}
void loop1() {
if (backends != nullptr) {
gcc->UpdateInputs(backends[0]->GetInputs());
}
}
تتأكد حلقة while
من انتظارنا حتى ينتهي setup()
على core0 من إعداد الواجهات الخلفية للاتصالات. نقوم بعد ذلك بإنشاء مصدر إدخال لوحدة تحكم GameCube بمعدل اقتراع يبلغ 2500 هرتز. نقوم أيضًا بتشغيله على pio1
كطريقة سهلة لتجنب التدخل في أي واجهات خلفية لـ GameCube/N64، والتي تستخدم pio0
ما لم يُنص على خلاف ذلك. في loop1()
نفترض أن الواجهة الخلفية الأساسية هي العنصر الأول في مصفوفة backends
(التي تم تكوينها في نفس الملف على أي حال، لذلك نحن لا نفترض حقًا أي شيء لا نعرفه) ونفحص وحدة تحكم GameCube مباشرة المدخلات في حالة الإدخال الخلفية.
كمثال افتراضي أكثر جنونًا، يمكن للمرء تشغيل جميع عناصر التحكم لخزانة أركيد لشخصين باستخدام Pico واحد عن طريق إنشاء مصدرين لإدخال مصفوفة التبديل باستخدام 10 دبابيس لكل منهما، وواجهتين خلفيتين لـ GameCube، كلاهما على نوى منفصلة. الاحتمالات لا حصر لها.
إذا كنت تستخدم محولًا رسميًا مع وحدة تحكم تعتمد على Arduino، فمن المحتمل أن تضطر إلى الضغط على A على المكون الإضافي الذي يعطل تحسين زمن انتقال الاستقصاء عن طريق تمرير معدل استقصاء قدره 0 إلى مُنشئ GamecubeBackend.
إذا كنت تستخدم وحدة تحكم تعتمد على Arduino بدون دائرة تعزيز، فستحتاج إلى طاقة 5 فولت، لذا بالنسبة لمحول Mayflash، فأنت بحاجة إلى توصيل كابلي USB، وعلى وحدة التحكم، يجب أن يكون خط الدمدمة سليمًا. يعمل Pico أصلاً بقوة 3.3 فولت، لذا فهذه ليست مشكلة.
أرحب بالمساهمات وإذا قمت بإنشاء وضع إدخال تريد مشاركته، فلا تتردد في تقديم طلب سحب. الرجاء تثبيت المكوّن الإضافي clang-format لـ VS Code واستخدامه لتنسيق أي رمز تريد إضافته.
نحن نستخدم SemVer للإصدار. للتعرف على الإصدارات المتوفرة، راجع العلامات الموجودة في هذا المستودع.
انظر أيضًا قائمة المساهمين الذين شاركوا في هذا المشروع.
هذا المشروع مرخص بموجب GNU GPL الإصدار 3 - راجع ملف الترخيص للحصول على التفاصيل