الباب السابع – المؤشر

أو كيف تضع نصا جديدا أطول من النص الأصلي


قبل البداية أنصحكم بالتمكن من درس الأعداد بالنظام الست عشري و الدروس السابقة نظرا أنها ضرورية جدا هنا.


للتذكير بسرعة:

الأعداد التي نستعملها نحن في الحياة اليومية هي الأعداد العشرية و تكتب بالأرقام 0 1 2 3 4 5 6 7 8 9.

الأرقام الست عشرية تتراوح بين 1 و 15 و تكتب هكذا 0 1 2 3 4 5 6 7 8 9 A B C D E F

عدد من نوع ABC123 بالست عشري كتب بهذه الأرقام،

يعادل عندنا في العشري 3 + 2×16 + 3×16×16 + 12×163 + 11×164 + 10×165

حيث في مثالنا هذا كما ذكرنا في الأعلى A هي 10، و B هي 11، و C هي 12.

و العدد 10 في الست عشري هو في الحقيقة عندنا في العشري 0 + 1×16 = 16


الأعداد الست عشرية نكتبها متبوعة بالرمز 0x إن كانت عنوانا في ملف الروم 0xABC123

و نكتبها متبوعة بالرمز $ إن كانت عنوانا في ذاكرة رام اللعبة أثناء عملها $ABC123


برامج الهيكس تستعمل النظام الست عشري لكتابة كل شيء،

من عناوين الروم (الموقع في الملف) إلى محتويات بيانات الروم نفسها.

البايت byte هو من وحدات البيانات و يكتب برقمي هيكس من 00 إلى FF. أي من 00 إلى 255 بالعشري.

البيت bit هو يكون إما 0 أو 1، و 8 بيتات مجتمعة مع بعضها تعادل بايت واحدا.



نحن رأينا في الدروس السابقة قاعدة مهمة جدا، و هي أن أي تغيير نقوم به هو تعويض.

بعبارة أخرى، لو ترجمنا نصا مثلا، يجب أن يكون النص الجديد بنفس طول النص القديم (أو أقصر منه).

و السبب هو أنه لو تهورنا و وضعنا نصا أطول بلا مبالاة، فإن هناك أمورا أخرى مخزنة مباشرة بعد النص سوف نتلفها.


إذن، لو كانت ترجمتنا أطول من النص الأصلي، مثلا ترجمة كلمة OK،

ماذا نفعل؟

عدا أساليب الإختزال (أي جعل النص يستهلك أقل مساحة، بحيل عديدة سنراها لاحقا)...

نستطيع أن نغير المؤشرات أو البوينتر Pointer.


ما هو المؤشر؟

المؤشر هو شيء في الروم يشير إلى مكان بداية النص. أو الصور. أو غيرها من الأمور.


سنأخذ مثالا بسيطا، لعبة الكابتن ماجد على النينتندو دي اس بنسختها الفرنسية.

هذه اللعبة لحسن الحظ تستخدم نظام ASCII في ملفاتها داخل الروم.

يوجد مشهد تظهر فيه هذه النصوص فقط عندما تضغط أنت الزر.



كيف تعرف اللعبة أين يبدأ نص كل مشهد من هذه المشاهد الثلاثة؟

لو نفتح الروم في برنامج Tinke سنجد أنها مقسمة إلى ملفات بشكل واضح بشكل يسهل علينا الفهم،

تحت المجلد f (الفرنسية) الذي به الصور و النصوص، إلى عدة ملفات تأتي أزواجا.

الملفان اللذان يهماننا هما EP0000.str و EP0000.siz


الأول و هو بإمتداد str (لعلها من كلمة string أي "سلسلة نص") فيه النصوص، و هو يظهر هكذا في برنامج الهيكس.

عدا رموز تحكم العودة للسطر (0A) لا يوجد أي شيء في ملف النص يقول للعبة أين يبدأ نص كل مشهد.

لكن نحن الآن قمنا بوضع إطارات حمراء فوق أول حرف من نص كل مشهد هنا.

يمكننا أن نقرأ العناوين على اليمين لو أردنا في برنامج الهيكس.

النصوص تبدأ في العناوين: 0000 ، و 00C5 ، و 0127 ، و (غير موجود في الصور أعلاه) 018D ...

و بالطبع يمكننا أن نواصل.



أما الملف الثاني، و هو بإمتداد siz، فهو أصغر بكثير...



لا يبدو أن خانة النصوص تهمنا، نظرا أنها كلها خرابيط.

لكن لو نظرنا لخانة الهيكس، سنجد قيما مألوفة جدا لدينا...

لو أخذنا عناوين بدايات النصوص التي عندنا سابقا.

0000 و 00C5 و 0127 و 018D

بعد كتابتها بحيث يكون كل بايت (رقمين هيكس) وحده.

00 00 و 00 C5 و 01 27 و 01 8D


هم هكذا كتبوا بالطرف الكبير Big Endian (أي أن البايت على اليسار في الأول، قيمته هي الأكبر).

نقلب البايتات ليصبحوا بالطرف الصغير Low Endian (أي أن البايت على اليسار في الأول، قيمته هي الأصغر).

السبب هو أن هذه اللعبة تعمل بالطرف الصغير، على فكرة هناك ألعاب تخزن المؤشرات بالطرف الكبير.

نتحصل على:

0000 و C500 و 2701 و 8D01 .

هذه هي المؤشرات.

و هي تدل على بداية النص.

هذا الملف هو جدول المؤشرات لهذا النص.


و على فكرة، نحن في الدروس السابقة تعاملنا مع ألعاب

تعرف أين تنتهي نصوصها فقط برمز تحكم موجود في آخر النص.

لكن في حالتنا هذه لا يوجد رمز تحكم في نهاية النص. فكيف تتوقف اللعبة عن قراءة النص؟

الجواب هو – هناك طريقة أخرى.

في ملف جدول المؤشرات لدينا، توجد أيضا قيم أطوال نصوص كل مشهد (بالأزرق).

مثلا أول نص طوله هو، بعد تحويل C500 من الطرف الصغير إلى الطرف الكبير،

هو 00C5 أي C5 بالست عشري (أو بالحساب العادي العشري، 12×16+5 = 197 رمزا).


لنقم بتجربة بسيطة للتثبت مما وجدناه:

لدينا هذا المشهد في النسخة الأصلية


نريد أن نجعل المشهد يبدأ من الجملة الثانية: Le tournoi…

مكان بداية الجملة الثانية في الملف EP0000.str الذي فيه النص، هو العنوان 0024



نذهب إلى ملف جدول المؤشرات EP0000.siz

و نغير المؤشر القديم الذي كان يشير إلى 0000، ليصبح يشير إلى 2400 (بعد التحويل للطرف الصغير)

و نجرب اللعبة، و النتيجة...



... كما كنا نريد بالنسبة لمؤشر نقطة بداية النص.

لكن ليس لنهاية النص. (هناك أجزاء من نص المشهد التالي تظهر)

قيمة الطول يجب إصلاحها.

قيمة الطول القديمة بالنظام ست عشري هي 00C5

نطرح منها إذن 0024 بالست عشري (يمكننا استخدام الآلة الحاسبة في الويندوز)

طبعا نطرح لأن لدينا حجما زائدا (في النهاية) نريد تقليصه.

النتيجة هي 00A1

نضعها إذن



و نجرب اللعبة، و النتيجة أفضل بكثير:




المؤشر الأصلي يشير إلى النص في مكانه الأصلي.

النص كان في حيز ضيق، محشورا بين عدة بيانات أخرى و لا يمكن تطويله أكثر.

لكن لو قمنا بتغيير المؤشر الأصلي، تحل هذه المشكلة.


نأخذ مثالا للعبة خيالية ما لا علاقة لها بالكابتن ماجد دي اس.

نفترض أن لدينا حوارات تبدأ في النسخة الأصلية من الروم في العناوين التالية

0000 ثم 0012 ثم 0020 ثم 0030

نقول أننا قررنا عمل ترجمة أطول لهذه الحوارات.


نبدأ بالحوار الأول.

الترجمة تتجاوز الحيز الأصلي (0012) و تصل إلى 0019.

نزيح كامل النص انطلاقا من الحوار الثاني كي يبدأ بعد 0019.

نضع ترجمة الحوار الأول التي تبدأ من 0000 إلى 0019.

نغير مؤشر بداية الحوار الثاني كي تصبح قيمته 0019 (أو لو كان بالطرف الأصغر 1900)

و نواصل نفس الشيء مع الحوار الثاني الذي لو كان أطول فنزيح الحوار الثالث للأمام...


هناك أدوات تحل هذه المسألة و تدعى أدوات إدخال النص Script Insertor

و لو قمت أنت بإستخراج النص (بأدوات استخراج نص) و إعداد جدول المؤشرات لها،

تقوم هي نيابة عنك بإزاحة النصوص الطويلة و مؤشراتها حسب ما يلزم.

على سبيل المثال: يوجد Atlas و Kruptar و أدوات أخرى.

سنخصص لها لاحقا مثالا صغيرا.


نستطيع أيضا توجيه المؤشر لمكان في نهاية الروم أو الملف (أو الكتلة، سنرى ما هي لاحقا)،

يكون ساحة فسيحة فارغة كلها أصفار 00 أو FF غير مستعملة،

يستطيع النص أن يطول فيها بشكل مريح...


لكن هيهات، ففي كثير من الأحيان، لن تخلو عملية حجز الساحة الفسيحة من العراقيل.

فسياسة الهروب للأمام هذه تتغافل عن أمرين مهمين للغاية تظهر فيهما محدودية فائدة المؤشر:


1 – المؤشر يغطي مجالا معينا محدودا

لو لاحظنا قبل قليل مع لعبة الكابتن ماجد دي اس،

فإن المؤشرات تكتب كل واحدة على شكل XX XX أي 2 بايت.

(هناك من يسميها أيضا مؤشرات 16 بيت 16-bit Pointers، لأن كل بايت هو 8 بيت)

أي أن قيمها القصوى تتراوح بين 0000 و FFFF بالهيكس. (أي 65535 بالعشري)

بعبارة أخرى، حتى لو كانت رومات الدي اس تستطيع أن تصل إلى 512 ميغابايت،

فإن المؤشر، و بالتالي النص، بالنسبة لملفات نصوص لعبة الكابتن ماجد دي اس،

محدود في جزء صغير جدا من مئات الميغابايتات تلك،

و لا يستطيع طول النص الإجمالي في كل ملف بالتالي أن يتعدى 65535 رمزا.


هذه المشكلة موجودة بشكل كبير في مؤشرات ألعاب أجهزة مثل النيس و السوبر نيس،

حيث أن بطاقة اللعبة مقسمة إلى "كتل" (banks)

و بداخلها مؤشرات 16 بيت لا تستطيع أن تشير (و تستخدم) إلا إلى بيانات في نفس الكتلة.

و لو كان النص قريبا جدا من نهاية كتلة مثلا... فهناك فرصة كبيرة أن يفسد عمل اللعبة.

حتى جهاز البلاي ستايشن فيه تقسيم مشابه إلى قطاعات قرص اللعبة.


في حالة جهاز مثل الجيم بوي أدفانس، المؤشر هو 32 بيت (4 بايت)،

و بالتالي يستطيع أن يشير لأي مكان في الروم كما يريد دون هذه القيود. لهذا، هو جهاز رائع.


و جهاز السوبر نيس فيه أيضا مؤشرات 24 بيت (3 بايت) تغطي كامل الروم،

تستعملها الألعاب للبرمجة الرئيسية كي تتوجه لمختلف الكتل و تتصرف فيها،

لكن في أمور مثل مؤشرات النصوص تعود لمؤشرات 16 بيت (2 بايت).

لذلك يقوم معدلو الألعاب كثيرا في عدة ترجمات بعمل تعديلات على البرمجة

لإجبار اللعبة على استخدام مؤشرات 24 بيت في جميع مجالات اللعبة التي يريدونها.


2 – مساحة الروم / الملف الفارغة قد تكون محدودة

تحدثنا عن مشكلة الكتل التي تجعل من الصعب علينا استخدام فراغ في كتلة غير كتلة النص مثلا.

ماذا لو كانت هذه المشكلة غير مطروحة و لدينا مؤشر يشير لكامل الروم،


لكن المشكل أن الروم لا يوجد فيها أي مساحة فارغة؟

مثلا، لدينا روم جيم بوي أدفانس ليس فيها أي مكان فارغ، و حجمها 8 ميغابايت.

