Основное внимание в этом проекте было для того, чтобы люди могли изучать программы сборки в веселом способе, выполняя графику. Фреймворк удаляет Бердер, изучая графический интерфейс Windows, и настраивает программирование и настройку всей котловой пластины и просто нажимает на землю, как и с помощью нескольких инструкций, которые они могут видеть, которые пиксели устанавливаются на экране без особых усилий. Кроме того, интересно писать графические эффекты и демонстрации в стиле 1990 -х годов.
Существует демонстрация шаблона, которую вы можете использовать для создания собственной демонстрационной сцены. Вы можете использовать это в качестве примера, копировав код в свой собственный каталог демоссена. * Demossenes yourdemo* Весь код должен будет перейти в каталог AMD64 , так как это проект сборки x86-64, не должно быть никакого использования C или других лангаугес . Файл источников нуждается в изменении, чтобы изменить целевое имя. Makefile скопирован, но вы не изменяете файл Make. Чтобы создать проект, вы используете команду BCZ . Вам также нужно будет обновить файл DIRS , чтобы ваши приложения и библиотеки были созданы с использованием BCZ из корневых каталогов.
Существует три функции для реализации, которые двигатель будет использовать для вас обратно.
Существует три функции для реализации, которые двигатель будет использовать, чтобы вызовать вас для игры.
Все эти функции передаются одним параметром, который является Master_demo_struct , как определено в Maven.inc. Это включает в себя видео буфер для «демонстрации», а также размер экрана и некоторая другая информация.
Обратите внимание, что шаг - это фактическая длина в байтах каждой горизонтальной линии в видео буфере. Он включает в себя скрытую часть, которую вы не должны рисовать. Поэтому используйте ширину для расчета границ рисования, но используйте шаг, чтобы вычислить, как добраться до следующей горизонтальной линии в видео буфере. Тем не менее, вы также можете использовать библиотеку двойного буфера для выполнения вашей графики и обновить ее на экран, используя API двойного буфера.
Есть x64 летучие и не нестабильные регистры. Вы можете посмотреть на них на MSDN: https://msdn.microsoft.com/en-us/library/9z1stfyw.aspx. Также каждый вызов функции будет происходить с RSP, выровненным до 0xffffffffffffffff8. Если вы планируете вызывать какие -либо функции, вы должны согласовать стек с 0xffffffffffffffff0, так как некоторые функции предполагают, что они могут использовать инструкции, которые требуют Alignemnt, таких как Movaps. Если стек не выровнен, вы используете риск сбоя в некотором вызове с более низким вызовом.
Вызовы функций в x86-64 требуют, чтобы в стеке было зарезервировано 4 местоположения параметров. Все резервирование стека выполняются до .endProlog, так что ходьбы стека могут работать, отслеживая количество места, зарезервированного в стеке. Первыми четырьмя параметрами являются RCX или XMM0, RDX или XMM1, R8 или XMM2 и R9 или XMM3. Параметры за пределами 4 должны быть переданы в стеке после необходимых 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 есть два макроса отладки.
.ENDPROLOG
DEBUG_RSP_CHECK_MACRO
Следующий макрос, который вы можете использовать, - это DEBUG_FUNCTION_CALL вместо использования инструкции по вызову. Этот макрос просто вызов, когда отладка не включена. Когда отладка будет включена, он сохранит нелетую регистры перед вызовом функции, после чего ваш функциональный вызов будет проверять, что они верны. Затем он испортит все нелетучивые регистры с мусором, за исключением 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_NUMBEROFIMAGE
GIF_GETIMAGESIZE
GIF_GETIMAGEWIDTH
GIF_GETIMAGEHEITH
GIF_GETIMAGE32BPP
GIF_GETIMAGE32BPPREALTIME
GIF_GETALLIMAGE32BPP
Следующие примеры кодирования того, как использовать некоторые из функциональности библиотеки и структуры в вашей демонстрации.
Создание палитры простое, вы просто предоставляете количество цветов и сохраняете обратный адрес в качестве ручки палитры.
MOV RCX, 256
DEBUG_FUNCTION_CALL VPal_Create
TEST RAX, RAX
JZ @Failure_Exit
MOV [VirtualPallete], RAX
Затем вы можете генерировать цвета для каждого индекса цвета. Приведенный ниже пример создает растущую белую палитру. Если вы используете API двойного буфера, он может взять ручку палитры и заполнить видео буфера с помощью цветов 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
Создание двойного буфера просто с использованием API, как определено ниже.
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. Однако ни одна из этих стандартных структур не имеет локальных переменных. Если вам нужно определить локальные переменные, то это отличные структуры, с которых можно начать, а затем добавить ваши локальные переменные. Я бы добавил ваши локальные переменные, где является переменная «прокладки», либо между параметрами и структурой Save Registers, как показано в приведенном ниже примере. Если вы добавляете локальные переменные, вы можете использовать позицию заполнения, ее не нужно сохранять. Он должен поддерживать выравнивание, но вы можете организовать свои локальные переменные, чтобы компенсировать проблему выравнивания, просто убедитесь, что вы не ловите в движении при сохранении регистров XMM и используйте Debug_rsp_check_macro, чтобы убедиться, что выравнивание стека поддерживается. Вам нужно будет запустить с отладочной работой, чтобы иметь макро -тестирование.
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