كان التركيز الرئيسي لهذا المشروع هو أن يكون الناس قادرين على تعلم برمجة التجميع بطريقة ممتعة عن طريق القيام بالرسومات. يزيل Framework Burdern لتعلم Windows GUI وبرمجة X المباشرة وإعداد جميع لوحة المرجل وضرب الأرض كما هو الحال مع بعض الإرشادات التي يمكنهم رؤية وحدات البكسل على الشاشة دون جهد كبير على الإطلاق. بالإضافة إلى أنه من الممتع كتابة تأثيرات الرسومات على نمط التسعينيات والعروض التوضيحية.
هناك عرض توضيحي لقالب يمكنك استخدامه لإنشاء مشهد التجريبي الخاص بك. يمكنك استخدام هذا كمثال عن طريق نسخ الرمز إلى دليل الديموسين الخاص بك. * demoscenes yourdemo* ستحتاج جميع الكود إلى الذهاب إلى دليل AMD64 لأن هذا مشروع تجميع x86-64 يجب ألا يكون هناك أي c أو langauges الأخرى المستخدمة . سيحتاج ملف المصادر إلى تعديل لتغيير الاسم الهدف. يتم نسخ Makefile لكنك لا تقوم بتعديل ملف Make. لبناء المشروع الذي تستخدمه أمر BCZ . ستحتاج أيضًا إلى تحديث ملف DIRS من أجل إنشاء تطبيقاتك ومكتباتك باستخدام BCZ من أدلة الجذر.
هناك ثلاث وظائف لتنفيذ ما سيستخدمه المحرك للاتصال بك مرة أخرى.
هناك ثلاث وظائف لتنفيذ المحرك الذي سيستخدمه للمحرك للاتصال بك مرة أخرى للعبة.
يتم تمرير كل هذه الوظائف معلمة واحدة وهي MASTER_DEMO_STRUCT على النحو المحدد في Master.inc يتضمن هذا المخزن المؤقت للفيديو لـ "Demo" إلى جانب حجم الشاشة وبعض المعلومات الأخرى.
لاحظ أن الخطوة هي الطول الفعلي في بايت كل خط أفقي في المخزن المؤقت للفيديو. يتضمن جزءًا مخفيًا لا يجب عليك رسمه. لذا استخدم العرض لحساب حدود الرسم ولكن استخدم الخطوة لحساب كيفية الوصول إلى الخط الأفقي التالي في المخزن المؤقت للفيديو. ومع ذلك ، يمكنك أيضًا استخدام مكتبة المخزن المؤقت المزدوجة لتنفيذ الرسومات الخاصة بك وتحديثها على الشاشة باستخدام واجهة برمجة تطبيقات مزدوجة المخزن المؤقت.
هناك x64 سجلات متقلبة وغير متطايرة. يمكنك إلقاء نظرة عليها على MSDN: https://msdn.microsoft.com/en-us/library/9z1stfyw.aspx أيضًا ، ستحدث كل استدعاء دالة مع RSP محاذاة مع 0xfffffffffffffff8. إذا كنت تخطط لاستدعاء أي وظائف ، فيجب عليك محاذاة المكدس إلى 0xffffffffffffff0 لأن بعض الوظائف ستفترض أنها يمكنها استخدام الإرشادات التي تتطلب محاذاة مثل movaps. إذا لم يتم محاذاة المكدس ، فستواجه خطر التعطل في مكالمة وظائف أقل.
تتطلب مكالمات الوظائف في x86-64 أن يكون هناك 4 مواقع معلمة مخصصة على المكدس. تتم جميع تحفظات المكدس من قبل. endprolog بحيث يمكن للمشي مكدس العمل من خلال تتبع مقدار المساحة المحجوزة على المكدس. المعلمات الأربعة الأولى هي RCX أو XMM0 أو RDX أو XMM1 أو R8 أو XMM2 و R9 أو XMM3. يجب تمرير المعلمات التي تتجاوز 4 على المكدس بعد مواقع المكدس 4 المطلوبة التي يتم حجزها بغض النظر عن عدد المعلمات التي يتم تمريرها. لا يتم ملء المعلمات الأربعة الأولى أيضًا أثناء استخدام السجلات لتمرير تلك المعلمات. ومع ذلك ، فإن المساحة متاحة للاستخدام من خلال الوظيفة التي يتم استدعاؤها إما لحفظ المعلمات لأنها في سجلات متطايرة أو تستخدم المساحة لتوفير كل ما يحتاجه.
Parameter N (Not Required, must be populated with Nth parameter if exists)
...
Parameter 5 (Not Required, must be populated with 5th parameter if exists)
Parameter 4 (Required, but not populated use register)
Parameter 3 (Required, but not populated use register)
Parameter 2 (Required, but not populated use register)
Parameter 1 (Required, but not populated use register)
Return Address
Save registers
Locals
Parameter Frame for Function Calls in this function.
هناك نوعان من وحدات الماكرو في debug_public.inc ، الأول هو debug_rsp_check_macro الذي لا يفعل شيئًا إذا لم يتم بناء تصحيح الأخطاء ، ولكن عندما يتم تصميم التصحيح ، فإنك تضعه مباشرة بعد .endprolog وسوف تحقق من RSP أنه يتم توافقه أو int 3.
.ENDPROLOG
DEBUG_RSP_CHECK_MACRO
الماكرو التالي الذي يمكنك استخدامه هو debug_function_call بدلاً من استخدام تعليمات الاتصال. هذا الماكرو هو ببساطة الاتصال عندما لا يتم تمكين التصحيح. عند تمكين التصحيح ، فإنه سيوفر سجلات غير متطايرة قبل استدعاء وظيفتك ، ثم بعد استدعاء Functoin الخاص بك ، سوف يتحقق من صحة. بعد ذلك سوف يفسد جميع السجلات غير المتطايرة مع القمامة باستثناء Rax/XMM0 حيث يمكنها إرجاع البيانات من الوظيفة. الهدف من ذلك هو أنه إذا كنت قد افترضت أن السجلات المتقلبة احتفظت بالمعلومات التي يجبرهم ذلك على أمل أن يتسبب في حدوث حادث أو خطأ إذا كنت قد فعلت ذلك.
;
; Generate new random color
;
DEBUG_FUNCTION_CALL Math_rand
ما يلي يصف تخطيط بنية الدليل.
يحتوي الإطار على وظائف مختلفة يمكنك استخدامها لتسريع بناء التجريبي الخاص بك من خلال توفير وظائف روتينية أساسية.
dbuffer_create
dbuffer_updatescreen
dbuffer_clearbuffer
dbuffer_free
debug_is_enabled
debug_function_call
debug_rsp_check_macro
engine_debug
frameloop_create
frameloop_performframe
frameloop_reset
frameloop_free
soft3d_init
soft3d_setcamerarotation
soft3d_setViewDistance
soft3d_setViewPoint
soft3d_setaspectratio
soft3d_convert3dto2d
soft3d_close
vpal_create
VPAL_SETCOLORINDEX
VPAL_GETCOLORINDEX
VPAL_ROTATE
VPAL_ROTATERESET
VPAL_FREE
prm_drawcircle
prm_drawline
GameEngine_Init
GameEngine_Printword
GameEngine_loadgif
gameengine_convertimagetosprite
gameengine_displayfullScreenAnimatedImage
gameengine_displayCenteredImage
GameEngine_Free
inputX64_RegisterKeyPress
inputX64_RegisterKeyRelease
GIF_OPEN
gif_close
gif_numberofimages
gif_getimagesize
GIF_GETIMAGEWIDTH
gif_getimageheight
GIF_GETIMAGE32BPP
gif_getimage32bpprealtime
gif_getallimage32bpp
فيما يلي أمثلة ترميز حول كيفية استخدام بعض وظائف المكتبة والإطار في العرض التوضيحي الخاص بك.
إن إنشاء اللوحة بسيط ، فأنت فقط تزود عدد الألوان وحفظ عنوان الإرجاع كمقبض لوحة.
MOV RCX, 256
DEBUG_FUNCTION_CALL VPal_Create
TEST RAX, RAX
JZ @Failure_Exit
MOV [VirtualPallete], RAX
يمكنك بعد ذلك إنشاء الألوان لكل فهرس ملون. المثال أدناه يخلق لوحة بيضاء متزايدة. إذا كنت تستخدم واجهة برمجة تطبيقات مزدوجة المخزن المؤقت ، فيمكن أن تأخذ مقبض اللوحة وملء المخزن المؤقت للفيديو بألوان Appropraite.
@CreateWhitePalette:
MOV RAX, R12
MOV AH, AL
SHL RAX, 8
MOV AL, AH
MOV R8, RAX
MOV RDX, R12
MOV RCX, [VirtualPallete]
DEBUG_FUNCTION_CALL VPal_SetColorIndex
INC R12
CMP R12, 256
JB @CreateWhitePalette
إنشاء المخزن المؤقت المزدوج بسيط باستخدام واجهة برمجة التطبيقات على النحو المحدد أدناه.
MOV RDX, 1 ; 1 Byte Per pixels
MOV RCX, RSI ; MASTER_DEMO_STRUCT
DEBUG_FUNCTION_CALL DBuffer_Create
MOV [DoubleBufferPointer], RAX
TEST RAX, RAX
JZ @Failure_Exit
يمكن الوصول إلى المؤشر الذي تم إرجاعه بشكل مباشر مع عرض ارتفاع الشاشة X استنادًا إلى حجم البكسل المحدد.
MOV RCX, [DoubleBufferPointer]
MOV BYTE PTR [RCX], 10h
يمكن بعد ذلك تحديث الشاشة عن طريق مكالمة وظيفة واحدة.
;
; Update the screen with the buffer
;
MOV RCX, [DoubleBufferPointer]
MOV RDX, [VirtualPallete]
MOV R8, DB_FLAG_CLEAR_BUFFER
DEBUG_FUNCTION_CALL Dbuffer_UpdateScreen
هناك وحدات الماكرو والهياكل المدرجة في demoscene.inc بواسطة paramhelp_public.inc التي توفر طريقة سريعة وسهلة لإعداد إطار المكدس المحلي. شيء واحد يجب تذكره هو أن مساحة المكدس مجانية حقًا هذه الأيام ، لذا فإن الاحتفاظ بمساحة المكدس التي لا تحتاجها في هذا الإطار التجريبي البسيط هو توفير بعض الوقت من تخصيص كل مكدس على وجه التحديد إلى المساحة التي تحتاجها. ومع ذلك ، يمكنك الحد من وقت التنفيذ من خلال توفير السجلات التي تخطط لاستخدامها بالفعل. هناك وحدات الماكرو في ملف الرأس للمساعدة في ذلك من خلال تزويدك بهيكل وحدات الماكرو لحجز وحفظ السجلات الخاصة بك. إذا كنت بحاجة إلى استخدام المتغيرات المحلية ، فستحتاج إلى إنشاء هياكل إضافية خاصة بك ، وإذا كنت ترغب في توفير عدد قليل من السجلات ، فقد تحتاج إلى حفظ تلك الماكرو يدويًا فقط حتى الآن وحفظ جميع السجلات أو بعض السجلات المحددة.
يتم تعريف std_function_stack_min على أنها جميع سجلات الأغراض العامة غير المتطايرة و 8 معلمات لمكالمات الوظائف. يوضح المثال أدناه استخدامه لحفظ عدد قليل من سجلات GP المطلوبة.
alloc_stack(SIZEOF STD_FUNCTION_STACK_MIN)
save_reg rdi, STD_FUNCTION_STACK_MIN.SaveRegs.SaveRdi
save_reg rbx, STD_FUNCTION_STACK_MIN.SaveRegs.SaveRbx
save_reg rsi, STD_FUNCTION_STACK_MIN.SaveRegs.SaveRsi
save_reg r12, STD_FUNCTION_STACK_MIN.SaveRegs.SaveR12
.ENDPROLOG
DEBUG_RSP_CHECK_MACRO
... Function Code ...
MOV RSI, STD_FUNCTION_STACK_MIN.SaveRegs.SaveRsi[RSP]
MOV RDI, STD_FUNCTION_STACK_MIN.SaveRegs.SaveRdi[RSP]
MOV rbx, STD_FUNCTION_STACK_MIN.SaveRegs.SaveRbx[RSP]
MOV r12, STD_FUNCTION_STACK_MIN.SaveRegs.SaveR12[RSP]
ADD RSP, SIZE STD_FUNCTION_STACK_MIN
MOV EAX, 1
RET
ومع ذلك ، هناك ماكرو يتيح لك مجرد حفظ واستعادة جميع سجلات GP. يظهر مثال على ذلك أدناه.
alloc_stack(SIZEOF STD_FUNCTION_STACK_MIN)
SAVE_ALL_STD_REGS STD_FUNCTION_STACK_MIN
.ENDPROLOG
DEBUG_RSP_CHECK_MACRO
... Function Code ...
RESTORE_ALL_STD_REGS STD_FUNCTION_STACK_MIN
ADD RSP, SIZE STD_FUNCTION_STACK_MIN
MOV EAX, 1
RET
يوضح أدناه تعريفات الحد الأدنى وهناك دائمًا نسختين. الأول هو تخصيص المكدس للوظيفة الحالية والثانية تتضمن الوصول إلى معلمات المكدس التي تم تمريرها إليها من المتصل.
STD_FUNCTION_STACK_MIN struct
Parameters LOCAL_PARAMETER_FRAME8 <?>
SaveRegs SAVE_REGISTERS_FRAME <?>
Padding dq ?
STD_FUNCTION_STACK_MIN ends
STD_FUNCTION_STACK_MIN_PARAMS struct
Parameters LOCAL_PARAMETER_FRAME8 <?>
SaveRegs SAVE_REGISTERS_FRAME <?>
Padding dq ?
FuncParams FUNCTION_PARAMETERS_FRAME <?>
STD_FUNCTION_STACK_MIN_PARAMS ends
يوجد أيضًا إصدار يتضمن سجلات XMM بالإضافة إلى ماكرو لحفظ واستعادة جميع سجلات XMM. ومع ذلك ، فإن أيا من هذه الهياكل القياسية لها متغيرات محلية. إذا كنت بحاجة إلى تحديد المتغيرات المحلية ، فهذه هياكل رائعة للبدء بها ثم إضافة المتغيرات المحلية. أود أن أضيف متغيراتك المحلية إما حيث يكون متغير "الحشو" أو بين المعلمات وهيكل حفظ السجلات كما هو موضح في المثال أدناه. إذا كنت تضيف متغيرات محلية ، فيمكنك استخدام موضع الحشو ، فلن يلزم الاحتفاظ به. هناك للحفاظ على المحاذاة ولكن يمكنك ترتيب متغيراتك المحلية للتعويض عن مشكلة المحاذاة ، فقط التأكد من أنك لا تصف على MOVAPs عند حفظ سجلات XMM واستخدام Debug_RSP_CHECK_MACRO لضمان محاذاة المكدس. ستحتاج إلى تشغيل مع تمكين Debug Eque لتمكين اختبار اختبار الماكرو.
DEMO_FUNCTION_STACK_MIN_PARAMS struct
Parameters LOCAL_PARAMETER_FRAME8 <?>
; Local Variables Here
SaveRegs SAVE_REGISTERS_FRAME <?>
; Or Local Variables Here
FuncParams FUNCTION_PARAMETERS_FRAME <?>
DEMO_FUNCTION_STACK_MIN_PARAMS ends