في حالة رومات الجيم بوي أدفانس، من حسن حظنا أن عملية التوسيع تتطلب فقط توسيع الملف في برنامج هيكس.

(لكن الأمر ليس بهذه البساطة في أجهزة أخرى)

أي نضيف ببساطة في النهاية الحيز الإضافي.


في برنامج مثل Tinke أو Crystaltile2، يكفي اضافة أصفار إلى أن نحصل على الحجم المطلوب.

برنامج WindHex يقترح طريقة أخرى:

نذهب إلى Tools ثم Increase/Decrease ROM Size (تكبير أو تصغير حجم الروم).



تظهر لنا هذه النافذة.

أمام Size of ROM يظهر لدينا حجم الروم الأصلي.

و هو 8388608 بايت. (لأن الوحدة هي BYTES)

نستطيع أن نغير الوحدة في الأسفل. سنجد أن الروم هي 8 ميغابايت.


أمام New ROM Size، نضع الحجم الجديد للروم.

لو كان هذا الحجم الجديد أكبر، فسيضيف أصفارا لنهاية الروم.

بما أننا نتعامل مع الجيم بوي أدفانس، من المحبذ في حالتنا هذه أن نعمل بالمضاعفات.

الأحجام التي استعملتها النينتندو رسميا كانت 4، 8، 16 و 32 ميغابايت.

إذن، نضع واحدا منها في تلك الخانة و نضغط Done و هكذا يتم اضافة بيانات لآخر الروم.

(لا شيء يمنعك من وضع حجم آخر طالما 32 أو أقل، لكن قد تحصل مشاكل مع بعض المحاكيات)


(أما Add Header (إضافة ترويسة)، فهو يضيف بيانات لأول الروم

و بما أن هذا قد يفسد الروم على الأرجح (نظرا أن عناوين المؤشرات سوف تفسد)

فلن نستعمله هنا. هناك استخدامات أخرى لهذا لكن ليس في حالتنا.)



صار لدينا حيز فارغ جديد كبير في نهاية الروم يمكننا استخدامه كما نريد!


كما يمكننا أيضا استعمال أدوات لتوسيع الروم.

مثلا في حالة السوبر نيس، هناك أداة Lunar Expand.

و على ما يبدو ظهرت بعض الأدوات لبعض أنواع رومات النيس.


لكن هناك حدود على أي مدى نستطيع توسيع الروم.

في حالة الجيم بوي أدفانس، لا يمكن أن يكون حجم الروم أكبر من 32 ميغابايت بأي حال من الأحوال،

لأن الجهاز صمم على أساس كون تلك الذاكرة هي الحد الأقصى.

هناك حدود شبيهة على الحجم الأقصى لرومات السوبر نيس أيضا.

و توسيع رومات النيس أمر صعب جدا، مع أنه يظل ممكنا، و يتطلب معرفة بالأسمبلي، ذلك لأسباب أخرى.

كذلك، إيزو الجيم كيوب لا يمكن أن يتجاوز 1.4 جيغابايت في أي حال من الأحوال.


من فوائد تغيير المؤشر أيضا اصلاح مشكلة تكرار النص عند تعديله بالطرق العادية.

أحيانا عندما نضع النص المترجم، تظهر قطع متكررة منه في السطر الثاني.

السبب هو أن هناك مؤشر النص التالي يبدأ منها رغم أنها استعملت في النص السابق.



حسنا، عرفنا الآن ما هو المؤشر.

الحالة التي أتتنا قبل قليل و هي لعبة الكابتن ماجد للنينتندو دي اس كانت بسيطة جدا.

و السبب أن المبرمجين كانوا لطفاء و وضعوا لنا جدول المؤشرات في ملف منفصل، واضح، سهل التعديل.


و عرفنا أن المؤشر مع أنه حل لكثير من مشاكلنا، إلا أنه ليس تماما وصفة سحرية لجميع المشاكل،

بما أن هناك أشياء يعجز عنها، بحكم قصر نفوذه و عدة إعتبارات أخرى ذكرناها.


لكن هذه حالة وحيدة من عديد الحالات الأخرى، التي تتنوع و تتعدد بتنوع طرق تفكير العقل الياباني (أو غير الياباني).

من الأحرى بنا أن نتحدث عن بعض هذه الحالات الأخرى.


عندما لا يكون هناك مؤشر

بادئ ذي بدء، يجب أن نعلم أنه أحيانا، قد لا يكون هناك مؤشر أصلا.

بعبارة أخرى، في بحر ظلمات سطور البرمجة (التي تظهر في الروم كبايتات هيكس غير مفهومة)،

قد تجد نصوصا مبعثرة هنا و هناك.

يقال لها نصوص مثبتة في البرمجة (hardcoded).

هذه من بين أسوء جرائم المبرمجين على فكرة.


ما باليد حيلة في هذه الحالات: لا تستطيع وضع نصوص أطول في هذه الحالات.

عليك فقط التعويض بنفس عدد البايتات أو الحروف بالضبط، و استعمال الفراغات إن لزم.

إلا لو كنت تريد تغيير البرمجة لسحب ذلك النص لمكان آخر، فهذا أمر آخر أصعب بكثير.


على سبيل المثال – –

لعبة Akuji the Demon و بعدها Guardian of Paradise على الويندوز، من انتاج مصمم هاو ياباني، ترجمت لاحقا للإنكليزية.

هذه الألعاب تخزن نصوص مقدماتها في تطبيق exe نفسه و هو ملف حساس للغاية.

نستطيع أن نلاحظ أن من ترجمها للإنكليزية اضطر لاستخدام الفراغات و اختصار الترجمة بسبب هذا.



و لا ننسى العدد الكبير من ألعاب Level-5 على النينتندو دي اس، التي تضع كميات من النصوص في ملفات الأوفرلاي overlay.

لكن أحيانا تكون البرمجة التي تغلف النص مقدورا على تغييرها و بالتالي يمكن تغيير طول النص.

مثل الألعاب المكتوبة بلغات مثل lua، أو التي تستخدم محركات معروفة.

مثلا، بالنسبة لألعاب الفلاش Flash، و هي ملفات swf، لدينا برنامج يفكك برمجتها اسمه ffdec_7.1.2

هذا مثال من لعبة فلاش يمكن رؤية النص فيه باللون البرتقالي في الصورة، و هو مختلط بالبرمجة.

يمكنك بهذا البرنامج تغيير النص و حتى البرمجة دون خوف.




هناك أيضا الألعاب التي لا تستخدم المؤشرات مع بعض النصوص لأن أطوال كل سطر ثابتة.

و قد حصل هذا كثيرا مع ألعاب الأجهزة القديمة، و يحصل كثيرا مع قوائم العدة، الأسلحة، الوحوش...


مثلا لدينا في قائمة العدة في لعبة Lufia II للسوبر فاميكوم، هذا الأسلوب.

لو نلاحظ جيدا، فإن جميع أسماء العدة طولها 12 رمزا هنا.

الأسماء الأقصر من 12 حرفا أضافت ببساطة فراغات لملء بقية الحروف.


عديد الألعاب الأخرى بها شيء كهذا، مثل الفاينال فانتازي 4 التي بها 9 حروف لكل إختيار من القوائم.

نفس الشيء رأيناه في قوائم لعبة Umihara Kawase في درس الألعاب اليابانية أيضا.



نستطيع ترجمة هذه الكلمات بالطول الذي نشاء ...

طالما يكون 12 حرفا أو أقل في حالة لوفيا 2. أو 9 في حالة الفاينال فانتازي 4. أو 16 في حالة الإسبر دريم 2، إلخ...

هذا الطول الأقصى لا يمكن تجاوزه.

لو أردنا تغييره، يجب أن نقوم بتغيير كبير في أسمبلي برمجة اللعبة (بعد تعلمه، طبعا).


و هناك ألعاب لا تحتاج المؤشرات، لأنها تحسب بنفسها أين يبدأ كل سطر.

و ذلك بعد البداية في قراءة الملف من أوله، بالبحث عن اشارات نهاية النص، و أحيانا اشارات أطوال النص، لمعرفة حدود كل سطر.

هذه الطريقة موجودة أكثر في الأجهزة الحديثة المتطورة أكثر

لو تتذكرون ملفات tk في لعبة Akuji the Demon ببساطة نحن نكتب بالطول الذي نريده

و عندما ينتهي كل سطر نضغط زر العودة للسطر (الذي يكتب لنا في الملف البايت 0A)، و اللعبة تعرف أين تنتهي النصوص.


هناك أمثلة عديدة على الأجهزة الحديثة من الجيم كيوب و الدي اس إلى الكمبيوتر على هذا،

و توجد حتى بعض الحالات على أجهزة قديمة (مثل Marvelous للسوبر نيس).

و التعرف عليها يكون ببساطة بالتجربة،

و هي من أسهل الحالات عندما نريد أن نضع نصوصا أطول: ببساطة نحرك إشارة نهاية النص و حسب.


الأمر الذي يجب التنبه إليه مع هذه المؤشرات: أن يكون عدد "السطور" هو نفسه دون زيادة أو نقصان.

و إلا فإن اللعبة قد تظهر النصوص بالترتيب الخاطئ.


أنواع المؤشرات

أما الألعاب التي تستخدم المؤشرات، فهناك طرق عديدة.

المؤشرات بصفة عامة أنواع، حسب المكان الذي يبدأ منه الحساب:


1 – من أول الروم (مطلق): الذي يبدأ الحساب من أول الروم. (أو من أول الملف)

2 – بإزاحة بمقدار (أوفسيت): الذي يبدأ الحساب من نقطة معينة وسط الروم أو الملف.

3 – من المؤشر (نسبي): الذي يبدأ الحساب من نقطة وجود المؤشر نفسه.


عدا هذا، فحسب الجهاز، قد يتم عمل زيادة بمقدار ثابت لهذا العنوان.


مثلا، في حالة النيس، الرومات في حالتها الأصلية لا تصلح لفتحها في المحاكيات لأن المحاكي لا يعرف نوع البطاقة.

لذلك تم إضافة 16 بايت (عددها 10 بالهيكس) في أول جميع الرومات، تدعى ترويسة iNES (iNES header)

لتدل المحاكي على نوع البطاقة، نوع الجهاز (منزلي أو أركاد، أوروبي أو أمريكي...).

تلك الترويسة ليست جزءا أصليا من محتويات الروم. بل أضافها من قام بإستخراج محتويات الروم إلى الحاسب.


إذن، تلك الترويسة طولها يطرح دائما، مهما كان نوع المؤشر، من أي عنوان نتعامل معه في النيس.


في حالة الجيم بوي أدفانس، المؤشرات تكتب على 4 بايت.

الجهاز يضع كامل الروم في ذاكرته عند فتح اللعبة، بداية من العنوان 80000000

إذن أي عنوان يظهر لنا في نافذة برنامج الهيكس، نضيف له القيمة 80000000 بالست عشري،

كي نحصل على عنوانه في الذاكرة كما يظهر في المؤشر.


هناك أمر آخر، و هو الطرفية Endianness.

رأينا مثالا عنه قبل قليل، لكن لا بأس في التوضيح أكثر.


نأخذ مثالا: نقول مثلا أن لدينا العدد العشري 1234567

1 مليون

234 ألف

5 مئة

6 عشرات (ستين)

و 7

هذا العدد فيه عدة أرقام.

الرقم 1 هو الرقم الذي لديه أكبر وزن (لأنه مليون! 10000000)

و الرقم 7 هو الرقم الذي لديه أقل وزن.


عندما نكتب نحن البشر هذا العدد، فنحن نضع الرقم الذي لديه أكبر وزن على اليسار.

أي أن الطرف في اليسار الذي تبدأ منه القراءة الإنكليزية، فيه الرقم الكبير الوزن.

طريقتنا العادية لكتابة الأعداد إذن تسمى: بالطرف الكبير Big Endian.


لو كنا داخل روم، و كان لدينا مؤشر نحو عنوان يكتب بالست عشري هكذا: ABCDE

بما أننا نتعامل مع بايتات، و كل بايت يتراوح بين 00 و FF أي يكتب مثل شيء هكذا XX

نعيد كتابة العنوان ليصبح فيه هذا التقسيم، و نضيف صفرا أمام A

0A BC DE

لكن الآن كيف يكتب المؤشر نحو هذا العنوان في الروم؟


XX

XX

XX

ثالث بايت

ثاني بايت

أول بايت


لدينا 3 مربعات ذاكرة.

