Эта статья целиком посвящена
ассемблерной разработке игр . Будет рассмотрен широкий круг вопросов -
от структурированного кода до графических аспектов . В широком смысле - для тех , кто
хотел бы научиться тому , чего не знал прежде ... Мало кто знает , что
полностью виндовское приложение можно написать на чистом асм-е . Способность читать . Для тех , кто
хочет писать , нужен MASM 6.11+. Общеизвестно , что
любой компилятор генерит код , в котором неизбежно присутствуют баги . Асм
- трудный язык как для понимания , так и для написания , что особенно
справедливо для дос-а . С переходом на виндовский асм многое меняется .
В чтении труден не
только асм - в си бывают такие дебри , что сам черт ногу сломает .
Читабельность исходников зависит от квалификации программера . Вообще-то
тут еще надо разобраться , что сложнее : сложить 2 переменные в асме или
проследить иерархию какой-нибудь виртуальной функции . Здесь комментарий
решает все . Помните : то , что известно вам , не значит , что это же
известно другим . Далее , вопрос с
портабельностью . Все больше игрушек пишется под винды . Это означает ,
что код привязан к директу и к WIN32 API . Конечно , асм труден в
понимании . На этой странице будут показаны его основы . Писание на
виндовском асм-е с помощью масм-а подозрительно напоминает сишные
исходники , и я думаю , что вы не должны быть разочарованы . Для начала предположим , что вы
знакомы с X86-архитектурой . Прежде всего нужно понимать , что в
асме все основано на командах , называемых инструкциями . Эта инструкция копирует из одного
места в другое : вы можете копировать из регистра в регистр , из
регистра в память , из памяти в регистр , но ! Нельзя с помощью этой
инструкции копировать напрямую из памяти в память . Example: Это 2 инструкции
сложения и вычитания . Example: Это инструкции
умножения и деления . Example: Вообще , инструкций море
. Но оставим их и примем правила вызова функций такие же , как и в win32 .
Это означает невиданную доселе в асме вещь : нам не надо будет заботиться
об очистке стека от параметров , это все будет прозрачно . Для вызова
функции мы просто будем использовать опцию INVOKE
. Ну и какой это асм ?.... Но для вызова функции нужно сначала
поиметь ее прототип , а потом уже вызывать . Вообще , масм обеспечивает высокий
уровень синтаксиса при написании . В нем есть конструкции , позволяющие
писать логику If-Then-Else и циклы For loops аналогично сишным
конструкциям . Несколько слов о проектировании игр
. Часто этим пренебрегают и сразу кидаются кодировать то , что в голову
пришло . Как говорится , сначала было слово .
Для написания игры сначала нужно представить в голове , как она будет
работать . Иногда просто полезно описать СЛОВАМИ то , что вы хотите видеть
в своей игре . Далее , необходимо продумать детали
: будут ли в игре элементы соревнования , нужны ли опции загрузки ,
сколько будет уровней и что должно происходить в их конце , будет ли
интродукция и т.д. После этого нужно будет
приниматься за наброски уровней . Какой должен быть экран и интерфейс ? Всегда имеет смысл насыщать код
возможно большим количеством комментариев , чем лично я , например ,
всегда пренебрегаю ... Далее следует примерная схема
организации ассемблерного игрового кода :О чем эта статья ?
Для кого это ?
Что для этого надо
?
Почему Ассемблер?
Основы Win32 ASM
MOV
MOV EAX, 30
MOV EBX, EAX
MOV my_var1, EAX
MOV DWORD PTR my_var, EAX
В первом примере число 30 копируется в регистр EAX . Во втором
примере регистр EAX копируется в регистр EBX . В 3-м примере регистр EAX
копируется в память . В 4-м примере регистр EAX копируется в то место
памяти , куда УКАЗЫВАЕТ пойнтер my_var , причем префикс DWORD указывает
на то , что пересылаются 4 байта .ADD &
SUB
ADD EAX, 30
SUB EBX, EAX
В этом примере к содержимому регистра EAX прибавляется 30 и затем
его содержание вычитается из регистра EBX . MUL &
DIV
MOV EAX, 10
MOV ECX, 30
MUL ECX
XOR EDX, EDX
MOV ECX, 10
DIV ECX
Сначала
загружаем в EAX=10 и ECX=30. EAX по умолчанию всегда один из 2-х
сомножителей , посему 3-я команда перемножает EAX и ECX . Инструкция XOR
обнуляет регистр EDX для того , чтобы после деления целая часть
результата оказалась в регистре EAX , а дробная , если таковая окажется
- в регистре EDX .Код
Назад
;###########################################################################
;###########################################################################
; ABOUT SPACE-TRIS:
;
; Главная секция - WinMain и т.д.
;
; - WinMain()
; - WndProc()
; - Main_Loop()
; - Game_Init()
; - Game_Main()
; - Game_Shutdown()
;
;
;###########################################################################
;###########################################################################
;###########################################################################
;###########################################################################
; THE COMPILER OPTIONS
;###########################################################################
;###########################################################################
.386
.MODEL flat, stdcall
OPTION CASEMAP :none ; case sensitive
;###########################################################################
;###########################################################################
; THE INCLUDES SECTION
;###########################################################################
;###########################################################################
;==================================================
; хидеры для Windows structs,
; unions, constants
;==================================================
INCLUDE Includes\Windows.inc
;================================================
; хидеры для Window calls
;================================================
INCLUDE \masm32\include\comctl32.inc
INCLUDE \masm32\include\comdlg32.inc
INCLUDE \masm32\include\shell32.inc
INCLUDE \masm32\include\user32.inc
INCLUDE \masm32\include\kernel32.inc
INCLUDE \masm32\include\gdi32.inc
;====================================
; хидеры Direct Draw
;====================================
INCLUDE Includes\DDraw.inc
;===============================================
; либы
;================================================
INCLUDELIB \masm32\lib\comctl32.lib
INCLUDELIB \masm32\lib\comdlg32.lib
INCLUDELIB \masm32\lib\shell32.lib
INCLUDELIB \masm32\lib\gdi32.lib
INCLUDELIB \masm32\lib\user32.lib
INCLUDELIB \masm32\lib\kernel32.lib
;=================================================
; хидеры с прототипами
;=================================================
INCLUDE Protos.inc
;###########################################################################
;###########################################################################
; LOCAL MACROS
;###########################################################################
;###########################################################################
szText MACRO Name, Text:VARARG
LOCAL lbl
JMP lbl
Name DB Text,0
lbl:
ENDM
m2m MACRO M1, M2
PUSH M2
POP M1
ENDM
return MACRO arg
MOV EAX, arg
RET
ENDM
RGB MACRO red, green, blue
XOR EAX,EAX
MOV AH,blue
SHL EAX,8
MOV AH,green
MOV AL,red
ENDM
hWrite MACRO handle, buffer, size
MOV EDI, handle
ADD EDI, Dest_index
MOV ECX, 0
MOV CX, size
ADD Dest_index, ECX
MOV ESI, buffer
movsb
ENDM
hRead MACRO handle, buffer, size
MOV EDI, handle
ADD EDI, Spot
MOV ECX, 0
MOV CX, size
ADD Spot, ECX
MOV ESI, buffer
movsb
ENDM
;#################################################################################
;#################################################################################
; глобальные переменные
;#################################################################################
;#################################################################################
;#################################################################################
;#################################################################################
; External variables
;#################################################################################
;#################################################################################
;#################################################################################
;#################################################################################
; BEGIN INITIALIZED DATA
;#################################################################################
;#################################################################################
.DATA
;#################################################################################
;#################################################################################
; BEGIN CONSTANTS
;#################################################################################
;#################################################################################
;#################################################################################
;#################################################################################
; BEGIN EQUATES
;#################################################################################
;#################################################################################
;=================
;Utility Equates
;=================
FALSE EQU 0
TRUE EQU 1
;#################################################################################
;#################################################################################
; BEGIN THE CODE SECTION
;#################################################################################
;#################################################################################
.CODE
start:
;########################################################################
; WinMain Function
;########################################################################
;########################################################################
; End of WinMain Procedure
;########################################################################
;########################################################################
; Main Window Callback Procedure -- WndProc
;########################################################################
;########################################################################
; End of Main Windows Callback Procedure
;########################################################################
;========================================================================
;========================================================================
; THE GAME PROCEDURES
;========================================================================
;========================================================================
;########################################################################
; Game_Init Procedure
;########################################################################
;########################################################################
; END Game_Init
;########################################################################
;########################################################################
; Game_Main Procedure
;########################################################################
;########################################################################
; END Game_Main
;########################################################################
;########################################################################
; Game_Shutdown Procedure
;########################################################################
;########################################################################
; END Game_Shutdown
;########################################################################
;######################################
; THIS IS THE END OF THE PROGRAM CODE #
;######################################
END start