اصل ماجرا
نویسنده با Zig یک بازی 2048 برای Game Boy Advance ساخت و تجربهٔ ابزار ساخت، ساختارهای بسته و کامپایل‑زمان را تحسین کرد. او توضیح داد چطور Zig نیاز به ابزارهای پیچیدهٔ devKitPro را حذف کرد و کار با رجیسترهای سختافزاری را راحتتر کرد. همچنین محدودیتهای کوچک Zig مثل پشتیبانی ناقص از Thumb/ARM را هم بیان کرد.
متن کامل ترجمهشده
چرا من یک بازی Game Boy Advance را در Zig نوشتم The Game Boy Advance یک کنسول بازی جالب است. آن را دارای یک CPU مدرن (32 بیتی ARM، بسیاری از ثبت نام)، اما استفاده از یک renderer مبتنی بر چوب های قدیمی مانند NES در 80s انجام داد. مرا اشتباه نکنید، از آنجا که یکی از آخرین سیستم های مبتنی بر چوب های Nintendo است، آنها ایده را تا جایی که می تواند با ویژگی های فانتزی مانند تبدیل های آفیانی، شفافیت و اثرات مورد استفاده برای sprites. اما در هسته خود، آن را یک فضای بسیار منحصر به فردی: تنها جایگاه مهم دیگری از این چارچوب است Nintendo DS، و در حالی که من خاطرات دوست دارم از آن، من فکر کردم که صفحه دوم برنامه نویسی سخت تر خواهد بود. بنابراین با این اطلاعات، من تصمیم گرفتم یک بازی برای Game Boy Advance: من ساعت هایاما جالب ترین چیز در مورد این پروژه برای من زبان بود. پروژه های بازی اولیه من با Game Boy Advance در C++ نوشته شده بود، اما من اولین بازی کامل ام را در Zig نوشتم. و این کمی عجیب است. اول از همه، این یک زبان بسیار ناخودآگاه است، هنوز در بتا است، و آن را 15 سال پس از انتشار Game Boy Advance در ژاپن ساخته شده است. اما اگرچه محبوب ترین نیست، من فکر می کنم که Zig برای این پروژه عالی بود، و این چیزی است که این پست وبلاگ در مورد است. این پست وبلاگ در مورد اینکه چگونه Zig خوب است به طور کلی نیست، و به طور عمده بر ویژگی های زبان تمرکز می کند که آن را برای این نوع برنامه نویسی وارد شده خوب است. شما می توانید افراد دیگر در اینترنت درباره اینکه چرا باید Zig استفاده کنید، و من آن را به آنها بگذارم.برای پنج سال از آن زمان من در حال ادامه مبارزه با بسته بندی، نسخه ها، بستگی ها، و تمام مشکلات دیگر که با مشکل مشکل پیدا کردن یک برنامه که در کامپیوتر شما کار می کند همراه است. به همین دلیل، هنگامی که تصمیم گرفتم یک صحنه ساده 3D در Nintendo DS حدود یک سال پیش، من بلافاصله احساس ناراحتی داشتم. محبوب ترین راه برای توسعه بازی برای کنسول های Nintendo “ریترو” از طریق چیزی به نام devKitPro است، که بسته های GCC toolchains، کتابخانه ها و ابزار توسعه برای این کنسول ها است. چگونه شما این بسته ها را دریافت می کنید؟ خوب، شما مدیریت بسته ArchLinux را دانلود کنید، آن را به سمت ذخایر خود را تنظیم کنید، و این راه را نصب کنید. حتی پس از آن، این من را ناراحتی کرد. به طور کلی، مدیریت بسته های مختلفی که من باید استفاده کنیدهنگامی که من پروژه های دمو GBA خود را آغاز کردم، این با من ایستاده بود. من دوباره با کپی کردن اسکرپت های لینکر devKitPro شروع کردم و برخی از تنظیمات Meson عجیب و غریب را با هم جمع کردم تا همه چیز با کلن کار کند. این یک جدایی بود، اما کار کرد. چیز خوبی این است که از آنجایی که من زنجیره های ابزار را بهتر فهمیدم، من قادر شدم newlib را کار کنم، که به من کتابخانه های استاندارد C و C++ داد. من چند دمو برای درک چگونگی Sprites کار می کرد، اما در نهایت من به: Zig فکر می کنم که اولین بار که درباره Zig شنیدم این پست وبلاگ توسط Andrew Kelly در مورد استفاده از Zig برای جمع آوری میانگین بود. شما نیازی به نصب این زنجیره های ابزار با استفاده از مدیریت بسته های عجیب و غریب نداشتید (در اینجا یک نظرسنجی از فرآیند ساخت برای بازی است: - با استفاده از یک script linker برای به دست آوردن طرح فایل درست، ترکیب یک ELF باینری برای بازی، همراه با یک فایل شروع نوشته در ترکیب - با استفاده از objcopy برای استخراج تمام داده ها از ساختار ELF (این در اصل یک رومی GBA در حال حاضر) - با استفاده از یک ابزار مانند gbafix برای اضافه کردن در اطلاعات عنوان درست (نیز در نرم افزار واقعی، اما بر روی آماتورها) از آنجا که Zig شامل objcopy، من می توانم تمام این مراحل در فایل ساخت خود را انجام دهد. این باعث می شود که فرایند کمتر ناخوشایند و حساس به اشتباه است. چیز دیگری که سیستم ساخت آسان تر می کند تولید کد است. من از تولید کد برای استفاده از تصاویر png و تبدیل آنها به داده های پیکسل که GBA درکZig ساخته شده در ارتباط با جمع آوری و مدیریت زنجیره ابزارهای، چیزی است که همیشه در حال وجود من بود، چیزی که من نمی خواهم نگران. ساختار بسته من این را به این ثانیه، زیرا حتی اگر این یک ویژگی است که به مدت طولانی در دسترس Zig است، این یکی از بهترین ویژگی ها برای برنامه نویسی Game Boy Advance است. اگر شما نمی دانستید، کنسول های مانند Game Boy Advance سیستم عامل به طور کامل با تماس های API سطح بالا برای انجام گرافیک. شما دسترسی به چیزهایی مانند ویدئو، کنترل، صوتی، و دیگر کنترل های نرم افزار از طریق ثبت ها. این مناطق حافظه هستند که معمولا 16 بیتی است، و جمع آوری یک مجموعه از زمینه ها. این ثبت ها در یک آدرس حافظه مطابقتی است که شما می خوانید و بنویسید. به عنوان مثال، BGxCNT. 4 نسخه از این با شماره های مختلف0-1 BG Priority (0-3, 0=Highest) 2-3 Character Base Block (0-3، در واحد های 16 KBytes) (=BG Tile Data) 4-5 Not used (must be zero) (در حالت NDS: MSBs of char base) 6 Mosaic (0=Disable, 1=Enable) 7 Colors/Palettes (0=16/16, 1=256/1) 8-12 Screen Base Block (0-31, در واحد های 2 KBytes) (=BG Map Data) 13 BG0/BG1: Not used (در حالت NDS: Ext Palette Slot for BG0/BG1) 13 BG2/BG3: Display Area Overflow (0=16/16, 1=256/1) 8-12 Screen Base Block (0-31, در واحد های 2 KBytes) (=BG Map Data) 13 BG0/BG1: Notدر چیزی مانند C++ یا Rust شما ممکن است یک مدل سازنده را ببینید که استفاده می شود. این باعث می شود روشن شود که چه اتفاقی می افتد، و به دلیل استثنایات قیمت صفر، شما با انجام این کار خیلی از دست ندهید. اما در مورد Zig چیست؟ Zig دارای یک ویژگی بسیار جالب است که این است که شما می توانید انواع کل که قدرت های دو نیستند داشته باشید. شما می توانید یک u8 برای یک کل بیست بیست بیست بیست داشته باشید، اما هیچ کس شما را از ایجاد یک u7 متوقف نمی کند. این کار با یک struct بسته می شود. به طور معمول، زمینه های ساختار به قدرت های دو متصل خواهد شد تا دسترسی ها سریع تر شود، اما ساختار های بسته به شما اجازه می دهد تا همه چیز را به طور نزدیک به هم نزدیک کنید. و ما می توانیم ساختار مثل این را ایجاد کنیم: constCntشاید شما هرگز این مشکل را نداشتید، اما اگر شما از نرم افزار مانند Game Boy Advance استفاده می کنید، شما با طرح های حافظه بسته شده مانند این کار می کنید. این تنها بزرگترین ویژگی فروش برای من است. Comptime هنگامی که من شروع به ساخت ساخت بازی من کردم، من دوست نداشتم که رومی به اندازه آن بود. من تصمیم گرفتم تمام sprites من را فشار دهید تا رومی کوچکتر باشد. خوشبختانه، Game Boy Advance شامل ویژگی های decompression در BIOS خود است، بنابراین من فقط نیاز به اجرای فشار، و تماس با عملکرد builtin. اما صبر کنید: اگر من آن را در زمان اجرا فشار دهید، پس من واقعا هیچ کاری انجام نمی دهم. من نیاز به فشار دادن آن در زمان جمع آوری است. بنابراین من دوباره از تولید کد استفاده می کنم؟ Nope. یکی از بهترین ویژگی های عمومی Zig است که قادر به اجرا کد خود را در زمان جمعمن قادر به نوشتن یک ویژگی برای اجرای رمزگشایی طول اجرا، تماس با عملکرد، و ذخیره نتایج در یک پایانه جهانی بود. Zig مراقبت از بسیاری از آن، و ساخت کم کردن داده های من بسیار آسان است. کتابخانه استاندارد یکی از چیزهایی که من دوست دارم در مورد کتابخانه استاندارد Zig است. مطمئنا، شما می توانید از newlib برای به دست آوردن کتابخانه استاندارد C / C ++ استفاده کنید، اما همیشه احساس می کردم که من باید با یک زیر مجموعه کوچک تر از کتابخانه ها در نرم افزار دوست داشت این. Zig، با این حال، بسیار انعطاف پذیر است. کتابخانه در هسته آن در اطراف یک زبان با ژنرییک ها ساخته شده است، و اکثر ویژگی های کتابخانه برای حمایت از آنها ساخته شده است. و Zig از این قابلیت ها استفاده می کند تا شما را کنترل بیشتری در مورد راه که کتابخانه استاندارد از سایر زبان ها انجام میاگر شما به سرعت بسیاری از توزیع را انجام می دهید، شما می توانید از یک توزیع کننده arena استفاده کنید. اگر می خواهید به دنبال حافظه ای که آزاد نشده است، شما می توانید از یک توزیع کننده هدف عمومی استفاده کنید. اگر شما فقط می خواهید از malloc(1) استفاده کنید، از std.heap.c_allocator استفاده کنید. شما می توانید مجموعه ای از بائیت در حافظه در جایی داشته باشید و یک توزیع کننده حافظه ثابت را برای توزیع از آنجا تنظیم کنید. من واقعا نیازی به استفاده از هیچ توزیع کننده برای این پروژه نداشتم، اما اگر من انجام دادم، این آخرین کار خوبی خواهد کرد. چیزهایی مانند این باعث می شود احساس رایگان برای استفاده از کل کتابخانه استاندارد هر زمانی که من فکر می کنم که بهترین برای مشکل من است. این یک درمان خوب پس از نوشتن یک هسته بدون libc بود. توجهبه همین دلیل، کد نسبتا بزرگ برای پردازش نقاط پرتاب در نهایی دوگانه شامل نیست، زیرا زبان می تواند بگوید که از آن استفاده نمی شود. مسائل بدبختانه، Zig یک زبان کامل نیست. همانطور که با تعریف mxy، همه مسائل که من در اینجا مطرح می کنم به اندازه کافی خاص به Game Boy Advance هستند، و واقعاً این طور کلی نیست. Inline Assembly Zig پشتیبانی برای جمع آوری در خط، و آن را بسیار خوب است. متاسفانه، آن را تنها پشتیبانی برای یک خروج. برخی از BIOS عملکرد در GBA است که شما ممکن است استفاده از جمع آوری در خط برای جمع آوری ارزش های متعدد در رستاخیز های مختلف، که برای Zig مشکل است. این در حال حاضر در حال کار است به طوری که ممکن است در آینده بهبود می یابد. Thumb Code / Arm CPU Code Boy Advance Game Boy دارای دو حالت کار. حالت ARM پیشرفتهدر Game Boy Advance، تقریبا همیشه بهتر است از Thumb استفاده کنید، زیرا چگونه حافظه در کنسول کار می کند. با این حال، چیزهای خاصی وجود دارد که شما نمی توانید فقط با استفاده از Thumb انجام دهید. اگر شما می خواهید از یک اختلال دستگاه استفاده کنید، عملکردی که اختلال را مدیریت می کند باید در حالت ARM باشد. این معمولا یک مشکل نیست، زیرا ARM و Thumb عملکرد می توانند یکدیگر را بدون هیچ مشکلی تماس بگیرند. در C و C++، شما می توانید مشخص کنید که آیا یک عملکرد ARM یا Thumb مانند این است: attribute((target(“arm”))) void interrupt_handler() { … } به دانش من، شما نمی توانید این کار را در Zig انجام دهید. این کار آن را کمتر مناسب برای استفاده از زبان، از آنجا که شما نیاز به مشخص کردن فعالیت های ARM در یک واحد جمع آوری جداگسوال غیر مرتبط: آیا شما می دانید که شما نمی توانید به حافظه ویدئویی در Game Boy Advance در واحد های 8 بیتی بنویسید، و اگر انجام دهید، هنوز هم کار می کند اما تمام گرافیک شما با هیچ راه آشکار برای پیدا کردن آن، مگر اینکه شما یک پاراگراف خاص از سند را بخوانید؟ Hey آیا شما می دانید که هنگامی که شما یک حافظه باینری به اندازه ای بهینه سازی شده، کپی حافظه به واحد های 8 بیتی خواهد بود، اما نه اگر شما از حالت محاسبه استفاده می کنید؟ خوب در هر صورت. پس از اینکه من این را درک کردم، من هنوز هم مشکلات در اطمینان از این است که sprites و پله های من به طور درست کپی شده اند. گاهی اوقات، کمپلیور به خود خلاقانه تر می شود، و درک می کند که یک عملکرد که من نوشتم فقطمن می دانم که این یک شلیک طولانی است، اما اگر راهی برای مشخص کردن چگونگی یادگیری در بخش های آدرس خاصی وجود داشته باشد، خوب خواهد بود. شاید این نشانه ای است که من فقط نیاز به نوشتن زبان برنامه نویسی خودم دارم.
چرا مهمه؟
این مقاله نشان داد که Zig میتواند فرایند ساخت برنامههای تعبیهشده را بدون نصب بستههای متعدد و تنظیمات پیچیده انجام دهد. توسعهدهندگان بازیهای رترو و مهندسان سیستمهای توکار که به ابزارهای ساده و قابل اعتماد نیاز دارند، مستقیماً از این روش سود میبرند. چون زمان توسعه کاهش مییابد و خطاهای ابزار زنجیرهای کمتر میشود، هزینهٔ پروژه و زمان خروج به بازار کم میشود.
به درد کی میخوره؟
• توسعهدهندگان بازیهای رترو • مهندسان سیستمهای تعبیهشده • برنامهنویسانی که به ابزارهای کراس‑کامپایل ساده نیاز دارند • علاقهمندان به زبان Zig
تو عمل چی کار کنیم؟
خواننده میتواند با استفاده از Zig یک زنجیرهٔ ساخت یکپارچه برای GBA یا سایر پلتفرمهای توکار راهاندازی کند، بدون نیاز به devKitPro یا تنظیمات پیچیدهٔ GCC. همچنین میتواند از ساختارهای بسته برای دسترسی به رجیسترهای سختافزاری استفاده کرده و دادهها را در زمان کامپایل فشرده کند، که باعث کاهش حجم ROM میشود.
نظر Blue IT News
اگر به دنبال کاهش زمان تنظیم محیط و بهدست آوردن کنترل دقیق بر حافظه هستید، Zig گزینهٔ جذابی برای پروژههای توکار میشود؛ ولی برای استفادهٔ پیشرفته از Thumb/ARM هنوز باید راهحلهای ترکیبی در نظر بگیرید.
این صفحه ترجمه و تفسیر کاملی از گزارش اصلی Jonot است که توسط تیم تحریریه بلو آی تی نیوز به فارسی ترجمه و تحلیل شده. برای مشاهده نسخه اصلی، به منبع مراجعه کنید.