تبدأ القراءة من الطرف في اليسار بالطبع (كما لاحظنا من إتجاه النصوص في برامج الهيكس و كل ما رأيناه في السابق).

كيف سنكتب المؤشر المذكور أعلاه في هذه المربعات الثلاثة؟

هناك طريقتان شائعتان.


0A

BC

DE


بالطرف الأصغر Low Endianأي أن الطرف (على اليسار) فيه البايت الأصغر وزنا.

طبعا، في 0ABCDE، البايت DE أصغر وزنا من البايت BC (أي BC00) و أصغر من البايت 0A (أي 0A0000).

إذن هو الذي يكون على اليسار في نظام الطرف الأصغر.

و يظهر هذا العنوان في الذاكرة هكذا:

DE BC 0A


هذه الطريقة رائجة جدا في عديد الأجهزة مثل النيس، السوبر نيس، جميع أنواع الجيم بوي حتى الأدفانس،

الدي اس و التري دي اس، البيسي انجين، الوندرسوان، و حتى الاكس بوكس (2002) و الويندوز ×86.

و هذا بسبب استعمال معالجات هذه الأجهزة لهذا النظام لكتابة العناوين.

لكن هذا لا يمنع أن تجد عديد الألعاب على هذه الأجهزة خير مبرمجوها جعلها تستخدم عناوينا بالنظام الآخر، و هو ...


DE

BC

0A


بالطرف الأكبر Big Endianأي أن الطرف (على اليسار) فيه البايت الأكبر وزنا.

و الذي سيكون في حالتنا هو 0A.

و يظهر هذا العنوان في الذاكرة هكذا:

0A BC DE


هذه الطريقة نجدها أكثر في أجهزة صممت معالجاتها باستعمالها، مثل السيغا ميغادرايف، الجيم كيوب و الوي، إلخ...

بالطبع هذا لا يمنع بتاتا ظهور الطرف الأكبر في ألعاب على أجهزة غير الميغادرايف،

أو ظهور الطرف الأصغر في ألعاب على الميغادرايف، فهذا الأمر عائد للمبرمجين أساسا.


أيضا هذه الطريقة هي التي نكتب بها نحن البشر الأعداد بطريقة عادية.

و هي أيضا المستعملة في برامج الهيكس، على اليسار، حيث نجد العناوين.

أو عندما نريد الذهاب لعنوان ما في ملف ما نفتحه في هذه البرامج.


أمر أخير...

قد يحصل لو كان عندنا مؤشر عنوان من 2 أو 3 بايت،

أن نجده مجزوءا و كل بايت في مكان وحده (لكن ليس بعيدا جدا عن إخوته).

هذا الأمر لاحظته في بعض ألعاب النيس و السوبر نيس.

لكن طالما نعثر على جميع الأجزاء و نغيرها كما يجب مثل أي مؤشر عادي، لا توجد مشكلة بحول الله.

المشكلة فقط أن البحث قد يكون معقدا.


الآن، نمر لبعض الأمثلة.

أولا، في لعبة الكابتن ماجد للدي اس التي كنا نتعامل معها قبل قليل.

لا داعي لنعيد المثال بما أننا تحدثنا عنه. لكن لنجب عن بعض الأسئلة على ضوء ما تعلمناه.

ما نوع المؤشر؟ هو مؤشر مطلق.

لأن القيمة 0000 كانت تشير لأول ملف النص. و القيم الأخرى كانت تبدأ الحساب من بداية الملف.

أيضا لاحظنا أن المؤشر كان مكتوبا بالطرف الصغير.

العنوان الذي نقول له نحن البشر (بالطرف الكبير) 0127 كان يرمز إليه المؤشر بالطرف الصغير هكذا 2701.


مثال 1 – لعبة سوبر نينتندو بتخطيط HiRom

نأخذ على سبيل المثال لعبة Terranigma بالنسخة الأوروبية الإنكليزية.

يمكننا تشغيلها على أي محاكي نريده و سنعرف إن كانت HiRom أو LoRom و هاتان طريقتان من أكثر الطرق المستعملة

لتخطيط ذاكرة السوبر نينتندو في ألعاب النيس. مثلا في Snes9X يمكن رؤية النوع تحت ROM Proprieties.

في البداية كانت كل الرومات تستعمل LoRom ثم مع حوالي 1993 بدأ إستعمال HiRom (مع الفاينال فانتازي 5).

كلا الطريقتين لتخطيط الذاكرة تسمحان بألعاب بأحجام تصل إلى 4 ميغابايت.

لاحقا، أتت أنواع جديدة لبعض الألعاب التي استنزفت السوبر نيس

مثل ExHiRom (مثل التيلز أوف فانتازيا) و ExLoRom (مثل الستار أوشيان) لتسمح ب 6 ميغابايت.

لكن هناك فرق كبير بين هذه الطرق فيما يخص طريقة تخطيط الروم، و في كتابة المؤشرات.


لعبة Terranigma الأوروبية تستعمل طريقة HiRom.

هناك أمر آخر – هل توجد ترويسة header في الروم أم لا؟

الجواب يختلف حسب المكان الذي أتيت به من الروم.

كما هو الحال مع النيس، فهناك من يضيف ترويسات بها معلومات عن بطاقة اللعبة و نوعها.

لكن في حالة السوبر نيس، هذه المعلومات غير ضرورية لتشغيلها على المحاكيات المعاصرة (كانت ضرورية مع محاكيات قديمة).


هذه الترويسة ليست موجودة في الأصل في داخل بيانات روم اللعبة في بطاقتها.

طول هذه الترويسة هو 512 بايت تكون في أول الروم.

يعني وجودها يحرك جميع عناوين الروم داخل اللعبة للأمام بقيمة 0x200 (أي 200 بالهيكس).

لذلك قبل تطبيق باتشات ترجمة أو تعديل روم سوبر نيس (مثل باتشات التعريب)،

يجب التثبت من هل أن الباتش يعمل مع روم بترويسة أم لا.

و إلا، فإنه سوف يطبق تعديلات اللعبة في المكان الخطأ، و من المؤكد أنه سيفسدها.


لكي نضيف أو نحذف ترويسة من روم سوبر نيس، نستطيع استخدام أداة tush.

نفترض أن الروم التي لدينا عندها ترويسة (headered).

أول شيء نقوم به هو البحث عن التيبل لهذه اللعبة.

الأمر على ما أظن في متناولنا و يكفي تطبيق الدروس السابقة و استعمال برامج البحث النسبي (مثل القرد monkeymoore).


هذا النص هو هدفنا، و هو يظهر في أول متجر يمكن دخوله في اللعبة:



نفتح الروم في برنامج هيكس، و نبحث عن النص.

سنجد أن الحرف الأول يبدأ بالضبط في العنوان 12A762



الروم التي لدينا فيها ترويسة.

الترويسة دائما طولها 200 بالهيكس و ليست جزءا أصليا من الروم.

نطرح 200 بالست عشري من 12A762.

النتيجة هي 12A562


الروم التي لدينا هي بتخطيط HiRom.

أي أنها مقسمة إلى كتل كل كتلة من 0000 إلى FFFF.

البايت 12 هو يشير إلى رقم الكتلة bank. و الذي هو في نظام HiRom يحتسب بإضافة C0 بالست عشري إليه،

أي أن رقم الكتلة بتخطيط HiRom هو D2


ننزع رقم الكتلة. ليبقى لنا فقط بايتان فقط (أي 4 رموز): A562

بما أن السوبر نيس بنظام الطرف الأصغر low endian، نقلب البايتين: 62A5

و هكذا نحصل على مؤشر بداية هذا النص.

في برنامج WindHex نستطيع استخدام Search Hex و كتابة هذين البايتين للبحث عن مكان المؤشر.


من حسن حظنا هنا أن المؤشر يبدأ الحساب من بداية الكتلة دون زيادة بأي مقدار.

أي أن ما قمنا به قبل قليل كاف لإيجاد المؤشر!

يمكننا رؤيته في الصورة أعلاه على فكرة.

و حتى مؤشر بداية النص القادم (Brother) موجود أيضا (85A5) بعده!


لكن! هذا مؤشر 16 بيت (أي مؤشر على 2 بايت فقط، لا تنسوا أن البايت هو 8 بيت).

أي أنه صالح فقط داخل تلك الكتلة، التي حجمها يتراوح بين 0000 و FFFF (64 كيلوبايت فقط من مجمل حجم الروم!!)

هناك مؤشرات 24 بيت تستخدم 3 بايتات و بالتالي تستطيع استخدام كامل الروم.

جل الألعاب تستخدمها بطريقة أو بأخرى لبعض بياناتها، و يمكن عمل تعديل برمجة بسيط لنستخدمها نحن كما نشاء.


قبل قليل نحن تحصلنا على مؤشر 16 بيت و هو 62A5

و نعرف أن رقم الكتلة هو D2

إذن نضيف رقم الكتلة على يسار المؤشر و نحصل على 62A5:D2

هذا هو مؤشر 24 بيت عنواننا السابق.

النقطتان نحتاجهما مع بعض المحاكيات و برامج الأسمبلي لاحقا، و غايتها تمييز رقم الكتلة.

لكن عند البحث عن المؤشر لا نكتب النقطتين. أي نبحث عن 62A5D2

(هناك حالات نجد فيها بعض المؤشرات 24 بيت تكون مفككة و يكون رقم الكتلة على مسافة من بقية المؤشر،

لكن هذا مجرد عقبة بسيطة جدا)


نعود إلى مثالنا.

يمكننا الآن وضع ترجمات أطول أو أقصر، كما نشاء، بالنسبة لهذا المقطع.

لنختبر قدراتنا، سنطلب منه أن يبدأ من كلمة What.

التي تبدأ في العنوان 12A76B ... إذن نغير المؤشر من 62A5 إلى 6BA5



مثال 2 – لعبة سوبر نينتندو بتخطيط LoRom

شركة كونامي مشهورة بكونها تمسكت بتخطيط LoRom بعد أن فقد شعبيته في 1993 بين عديد المبرمجين،

لذلك سنختار إحدى ألعابها و هي The Legend of the Mystical Ninja بنسختها الإنكليزية الأمريكية.

و هي الترجمة المشوهة للعبة غويمون الأولى على السوبر نيس.


هذه المرة اخترت روم بدون ترويسة.

أي أنني لن أحتاج لطرح 0x200 من العناوين.

لو كان الروم لديكم لديه ترويسة header، يمكنكم حذفها ببرنامج مثل tush.


نفتح الروم في المحاكي. تحت Rom Proprieties سيخبرنا أن الروم هي LowRom. و بالتحديد Slow LoRom.

هناك Fast LoRom لكن الفرق طفيف للغاية، سنذكره لاحقا.


هدفنا هو هذا النص.



نبحث عنه في الروم في برنامج الهيكس.

من حسن حظنا أن الترميز هو ASCII أي أننا لن نحتاج للبحث عن التيبل.

سنجده في العنوان 13A16

بما أن كل بايت يكتب برقمين XX نصلح الكتابة أعلاه بإضافة الأصفار، لتصبح 013A16



بما أن الروم تستعمل تخطيط LoRom فهذا يعني... أن الأمر أكثر تعقيدا قليلا.

كتل LoRom هي نصف كتل HiRom، أي أنه لنفس حجم الكارت لدينا ضعف عدد الكتل.


في العنوان الذي لدينا، الشيء الذي يشير لعنوان الكتلة هو البايت 01.


كتلة ال HiRom تكون بين 0000 و FFFF

تكون كتلتين في ال LoRom ، الأولى بين 0000 و 7FFF، و الثانية بين 8000 و FFFF.

لو كانت الكتلة من نوعية النصف الثاني أي أكبر من 8000، لا نفعل شيئا.

لو كانت الكتلة من نوعية النصف الأول أي بين 0000 و 7FFF نضيف لأول بايتين القيمة 8000 بالست عشري.


في حالتنا، لدينا العنوان 013A16


نحذف البايت الذي يشير للكتلة كي يبقى لنا أصغر بايتان، أي 3A16

أصغر من 8000 أي أنهما في كتل من نوعية كتل النصف الأول.

إذن نضيف 8000 بالست عشري إليهما. (3+8=11 أي B بالست عشري)

(هذه المرحلة نتجاهلها تماما و لا نقوم بها عندما يكون أكبر من 8000)

نحصل على BA16

بما أننا نعمل في السوبر نيس التي بالطرف الأصغر Low Endian، نقلب البايتين. نحصل على 16BA


