Cemu Patches
.asm Format
PowerPC PPC32
طريقة إنشاء باتشات Cemu بصيغة .asm وتحويل patches.txt
دليل للمطورين يشرح بنية باتشات Cemu الأصلية، وتحديد ملفات RPX وRPL
عبر CRC، وكتابة التعليمات داخل Codecave، واستخدام Labels وConstants
وData Directives، ثم تحويل باتشات Cemuhook القديمة إلى الصيغة الحديثة.
نافذة Graphic Packs التي يستخدمها المستخدم لتنزيل الحزم، البحث عنها،
وتفعيل الباتش المطلوب داخل Cemu.
وش هي Cemu Patches؟
بداية من Cemu 1.17.0 صار المحاكي يدعم تعديل Game Code مباشرة من
خلال Graphic Packs. قبل ذلك كانت عملية Assembly Patching تعتمد
على Cemuhook وملف patches.txt.
الصيغة القديمة
patches.txt
الخاصة بـCemuhook، وما زالت بعض الحزم القديمة تستخدمها.
صيغة Cemu الأصلية
patch_<anything>.asm
وهي الصيغة المشروحة في هذا الموضوع.
هذا موضوع تطوير باتشات، مو شرح تفعيل Graphic Packs للمستخدم العادي.
كتابة عنوان خاطئ أو CRC غير صحيح ممكن يمنع الباتش من العمل أو يكسر تنفيذ اللعبة.
مكان الملف وتسميته
عندما يطابق rules.txt اللعبة،
يفحص Cemu مجلد Graphic Pack بحثًا عن أي ملف يطابق النمط:
File pattern
ASM
patch_<anything>.asm
صحيح
patch_main.asm
صحيح
patch_fps.asm
غير مطابق
my_patch.asm
تقدر تحط أكثر من ملف Patch داخل الحزمة، وتقدر تحط أكثر من Patch Group
داخل نفس الملف.
وش يشوف المستخدم النهائي داخل Cemu؟
Cemu Wiki + Community Graphic Packs
المطور يكتب rules.txt وملفات
patch_*.asm، لكن المستخدم النهائي
ما يحتاج يفتح الكود. كل اللي يشوفه هو اسم الحزمة ومسارها ووصفها
والخيارات الموجودة في نافذة Graphic Packs.
1
افتح Options → Graphic packs.
2
للحزم الرسمية اضغط
Download latest community graphic packs.
3
للحزمة اليدوية أو التجريبية ضع المجلد داخل
graphicPacks، وليس
downloadedGraphicPacks.
4
فعّل المربع بجانب الحزمة، ثم شغل اللعبة أو أعد تشغيل Cemu.
5
ظهور اسم الحزمة باللون الأخضر أثناء تشغيل اللعبة يعني أنها Active.
لو عدلت حزمة موجودة داخل
downloadedGraphicPacks،
انسخها أولًا إلى مجلد
graphicPacks
حتى ما يستبدلها التحديث التلقائي للحزم.
مثال واضح على ظهور الحزمة وخياراتها للمستخدم النهائي؛
الاسم والمسار والوصف والـPresets كلها تأتي من ملفات Graphic Pack.
ملاحظات مهمة من تطوير Cemu
Release Notes + Developer Tracker
Cemu 1.17.0
أضاف Automatic Codecave Sizing، وWrite Cursor، وLabels وVariables،
وإمكانية تقسيم الباتش إلى عدة ملفات ومجموعات.
Cemu 1.20.2
صار Cemu نفسه يتولى تطبيق باتشات Cemuhook حتى لو كانت الإضافة مثبتة،
مع تنبيه أن بعض Syntax وSemantics تختلف عند التحويل.
Cemu 1.22.2
صار Disassembly View يعرض أسماء Functions وLabels المعرفة داخل
Graphic Pack، ويعرض نوع البيانات مثل
.float.
Community Repository
الأمثلة الحقيقية موجودة في مستودع
cemu_graphic_packs،
وخصوصًا مجلد Mods الذي يحتوي باتشات FPS والغش وتعديلات اللعب.
أفضل طريقة لتعلم الصيغة بعد فهم الأساسيات هي فتح باتش فعلي من المستودع،
ومقارنة rules.txt مع
patch_*.asm وسجل تشغيل اللعبة.
Patch Groups وmoduleMatches
كل مجموعة باتش تبدأ باسم داخل أقواس مربعة، ثم
moduleMatches الذي يحتوي CRC واحدًا
أو أكثر لتحديد ملفات RPX أو RPL المستهدفة.
patch_main.asm
Patch group
[group_name]
moduleMatches = 0x11223344, 0xCFF30E4E
اسم المجموعة
يستخدم أساسًا في Debugging. رسائل الأخطاء تشير إلى اسم المجموعة
ورقم السطر.
moduleMatches
قائمة CRCs تطابق Modules مختلفة أو إصدارات مختلفة من نفس اللعبة.
تقدر تحصل CRC الخاص بكل Module من ملف
log.txt بعد تشغيل اللعبة في Cemu.
Labels وConstants تقدر تُستخدم بين مجموعات مختلفة داخل نفس Graphic Pack
فقط عندما تكون المجموعات مفعلة لنفس Module أو CRC. ما تقدر المجموعة
تصل إلى تعريفات خارج الحزمة الحالية.
تعديل تعليمات منفردة
أبسط استخدام هو استبدال تعليمة PowerPC داخل عنوان محدد. اكتب العنوان،
ثم علامة =، ثم التعليمة الجديدة.
patch_main.asm
Per-line addresses
0x0200E3A4 = li r3, 0
0x0200E400 = nop
li r3, 0
يستبدل التعليمة الموجودة في العنوان ويضع القيمة 0 في r3.
nop
يعطل التعليمة الأصلية في العنوان المحدد.
Write Cursor واستخدام .origin
لما تكتب عدة تعليمات متتالية، ما تحتاج تحسب عنوان كل سطر يدويًا.
استخدم .origin لتحديد مؤشر الكتابة،
وCemu يزيده تلقائيًا بعد كل تعليمة أو Data Directive.
patch_main.asm
Text section
.origin = 0x0200E3A4
bla someLabel
blr
السطر الأول
يكتب في 0x0200E3A4.
السطر الثاني
يكتب تلقائيًا في 0x0200E3A8.
العنوان المكتوب مباشرة بصيغة
address = instruction
له أولوية أعلى من .origin، ولا يزيد
مؤشر الكتابة الحالي.
كتابة Function داخل Codecave
الكلمة codecave تنقل مؤشر الكتابة
إلى مساحة غير مستخدمة مخصصة للكود الإضافي.
patch_main.asm
Codecave function
.origin = codecave
someLabel:
li r3, 0
blr
1
يبدأ Cemu الكتابة داخل منطقة Codecave.
2
ينشئ Label باسم someLabel
في الموضع الحالي.
3
يكتب التعليمات بالتتابع ويحدث العناوين تلقائيًا.
Labels والعناوين الخارجية
عرّف Label بكتابة الاسم متبوعًا بنقطتين. Cemu يعالج Relocation
تلقائيًا عشان يظل الاسم يشير إلى مكان الكود الصحيح في الذاكرة.
patch_main.asm
Local label
OurLabel:
وتقدر تربط Label بعنوان موجود داخل Text أو Data Section في اللعبة:
patch_main.asm
External address label
0x0202034C = ExternalLabel:
هذا مفيد عند استدعاء Function موجودة داخل اللعبة أو الوصول إلى
Variable خارج كودك الإضافي.
Constants وExpressions
صيغة Cemu تدعم Constants وعمليات حسابية وقت التجميع، وتقدر تستخدم
Preset Variables القادمة من Graphic Pack.
patch_main.asm
Constant
myConst = $presetVariable + 5
li r3, myConst
أو تكتب التعبير مباشرة داخل التعليمة:
patch_main.asm
Inline expression
li r3, $presetVariable + 5
Constant ما يحجز مساحة في الذاكرة، لذلك ما يصلح كهدف لتعليمات
Load أو Store. لما تحتاج Variable قابلًا للعنونة استخدم Data Directive
مع Label.
Data Directives المدعومة
.byteعدد 8-bit
.shortعدد 16-bit
.intعدد 32-bit
.ptrAlias لـ.int
.floatFloat 32-bit
.doubleFloat 64-bit
.stringنص بطول متغير
patch_main.asm
Float variable
SomeFloat:
.float 123.45
lis r12, SomeFloat@ha
lfs f0, SomeFloat@l(r12)
Label SomeFloat يشير إلى مكان القيمة
داخل الذاكرة، لذلك تقدر تستخدمه مع تعليمات Load وStore.
الفرق الخطير عند التحويل من Cemuhook
الصيغتان تقبلان كتابة
name = value،
لكن معنى السطر مختلف.
Cemuhook
name = 0x12345
يتعامل معها كPointer إلى العنوان ويطبق Relocation.
Cemu .asm
نفس السطر ينشئ Constant قيمته
0x12345
بدون Relocation.
للحصول على نفس سلوك Cemuhook اكتب:
name = reloc(0x12345)
أو:
0x12345 = name:
مثال كامل: الصيغة القديمة مقابل صيغة Cemu
Cemuhook — patches.txt
[PatchName]
moduleMatches = 0x12345678
# code Cave
codeCaveSize = 0x24
# preset variable
_ourVariable = 0x0000000
0x0000000 = .int $gfxPackPresetVariable
# function in code cave
_codeCaveFunction = 0x0000004
0x0000004 = lis r11, _ourVariable@ha
0x0000008 = lwz r11, _ourVariable@l(r11)
0x000000C = cmpwi r11, 1
0x0000010 = bne .+0x0C
0x0000014 = li r3, 0
0x0000018 = blr
0x000001C = addi r3, r3, 1
0x0000020 = blr
# redirect game code
0x21EFAA8 = bla _codeCaveFunction
Cemu — patch_main.asm
[PatchName]
moduleMatches = 0x12345678
.origin = codecave
# preset variable
_ourVariable:
.int $gfxPackPresetVariable
# function in code cave
_codeCaveFunction:
lis r11, _ourVariable@ha
lwz r11, _ourVariable@l(r11)
cmpwi r11, 1
bne label_skip
li r3, 0
blr
label_skip:
addi r3, r3, 1
blr
# redirect game code
0x21EFAA8 = bla _codeCaveFunction
صيغة Cemu أوضح لأن Labels تستبدل الحسابات اليدوية لعناوين Codecave،
و.origin = codecave يدير مؤشر الكتابة
بدل تحديد Offset لكل سطر.
ترتيب إنشاء باتش جديد
1
أنشئ Graphic Pack صحيحًا يحتوي
rules.txt.
2
شغل اللعبة واستخرج CRC للـRPX أو RPL من
log.txt.
3
أنشئ ملفًا باسم يبدأ بـ
patch_
وينتهي بـ.asm.
4
أضف Patch Group واكتب
moduleMatches.
5
ضع الكود الإضافي في Codecave، ثم اربط Game Code به باستخدام
Branch مناسب مثل bla.
6
فعّل Graphic Pack، شغل اللعبة، وراجع
log.txt
لأي Parse أو Assembly Error.
تأكد أن الباتش اشتغل من log.txt
Cemu Bug Tracker — سجل حقيقي
سجل Cemu يعطيك ثلاث معلومات أساسية: اسم الـModule، والـChecksum،
واسم Patch Group الذي تم تطبيقه. المثال التالي مأخوذ من تقرير مطورين
حقيقي خاص بباتش Mario Kart 8:
log.txt
Runtime verification
Loaded module 'turbo' with checksum 0xd09700ce
Applying patch group 'MK8FullDrawVer4_1'
Activate graphic pack: Mario Kart 8/Mods/60FPS in splitscreen
Applying patch group 'MK8AspectVer4_1' (Codecave: 01800000-01800018)
Loaded module + checksum
هذه القيمة هي اللي تقارنها مع
moduleMatches.
Applying patch group
ظهورها يعني أن CRC طابق وأن Cemu بدأ تطبيق المجموعة.
Codecave range
ظهور النطاق يؤكد أن Cemu حجز مساحة للكود الإضافي.
Activate graphic pack
يوضح اسم الحزمة والمسار والـPreset الذي اشتغل فعليًا.
ابحث داخل السجل عن:
Loaded module
checksum
Applying patch group
Codecave
إذا الحزمة ظهرت Active لكن ما ظهر
Applying patch group،
فالسبب الأقرب CRC غير مطابق، اسم ملف غير صحيح، أو Parse Error قبل التطبيق.
أخطاء شائعة تمنع الباتش من العمل
اسم الملف غير صحيح
لازم يطابق patch_<anything>.asm.
CRC غير مطابق
الباتش ما يتفعل إذا Module CRC مختلف عن
moduleMatches.
Relocation خاطئ
نقل تعريفات Cemuhook بصيغة
name = address
بدون reloc().
Branch خارج المدى
استخدم طريقة Branch مناسبة ومكان Codecave صحيح.
Preset Variable مفقود
تأكد أن الاسم معرف في
rules.txt.
تعارض Graphic Packs
حزمتان تعدلان العنوان نفسه ممكن تسببان كراش أو سلوكًا غير متوقع.
متى المشكلة من الباتش وليست من Cemu؟
في Bug Tracker الرسمي أُغلق تقرير كراش لأن العطل كان يظهر فقط مع
Graphic Pack، وتم توجيهه ليُصلح داخل الحزمة نفسها بدل تعديل Cemu Core.
1
عطل الحزمة وحدها وجرب نفس المكان داخل اللعبة.
2
إذا اختفت المشكلة، أعد تفعيل الحزمة وحدد أي Patch Group يسببها.
3
أرفق log.txt بعد حدوث المشكلة مباشرة.
4
اكتب Cemu Version، إصدار اللعبة، Region، Module Checksum،
واسم الحزمة والـPreset.
5
افتح التقرير في Issues الخاصة بمستودع Community Graphic Packs
عندما تكون المشكلة مرتبطة بالحزمة فقط.
المشاكل اللي تستمر بعد تعطيل جميع Graphic Packs تُفحص بعدها كمشكلة
في Cemu أو اللعبة أو التعريفات، مو كخطأ باتش.
0 تعليقات