;---"the wall in your mind" by Kuemmel for Outline 2020
;---"...inspired by sensenstahlism and rrrola's gaussian blurism
org 100h
use16

blur_style%=0  ;0 = gaussian blur by rrrola, 1 = 4 surrounding pixel average blur (takes 6 bytes more)
blur_iter%=8   ;blur iterations before next wall level

mov al,13h
int 10h
push 0a000h
pop ds
xchg ax,bp	   ;defined randomizer start with uneven number, ax=19

;---"greyscale palette
palette:				
    mov dx,0x3c8 ;safe way for real DOS...
    mov ax,cx
    out dx,al
    inc dx
    shr al,2
    out dx,al
    out dx,al
    out dx,al
loop palette

main_loop_reset:
mov bx,150*320	;build wall from bottom to top
main_loop:

;---"randomizer for stone surface
mov cx,50*320
plot_random_block:
   imul dx,bp	      ;randomizer
   mov byte[bx],dh
   inc bx
loop plot_random_block

pusha	    ;preserve ax,dx,bx,si
xchg ax,cx
dec ax	    ;create colour 0xffff with 2 bytes

;---"mörtel plot"
movzx dx,bl
shr dl,2
mov cx,640		    ;zwei linien
plot_hline_loop:
   test cl,1111111b		;steinbreite 64
   jnz skip_vhline
      mov di,50
	  plot_vline_loop:
	     imul si,di,-320
	     add si,dx		;steinversatz
	     mov word[si+bx],ax
	     dec di
	  jnz plot_vline_loop 
   skip_vhline:
   mov byte[bx-50*320],al
   mov byte[bx],al
   inc bx
loop plot_hline_loop   

;---"gaussian blur routine by RRROLA - comments added by me to understand it :-)"
;clear si needed !? => xor si,si
;dh must be zero
if blur_style%=0
mov dl,blur_iter%				;blur steps
gaussian_blur:					;operates on one screen, genius :-)
	mov bx,321					; 1 2 1
	vert_hor_pass: 
		std						; 2 4 2 / 16		;set direction flag to 1 => first pass is decrement !!!
		next_byte: 
			lodsb			    ; 1 2 1
			add [bx+si],al
			rcr byte[bx+si],1	; catches overflow also of the byte addition before and does a correct div by 2
		loop next_byte
		neg bx
		cld						; set direction flag to 0 => second pass is increment !!!
		js  next_byte			; +/- pass
		shr bx,7				; from +321 to +2 to 0 => two passes
	jnz vert_hor_pass			; vertical/horizontal pass
	dec dx
jnz gaussian_blur
end if

;---"4 pixel average blur"
;clear di needed !? => xor di,di
;ah should be 0 or the second pixel is ;-)
;dh must be 0
if blur_style%=1
mov cl,blur_iter%
	blur:
		mov al,byte[di+1]
		mov dl,[di-1]
		add ax,dx
		mov dl,[di+320]
		add ax,dx
		mov dl,[di-320]
		add ax,dx
		shr ax,2			;clears also ah for next round
		mov byte[di],al
	    inc di
	jnz blur
loop blur
end if

popa	    ;restore ax,dx,bx,si
;---"adjust randomizer	
add bp,4
;inc bp      ;inc twice to be uneven for randomizer
;---"handle overflow
sub bh,0x7d				;next layer on top 100*320
js main_loop_reset
;---"check keyboard" 
wait_for_keyboard:
in al,0x60				;check for ESC
dec ax					;...as ah is zero...
jnz main_loop
ret