نقوم بالبحث عن 16BA بخاصية البحث عن الهيكس Search Hex في برنامج الهيكس

سنجده في الروم قبل النص بقليل في العنوان 013652

نجرب ... مثلا تغيير القيمة في هذا العنوان إلى 17BA كي يختفي الحرف الأول



عند التجربة في اللعبة نتحصل على النتيجة المطلوبة تماما:



لو كنا نريد مؤشر 24 بيت، فهنا يصبح للنوع Slow Rom أو Fast Rom أهمية.

أولا، العنوان الأصلي كان 013A16

لو كنا في HiRom لكان رقم الكتلة هو الكتلة الثانية في الروم (نظرا أن 01 تأتي بعد 00)

و كنا في النصف الأول من الكتلة الثانية (نظرا أن 3A16 أصغر من 8000)

بما أننا في LoRom حيث كل كتلة من كتل HiRom مقسومة جزئين،

فهذه في الواقع الكتلة الثالثة و رقمها في LoRom يكون 02 (في حالة Slow Rom مثل الآن، +80 و يصبح 82 في حالة Fast Rom)


هناك برنامج لطيف جدا إسمه LunarAdress يسمح بتحويل العناوين من صيغتها كما تظهر في برامج الهيكس،

إلى مختلف الصيغ بتخطيطات السوبر نيس المختلفة.


ملاحظة بالنسبة لرومات ExHiRom و ExLoRom الضخمة

نظرا أني تعذبت قليلا لإيجاد هذه المعلومات على النت (يمكنكم المرور للمثال التالي لو شئتم):

هذه الأنواع من التخطيطات سمحت بتمديد بعض الرومات التجارية مثل Tales of Phantasia (ExHiRom)

و Star Ocean (ExLoRom) إلى أحجام تفوق أقصى الحجم الأقصى العادي (4 ميغابايت) لتخطيط HiRom و LoRom.

أتت باتشات ترجمات لعدة ألعاب أخرى قامت بتمديد الروم (هناك أداة اسمها LunarExpand للغرض) لتخزين أكثر نصوص.


الفكرة أن هناك قسطا من الذاكرة في السوبر نيس بقي غير مستغل.

فأتت ألعاب ExHiRom و ExLoRom ببطاقة لعبة بها محول عناوين

ليستغل ذلك القسط لتخطيط أجزاء الروم التي تتجاوز "الحد الأقصى" العادي (4 ميغابايت).

لهذا السبب، فإن احتساب مؤشرات ExHiRom و ExLoRom

بالنسبة لأي جزء من الروم تحت 4 ميغابايت (أي قبل العنوان 400000)

تخضع لنفس القواعد العادية المذكورة في السابق ل HiRom و LoRom.


المساحات الجديدة من الروم بعد حاجز 4 ميغابايت

تستطيع أن تصل إلى 8 ميغابايت (7FFFFF) كحد أقصى منصوح به (الأدوات المتوفرة مثل LunarExpand تتوقف عند ذلك)،

و في حالة بعض المجانين هناك حتى من وصل ل12 ميغابايت لكن ذلك الحد الذي يستحيل تمديد الروم فوقه.


رومات ExHiRom و ExLoRom التجارية الرسمية اكتفت بحد 6 ميغابايت.

و هذا يجنبها مشاكل تضارب الإستعمال حول بعض مناطق الذاكرة انطلاقا من 7 ميغابايت فصاعدا.


بالنسبة لمؤشرات ExHiRom و ExLoRom التي تخص المناطق من الروم

بعد حاجز 4 ميغابايت (أي من العنوان 400000 فما بعده) فلديها قواعد أخرى كالتالي:


بالنسبة إلى ExHiRom يحتسب المؤشر كالتالي:

لا إضافة C0 و لا هم يحزنون.

تأخذ العنوان العادي كما يظهر في برنامج الهيكس كما هو. (ثم بالطبع تقلبه بالطرف الأصغر)

مثلا لو كان لدينا العنوان 410000 في الروم (نفترض أنها بدون ترويسة يعني لا نضيف 200)،

فمؤشره بتخطيط ExHiRom هو 000041 ، أو 0000:41 لو أردنا كتابة رقم الكتلة (41).


بالنسبة إلى ExLoRom:

كالعادة كل كتلة تتراوح بين 8000 و FFFF

يعني لو كان البايتان الأصغر وزنا (الاثنان على اليمين) أصغر من 8000 نضيف إليهما 8000.

المساحة من 4 ميغابايت (العنوان 400000) إلى 8 ميغابايت (العنوان 7FFFFF) مخططة بتلك الطريقة.

و رقم الكتل في هذه المساحة الجديدة يتراوح

من 00 بالنسبة لأول كتلة (من 400000 إلى 407FFF)

إلى 7D بالنسبة لآخر كتلة (من 7E8000 إلى 7EFFFF)


لا نستطيع استخدام الكتل 7E و 7F لأن الرام تستخدمها.

هذا التضارب موجود حتى في حالة ExHiRom بالنسبة

للنصف السفلي (0000 الى 7FFF) من الكتل انطلاقا من 7 ميغابايت (700000)


يعني مثلا، أن المؤشر نحو العنوان 411000 سيكون

رقم الكتلة هو 02 (الثالث، انطلاقا من 400000)

1000 أصغر من 8000 إذن نضيف لها 8000 فيصبح لدينا 9000

و المؤشر سيكون بعد قلب البايتات بالطرف الأصغر هو ... 0010:02


الروم الوحيد المعروف التجاري الذي استخدم ExLoRom

و هو Star Ocean كان يستعمل الذاكرة السريعة Fast Rom

يعني أن عناوين الروم لما تحت 4 ميغابايت، كانت تستخدم الكتل من 80 فصاعدا.

مثلا عنوان 009000 سيكون:

رقم الكتلة هو 01 الثاني انطلاقا من 000000 (لدينا الكتلة من 0000 الى 7FFF قبلها)

نضيف 80 إلى 01 لنحصل على رقم الكتلة في Fast Rom و نحصل على 81

9000 أكبر من 8000 لا نفعل شيئا

و المؤشر يكون بعد قلب البايتات بالطرف الأصغر هو 0090:81


لو أردنا توسيع روم LoRom يستخدم Slow Rom ...

فالأمر معقد أكثر و يجب نسخ الروم الأصلي في المساحة الجديدة (كتلة 40 فصاعدا)

و طبعا عدم استعمال تلك المساحة لغير ذلك.

لكن هذه حالة لا داعي للقيام بها

نظرا أن رومات Slow Rom في الأصل عادة صغيرة

و يمكن تمديدها إلى 4 ميغابايت LoRom عادي.


بالنسبة للرومات التي بها شرائح خاصة (مثل DSP أو SPC7110 للعبة Tengai Makyou أو SFX بالنسبة إلى Yoshi’s Island.. الخ)

فهي قد تستخدم تخطيطات ذاكرة خاصة جدا بها

و بالتالي وجب البحث عن هذه التخطيطات لمعرفة كيف تحسب المؤشرات.


مثال 3 – لعبة جيم بوي كولور

جهاز الجيم بوي، و كذلك الجيم بوي كولور، كان مصمما في الواقع في البداية لألعاب لا تتجاوز

سعتها 32 كيلوبايت، أي أن جميع عناوين محتوى الروم تتراوح من 0000 إلى 7FFF.


لكن دوام الحال من المحال، و قررت نينتندو إضافة ما يسمى بوحدة تحكم كتل الذاكرة أي

Memory Bank Controller و اختصارها MBC (ليس القناة).

هذه الوحدة يمكننا التعرف على وجودها بفتح الروم داخل برنامج هيكس و الإطلاع على

ترويسة الروم الداخلية (التي على عكس النيس و السوبر نيس هي جزء أصلي من الروم

وضعه المبرمجون و لم يضفه أحد بعدهم)، و بالتحديد البايت في العنوان 0147 لا يجب أن يكون 00 (بدون MBC).

هناك أنواع من MBC و نوعها، بالإضافة إلى وجود تمديدات الرام و ذاكرة الحفظ

يغير قيمة هذا البايت. MBC1 و MBC3 أقصاها 2 ميغابايت، MBC2 أقصاها 256 كيلوبايت،

و MBC5 قد تصل إلى 8 ميغابايت، و أنواع أخرى...


المؤشرات في رومات الجيم بوي / الجيم بوي كولور تكون عادة بطول 2 بايت،

و في نفس الكتلة التي فيها البيانات و النصوص التي تشير إليها (و قريبة منها، كالعادة).

في بعض الألعاب (و فقط تلك التي تستعمل MBC) هناك مؤشرات بطول 3 بايت،

لو كانت البيانات لم تسعها كتلة واحدة و احتاج المبرمجون الإشارة إليها.


طريقة إحتساب المؤشرات في ألعاب الجيم بوي (كولور) تختلف قليلا عن السابق،

لكن ليس كثيرا.

أولا، يجب أن نعلم أن الجيم بوي كولور عادة تستخدم المؤشرات مكتوبة بالطرف الصغير،

لكن هناك بعض الإستثناءات (مثل ألعاب دونكي كونغ) و هي قليلة جدا.


نبدأ بلعبة مثل The Legend of Zelda Link’s Awakening بنسختها الإنكليزية على الجيم بوي كولور.

هذه اللعبة نصوصها مخزنة بنظام ASCII و يمكن رؤيتها مباشرة في برنامج الهيكس.

هدفنا هو هذا النص:



يمكننا إيجاد هذا النص بكل سهولة حيث يبدأ، في العنوان 05198A

نلاحظ أيضا أن اللعبة لا تستعمل كثيرا رموز العودة للسطر، بل المسافات.



و الآن نبحث عن المؤشر 16 بيت (أي بطول 2 بايت) الذي يشير لهذا العنوان 05198A

البايت 05 لا نحتاج إليه بل فقط إلى البايتين قبله. 198A


الآن هناك قاعدة لتحويل هذين البايتين: إذا كان البايتين...

المهم أن الهدف هو الحصول على قيمة تتراوح بين 4000 و 7FFF مهما كان الثمن.


في حالتنا هذه، 198A بين 0000 و 3FFF إذن نضيف 4000، بالهيكس طبعا.

نحصل على 598A

بما أن الجيم بوي يعمل بالطرف الأصغر، نقلب البايتين: 8A59.

هذا هو المؤشر 16 بيت (أي بطول 2 بايت) لهذا النص.


بعد البحث بالهيكس Hex Search في هذا الملف، سنعثر بعد العنوان 70000 بقليل

على هذا المؤشر و عديد المؤشرات الأخرى لنصوص في نفس المكان.



هناك مؤشرات عدة نصوص في جدول المؤشرات هذا.

ماذا لو عوضنا مؤشر نص مارين (8A59) بمؤشر يشير لنص آخر؟

مثلا نختار 955E من هذه القائمة و نضعها مكانه.

ماذا ستقول مارين؟



مارين تقمصتها روح الساحرة.

هذا يعني إذن أن المؤشر الذي عدلناه صحيح.


و بالمناسبة، هناك نصوص محذوفة من لعبة Terranigma بنسخها الأوروبية،

لكنها مثيرة للإهتمام و مازال بالإمكان فتحها بتغيير المؤشرات بهذه الطريقة...


لكن لو افترضنا أن هذه لعبة تستعمل MBC

و أردنا أن نجد المؤشر 24 بيت (3 بايتات) لهذا العنوان نفسه، ماذا نفعل؟

العنوان الذي لدينا هو 05198A

المؤشر 16 بيت (2 بايتات) الذي يشير إليه نكتبه بالطرف الأكبر أي 59A8


نأخذ العنوان الكامل و نرى كم فيه من جزء بحجم 4000 بايت.

و لذلك، نقسم 05198A على 004000 بالست عشري،

باستخدام حاسبة الويندوز، و نتجاهل باقي القسمة و أي شيء بعد الفواصل.

النتيجة هي 14 بالست عشري.

14 هي رقم الكتلة.


لكي نجد المؤشر 24 بيت: هو مجموع عددين.

العدد الأول: نضرب رقم الكتلة × 4000 بالست عشري.

14 × 4000 تعطينا بالست عشري 050000

العدد الثاني: نطرح 4000 من مؤشر 2 بايت مهما كان.

59A8 نطرح منه 4000 تعطينا 19A8

نجمع العدد الأول و العدد الثاني.

نتحصل على 0519A8

نقلب هذه البايتات الثلاثة بالطرف الأصغر و تعطينا مؤشر 3 بايت المطلوب: A81905


