📄 mos3de01.asm
字号:
;MOS3DE V 0.1 - MENUETOS 3D Engine V 0.1
; Compile with FASM for MENUET
; this is a very early Version: I'm so happy that it runs at all.
; Of course it's a bad ASM style and it can be optimized a lot.
; anyway - I have thought I uploap this so other PPL might optimize it
; as well or transform it to something completely diffrent.
; There are some Mouse- and Keyboardhandling Subs and Constructs. They are here
; because I will probably use them for the Navigation in a First Person
; Perspective Game - which is the goal of this project.
; http://www.melog.ch/mos_pub/ dietermarfurt@angelfire.com
; of course you can remove or replace them. It has only linear Texturemapping.
; Perspective Correction is a future option.
; a flag for multiple Textures selection should be implemented in the
; Meshfile Format. As I said - it's a very erarly version.
use32
org 0x0
db 'MENUET01' ; 8 byte id
dd 0x01 ; header version
dd START ; start of code
dd I_END ; size of image
dd 0x200000 ; memory for app
dd 0x7fff0 ; esp
dd 0x0 , 0x0 ; I_Param , I_Icon
START: ; start of execution
call init_gfx
call draw_window ; at first, draw the window
gamestart:
; ******* MOUSE CHECK *******
mov eax,37
mov ebx,1 ; check mouseposition
int 0x40
mov ebx,eax
shr eax,16
and eax,0x0000FFFF ; mousex
and ebx,0x0000FFFF ; mousey
mov [mousex],eax
mov [mousey],ebx
cmp eax,5 ; mouse out of window ?
jb check_refresh ; it will prevent an app-crash
cmp ebx,22
jb check_refresh
cmp eax, 320
jg check_refresh
cmp ebx,221
jg check_refresh
cmp eax,160 ; navigating?
jb m_left
cmp eax,170 ;
jg m_right
continue:
cmp ebx,100 ;
jb s_up
cmp ebx,144 ;
jg s_down
; ******* END OF MOUSE CHECK *******
check_refresh:
mov eax,23 ; wait for system event with 10 ms timeout
mov ebx,1 ; wait 10 ms, then continue
int 0x40
; mov eax,11 ; or use this for full speed instead
; int 0x40
cmp eax,1 ; window redraw request ?
je red2
cmp eax,2 ; key in buffer ?
je key2
cmp eax,3 ; button in buffer ?
je button2
call clear_screen
call updateworld
call put_screen
;call log ; used for debugging
mov edi,[mouseya] ; check flag if a refresh has to be done
cmp edi,1
jne gamestart
mov [mouseya],dword 0
jmp gamestart
; END OF MAINLOOP
red2: ; redraw
call draw_window
; call draw_stuff
jmp gamestart
key2: ; key
mov eax,2
int 0x40
cmp al,1
je gamestart ; keybuffer empty
cmp ah,27 ; esc=End App
je finish
cmp ah,178 ; up
je s_up
cmp ah,177 ; down
je s_down
cmp ah,176 ; left
je s_left
cmp ah,179 ; right
je s_right
jmp gamestart ; was any other key
s_up: ; walk forward (key or mouse)
mov eax,[vpx]
mov ebx,[vpy]
mov ecx,[vheading]
imul ecx,4
add ecx,sinus
mov edi,[ecx]
mov edx,[vheading]
imul edx,4
add edx,sinus
add edx,3600
cmp edx,eosinus ;cosinus taken from (sinus plus 900) mod 3600
jb ok200
sub edx,14400
ok200:
mov esi,[edx]
; sal esi,1 ; edit walking speed here
; sal edi,1
add eax,edi ; newPx
add ebx,esi ; newPy
mov edi,eax ; newPx / ffff
mov esi,ebx ; newPy / ffff
sar edi,16
sar esi,16
mov ecx,esi
sal ecx,5 ; equal *32
add ecx,edi
add ecx,grid
cmp [ecx],byte 0 ; collision check
jne cannotwalk0
mov [vpx],eax
mov [vpy],ebx
mov [mouseya],dword 1 ; set refresh flag
cannotwalk0:
jmp check_refresh
s_down: ; walk backward
mov eax,[vpx]
mov ebx,[vpy]
mov ecx,[vheading]
imul ecx,4
add ecx,sinus
mov edi,[ecx]
mov edx,[vheading]
imul edx,4
add edx,sinus
add edx,3600
cmp edx,eosinus ;cosinus taken from (sinus plus 900) mod 3600
jb ok201
sub edx,14400
ok201:
mov esi,[edx]
; sal esi,1 ; edit walking speed here
; sal edi,1
sub eax,edi ; newPx
sub ebx,esi ; newPy
mov edi,eax ; newPx / ffff
mov esi,ebx ; newPy / ffff
sar edi,16
sar esi,16
mov ecx,esi
sal ecx,5
add ecx,edi
add ecx,grid
cmp [ecx],byte 0
jne cannotwalk1
mov [vpx],eax
mov [vpy],ebx
mov [mouseya],dword 1
cannotwalk1:
jmp check_refresh
s_left: ; turn left (key)
mov edi,[vheading] ; heading
add edi,50
cmp edi,1800
jb ok_heading0
sub edi,1800
ok_heading0:
mov [vheading],edi
mov [mouseya],dword 1
jmp check_refresh
s_right: ; turn right
mov edi,[vheading]
sub edi,50
cmp edi,-1
jg ok_heading1
add edi,1800
ok_heading1:
mov [vheading],edi
mov [mouseya],dword 1
jmp check_refresh
m_left: ; turn left (mouse)
mov edi,[vheading] ; heading
mov ecx,160
sub ecx,eax
sar ecx,2
add edi,ecx
cmp edi,1800
jb ok_heading2
sub edi,1800
ok_heading2:
mov [vheading],edi
mov [mouseya],dword 1
jmp continue ; allow both: walk and rotate
m_right: ; turn right
mov edi,[vheading]
sub eax,170
sar eax,2
sub edi,eax
cmp edi,-1
jg ok_heading3
add edi,1800
ok_heading3:
mov [vheading],edi
mov [mouseya],dword 1
jmp continue
button2: ; button
mov eax,17 ; get id
int 0x40
cmp ah,1 ; button id=1 ?
jne gamestart
; eo GAME mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
finish:
mov eax,-1 ; close this program
int 0x40
; *********************************************
; ******* WINDOW DEFINITIONS AND DRAW ********
; *********************************************
draw_window:
mov eax,12 ; function 12:tell os about windowdraw
mov ebx,1 ; 1, start of draw
int 0x40
; DRAW WINDOW
mov eax,0 ; function 0 : define and draw window
mov ebx,192*65536+329 ; [x start] *65536 + [x size]
mov ecx,119*65536+264 ; [y start] *65536 + [y size]
mov edx,0x02ffffff ; color of work area RRGGBB,8->color gl
mov esi,0x80777777 ; color of grab bar RRGGBB,8->color gl
mov edi,0x00777777 ; color of frames RRGGBB
int 0x40
; WINDOW LABEL
mov eax,4 ; function 4 : write text to window
mov ebx,8*65536+8 ; [x start] *65536 + [y start]
mov ecx,0x00FFFFFF ; color of text RRGGBB
mov edx,labelt ; pointer to text beginning
mov esi,labellen-labelt ; text length
int 0x40
; CLOSE BUTTON
mov eax,8 ; function 8 : define and draw button
mov ebx,(329-19)*65536+12 ; [x start] *65536 + [x size]
mov ecx,5*65536+12 ; [y start] *65536 + [y size]
mov edx,1 ; button id
mov esi,0x777777 ; button color RRGGBB
int 0x40
mov eax,12 ; function 12:tell os about windowdraw
mov ebx,2 ; 2, end of draw
int 0x40
ret
; ---------------------------------------------------------------------
init_gfx:
; Pwidth = 63 Shl 16 ;original texture width in pixels -1 shl 16
; Pheight = 63 Shl 16 ;original texture height in pixels -1 shl 16
mov [pwidth],dword 63
shl dword[pwidth],16
mov [pheight],dword 63
shl dword[pheight],16
;; Read in a mesh
mov eax,0 ; tex1+4
mov edi,anz
add edi,4 ; beginning of mesh data
;using a copy will allow inverse kinematic transformations (future option)
readmesh:
mov edx,eax
add edx,a_xwww ; desti
mov ecx,[edi] ; value in ecx
mov [edx],ecx
add edi,4
;---
mov edx,eax
add edx,a_ywww ; desti
mov ecx,[edi] ; value in ecx
mov [edx],ecx
add edi,4
;---
mov edx,eax
add edx,a_zwww ; desti
mov ecx,[edi] ; value in ecx
mov [edx],ecx
add edi,4
;---
add eax,4
cmp edi,eo_mesh
jl readmesh
; zoom=-500
mov [zoom],dword -500
ret
;------------------------------------------------------------------
log:
;write some Variable info to screen (used for debugging)
pusha
mov edi,wonder ;a_xwww
;add edi,200
mov [remecx], dword 24
print:
mov eax,47
mov ebx,0x000f0000
;mov ebx,0x000f0100 ; hex
mov ecx,[edi]
mov edx,[remecx]
or edx,0x000C0000
mov esi,0x00ff0000
int 0x40
add [remecx],dword 8
add edi,dword 4
cmp [remecx], dword 250
jl print
popa
ret
; ---------------------------------------------------------------------
; UPDATE WORLD
; ---------------------------------------------------------------------
updateworld:
mov edx,[a_xw]
; Miny% = 32767
; Maxy% = 0
mov [miny],dword 32737
mov [maxy],dword 0
; Color 0,0,0 ; clear screen - l8er
; Rect 0,0,320,240,1
; a=a+1.0 ; automatic rotation...
add [a],dword 10
cmp [a],dword 3598
jl ok360
mov [a],dword 0
ok360:
; If a>359.9 Then a=0
; alpha=a
; beta=a
; gamma=a+a Mod 360
mov eax,[a]
mov [alpha],eax
mov [beta], eax
mov [gamma],eax
add [gamma],eax
cmp [gamma],dword 3599
jl ok360_2
sub [gamma],dword 3600
ok360_2:
; mausy#=0.1+(MouseY()/50.0) ; >>>>>>l8er
mov eax,[alpha]
mov [alphacopy],eax
mov eax,[beta]
mov [betacopy],eax
mov eax,[gamma]
mov [gammacopy],eax
; For i=0 To anz ; do rotation and projection etc
mov esi,0
for_i:
; *****************************
; ROTATE pitch jaw roll...
; *****************************
;; xl1#=zwww(i)*Sin(gamma)+xwww(i)*Cos(gamma)
mov eax,esi
imul eax,4
add eax,a_zwww
mov ebx,[eax]
mov eax,[gammacopy]
call get_sinus
imul ebx,[eax]
mov [tempdiv],ebx ; is zwww(i)*sin(gamma)
mov eax,esi
imul eax,4
add eax,a_xwww
mov ebx,[eax]
mov eax,[gammacopy]
call get_cosinus
imul ebx,[eax] ; is xwww*cos(gamma
add ebx,[tempdiv]
mov eax,ebx
;or eax,1
cdq
mov ecx,6553
idiv ecx
mov [xl1],eax
;; yl1#=ywww(i)
mov eax,esi
imul eax,4
add eax,a_ywww
mov ebx,[eax]
mov [yl1],ebx
;; zl1#=zwww(i)*Cos(gamma)-xwww(i)*Sin(gamma)
mov eax,esi
imul eax,4
add eax,a_zwww
mov ebx,[eax]
mov eax,[gammacopy]
call get_cosinus
imul ebx,[eax]
mov [tempdiv],ebx ; is zwww(i)*cos(gamma)
mov eax,esi
imul eax,4
add eax,a_xwww
mov ebx,[eax]
mov eax,[gammacopy]
call get_sinus
imul ebx,[eax] ; is xwww*sin(gamma
sub [tempdiv],ebx
mov eax,[tempdiv]
;or eax,1
cdq
mov ecx,6553 ; once 6500
idiv ecx
mov [zl1],eax
;
;-----------------------------------------------------------------------
;; xl2#=xl1
mov eax,[xl1]
mov [xl2],eax
;; yl2#=yl1*Cos(beta)-zl1*Sin(beta)
mov ebx,[yl1]
mov eax,[betacopy]
call get_cosinus
imul ebx,[eax]
mov [tempdiv],ebx ; is yl1*cos(beta)
mov ebx,[zl1] ; zl1
mov eax,[betacopy]
call get_sinus
imul ebx,[eax] ; is zl1*sin(beta
sub [tempdiv],ebx
mov eax,[tempdiv]
;or eax,1
cdq
mov ecx,6553
idiv ecx
mov [yl2],eax
;; zl2#=yl1*Sin(beta)+zl1*Cos(beta)
mov ebx,[yl1]
mov eax,[betacopy]
call get_sinus
imul ebx,[eax]
mov [tempdiv],ebx ; is yl1*sin(beta)
mov ebx,[zl1] ; zl1
mov eax,[betacopy]
call get_cosinus
imul ebx,[eax] ; is zl1*cos(beta
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -