Fokus utama dari proyek ini adalah agar orang dapat belajar pemrograman perakitan dengan cara yang menyenangkan dengan melakukan grafik. Kerangka kerja menghilangkan burdern belajar Windows GUI dan pemrograman langsung X dan menyiapkan semua pelat boiler dan cukup mulai berjalan seperti dengan beberapa instruksi mereka dapat melihat piksel diatur di layar tanpa banyak usaha sama sekali. Plus itu menyenangkan untuk menulis efek grafis gaya tahun 1990 -an dan demo.
Ada demo template yang dapat Anda gunakan untuk membuat adegan demo Anda sendiri. Anda dapat menggunakan ini sebagai contoh dengan menyalin kode ke direktori Demoscene Anda sendiri. * Demoscenes YourDemo* Semua kode perlu masuk ke direktori AMD64 karena ini adalah proyek perakitan x86-64 seharusnya tidak ada C atau langauge lain yang digunakan . File sumber perlu dimodifikasi untuk mengubah nama target. Makefile disalin tetapi Anda tidak memodifikasi file Make. Untuk membangun proyek yang Anda gunakan perintah BCZ . Anda juga perlu memperbarui file DIRS agar aplikasi dan perpustakaan Anda dibangun menggunakan BCZ dari direktori root.
Ada tiga fungsi untuk diimplementasikan yang akan digunakan mesin untuk menelepon Anda kembali.
Ada tiga fungsi untuk diimplementasikan yang akan digunakan mesin untuk menelepon Anda kembali untuk permainan.
Semua fungsi ini dilewatkan satu parameter yang merupakan master_demo_struct sebagaimana didefinisikan dalam master.inc ini termasuk buffer video untuk "demo" bersama dengan ukuran layar dan beberapa informasi lainnya.
Perhatikan bahwa langkah adalah panjang sebenarnya dalam byte dari setiap garis horizontal dalam buffer video. Ini termasuk porsi tersembunyi yang tidak boleh Anda gambar. Jadi gunakan lebar untuk menghitung batas gambar tetapi gunakan langkah untuk menghitung cara mencapai garis horizontal berikutnya dalam buffer video. Namun, Anda juga dapat menggunakan pustaka buffer ganda untuk melakukan grafik Anda dan memperbaruinya ke layar menggunakan API buffer ganda.
Ada register x64 volatile dan tidak mudah menguap. Anda dapat melihatnya di msdn: https://msdn.microsoft.com/en-us/library/9z1stfyw.aspx Juga, setiap panggilan fungsi akan terjadi dengan RSP yang disejajarkan dengan 0xffffffffffffff8. Jika Anda berencana untuk memanggil fungsi apa pun, Anda harus menyelaraskan tumpukan ke 0xffffffffffffFF0 karena beberapa fungsi akan menganggap mereka dapat menggunakan instruksi yang memerlukan alignemnt seperti movap. Jika tumpukan tidak selaras, Anda berisiko menabrak beberapa panggilan fungsi yang lebih rendah.
Panggilan fungsi di x86-64 mensyaratkan bahwa ada 4 lokasi parameter yang dicadangkan pada tumpukan. Semua reservasi tumpukan dilakukan sebelumnya .EnDPROGROG sehingga tumpukan dapat bekerja dengan melacak jumlah ruang yang disediakan di tumpukan. Empat parameter pertama adalah RCX atau XMM0, RDX atau XMM1, R8 atau XMM2 dan R9 atau XMM3. Parameter di luar 4 harus diteruskan pada tumpukan setelah 4 lokasi tumpukan yang diperlukan yang dicadangkan tidak peduli berapa banyak parameter yang dilewati. 4 parameter pertama juga tidak dihuni saat Anda menggunakan register untuk melewati parameter tersebut. Namun, ruang tersedia untuk digunakan oleh fungsi yang dipanggil untuk menyimpan parameter karena mereka berada dalam register yang mudah menguap atau menggunakan ruang untuk menghemat apa pun yang dibutuhkan.
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.
Ada dua makro debug di debug_public.inc, yang pertama adalah debug_rsp_check_macro yang tidak melakukan apa -apa jika debug tidak sedang dibangun tetapi ketika debug dibangun, Anda meletakkannya langsung setelah .EndPolog dan akan memeriksa RSP bahwa itu diselaraskan atau int 3.
.ENDPROLOG
DEBUG_RSP_CHECK_MACRO
Makro berikutnya yang dapat Anda gunakan adalah debug_function_call alih -alih menggunakan instruksi panggilan. Makro ini hanya panggilan ketika debug tidak diaktifkan. Ketika debug diaktifkan, itu akan menyimpan register yang tidak mudah menguap sebelum fungsi Anda menelepon, kemudian setelah functoin Anda akan memverifikasi bahwa mereka benar. Ini kemudian akan merusak semua register non-volatile dengan sampah kecuali untuk RAX/XMM0 karena mereka dapat mengembalikan data dari fungsi. Tujuannya adalah bahwa jika Anda mengasumsikan register yang tidak stabil. Informasi yang dipertahankan, ini memaksa mereka untuk diharapkan menyebabkan kecelakaan atau bug jika Anda telah melakukan ini.
;
; Generate new random color
;
DEBUG_FUNCTION_CALL Math_rand
Berikut ini menjelaskan tata letak struktur direktori.
Kerangka kerja berisi berbagai fungsi yang dapat Anda gunakan untuk mempercepat pembangunan demo Anda dengan menyediakan fungsionalitas rutin dasar.
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_DisplayCentedImage
GameEngine_Free
Inputx64_registerkeypress
Inputx64_registerkeyrelease
Gif_open
Gif_close
Gif_numberofimages
Gif_getimageSize
Gif_getimagewidth
Gif_getimageHeight
Gif_getimage32bpp
Gif_getimage32bpprealtime
Gif_getallimage32bpp
Berikut ini adalah contoh pengkodean tentang cara menggunakan beberapa fungsionalitas perpustakaan dan kerangka kerja dalam demo Anda.
Penciptaan palet sederhana, Anda hanya menyediakan jumlah warna dan menyimpan alamat pengembalian sebagai pegangan palet.
MOV RCX, 256
DEBUG_FUNCTION_CALL VPal_Create
TEST RAX, RAX
JZ @Failure_Exit
MOV [VirtualPallete], RAX
Anda kemudian dapat menghasilkan warna untuk setiap indeks warna. Contoh di bawah ini menciptakan palet putih yang meningkat. Jika Anda menggunakan Double Buffer API, itu dapat mengambil pegangan palet dan mengisi buffer video dengan warna -warna 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
Pembuatan buffer ganda sederhana menggunakan API sebagaimana didefinisikan di bawah ini.
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
Pointer yang dikembalikan dapat diakses secara langsung sebagai lebar layar x lebar berdasarkan ukuran piksel yang ditentukan.
MOV RCX, [DoubleBufferPointer]
MOV BYTE PTR [RCX], 10h
Layar kemudian dapat diperbarui dengan satu panggilan fungsi.
;
; Update the screen with the buffer
;
MOV RCX, [DoubleBufferPointer]
MOV RDX, [VirtualPallete]
MOV R8, DB_FLAG_CLEAR_BUFFER
DEBUG_FUNCTION_CALL Dbuffer_UpdateScreen
Ada makro dan struktur yang termasuk dalam demoscene.inc oleh paramhelp_public.inc yang memberikan cara yang cepat dan mudah untuk mengatur bingkai tumpukan lokal. Satu hal yang perlu diingat adalah bahwa ruang tumpukan benar -benar gratis hari ini, jadi memesan ruang tumpukan yang tidak Anda butuhkan dalam kerangka demo sederhana ini akan menghemat waktu daripada menyesuaikan setiap tumpukan khusus untuk ruang yang Anda butuhkan. Namun, Anda dapat membatasi waktu eksekusi dengan hanya menyimpan register yang sebenarnya Anda rencanakan untuk digunakan. Ada makro dalam file header untuk membantu dengan ini dengan menyediakan struktur dan makro untuk memesan dan menyimpan register Anda. Jika Anda perlu menggunakan variabel lokal, Anda perlu membuat struktur tambahan sendiri dan jika Anda hanya ingin menyimpan beberapa register, Anda mungkin perlu menyimpannya secara manual serta makro hanya melangkah sejauh ini dan menyimpan semua register atau beberapa register tertentu.
STD_Function_stack_min didefinisikan sebagai semua register tujuan umum yang tidak mudah menguap dan 8 parameter untuk panggilan fungsi. Contoh di bawah ini menunjukkan menggunakannya untuk menyimpan hanya beberapa register dokter umum yang diperlukan.
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
Namun, ada makro yang memungkinkan Anda untuk menyimpan dan memulihkan semua register GP. Contohnya ditunjukkan di bawah ini.
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
Di bawah ini menunjukkan definisi minimum dan selalu ada dua versi. Yang pertama adalah alokasi tumpukan untuk fungsi saat ini dan yang kedua termasuk akses ke parameter tumpukan yang diteruskan ke sana dari penelepon.
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
Ada juga versi yang menyertakan register XMM serta makro untuk menyimpan dan mengembalikan semua register XMM. Namun, tidak satu pun dari struktur standar ini memiliki variabel lokal. Jika Anda perlu mendefinisikan variabel lokal, ini adalah struktur yang bagus untuk memulai dan kemudian menambahkan variabel lokal Anda. Saya akan menambahkan variabel lokal Anda baik di mana variabel "padding" berada atau di antara parameter dan struktur register simpan seperti yang ditunjukkan pada contoh di bawah ini. Jika Anda menambahkan variabel lokal, Anda dapat menggunakan posisi padding, tidak perlu disimpan. Di sana adalah untuk menjaga penyelarasan tetapi Anda dapat mengatur variabel lokal Anda untuk menebus masalah penyelarasan, cukup pastikan bahwa Anda tidak menjebak pada gerakan saat menyimpan register XMM dan menggunakan debug_rsp_check_macro untuk memastikan penyelarasan tumpukan dipertahankan. Anda perlu menjalankan dengan debug equal diaktifkan untuk memiliki penegakan tes makro.
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