مثال 4 – لعبة بلاي ستايشن 1

إيزو البلاي ستايشن 1 يمكن استخراج و تعويض ملفاته ببرامج مثل CDMage و PSX-MODE2.

(البرنامج الذي يعادل هذا في البلاي 2 هو Xpertن و في حالة ال PSP هو UmdGen)


غالبا إيزو البلاي 1 يحتوي التطبيق الرئيسي PS-EXE و اسمه يكون فيه SLUS/SLJP/SLPS متبوعا بأرقام،

إضافة إلى ملفات اللعبة العادية،


و ملفات خاصة اسمها فيه XA و هذه تكون مخصصة للصوت (و أحيانا تكون مدمجة بملفات الفيديو STR)

و استخراجها ممكن لكن أصعب من العادية (نظرا أنها مشتتة على القرص).

يمكن تغيير ملفات الصوت و الفيديو هذه بأدوات مثل jPSXdec و XA Audio Convertor.

استخراج هذه الملفات بمجرد فتح القرص على الويندوز ليس بالفكرة السديدة (قد ينفع مع الملفات العادية).


أيضا، على ذكر الملفات العادية، صيغة TIM لتخزين الصور كانت رائجة جدا على الجهاز (لكن ليست الوحيدة) لذلك،

طالما كانت الملفات غير مضغوطة بإختزال ما، يمكن البحث عن الصور فيها و تعديلها ببرنامج TimViewer.


التعديل على جهاز ضخم كهذا فيه عدة حلول،

لكن يمكن التقليل من الجهد المطلوب باستخراج ملفات منفردة و التعامل معها

عوض فتح كامل الإيزو (700 ميغابايت) في برنامج هيكس.


بخصوص المؤشرات و هذا ميدان حديثنا...

هناك عديد الأنواع، و عدد منها عادي و يشبه ما نراه في مثال لعبة الدي اس أعلاه.

مثلا في لعبة غويمون و قراصنة الفضاء (يابانية فقط، من احدى الدروس السابقة)،

المؤشرات داخل ملفات النصوص طولها 2 بايت

و تبدأ الحساب من أول الملف، و كالعادة تشير لملفات وسط ذلك الملف في الإيزو.


لكن هناك نوع آخر مقلق قليلا، و مستعمل خاصة في التطبيق الرئيسي.

لحد الآن، المؤشرات التي رأيناها تشير نحو ملفات في الروم (أو القرص).

لكن هذا النوع من المؤشرات يعتمد على فكرة مغايرة تماما.


البلاي كانت الذاكرة الحية (الرام له) محدودة جدا (2 ميغابايت زائد الذاكرة البصرية).

لا يمكن تحميل كامل اللعبة فيها، لذلك يتم وضع قطع منها (غرفة أو غرفتين فقط مثلا) كل مرة.

لذلك اشتهر الجهاز بشاشات التحميل و Now Loading ...

عندما تشحن المعلومات في الرام، هذه المؤشرات تشير إلى الرام و ليس الملف في الإيزو.


الرام ذاكرة وقتية لا تضع إلا ما تحتاجه في ذلك الموقف.

يعني لو كنت تريد نصا من غرفة معينة، يجب أن تلعب حتى ترى ذلك النص،

كي تتأكد أن الذاكرة الحية تحتويه عندها.

هذا الأمر يتعبنا... لكنه قد يفيدنا أيضا.

السبب... أن أي شيء ينسخ للرام عادة يكون في وضع جاهز للإستعمال...

أي غير مضغوط أو مشفر، و بالتالي سهل الإيجاد.


مثال من هذه الحالات – أولا وجب التنويه أن هذه المؤشرات عادة تكون بطول 4 بايت.

و أحيانا أندر، تكون بطول 2 بايت. كذلك هي عادة بالطرف الأصغر لذلك نقلب ترتيب البايتات.


لعبة Silent Hill الأولى بنسختها الأمريكية (1.1 تحديدا).

من حسن حظنا أن النص في هذه اللعبة غير مضغوط.

ليس هذا فقط، بل و يستخدم أيضا نظام ASCII (فقط المسافات عوضت بالرمز "_").

في بداية اللعبة، يمكن الذهاب للوراء و تفحص السيارة لرؤية هذا النص:



من الضروري أن نفتح اللعبة في محاكي ePSXe و يظهر لنا هذا النص تحديدا.

لأننا نحتاج أن يكون في الذاكرة الحية (الرام RAM) و كما نعلم البلاي لا تضع شيئا هناك إلا عندما تستعمله.

عند القيام بذلك نذهب إلى Debug ثم r3000 (اسم معالج البلاي)،

ثم File و Dump binary (استخراج ملف ثنائي) لكي يستخرج لنا الروم.

القيمة الأولى هي العنوان الذي منه بداية الاستخراج، نضع له 0.

القيمة الثانية هي كم نريد أن يكون طول الملف المستخرج،

بما أن البلاي بها 2 ميغابايت من الرام و نحن نريد كل الرام، نكتب له 200000



نفتح ملف الرام المستخرج في برنامج الهيكس.

نبحث الآن عن النص.



النص يبدأ مع الحرف الأول من كلمة My_car أليس كذلك؟ خطأ.

لو نتذكر جيدا الدروس السابقة، هناك بايتات التحكم.

في حالتنا هذه هنا، لو نظرنا للنصوص الأخرى، سنجد أن البايت 09 دائما في مطلع كل جملة.

ما يعني أن هذا النص في الواقع يبدأ به هو.


إذن: عنوان النص في ملف الذاكرة الحية الرام: 000CAEB4


نبحث في الرام عن مؤشر يكون بطول 4 بايت،

مكتوب بالطرف الأصغر (يقال أن البلاي 1 فيها حالات بالطرف الأكبر لكن لم أتثبت)،

و يشير إلى 000CAEB4

و بالفعل نجده هنا... لو بدأنا بالبحث عن أجزاء من المؤشر عوض البحث عنه كله.

في حالتنا هذه أضيف له 80000000 و صار 800CAEB4

يمكننا أن نجد أيضا بالقرب منه مؤشرات لنصوص أخرى قريبة منه.



إذن: مؤشر النص هو 800CAEB4


نذهب الآن لملف اللعبة نفسه، الروم، أو بالأحرى هنا الإيزو بما أنها لعبة بلاي 1.

لكن هذا الإيزو حجمه يقارب 600 ميغابايت.

يمكننا فتحه كله في ملف الهيكس...

لكن هناك حل أفضل قليلا و هو فتح الملفات الفرعية التي بداخله.

و بالفعل، يمكننا استخراج ملف أصغر بكثير، حجمه 78 ميغابايت، اسمه SILENT

و ليس به ملفات الصوت و الفيديو ضخمة الحجم التي لا تهمنا الآن.


بما أن هذا الملف غير مضغوط سنجد النص واضحا فيه.

(في حالة الذاكرة الحية (الرام) سنجد دائما النص واضحا سواء كان ملف الإيزو مضغوطا أم لا، لأن اللعبة تحتاج قراءته)



إذن: عنوان النص في الملف الأصلي للعبة (SILENT، ليس الإيزو كله هنا) هو: 0493913C


لو أردنا التعديل على ذلك المؤشر في الملف الأصلي للعبة

(نظرا أنه من الجنون التعديل عليه في ملف الرام الذي يتغير باستمرار..

إلا لو كنتم تريدون التدليس و الضحك على أنفسكم)

نستطيع أن نبحث عن نفس المؤشر الذي وجدناه قبل قليل و سنجده



في أربعة أماكن مختلفة من الملف الأصلي (!) – مقارنة بتكرره مرة واحدة في الرام

ليس الأمر مستغربا، نظرا أن ملف SILENT به كامل نصوص اللعبة،

و التي على الأرجح نادت على ذلك النص في 4 فرص مختلفة.


لكن، هناك سؤال مهم.

عندما نعدل على الملف الأصلي للعبة و نغير النصوص و المؤشرات.

نصنا في 0493913C

ما علاقته بهذا المؤشر؟ لو غيرت مكان بداية النص، ماذا أضع في المؤشر؟


يجب أن نحسب الفارق بين العنوان في المؤشر و العنوان في الملف الأصلي.

الأول هو 800CAEB4

الثاني هو 0493913C

سنجد عددا ست عشري اما سالبا أو موجبا، ينفع مع جميع النصوص (وجب التثبت طبعا)،

نضيفه دائما إلى قيمة العنوان في الملف الأصلي

كي نتحصل على المؤشر – و طبعا نكتب المؤشر بالطرف الأصغر (نقلب البايتات)


في حالتنا هذه مثلا، بعد ان استعملنا الآلة الحاسبة في الويندوز

في النظام الست عشري، هذا الفارق أعطانا 7B791D78


النص الذي فيه Can’t get out of town

يبدأ في الملف الأصلي في العنوان 4939164

لنحتسب المؤشر، نضيف إلى هذا العنوان، "الفارق" الذي وجدناه قبل قليل 7B791D78

و سنجد 800CAEDC

نكتبه بالطرف الصغير (نقلب البايتات الأربعة) و نحصل على المؤشر: DCAE0C80

هذا المؤشر مألوف قليلا...



و هكذا نستطيع بهذا الفارق استنتاج أغلب المؤشرات الأخرى.


مثال 5 – أمثلة لمؤشرات خطية Linear (عادية)

رومات النيس

جميع العناوين في برنامج الهيكس متقدمة ب 10 بايت (بالهيكس، 16 بالعشري) عن مواقعها الأصلية.

في حالة النيس، الرومات في حالتها الأصلية لا تصلح لفتحها في المحاكيات لأن المحاكي لا يعرف نوع البطاقة.

لذلك تم إضافة 16 بايت (عددها 10 بالهيكس) في أول جميع الرومات، تدعى ترويسة iNES (iNES header)

لتدل المحاكي على نوع البطاقة، نوع الجهاز (منزلي أو أركاد، أوروبي أو أمريكي...).

تلك الترويسة ليست جزءا أصليا من محتويات الروم. بل أضافها من قام بإستخراج محتويات الروم إلى الحاسب.


إذن، تلك الترويسة طولها يطرح دائما، مهما كان نوع المؤشر، من أي عنوان نتعامل معه في النيس.


يعني لنجد أي مؤشر يجب نأخذ عنوان الهيكس،

مثلا في حالة الفاينال فانتازي 1 عنوان أول نص يبدأ من 28210 أو بالأحرى 028210

ثم نطرح 10 (طول الترويسة) من عنوان الهيكس، 028200

ثم نترك فقط البايتين على اليمين 8200

و نقلب (النيس بالطرف الأصغر). 0082

و بالفعل يمكننا أن نجد هذا المؤشر في العنوان $28010 و تغييره يغير أين يبدأ النص.


المؤشرات في الغالب بطول 2 بايت (أحيانا تكون 1 بايت و العياذ بالله)

في حالة الفاينال فانتازي و عدة حالات مشابهة، لم نحتج لغير المراحل أعلاه.


لكن عددا كبيرا من مؤشرات النيس بالإزاحة بمقدار، غالبا بمقدار مثل X000 حيث X مجهول يجب معرفته.

على سبيل المثال هذه روم Journey to Silius بنسختها الأمريكية.

لدينا هذا النص من المقدمة و منه قمنا بالبحث عن جدول التيبل و اظهار النص بالصحيح في برنامج الهيكس.



النص الأول يبدأ في العنوان 011584

لنحصل على المؤشر لهذا العنوان

نطرح 10 و نحصل على 011574

نضيف مقدار الإزاحة X000 (بعد أن نعثر عليه، كيف؟ سنرى) ثم نترك فقط البايتين على اليمين.

يصبح لدينا شيء مثل Y574 (Y مجهول، و هو X+1)

بما أن النيس بالطرف الأصغر، نقلب البايتين، يصبح عندنا 74Y5.


نستطيع البحث في الهيكس Search Hex عن البايتان 74*5 حيث النجمة تعوض الرقم المجهول.

كما نستطيع أيضا البحث بالعين في حالتنا هذه.

و لمساعدتنا في البحث، نبحث عن مؤشر النص الثاني الذي سيكون C1Y5

و مؤشرات بقية النصوص لو أردنا أيضا.

سنستنتج في النهاية أن Y هي 9،

و أن مقدار الإزاحة X000 هو في الواقع 8000. – هذه قيمة إزاحة مستعملة كثيرا على فكرة في النيس أكثر من غيرها.


في حالة الإزاحة بمقدار سواء في النيس أو غيرها،

