memories: work on tunnel

This commit is contained in:
Vince Weaver 2020-05-07 15:22:06 -04:00
parent 3524f3c9a0
commit db894d69cd
2 changed files with 243 additions and 40 deletions

View File

@ -28,9 +28,9 @@ static unsigned short frame;
#if 0
static unsigned short stack[128];
static int sp=0;
static unsigned short ax,bx,cx,dx,es;
static int cf=0,of=0,zf=0,sf=0;
static int sp=0;
/* unsigned multiply */
static void mul_16(unsigned short value) {
@ -73,7 +73,6 @@ static void imul(short value) {
*/
/* signed multiply */
static void imul_8(char value) {
@ -204,8 +203,9 @@ static void div_8(unsigned char value) {
}
#endif
#if 0
static void push(int value) {
//printf("Pushing %x\n",value);
stack[sp]=value;
@ -408,40 +408,45 @@ fx4q:
#endif
/* raycast bent tunnel */
static int fx5(int xx, int yy, int xprime) {
return 0;
}
#if 0
unsigned char al,cl;
unsigned short temp;
dx=((yy&0xff)<<8) | (xprime&0xff);
unsigned char al;
unsigned short xcoord,ycoord;
signed short color,yproj,xproj,depth,ax=0;
int zf=0;
signed char m1,m2;
/* adjust to be centered */
xcoord=(xprime-10)*4;
ycoord=(yy-10)*4;
/* set depth to -9 (move backwards) */
depth=(-9&0xff);
cx=cx&0xff00;
cx|=(-9&0xff); // mov cl,-9 ; start with depth 9 (moves backwards)
fx5L:
cl=cx&0xff;
/* put Ycoord into AL */
al=ycoord&0xff;
/* center Y. Necessary? */
al-=24;
push(dx); // push dx ; save DX, destroyed inside loop
al=(dx>>8)&0xff;// mov al,dh ; get Y into AL
al-=100; // sub al,100 ; centering Y manually
ax=ax&0xff00;
ax|=(al&0xff);
/* 8x8 signed multiply Ycoord*depth to get projection */
m1=al;
m2=depth&0xff;
yproj=m1*m2;
/* only top used? */
imul_8(cl); // imul cl ; multiply AL=Y by current distance to get projection
// xchg ax,dx ; gt X into AL while saving DX
temp=ax;
ax=dx;
dx=temp;
/* Get X paramater */
al=xcoord;
/* add distance to projection (bend right) */
al+=depth&0xff;
al=ax&0xff;
al+=cl; // add al,cl ; add distance to projection (bend right)
/* 8x8 signed multiply Ycoord*depth to get projection */
m1=al;
m2=depth&0xff;
xproj=m1*m2;
ax=ax&0xff00;
ax|=(al&0xff);
imul_8(cl); // imul cl ; multiply AL=X by the current projection
al=(dx>>8)&0xff;// mov al,dh ; get projection(1) in AL
al^=(ax>>8); // xor al,ah ; combine with projection(2)
al=(yproj>>8)&0xff;// mov al,dh ; get projection(1) in AL
al^=(xproj>>8); // xor al,ah ; combine with projection(2)
al+=4; // add al,4 ; center the walls around 0
if (al&-8) { // test al,-8 ; test if the wall is hit
zf=0;
@ -450,23 +455,22 @@ fx5L:
zf=1;
}
dx=pop(); // pop dx (restore dx)
cx&=0xff00;
cx|=(cl&0xff);
cx--;
if ((cx!=0) && (zf==1)) goto fx5L;
depth--;
if ((depth!=0) && (zf==1)) goto fx5L;
// loopz fx5L (repeat until "hit" or "iter=max"
cx=cx-frame; // sub cx,bp ; offset depth by time
al^=(cx&0xff); // xor al,cl ; XOR pattern for texture
depth=depth-frame; // sub cx,bp ; offset depth by time
// color=ax;
al^=(depth&0xff); // xor al,cl ; XOR pattern for texture
// ah=al/6;
al=al%6; // aam 6 ; irregular pattern with MOD 6
color=color; // aam 6 ; irregular pattern with MOD 6
al+=20; // add al,20 ; offset into grayscale pattern
ax=al&0xff;
return ax;
}
#endif
/* ocean night */
static int fx6(int xx, int yy, int xprime) {
@ -547,12 +551,12 @@ int main(int argc, char **argv) {
which=frame/512;
switch (which&0xff) {
case 0: color=fx2(xx,yy,xprime); break;
case 0: color=fx5(xx,yy,xprime); break;
case 1: color=fx1(xx,yy,xprime); break;
case 2: color=fx0(xx,yy,xprime); break;
case 3: color=fx3(xx,yy,xprime); break;
case 4: color=fx4(xx,yy,xprime); break;
case 5: color=fx5(xx,yy,xprime); break;
case 5: color=fx2(xx,yy,xprime); break;
case 6: color=fx6(xx,yy,xprime); break;
case 7: return 0;
default: printf("Trying effect %d\n",which);
@ -567,6 +571,7 @@ int main(int argc, char **argv) {
/* so wraps 3 times before updating screen? */
}
}
if (frame%128==0) printf("frame: %d\n",frame);
grsim_update();

198
hellmood_memories/tunnel.s Normal file
View File

@ -0,0 +1,198 @@
; Tunnel, based on the code in Hellmood's Memories
; by deater (Vince Weaver) <vince@deater.net>
; Zero Page
COLOR = $30
XCOORD = $F0
YCOORD = $F1
DEPTH = $F2
VALUE = $F6
M1 = $F7
M2 = $F8
FRAME = $F9
TEMP = $FA
; Soft Switches
KEYPRESS= $C000
KEYRESET= $C010
SET_GR = $C050 ; Enable graphics
FULLGR = $C052 ; Full screen, no text
; ROM routines
PLOT = $F800 ; plot, horiz=y, vert=A (A trashed, XY Saved)
SETCOL = $F864
SETGR = $FB40
tunnel:
;===================
; init screen
jsr SETGR ; 3
bit FULLGR ; 3
tunnel_forever:
inc FRAME ; 2
ldx #47 ; 2
yloop:
ldy #39 ; 2
xloop:
; Xcoord = (x-10)*4
sec ; 1
tya ; 1
sbc #10 ; 2
asl ; 1
asl ; 1
sta XCOORD ; 2
; Ycoord = (y-10)*4
sec ; 1
txa ; 1
sbc #10 ; 2
asl ; 1
asl ; 1
; center
sbc #24
sta YCOORD ; 2
; set depth to -9 (move backwards)
lda #$f7 ; 2
sta DEPTH ; 2
fx5_loop:
; get ycoord
lda YCOORD ; 2
; 8x8 signed multiply of M1*DEPTH
;sta M1 ; 2
jsr imul ; 3
lda M2 ; 2
sta VALUE ; 2
; get xcoord
lda XCOORD ; 2
; add distance to projection (bend right)
clc ; 1
adc DEPTH ; 2
;sta M1 ; 2
; 8x8 signed multiply of M1*DEPTH
jsr imul ; 3
; do the calculation
dec DEPTH ; 2
beq putpixel ; 2 ; is this needed?
; load the yprojection
lda VALUE ; 2
; xor with the xprojection
eor M2 ; 2
; center walls around 0
clc ; 1
adc #$4 ; 2
; test with -8, see if wall hit
sta VALUE ; 2
and #$f8 ; 2
beq fx5_loop ; 2
putpixel:
; adjust color by frame and set
sec ; 1
lda DEPTH ; 2
sbc FRAME ; 2
eor VALUE ; 2
and #$7 ; 2
;adc #$20
jsr SETCOL ; 3
txa ; A==Y1 ; 1
jsr PLOT ; (X2,Y1) ; 3
dey ; 1
bpl xloop ; 2
dex ; 1
bpl yloop ; 2
bmi tunnel_forever ; 2
;=================================================
; A = M1
; DEPTH (preserve) is M2
imul:
stx TEMP ; save as we trash it
sta M1 ; get values in right place
lda DEPTH
sta M2
eor M1 ; calc if we need to adjust at end
; (++ vs +- vs -+ vs --)
php ; save status on stack
; if M1 negative, negate it
lda M1
bpl m1_positive
eor #$ff
clc
adc #0
m1_positive:
sta M1
; if M2 negative, naegate it
lda M2
bpl m2_positive
eor #$ff
clc
adc #0
m2_positive:
sta M2
;==================
; unsigned multiply
; factors in M1 and M2
lda #0
ldx #$8
lsr M1
clc
imul_loop:
bcc no_add
clc
adc M2
no_add:
ror
ror M1
dex
bne imul_loop
sta M2
; done, high result in factor2, low result in factor1
; adjust to be signed
; if m1 and m2 positive, good
; if m1 and m2 negative, good
; otherwise, negate result
plp ; restore saved pos/neg value
bpl done_result
negate_result:
sec
lda #0
sbc M1
lda #0
sbc M2
done_result:
sta M2
ldx TEMP
rts