;**************************************************************************** ;HeliCave a 256 bytes game by Baudsurfer/rsi 2014 aka olivier.poudade.free.fr ; _ _ -- - -__ -_ ; -- --___ _ __--__ -" _ ; _ _ -- -_ "-_ ; /;:`. _--,_ ; ______ _,-'._,' /"("\"\ ; _,--''' `'-._,-'_,-' `' _/"/"|\ )\>_ ; ,' ` - .,_ __,-' ),-' _/"_." _/ / / \"\ ;( __|-`' . _,'/ /""_-" ,/" /\ \ ) "-,_ ; `--...'___,..--' / _-"/ ( .-/ \ ! ) \ _\"-_"\_ ; / _/,-'_,-' _ _ __ ___ _-"/_-" / ( | / \ | \ \_- "-_ __ _ ; (`---'' _,-' |_,- - -- -<_"__" / _/| \ \ | /! \ \ -_( _"-<_">-- - ; `----''|_,--' --"--"-" "-"' "-" '" _ ; -' _,-' jrei "" -_O "O-' '"> __ - - ; __ - O __ - - " - - jjs ; _ .-- " - """ ;Synopsis : Help helicopter pilot TC save Island Hoppers charity funds ; : from bankrupcy by escaping the nine Hawaïan island underwater ; : volcano caves through your unique flying skills avoiding the ; : lethal earthquake pillow lava flow thus saving the children. ; : See http://www.ltcstudentweb.com/birrn/charitable-work.html ;Controls : inscrease helicopter altitude. ;Tested on : WinXP SP3=Yes, Win7 v32-bit=Maybe, DosBox all=No. ;Credits : Jens "jrei" Reissenweber (ascii) John "jjs" Stachowicz (ascii) ;Greets : baah Cyg ferris Maracuja p01 Rez rrrola rudi sensenstahl Sir ; : Stingray wysiwtf and all forgotten assembly language programmers ;YouTube : http://youtu.be/pcdHY-eJVIY ;**************************************************************************** org 100h ;assumed dl=0 cx=ff sp=di=-2 bp=9xxh str equ 0f000fd1ch ;little endian str("L-0 " - "0000") beg:mov dword [si-26h],str;cs:0dah free placeholder in psp dta mov al,13h ;ah=set video mode,al=chained 320*200*256 AND cls int 10h ;heli. sprite=ascii(236)+ascii(235)+...ascii(195) spr:int 29h ;dos 2.x+ fast character i/o,al=char to write dec al ;reverse charmap order asci(255)->asci(108) loop spr ;len(charmap)=93h/147 vs. insufficient 13h/19 lgs cx,[bx] ;ds=9fffh,bx=0,cx=[0]=20cdh=8397d sub di,cx ;si=org=100h,di=0fffeh-20cdh=0df31h rep gs movsb ;copy heli sprite bytes to cs:df31h mov al,13h ;ntvdm can't pop ax with gs used apparently int 10h ;clear screen short form les di,[bx] ;bx=0,di=terrain array start address=20cdh=8397d mov al,051h ;bl=si+0aeh bh=0 ax=seed/ang mov dl,83h ;dl=synced al+50 param bez:inc dl ;al=bl=x ax=dw coord_x "mov dl,al" mov bl,al ;very modified tiny sine (left original comments) pusha ;save ax cx mul al ;ax=x*x mul cl ;ax=x*x*4/pi*pi xchg ax,bx ;bx=ax=x*x*4/pi*pi mul ch ;ax=x*4/pi shr ax,3 ;tweaked to reproduce some procedural graphics sbb ax,bx ;ax=(x*4/pi)-x*x*(4/pi*pi) mov cx,0c0bh ;ch=write gfx pixel fun, cl=color cx=col and ax,0fc0h ;and 0000111111100000b ax=(ax/32)%128=[0,127] rol ax,cl ;=sar ax,cl/and ax,127 /w cl=5, enables cl=11 use inc ah ;sub ax,64=position bezel rightside xchg ax,cx ;cx=col dx=row al=pixel color bh=ignored page int 10h ;bios video api dx=row bh=ignored 13H mode page popa ;restore ax cx skp:inc ax ;inc seed/angle loop bez ;repeat 65535 times snd:mov dx,331h ;dx=midi command port 331h (helicopter soundfont) mov al,3fh ;3fh=set UART mode on out dx,al ;send midi command dec dx ;dx=midi data/status port 330h mid equ 389a7dcah ;endian order cah=program change 7dh=program num. mov dword [si],mid ;... 9ah=channel select (11), 38h=note value lev:dec cl ;byte rollover cl=255 ini:inc di ;store flat terrain value before mov [di],dl ;flatten level start for safety outsb ;output dat msg. opportunistic note vol and on (7) loop ini ;255 columns landmark collision-free level start inc byte [0dch] ;[220d]++=increase level number gam:mov si,0dah ;si=218d=hexa val score head ptr gen:inc dx ;assume PF(t)=1=>y=y+1 in al,40h ;read rand from 8253 pic2/pit channel 0 aaa ;garble and affect flags jp dwn ;probability(pf)=50% dec dx ;PF(t)=0=>y=y dec dx ;PF(t)=0=>y=y-1 dwn:test dl,128 ;poor man's clipping : y>128 ? jnz gen ;repeat until valid conforming terrain value mov ah,al ;save rnd val in case of earthquake displacement adv:inc di ;di++=advance map ptr (speed/3) mov [di],dl ;store new col terrain value mov cl,0ch ;score format 8 chars+len(levelstr)=4 preceeding pusha ;save di=*map si=*score cx=len(score) bp=heli_y asc:lodsb ;handle this* unit digit add al,30h ;normalize to ascii '0' int 29h ;dos 2.x+ fast character i/o,al=char to write loop asc ;repeat left for (n-1) unit digits mov cl,0bfh ;x=191 wide ending at 255 test byte [si-3],cl ;bit test for earthquake event true for digit 0 jnz frm ;if no earthquake then goto frame sub cl,ah ;add eathquake displacement frm:mov bl,[di] ;terrain intervals bl=lo limit add bx,-98 ;-((256-64)/2)-sp startup value add bx,sp ;decrease cave height=increase level difficulty mov dX,0c8h ;display dx=row=200d tex:mov ax,di ;texture texel=x+dx imul dl ;tex=(x*dx)*y aaa ;tex&15>9 ? tex+=262 : tex&=15 and ax,sp ;tex&15>9 ? tex+=262&sp : tex&=15&sp cmp dl,bl ;(clipping) yy1 ? bottom terrain under cave jc put ;if so then text salc ;else y1[es:di+=2] ? jnc row ;no collision detected goto die:int 1ah ;ah=0=fun bios get system time test dl,dl ;dl=bda 18.2 Hz rtc little endian hibyte jnz die ;have max 14"=(256/18.2)" elapsed ? Dirty exit row:mov cl,9ah ;sprite cx=(scanline-sprite-collisiontest)/2 cmpsw ;si+=2 di+=2 (prefix rep=repnz unfit) loop $-1 ;next row (speed vs. size) 5*2+2+154*2=320 dec dx ;dx=row-- jnz cpy ;row==sprite height ? popa ;restore di=*map si=*score cx=len(score) bp=y in al,60h ;al=polled scancode of kbd 8042 controller aaa ;up=up down=up default=gravity startup=liftoff mov bx,140h ;assumption key up false jc kbd ;bx=+320 key up false =>altitude-- neg bx ;bx=-320 key up true =>altitude++ (cyclic stick) kbd:add bp,bx ;bp+=320(down) or bp-=320(up) rep lodsb ;si+=cl=0d3h=decimal score tail ptr, clears cf hex:dec si ;si-- ascending order=stored left to right (df=0) mov al,byte [si] ;get decimal unit inc ax ;test if decimal unit overflow aaa ;ascii adjust after addition jnc ten ;cf=0 => (al AND 0fh)<10 mov ax,cx ;al=0 reset unit digit and clear ah ten:mov byte [si],al ;player score=heli progression=linear delta t jc hex ;cf preserved -> add carry to next bcd left ? mov al,0e2h ;al=10^4 off=cursy=int(226/40)=cursx=(226/40)%25 mov [fs:450h],al ;set bda x cursor pos. for next putchar call mov [fs:41ch],al ;avoid key overflow,buff tail ptr=buff head ptr+al cmp si,ax ;is last rollover unit=10^4 ? jnz gam ;if last rollover unit<10^4 return to same level pusha ;sp-=16=new cave height for new level call lev ;sp-=2=new texture scheme for new level