من المفيد البحث عن الفارق بين العناوين أولا لأنه يساعدنا (بما أن نفس الفارق سيكون بين قيم المؤشرات أيضا).


رومات الجيم بوي أدفانس

جميع المؤشرات هي بطول 4 بايت.

و للحصول على المؤشر، نأخذ عنوان الهيكس، مثلا 01240030

و نضيف اليه 08000000، مثلا 09240030

و نقلب البايتات بالطرف الاصغر: 30002409 (ملاحظة: بعض الألعاب بالطرف الأكبر، فيتم تجاهل هذه المرحلة)

و هذا هو المؤشر.

عندما تبحث في برنامج هيكس (بحيث يكون البايت المجهول مرموزا له **) عن شيء مثل 08******08

فإنك على الأرجح قد تجد جدول مؤشرات في لعبة جيم بوي أدفانس.

لهذا السبب صدرت كل تلك الهاكات لألعاب بوكيمون الجيم بوي أدفانس نظرا لسهولة تعديل المؤشرات و النصوص.


يمكن العودة لدرس اكسترا أورديناري على منتدى الومض لمثال مع لعبة البوكيمون لهذه المؤشرات.


رومات السيغا ميغادرايف

مؤشراتها هي الأسهل في الواقع.

طالما لا نعمل مع رومات smd التي يجب أن نحولها أولا إلى رومات bin (بدون تشابك deinterleaved) بأدوات مثل SBWin.

فهي بطول 4 بايت في 90% من الحالات (أو 2 بايت في حالات نادرة).

كما أنها مكتوبة بالطرف الأكبر. يعني لا حاجة لتقلب البايتات.


يعني لو كان عنوانك هو 00012345

فالمؤشر هو ببساطة... 00012345

بالطبع، عدة ألعاب تستخدم الإزاحة بمقدار، ة بعضها يستخدم مؤشرات بطول 2 بايت...

مثلا Monster World 4 تأخذ البايتين الأولين فقط و تضيف 800 بالنسبة لمؤشرات النصوص.

لكن أيضا في نفس اللعبة، مؤشرات الصور تستخدم البايتات الأربعة.


المؤشرات التي تحيد قليلا عن المألوف تظهر مع الرومات القليلة التي صدرت لملحق X32،

و التي مؤشراتها مثل الميغادرايف لكن بزيادة مقدار متغير حسب البرنامج و نوع المعالج المستعمل

(في Knuckles Chaotix مثلا، هذا المقدار هو 700000).


رومات PC Engine

هذا الجهاز محدود كثيرا في قدراته على تخزين البيانات.

الروم مقسمة إلى كتل حجمها 8 كيلوبايت أي 2000 بالهيكس. فقط.

هذه الكتل توزع أثناء عمل اللعبة على ثمانية سجلات ذاكرة كل واحد فيها أيضا حجمه $2000

و اسمها MMR. ثلاثة من هذه السجلات تخصص عادة لأغراض أخرى،

و هي السجلات من 0000، من 2000، و من E000 (هذا الأخير عادة مخصص لأول كتلة للروم).


لو كان لدينا عنوان مثل 02E750 مثلا:

نقسم على 2000 بالهيكس (و لا نهتم بالفاصل): 17 – هذا رقم الكتلة.

هذه الكتلة تبدأ في $17×$2000 = $02E000

يعني أن المؤشر سيكون 0750.

أو 2750، 4750، 6750، 8750، A750، C750، E750.

نستبعد 0750 لأنها في دفتر ذاكرة الجهاز.

نستبعد 2750 لأنها في دفتر تابع للرام.

نستبعد E750 لأن هذا دفتر مخصص فقط لأول كتلة في الروم.

بقيت لنا 5 احتمالات: 4750 6750 8750 A750 C750

نجرب البحث عن كل واحد على حدة، بعد قلب البايتات بما أن الجهاز يعمل بالطرف الأصغر،

و نبدأ مثلا بالبحث عن 5047 و هكذا...

و في النهاية سنجد المؤشر الذي نبحث عنه ان شاء الله، لو لم يكن مشوها بطريقة ما.


مثال 6 – مؤشرات بإزاحة مقدار و مؤشرات نسبية في ألعاب دي اس

نأخذ على سبيل المثال لعبة Megaman ZX Advent بنسختها الإنكليزية.

نستخرج إحدى ملفات النص و هو الملف talk_sys_en،

و نبحث عن قيم التيبل ببرنامج بحث بالمقارنة كي تظهر لنا النصوص بشكل صحيح.

عندها يمكننا البداية في البحث عن المؤشرات.


هناك خرابيط في بداية النص من 0000 إلى 017D و هي قبل النص مباشرة و لا يوجد غيرها في الملف،

إذن هناك إحتمال كبير أن تكون تلك الخرابيط لها علاقة بتعليمات إظهار النص،

و المؤشرات بالطبع قد تكون بينها – و الأمر بالفعل كذلك.


هناك أمر وجب توضيحه هنا لأنه يفيدنا هنا، و هو أن هذا الملف بكله ينتهي في العنوان 188B

لدينا في أول الملف بايتان 8818 (بنفسجي) مثيران للشبهة، و يبدوان و كأنهما العنوان 1888 مكتوبا بالطرف الأصغر.

إذن، هذان البايتان يشيران لحجم الملف.

هناك فرق 4 بايتات بين 1888 و 188B (B هي 12 بالست عشري).

إذن حجم الملف هذا لا يحتسب أول 4 بايتات، و سنسميها ترويسة الملف.

(ملاحظة: في الملفات المضغوطة عادة يكون هناك حجمان للملف، الحجم المضغوط و الحجم الأصلي)


ما سر بقية هذه البايتات الأربعة؟

بقي البايتان (أزرق) الذان بهما 7A01 و هي كتابة الطرف الأصغر للعنوان 017A

لا يوجد شيء مثير للاهتمام في 017A بل على ما يبدو يجب أن لا نحسب الترويسة،

إذن نبدأ الحساب مما بعد هذه الترويسة. يعني من البايت 0004.

0004 + 017A تعطينا 017E و هي نقطة بداية نصوص الملف. إذن هذا المؤشر يشير لبداية النصوص.


زيادة الترويسة هذه أمر عادي إعتدنا عليه مع عناوين النيس أو الجيم بوي أدفانس،

أو رومات السوبر نيس التي بها ترويسة.

لكن هناك المزيد من هذه المؤشرات و هي غير واضحة مباشرة للعيان.

سأكتب المؤشرات التي في بداية النص بعد "فك تشفيرها" بما أنها في الأصل كتبت بالطرف الأصغر.

0000

0017

002F

0049

0064

...


الواضح أن المؤشر 0000 يشير لأول نص، و هو ذاته الموجود في العنوان 017E.

إذن هو يبدأ الحساب من تلك النقطة.

يعني كي نجد إلى أين يشير المؤشر الثاني 0017 نضيفه للعنوان الذي يبدأ منه النص 017E

و نجد 0195 ... التي تطابق نقطة بداية النص الثاني.

المؤشرات التي رأينهاها الآن هي مؤشرات بالإزاحة بمقدار (أوفسيت)

و هي تبدأ الحساب من نقطة وسط الملف، عوض البداية من أول الملف مثل المؤشرات المطلقة.


هناك نوع ثالث و هو المؤشرات النسبية و هو يبدأ الحساب من المؤشر نفسه.

و هو مستخدم خاصة في تحديد أطوال الجمل.

على سبيل المثال:



مع العلم أن كل رمز ياباني يعادل 2 بايت.

أمام كل كلمة يابانية في هذا الملف من لعبة كيرورو 2010 للدي اس،

يوجد مؤشر طوله بايت واحد.

هذا المؤشر يبدأ الحساب من مكانه (و هو لذلك مؤشر نسبي) ليعطي أين تنتهي كل جملة.

في لعبة Ni no Kuni DS و بعض ألعاب Level-5 الأخرى، استخدم مثل هذا النوع من المؤشرات.


مثال 7 – مؤشر نحو صورة داخل ملف مجهول في لعبة للويندوز

لأن المؤشرات لا تشير فقط للنصوص.

بل أي شيء في اللعبة يمكن أن يشار إليه بمؤشر. من النصوص إلى الصور و حتى جداول المؤشرات نفسها.


في لعبة Akuji the Demon هناك عدة ملفات مرافقة لتطبيق اللعبة، لكن لا توجد ملفات صور ظاهرة.

كل ما لدينا هو ملف bmp.qda لا يمكن تغييره ببرامج الصور المعتادة. و هو ضخم أيضا. ما الحل؟

نفتح هذا الملف في برنامج الهيكس WindHex الذي سيفيدنا جدا هنا.



في أول ملف QDA توجد مجموعة 4 بايتات غريبة هي ترميز ASCII لكلمة QDA0

هذه علامة مميزة لهذا النوع من الملفات نظرا أنها تتكرر في ملفات أخرى، و نقول لها الرقم السحري magical number.


البايت 2C يختلف حسب الألعاب.

بعد مجموعة من الأصفار، نجد أمورا مهمة نوعا ما،

هناك بعض البايتات متبوعة بإسم ملف.

في المجمل، هناك 44 اسم ملفات فرعية في هذا الملف. أي 2C بالست عشري.

إذن بعد الرقم السحري كان يوجد عدد الملفات الفرعية داخل هذا الملف الكبير.


الملف الفرعي الأول على ما يبدو هو ملف صورة بيتماب بصيغة bmp.

قبل الإسم بالأخضر، توجد بايتات نستطيع أن نجزم أنها عناوين مكتوبة بالطرف الأصغر low endian،

بما أن الويندوز يستعمل الطرف الأصغر. هذه العناوين هي:

00002F10

00038438 (مرتين)


نتقدم قليلا في الملف الكبير و نجد اسما ثانيا معه هذه العناوين:

0003B348

00038438 (مرتين)



لو نلاحظ جيدا، فلو جمعنا أول عددين 00002F10 و 00038438 من الملف الأول

سنجد أول عدد في الملف الثاني 0003B348

بعبارة أخرى:

العدد الأول هو عنوان بداية الملف الفرعي

العدد الثاني هو طول الملف الفرعي (مكتوبا مرتين).


سنحاول الآن إلقاء نظرة على العنوان 00002F10

و سنجد في البداية البايتين الذان يعادلان BM

و هذا الرقم السحري المعروف لملفات بيتماب Bitmap التابعة للويندوز.

إذن هذه بالفعل نقطة بداية هذا الملف الفرعي.



لإستخراج هذا الملف الفرعي، الذي بالطبع هو ليس نصا، علينا استخراجه بيانات ثنائية Binary Data.

لذلك، نذهب إلى Tools ثم Dump Binary Data.

نحدد اسم الملف الفرعي الذي نريد استخراجه،

عنوان بدايته،

عنوان نهايته (عنوان البداية + الطول – 1)،

بناء على ما وجدناه سابقا،

ثم نضغط زر الموافقة.



الملف الذي استخرجناه هو ملف يعمل على برامج الصور العادية:



يمكننا أيضا تغييره، و إعادة إدخاله للملف الرئيسي،

عبر الذهاب ل Tools ثم Insert Binary File (ادخال ملف ثنائي)،

و كتابة عناوين البداية و النهاية كالعادة.


للتعامل مع الملفات المجهولة من هذا النوع، الفكرة تقريبا هي نفسها.

هناك أنواع أخرى من الملفات الفرعية داخل الملفات الكبيرة مجهولة الهوية،

و التعرف على الأرقام السحرية قد يساعد على ذلك (هذه قائمة للأرقام السحريةرابط آخر).



استخراج و دمج النصوص بالجملة بإستخدام الأدوات

إلى حد الآن أغلب مشاريعنا كانت بإستخدام برنامج الهيكس.

لكن هذا ليس ناجعا تماما مع ألعاب نصوصها كبيرة جدا مثل لعبة الأربيجي هذه.

في حقيقة الأمر، هذا الدرس كان فرصة لي لأتعلم كيف أقوم بهذا.


الحل موجود لإخراج النص في شكل ملفات نصوص يتم تعديلها ثم إعادة إدخالها في الروم،

و لكنه يتطلب التالي:


نعود للمثال الذي فيه السوبر نينتندو بتخطيط HiRom، و هو روم Terranigma الأوروبي.

و نواصل ما بدأنا به في ذلك المثال.

في الواقع بدأت بكتابة هذه الفقرة تحت ذلك المثال لكن وجدت أنها ستصبح أطول من بقية الدرس فوضعتها هنا.


المرحلة 1 من 4 – إيجاد جدول المؤشرات

المثال الذي سنقوم بتناوله حاليا هو هذه المجموعة الصغيرة من نصوص المتاجر.

عملية البحث عن المؤشرات التي قمنا بها قبل قليل كانت مهمة جدا،

لأنها أعطتنا أين يوجد جدول المؤشرات:



مع العلم أن:

البايت D4 هو إشارة نهاية النص في هذه الحوارات

البايت CF هو إشارة العودة للسطر في هذه الحوارات

البايتين E546 معا يعطياننا [Welcome ] ...

هذه من طرق إختزال النص: عوض استخدام 8 بايتات لهذه الكلمة، استخدمت اللعبة 2 فقط.

سنتحدث أكثر عن هذا في الدرس القادم.


جدول المؤشرات هو بالأحمر في الصورة أعلاه.

أول مؤشر هو 62A5 و يشير إلى 12A750 أي أول الحوار Welcome! What can I help you with?

لا يهمنا هنا أين يشير، بل يهمنا أين هو. هو موجود في الروم في العنوان 12A750

نقول أن جدول المؤشرات يبدأ في العنوان 12A750.


آخر مؤشر في الجدول هو 4AA6 و هو يشير إلى 12A84A أي أول الحوار Welcome to Marily’s Shop.

هذا المؤشر نفسه موجود في الروم في العنوان 12A760 و طوله 2 بايت.

نقول أن جدول المؤشر ينتهي قبل العنوان 12A762.


هذه المؤشرات مخزنة بالطرف الصغير Low Endian. لذلك هي مكتوبة مقلوبة.

هذه المؤشرات أيضا طولها 2 بايت.

و هي مكتوبة بجوار بعضها دون أي مسافة فاصلة. (0 بايت مسافة فاصلة)

كما أنها مؤشرات لا تبدأ الحساب من أول الروم.

بل تبدأ الحساب من أول الكتلة Bank.

بما أن البايت الذي يرمز لرقم الكتلة هو 12 إذن نبدأ بالحساب من 120000

أو بالأحرى من 120200 بإضافة 200 (نظرا أن الروم الذي نعمل عليه فيه ترويسة).

هذه المؤشرات بالإزاحة بمقدار 120200.


المرحلة 2 من 4 – استخراج النص

في نفس مجلد برنامج Cartographer نحتاج إلى:


لنبدأ إذن في إعداد هذه الأشياء!


نصنع في برنامج Notepad أو أي برنامج نص مشابه، ملف تعليمات إسخراج النص terranigma.txt

بحيث يحتوي جميع المعلومات المذكورة أعلاه:


#GAME NAME: Terranigma E (SNES)


#BLOCK NAME: Shop Block (POINTER_RELATIVE)

#TYPE: NORMAL

#METHOD: POINTER_RELATIVE

#POINTER ENDIAN: LITTLE

#POINTER TABLE START: $12A750

#POINTER TABLE STOP: $12A762

#POINTER SIZE: $02

#POINTER SPACE: $00

#ATLAS PTRS: Yes

#BASE POINTER: $120200

#TABLE: terranigma.tbl

#COMMENTS: Yes

#END BLOCK


و فيه:


نذهب لملف التيبل terranigma.tbl و الذي أعددناه مسبقا كما رأينا في الدروس السابقة.

نتأكد من صحة ترميزه (أي أن الرمز الأول فيه هو رقم و لا شيء غير الأرقام)

و بالنسبة لبايتات التحكم المسؤولة عن العودة للسطر و نهاية النص، نضيفها في التيبل هكذا:


/D4=[END]\n\n

CF=[LINE]\r


الرمز \r يمثل عودة للسطر، و الرمز \n عودة للسطر مصحوبة بالرموز // في البداية.

هذه الرموز هي تعليمات للبرنامج كيف يكتب النصوص عند استخراجها في ملف النص.


كان بإمكاننا وضع \r فقط عوض [LINE]\r لكن... لا يهم، إن شاء الله المرة القادمة.



نذهب لبرنامج Notepad لصنع ملف نص فارغ. نكتب في هذا الملف الآتي.

هذه التعليمات تأمر البرنامج باستخدام الملفات المذكورة لصنع ملف نص اسمه nass فيه النص المستخرج.

الرمز –m يعني أن كل مجموعة نص تستخرج لملف وحدها، لكن نحن هنا لدينا مجموعة نص واحدة لذا لا يهم.


cartographer terranigma.smc terranigma.txt nass -m


pause


عندما نسجل ملف النص هذا، نغير له اسمه و امتداده بحيث يكون بامتداد .bat

مثلا نسميه istikhraj.bat أو شيء كهذا.

المهم أن نسجله في نفس مجلد برنامج cartographer

و نفس المجلد يحتوي ملف الروم (.smc أو أي جهاز آخر)، ملف التعليمات (.txt) و ملف التيبل (.tbl).


ننقر مرتين فوق ملف istikhraj.bat و سيفتح لنا برنامج Cartographer

الذي سيستخرج النص أو يظهر لنا رسالة خطأ يشتكي فيها أمرا ما.

النتيجة في النهاية أنه سيصنع لنا ملف نص مثل هذا:


//GAME NAME: Terranigma E (SNES)


//BLOCK #000 NAME: Shop Comment Block (POINTER_RELATIVE)


//POINTER #0 @ $12A750 - STRING #0 @ $12A762


#W16($12A750)

//Welcome! What can[LINE]

//I help you with?[END]



//POINTER #1 @ $12A752 - STRING #1 @ $12A785


#W16($12A752)

//Brother have I got[LINE]

//a deal for you![END]



//POINTER #2 @ $12A754 - STRING #2 @ $12A7A8


#W16($12A754)

//Get lost if you're[LINE]

//just looking.[END]



//POINTER #3 @ $12A756 - STRING #3 @ $12A7C9


#W16($12A756)

//Welcome to[LINE]

//Magishop. Hehehe.[END]



//POINTER #4 @ $12A758 - STRING #4 @ $12A7E0


#W16($12A758)

//Greetings! Take a[LINE]

//good look around![END]



//POINTER #5 @ $12A75A - STRING #5 @ $12A804


#W16($12A75A)

//......[END]



//POINTER #6 @ $12A75C - STRING #6 @ $12A80B


#W16($12A75C)

//Welcome. Nice of[LINE]

//you to come.[END]



//POINTER #7 @ $12A75E - STRING #7 @ $12A829


#W16($12A75E)

//Hi! Come over and[LINE]

//buy something![END]



//POINTER #8 @ $12A760 - STRING #8 @ $12A84A


#W16($12A760)

//Welcome to[LINE]

//Marily's Shop.[END]



المرحلة 3 من 4 – تعديل النص

و الآن، حان وقت الترجمة، لكن في ملف نص جميل مثل هذا و دون القلق على حدود النص.


برنامج محول الحروف لأحمد، بعد الإصدار 3.0،

يسمح لنا بترجمة هذه النوعية من الملفات بسرعة كبيرة.

لكن على شرط... في المراحل السابقة، يجب أن يكون رمز نهاية النص هو تحديدا <END>

و ليس [END] كما كتبنا نحن في الأعلى. يعني، نغير التيبل و نعيد الإستخراج.

نضغط الزر (فتح ملف نص) و نفتح ملف النص الذي استخرجناه قبل قليل...

و سنجد الحوارات مقسمة كلها حسب عددها و يمكن ترجمتها بسرعة هنا.



نقول أننا غيرنا ملف النص المستخرج كما شئنا.

ليس تماما كما شئنا، كما نعلم هناك بيانات بعد هذا النص مباشرة و لو وضعنا نصا أطول، قد نمس بها.

هناك حل لهذا و هو تحسين طريقة اختزال النصوص، لكن هذا أمر نراه في الدرس القادم.


المرحلة 4 من 4 – دمج النص في الروم

و الآن لندمج النص المعدل في الروم من جديد، نحتاج إلى برنامج Atlas.

في حالتنا هذه، سأعيد إدخال ملف النص الإنكليزي بعد تغييره في برنامج محول الحروف.

لكن بما أنني إنسان بخيل و كسول للغاية،

و لكي يكون المثال واضحا خاصة أن خرابيط محول الحروف بعد تحويل النص، لا تنفعنا كثيرا للفهم هنا...


فإن "التعريب" الذي نتظاهر أننا قمنا به سأشير له في المثال بتعويض كل الحروف بأحرف كبيرة.

نقول أننا عربنا ملف النص ذاك. لكي لا يطول المثال كثيرا، سأكتفي بأول حوارين فقط.


//GAME NAME: Terranigma E (SNES)


//BLOCK #000 NAME: Shop Comment Block (POINTER_RELATIVE)


//POINTER #0 @ $12A750 - STRING #0 @ $12A762


#W16($12A750)

//WELCOME! HAL[LINE]

//TURID CHAY?<END>



//POINTER #1 @ $12A752 - STRING #1 @ $12A785


#W16($12A752)

//YA AKHI ENDI[LINE]

//LIK FORSA LA TOUAD!<END>





الرموز // تجعل ما بعدها يظهر على شكل تعليق.

لا نريدها أن تظهر أمام النص.

كان علينا إذن حذفها (بخيار COMMENTS) من جهة Cartographer ...

نذهب لملف التيبل بامتداد tbl و نغير العودة للسطر لتكون D4=[LINE]


الأجزاء الضرورية من هذا الملف هي هذه (نحذف الزائد، أو نتركه و قبله // )


#W16($12A750)

WELCOME! HAL[LINE]

TURID CHAY?<END>


#W16($12A752)

YA AKHI ENDI[LINE]

LIK FORSA LA TOUAD!<END>


السطر #W16 يغير محتوى المؤشر 16 بيت (2 بايت) الذي كتب عنوانه أمامه،

حسب طول الجملة السابقة.

النص الذي كتب بعده سوف يكتب إلى الروم أيضا.


لكن... هذا الملف غير كاف.

يجب إضافة بعض التعريفات في أول الملف.

انتهينا.


#VAR(tbl_nas_hiwar, TABLE)

#ADDTBL("terranigma.tbl", tbl_nas_hiwar)

#ACTIVETBL(tbl_nas_hiwar)


#SMA("HIROM")


#HDR($200)

#JMP($12A762, $12A85D)


#W16($12A750)

WELCOME! HAL[LINE]

TURID CHAY?<END>


#W16($12A752)

YA AKHI ENDI[LINE]

LIK FORSA LA TOUAD!<END>


خذنيٍ~ بكل ببساطة

ماذا يفعل الشيء الذي أضفناه لبداية هذا الملف.

الأمر قد يبدو صعبا و معقدا، لكنه ليس كذلك.


أولا، بما أنه قد يحصل لنا أن نستعمل عدة جداول تيبل في نفس اللعبة (قد يحصل هذا، نعم)،

حجزنا متغيرا للذاكرة نوعه "جدول تيبل" TABLE – السطر #VAR

وضعنا في هذا المتغير ملف terranigma.tbl – السطر #ADDTBL

قلنا للبرنامج أن يبدأ استعمال هذا الجدول – السطر #ACTIVETBL

و الذي يمكن استعماله عدة مرات في الملف أيضا مع كل تغيير نجريه لاستعمال ملف تيبل آخر.


ثانيا.

هل اللعبة تستعمل الطرف الأصغر Low Endian؟ نعم.

في هذه الحالة لا داعي لإضافة السطر الذي يأمر بإستعمال الطرف الأكبر Big Endian،

و الذي هو على فكرة:


#ENDIANSWAP("TRUE")


هل هناك ترويسة في ملف الروم الذي نستعمله،

أو فرق بين قيمة المؤشر و العنوان الحقيقي الذي يشير إليه؟

في حالتنا نعم، لذلك نضع سطر #HDR

الذي يؤثر فقط على قيمة المؤشرات الجديدة.

لا نحتاج هذا السطر بكله لو كنا نعمل على روم بدون ترويسة.


ما هو نوع المؤشر؟ لدينا المؤشرات العادية التي هي نفسها التي تظهر في برامج الهيكس LINEAR

و لدينا المؤشرات التي تطرأ عليها عمليات حسابية غريبة.

و هي مؤشرات السوبر نيس LOROM00 و LOROM80 و HIROM

و هناك مؤشرات الجيم بوي كولور GB

و التي شرحناها في أعلى الدرس.

في أغلب الأجهزة عدا السوبر نيس و الجيم بوي (ليس الأدفانس)، فإن المؤشرات العادية LINEAR تكفي.

هنا، نستخدم HIROM.


أين نبدأ في كتابة النص؟

نضع العنوان الذي منه نبدأ كتابة النص و هو 12A762 (في روم بها ترويسة)

#JMP($12A762)

لكن لو أردنا أيضا وضع حد نهاية له، نظرا أن نصنا ينتهي في 12A85D

و هناك بيانات بعده (و هي بالمناسبة جدول مؤشرات لنصوص أخرى بعد هذه)

لو كتبنا فوقها نصا زائدا لو كان نصنا أطول من الأصل، فستكون الكارثة.

نكتب التعليمة #JMP لكن بعنصر ثان:

#JMP($12A762, $12A85D)

و هكذا نكون قمنا بتأمين أنفسنا من هذا الخطر. البرنامج لن يكتب بعد هذا العنوان.


و بالطبع كما قلنا سابقا...

السطر #W16 يغير محتوى المؤشر 16 بيت (2 بايت)

الذي كتب عنوانه أمامه، حسب طول الجملة السابقة.

النص الذي كتب بعده سوف يكتب إلى الروم أيضا.


و الآن، نسجل هذا الملف، الذي سميناه nass.txt في السابق بعد أن استخرجناه.

نتأكد من أن لدينا هذه الأشياء في نفس المجلد:


نذهب لبرنامج Notepad لصنع ملف نص فارغ. نكتب في هذا الملف الآتي.

هذه التعليمات تأمر Atlas بتنفيذ الأوامر في ملف nass.txt و دمج البيانات كما يطلب بالضبط،

و ذلك في الروم terranigma.smc مع صنع ملف اسمه result.txt فيه تقرير عن نجاح (أو فشل) العملية.


Atlas –d result.txt terranigma.smc nass.txt


pause


عندما نسجل ملف النص هذا، نغير له اسمه و امتداده بحيث يكون بامتداد .bat

مثلا نسميه idkhal.bat أو شيء كهذا.

المهم أن نسجله في نفس مجلد برنامج Atlas

و نفس المجلد يحتوي ملف الروم (.smc أو أي جهاز آخر)، ملف التعليمات (.txt) و ملف التيبل (.tbl).


ننقر مرتين فوق ملف idkhal.bat و سيفتح لنا برنامج Atlus الذي سينفذ لنا ما طلبناه.

و هكذا قمنا بإدخال النص بنجاح في الروم!

أدعوكم لتجربة هذا مع الأمثلة السابقة.


طرق أخرى لكتابة تعليمات الدمج لبرنامج Atlas

الطريقة المذكورة أعلاه هي الطريقة القديمة، و هي بحد ذاتها كافية بأقل عدد ممكن من التغييرات.

و هي تستعمل التعليمات SMA، W16، W24 و W32.

لكن هناك طرق أخرى أفضل لكتابة تعليمات الدمج.


في حالتنا، جدول المؤشرات ليس مبعثرا.

بل جميع المؤشرات متتالية، و صفر فراغ يفصل بينها.

إذن يمكننا تطبيق الطريقة الجديدة لكتابة تعليمات الدمج.


لو كتبنا نفس المثال لكن بالطريقة الجديدة، نتحصل على الآتي:


#VAR(tbl_nas_hiwar, TABLE)

#ADDTBL("terranigma.tbl", tbl_nas_hiwar)

#ACTIVETBL(tbl_nas_hiwar)


#VAR(ishara, CUSTOMPOINTER)

#CREATEPTR(ishara, "HIROM", $0, 16)

#VAR(jdwl, POINTERTABLE)

#PTRTBL(jdwl, $12A750, 0, ishara)


#HDR($200)

#JMP($12A762, $12A85D)


#WRITE(jdwl)

WELCOME! HAL[LINE]

TURID CHAY?<END>


#WRITE(jdwl)

YA AKHI ENDI[LINE]

LIK FORSA LA TOUAD!<END>


الآن لو تلاحظون صرنا نستعمل #WRITE(jdwl) حيث jdwl إسم الجدول،

عوض إستخدام تعليمة #W16 التي تتطلب منا كل مرة عنوان المؤشر.

مقابل هذه البساطة في الكتابة، أضفنا أربعة أسطر بالأزرق. و هي:

على أنه المتغير "اشارة"،

من نوع HIROM،

القيمة التي نطرحها من المؤشر لنجد العنوان الحقيقي هي 0،

و هو 16 بيت أي 2 بايت

على أنه المتغير "جدول"،

يبدأ في العنوان 12A750،

الفراغ بين المؤشرات المتتالية هو 0 بايت،

و يستعمل مؤشرات من نوع "اشارة".


يمكننا تحسين هذه التعليمات أكثر بتعويض هذا الجزء:


#WRITE(jdwl)

WELCOME! HAL[LINE]

TURID CHAY?<END>


#WRITE(jdwl)

YA AKHI ENDI[LINE]

LIK FORSA LA TOUAD!<END>


بتعليمة الكتابة الآلية #AUTOWRITE، التي تغير المؤشرات تباعا مع كل رمز نهاية نص <END> و تدخل النص أيضا.

التعليمة #DISABLE توقف الكتابة الآلية.

لو كان لدينا عشرات النصوص لكتابتها، فالكتابة الآلية توفر علينا كتابة #WRITE عشرات المرات.


#AUTOWRITE(jdwl,"<END>")

WELCOME! HAL[LINE]

TURID CHAY?<END>

YA AKHI ENDI[LINE]

LIK FORSA LA TOUAD!<END>

#DISABLE(jdwl,"<END>")


هناك حالات تكون فيها المؤشرات مبعثرة.

من بين هذه الحالات نذكر لعبة The Legend of the Mystical Ninja التي أخذناها مثالا أعلاه.

في مثل تلك الحالات، نصنع ملف قائمة المؤشرات. نسميه مثلا list.txt

و محتوياته تكون قائمة عناوين حيث توجد المؤشرات.

لا نحتاج لذلك في مثالنا هذا مع تيرانيغما لأن المؤشرات قريبة من بعضها،

لكن لو أردنا استعمال هذه الطريقة، تكون محتويات الملف list.txt هكذا:


$12A750

$12A752


و في ملف تعليمات الدمج، نضع هذا،

مع الحرص أن يكون الملف list.txt بترميز ASCII و في نفس المجلد.

السطور التي تغيرت كتبت بالبنط الغليظ،

و هي حجز متغير لقائمة المؤشرات "قائمة"،

و النداء على ملف قوائم المؤشرات list.txt لملئ قائمة المؤشرات "قائمة" هذه.


#VAR(tbl_nas_hiwar, TABLE)

#ADDTBL("terranigma.tbl", tbl_nas_hiwar)

#ACTIVETBL(tbl_nas_hiwar)


#VAR(ishara, CUSTOMPOINTER)

#CREATEPTR(ishara, "HIROM", $0, 16)

#VAR(kaima, POINTERLIST)

#PTRLIST(kaima, list.txt, ishara)


#HDR($200)

#JMP($12A762, $12A85D)


#WRITE(kaima)

WELCOME! HAL[LINE]

TURID CHAY?<END>


#WRITE(kaima)

YA AKHI ENDI[LINE]

LIK FORSA LA TOUAD!<END>


كان بإمكاننا أيضا استخدام #AUTOWRITE(kaima,"<END>")

و طبعا تعليمة إيقافها #DISABLE(kaima,"<END>")

بغض النظر عن ترتيب المؤشرات داخل الروم، طالما لدينا ملف قائمة مؤشرات list.txt


الجدير بالذكر أيضا بخصوص Atlas هو كيفية تعامله مع النصوص التي لا تستعمل المؤشرات

و يكون عرضها ثابتا.

مثلا قائمة العدة في Lufia 2 التي تحدثنا عنها في الأعلى.

يكون ذلك بهذه التعليمة #FIXEDLENGTH

مع تحديد الطول الثابت و الرمز الذي تملئ به الفراغات ان كانت الكلمة أقصر من ذلك الطول.

ان كانت الكلمة أطول من ذلك الطول تكتب منها فقط الحروف التي تحت ذلك الطول.

هنا، الطول الأقصى كان 12 (لو وضعنا 0، يتوقف الطول الثابت عن العمل و يعود البرنامج للعمل العادي)

و البايت لملئ الفراغات كان 20، و هو بايت الهيكس المطابق للمسافة مثلا لو كنا في لعبة بنظام ASCII.


المهم أن نضيف أيضا في ملف التيبل هذا السطر في النهاية /<END>

لكي يعرف أن <END> ترمز لنهاية الجمل في النصوص ثابتة العرض و من أين يبدأ ملئ الفراغات.


#FIXEDLENGTH(12, $20)

ASIR<END>

ASIR KAWI<END>

ASIR LIMON<END>

CHAY<END>

#FIXEDLENGTH(12, $20)


و لنختم، نعود لمثالنا الأول مع الكابتن ماجد الذي فيه عدة ملفات،

حيث المؤشرات في ملف ev0000.siz،

و النصوص في ملف آخر ev0000.str.


برنامج Atlas يغير النصوص و المؤشرات

في نفس الملف الذي اسمه في ملف أمر الباتش bat.

قول مثلا أنه ev0000.str في حالتنا.


عندما نريد أن نأمره بتغيير الملف

الذي منه يقرأ المؤشرات و إليه يكتب المؤشرات الجديدة، نكتب له


#SETPTRFILE("ev0000.siz")


هناك تعليمة أخرى لتغيير الملف الذي يكتب إليه النص (لكن لا نحتاجها)،

و هي #SETTARGETFILE("ev0000.str")

توجد أمور أخرى تساعد في بعض الحالات التي قد تواجهنا،

مثل الحالات التي يكون فيها المؤشر مفككا – مثلا مع المؤشر 1234

يكون بايت الوزن الأكبر (على اليسار) 12 في مكان (مثلا $1024)،

و بايت الوزن الأصغر (على اليمين) 34 في مكان آخر (مثلا 1020$).

تعليمات كتابة المؤشرات الجديدة التي تساعدنا في هذه الحالات هي

WLB(ishara,$1020) يكتب بايت الوزن الأصغر للمؤشر الجديد في ذلك العنوان

WHB(ishara,$1024) يكتب بايت الوزن الأكبر للمؤشر الجديد في ذلك العنوان




في النهاية...

رأينا الكثير من الأمثلة حول المؤشرات و كيف تسمح لنا باختيار مكان ابتداء النص كما نريد،

بما يسمح لنا بوضع نصوص أطول من الأصلية. لكن... حتى هذا لديه حدوده.


فمن جهة، قد يكون التوسيع في النص غير ممكن كثيرا،

ما يجبرنا في التفكير في حلول لتقليص نصنا المترجم أي اختزاله.

و من جهة أخرى فإن المؤشر أحيانا لا نجده لأنه في ملفات مضغوطة.


هذه الأمور تحدو بنا للتفكير في طرق إختزال و ضغط البيانات في الروم لتقليص الحيز الذي تشغله.


و كذلك، فالبحث عن المؤشرات صار يتم بتعقب البرمجة في المحاكي

حيث ننصب للعبة مصيدة كلما حاولت قراءة النص من الرام (نقطة التوقف البريك بوينت breakpoint)،

و نحاول أن نتبع التعليمة التي حاولت القراءة (التتبع trace) إلى أن نجد من أين أتت بالمؤشر الذي دلها لذلك النص.

ما يعني أن علينا أيضا التفكير في تعلم لغات برمجة أجهزة الألعاب (الأسمبلي) لقرائتها و فهمها،

و ربما حتى تعديلها كما نريد (لحل مشكلة النص من اليسار لليمين مثلا!).


موعدنا ان شاء الله في درس قادم حول الإختزال و الضغط،

و أتمنى أن تردوا لي جميل هذا الدرس، بأن تطبقوه لتعريب لعبة جديدة، فذلك منتهى رجائي.


أود أن أشكر ...

صناع أدوات دمج و إستخراج النصوص،

أحمد مبرمج محول الحروف و لو أن لا يمكن أن نوفيه الشكر على محول الحروف،

خاصة لأنه لفت إنتباهي لهذه الأدوات بإصداره المحسن من محول الحروف 3.0،

إضافة إلى اكسترا أورديناري من موقع الومض بما أن درسه حول مؤشرات الجيم بوي أدفانس،

و لو أنه بسيط، إلا أن بساطته هي التي قربت الفكرة لي أول مرة و شجعتني على تعلم المزيد.