From 0c81be5e23f584bdf4e5a73d781494ef28c73781 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Sat, 25 Nov 2023 00:16:15 -0500 Subject: [PATCH] gr-sim: dots: more work on dots nonsense --- utils/gr-sim/dots/Makefile | 20 +- utils/gr-sim/dots/dots_dump.c | 920 +++++++++++++++++++++++++++++++ utils/gr-sim/dots/dots_minimal.c | 400 ++++++++++++++ utils/gr-sim/dots/dots_play.c | 64 +++ 4 files changed, 1402 insertions(+), 2 deletions(-) create mode 100644 utils/gr-sim/dots/dots_dump.c create mode 100644 utils/gr-sim/dots/dots_minimal.c create mode 100644 utils/gr-sim/dots/dots_play.c diff --git a/utils/gr-sim/dots/Makefile b/utils/gr-sim/dots/Makefile index ca91365f..069b3014 100644 --- a/utils/gr-sim/dots/Makefile +++ b/utils/gr-sim/dots/Makefile @@ -4,7 +4,23 @@ CFLAGS = -O2 -Wall -g SDL_LIBS= `sdl-config --libs` SDL_INCLUDE= `sdl-config --cflags` -all: dots +all: dots dots_dump dots_play + +### + +dots_play: dots_play.o vga_emulator.o 8086_emulator.o ../gr-sim.a + $(CC) -o dots_play dots_play.o vga_emulator.o 8086_emulator.o ../gr-sim.a $(LFLAGS) $(SDL_LIBS) + +dots_play.o: dots_play.c vga_emulator.h + $(CC) $(CFLAGS) $(SDL_INCLUDE) -c dots_play.c + +### + +dots_dump: dots_dump.o vga_emulator.o 8086_emulator.o ../gr-sim.a + $(CC) -o dots_dump dots_dump.o vga_emulator.o 8086_emulator.o ../gr-sim.a $(LFLAGS) $(SDL_LIBS) + +dots_dump.o: dots_dump.c vga_emulator.h + $(CC) $(CFLAGS) $(SDL_INCLUDE) -c dots_dump.c ### @@ -27,4 +43,4 @@ vga_emulator.o: vga_emulator.c vga_emulator.h ### clean: - rm -f *~ *.o dots hellmood_memories + rm -f *~ *.o dots dots_dump dots_play diff --git a/utils/gr-sim/dots/dots_dump.c b/utils/gr-sim/dots/dots_dump.c new file mode 100644 index 00000000..94c08d73 --- /dev/null +++ b/utils/gr-sim/dots/dots_dump.c @@ -0,0 +1,920 @@ +#include +#include +#include +#include +#include +#include + +#include "8086_emulator.h" +#include "vga_emulator.h" + +#include "../gr-sim.h" +#include "../tfv_zp.h" + +#include "sin1024.h" + +#define MAXDOTS 1024 + +#define BOTTOM 8000 + +#define SKIP 2 + +static short gravitybottom=BOTTOM; + +static short bpmin=30000; +static short bpmax=-30000; +static short gravity=0; +static short dotnum=0; +static short gravityd=16; + +//???,-1280,-960,-640,-320}; + +static short rows[200]; + +//dot dw MAXDOTS dup(0,0,0,0,0,0,0,0) ;x,y,z,oldposshadow,oldpos,-,-,- + +static struct { + short x; // 0 + short y; // 2 + short z; // 4 + short old1; // 6 oldpos shadow + short old2; // 8 oldpos + short old3; // 10 + short old4; // 12 + short yadd; // 14 +} dot[MAXDOTS]; + +static short rotsin=0; +static short rotcos=0; + +static char *bgpic; + +static int depthtable1[128]; +static int depthtable2[128]; +static int depthtable3[128]; +//static int depthtable4[128]; + +static unsigned char depthtable1_bytes[512]; +static unsigned char depthtable2_bytes[512]; +static unsigned char depthtable3_bytes[512]; +//static unsigned char depthtable4_bytes[512]; + + +static void drawdots(void) { + int temp32; + int yy; + + // CBEG + ax=0xa000; // mov ax,0a000h + es=ax; // mov es,ax + ax=cs; // mov ax,cs + ds=ax; // mov ds,ax + + /* why [2]? */ + fs=bgpic[2]; // mov fs,cs:_bgpic[2] + cx=dotnum; // mov cx,cs:_dotnum + si=0; // mov si,OFFSET dot + +label1: + push(cx); // push cx + ax=dot[si].x; // mov ax,ds:[si+0] ;X + imul_16(rotsin); // imul ds:_rotsin + ax=ax; // mov ax,ax + cx=dx; // mov cx,dx + ax=dot[si].z; // mov ax,ds:[si+4] ;Z + imul_16(rotcos); // imul ds:_rotcos + ax=ax-bx; // sub ax,bx + dx=dx-cx; // sub dx,cx + bp=dx; // mov bp,dx + bp=bp+9000; // add bp,9000 + + ax=dot[si].x; // mov ax,ds:[si+0] ;X + imul_16(rotcos); // imul ds:_rotcos + bx=ax; // mov bx,ax + cx=dx; // mov cx,dx + ax=dot[si].z; // mov ax,ds:[si+4] ;Z + imul_16(rotsin); // imul ds:_rotsin + + temp32=ax+bx; // add ax,bx + ax=ax+bx; // + dx=dx+cx; // adc dx,cx + if (temp32&(1<<16)) dx=dx+1; + + +// printf("Before: ax=0x%04X dx=%04X\n",ax,dx); + ax=(ax>>8)|(dx<<8); // shrd ax,dx,8 + dx=sar(dx,8); // sar dx,8 +// printf("After: ax=0x%04X dx=%04X\n",ax,dx); + + bx=ax; // mov bx,ax + cx=dx; // mov cx,dx + ax=(ax>>3)|(dx<<13); // shrd ax,dx,3 + + dx=sar(dx,3); // sar dx,3 + temp32=ax+bx; // add ax,bx + ax=ax+bx; + dx=dx+cx; // adc dx,cx + if (temp32&(1<<16)) dx=dx+1; + + temp32=(dx<<16)|(ax&0xfffff); + idiv_16(bp); // idiv bp + ax=ax+160; // add ax,160 + push(ax); // push ax + + /* if off end of screen, no need for shadow */ + + if (ax>319) goto label2; // cmp ax,319 + + // ja @@2 + /**********/ + /* shadow */ + /**********/ + + ax=0; // xor ax,ax + dx=8; // mov dx,8 + idiv_16(bp); // idiv bp + ax=ax+100; // add ax,100 + + /* if shadow off screen, don't draw */ + if (ax>199) goto label2; // cmp ax,199 + // ja @@2 + bx=ax; // mov bx,ax + + // not needed, it's a C array + //bx=bx<<1; // shl bx,1 + bx=rows[bx]; // mov bx,ds:_rows[bx] + ax=pop(); // pop ax + bx=bx+ax; // add bx,ax + push(ax); // push ax + +// printf("Drawing shadow at %d,%d\n",bx%320,bx/320); + + + + /* erase old shadow (?)*/ + di=dot[si].old1; // mov di,ds:[si+6] + + yy=((di/320)*48)/200; + if (yy>23) color_equals(5); + else color_equals(0); + plot( (di%320)/8,yy); + + //ax=bgpic[di]; // mov ax,fs:[di] + //framebuffer[di]=ax; // mov es:[di],ax + +// framebuffer[di]=bgpic[di]; +// framebuffer[di+1]=bgpic[di+1]; + framebuffer_write(di,bgpic[di]); + framebuffer_write(di+1,bgpic[di+1]); + + + + /* draw new shadow (?) */ +// ax=87+87*256; // mov ax,87+87*256 +// framebuffer[bx]=ax; // mov word ptr es:[bx],ax + +// framebuffer[bx]=87; +// framebuffer[bx+1]=87; + framebuffer_write(bx,87); + framebuffer_write(bx+1,87); + +// bx/320 -> 200 200->48 *48/200 + + yy=((bx/320)*48)/200; + color_equals(0); + plot( (bx%320)/8,yy); +// printf("0,%d,%d\n",(bx%320)/8,yy); + +// printf("Plotting at %d,%d\n",(bx%320)/8,(bx/320)/5); + + /* save this to erase next time */ + dot[si].old1=bx; // mov ds:[si+6],bx + + /********/ + /* ball */ + /********/ +// ax=gravity; // mov ax,ds:_gravity +// dot[si].yadd+=ax; // add ds:[si+14],ax + +// if (si==100) printf("Gravity: %hd (%04x) Yadd: %hd (%04x)\n", +// gravity,gravity,dot[si].yadd,dot[si].yadd); + + dot[si].yadd+=gravity; + +// if (si==100) printf("\tyadd after yadd+=gravity: %hd (%04x)\n", +// dot[si].yadd,dot[si].yadd); + +// ax=dot[si].y; // mov ax,ds:[si+2] ;Y +// ax+=dot[si].yadd; // add ax,ds:[si+14] + ax=dot[si].y+dot[si].yadd; + +// if (si==100) printf("\tax=y+yadd: %hu (%04x) = " +// "%hd (%04x) + %hd (%04x)\n", +// ax,ax,dot[si].y,dot[si].y,dot[si].yadd,dot[si].yadd); + +// if (si==100) printf("\tcomparing if (ax>4 is %x (%hu))\n", +// ax,ax); + dot[si].yadd=ax; // mov ds:[si+14],ax + ax=pop(); // pop ax +// if (si==100) printf("\trestoring ax=%x, adding yadd %x\n", +// ax,dot[si].yadd); + + ax+=dot[si].yadd; // add ax,ds:[si+14] + +// if (si==100) printf("\tax=%x\n",ax); + +label4: + dot[si].y=ax; // mov ds:[si+2],ax + +// if (si==100) printf("\tdot[si].y=%x\n",dot[si].y); + + if (ax&0x8000) { // cwd + dx=0xffff; + } + else { + dx=0; + } + +// if (si==100) printf("\tdx:ax = %04hx:%04hx\n",dx,ax); + + dx=(dx<<6)|(ax>>10); // shld dx,ax,6 + ax=ax<<6; // shl ax,6 + +// if (si==100) printf("\tdx:ax <<6 = %04hx:%04hx, bp=%04hx\n",dx,ax,bp); + + idiv_16(bp); // idiv bp +// if (si==100) printf("\tY ax=%d\n",ax); + ax=ax+100; // add ax,100 + if (ax>199) goto label3; // cmp ax,199 + // ja @@3 +// if (si==100) printf("\tdraw Y ax=%d\n",ax); + bx=ax; // mov bx,ax + + // not needed, C array + //bx=bx<<1; // shl bx,1 + bx=rows[bx]; // mov bx,ds:_rows[bx] + + ax=pop(); // pop ax + bx=bx+ax; // add bx,ax + + di=dot[si].old2; // mov di,ds:[si+8] +// framebuffer[di]=bgpic[di]; // mov eax,fs:[di] +// framebuffer[di+1]=bgpic[di+1]; // mov es:[di],eax +// framebuffer[di+2]=bgpic[di+2]; +// framebuffer[di+3]=bgpic[di+3]; + + yy=((di/320)*48)/200; + if (yy>23) color_equals(5); + else color_equals(0); + plot( (di%320)/8,yy); + + framebuffer_write(di,bgpic[di]); + framebuffer_write(di+1,bgpic[di+1]); + framebuffer_write(di+2,bgpic[di+2]); + framebuffer_write(di+3,bgpic[di+3]); + + + + + di=di+320; // add di,320 +// framebuffer[di]=bgpic[di]; // mov eax,fs:[di] +// framebuffer[di+1]=bgpic[di+1]; // mov es:[di],eax +// framebuffer[di+2]=bgpic[di+2]; +// framebuffer[di+3]=bgpic[di+3]; + + framebuffer_write(di,bgpic[di]); + framebuffer_write(di+1,bgpic[di+1]); + framebuffer_write(di+2,bgpic[di+2]); + framebuffer_write(di+3,bgpic[di+3]); + + + di=di+320; // add di,320 +// framebuffer[di]=bgpic[di]; // mov eax,fs:[di] +// framebuffer[di+1]=bgpic[di+1]; // mov es:[di],eax +// framebuffer[di+2]=bgpic[di+2]; +// framebuffer[di+3]=bgpic[di+3]; + + framebuffer_write(di,bgpic[di]); + framebuffer_write(di+1,bgpic[di+1]); + framebuffer_write(di+2,bgpic[di+2]); + framebuffer_write(di+3,bgpic[di+3]); + + //;; add di,320 + //;; mov eax,fs:[di] + //;; mov es:[di],eax + + bp=bp>>6; // shr bp,6 + bp=bp&(~3L); // and bp,not 3 + + temp32=bp; + if (temp32&0x8000) temp32|=0xffff0000; + if (temp32>=bpmin) goto label_t1; // cmp bp,cs:_bpmin + // jge @@t1 + bpmin=bp; // mov cs:_bpmin,bp +label_t1: + temp32=bp; + if (temp32&0x8000) temp32|=0xffff0000; + if (temp32<=bpmax) goto label_t2; // cmp bp,cs:_bpmax + // jle @@t2 + bpmax=bp; // mov cs:_bpmax,bp +label_t2: +// eax=depthtable1[bp]; // mov ax,word ptr ds:_depthtable1[bp] + // mov word ptr es:[bx+1],ax + + + yy=((bx/320)*48)/200; + color_equals(6); + plot( (bx%320)/8,yy); +// printf("6,%d,%d\n",(bx%320)/8,yy); + + framebuffer[bx+1]=depthtable1_bytes[bp]; + framebuffer[bx+2]=depthtable1_bytes[bp+1]; + + //eax=depthtable2[bp]; // mov eax,ds:_depthtable2[bp] + // mov dword ptr es:[bx+320],eax + framebuffer[bx+320]=depthtable2_bytes[bp]; + framebuffer[bx+321]=depthtable2_bytes[bp+1]; + framebuffer[bx+322]=depthtable2_bytes[bp+2]; + framebuffer[bx+323]=depthtable2_bytes[bp+3]; + +// eax=depthtable3[bp]; // mov ax,word ptr ds:_depthtable3[bp] + // mov word ptr es:[bx+641],ax + framebuffer[bx+641]=depthtable3_bytes[bp]; + framebuffer[bx+642]=depthtable3_bytes[bp+1]; + dot[si].old2=bx; // mov ds:[si+8],bx + + +//labelz: + cx=pop(); // pop cx + si=si+SKIP; // add si,16 point to next dot + cx=cx-SKIP; + if (cx!=0) goto label1; // loop @@1 +label0: + return; + // @@0: CEND + +label2: + /* This is called when we are off the screen */ + /* erases old but didn't draw new */ + + /* erase old dot */ + di=dot[si].old2; // mov di,ds:[si+8] + + + yy=((di/320)*48)/200; + if (yy>23) color_equals(5); + else color_equals(0); + plot( (di%320)/8,yy); + + framebuffer[di]=bgpic[di]; // mov eax,fs:[di] + framebuffer[di+1]=bgpic[di+1]; // mov es:[di],eax + framebuffer[di+2]=bgpic[di+2]; + framebuffer[di+3]=bgpic[di+3]; + + di=di+320; // add di,320 + + framebuffer[di]=bgpic[di]; // mov eax,fs:[di] + framebuffer[di+1]=bgpic[di+1]; // mov es:[di],eax + framebuffer[di+2]=bgpic[di+2]; + framebuffer[di+3]=bgpic[di+3]; + + di=di+320; // add di,320 + + framebuffer[di]=bgpic[di]; // mov eax,fs:[di] + framebuffer[di+1]=bgpic[di+1]; // mov es:[di],eax + framebuffer[di+2]=bgpic[di+2]; + framebuffer[di+3]=bgpic[di+3]; + + ax=(framebuffer[di]|(framebuffer[di+1]<<8)); + + /* doing something to shadow here? */ + + di=dot[si].old1; // mov di,ds:[si+6] + dot[si].old1=ax; // mov ds:[si+6],ax + + framebuffer[di]=bgpic[di]; // mov ax,fs:[di] + framebuffer[di+1]=bgpic[di+1]; // mov es:[di],ax + + bx=pop(); // pop bx + cx=pop(); // pop cx + si=si+SKIP; // add si,16 + cx=cx-SKIP; // loop @@1 + if (cx!=0) goto label1; + goto label0; // jmp @@0 + +label3: + /* erase old dot */ + di=dot[si].old2; // mov di,ds:[si+8] + + yy=((di/320)*48)/200; + if (yy>23) color_equals(5); + else color_equals(0); + plot( (di%320)/8,yy); + + framebuffer[di]=bgpic[di]; // mov eax,fs:[di] + framebuffer[di+1]=bgpic[di+1]; // mov es:[di],eax + framebuffer[di+2]=bgpic[di+2]; + framebuffer[di+3]=bgpic[di+3]; + + di=di+320; // add di,320 + + framebuffer[di]=bgpic[di]; // mov eax,fs:[di] + framebuffer[di+1]=bgpic[di+1]; // mov es:[di],eax + framebuffer[di+2]=bgpic[di+2]; + framebuffer[di+3]=bgpic[di+3]; + + di=di+320; // add di,320 + + framebuffer[di]=bgpic[di]; // mov eax,fs:[di] + framebuffer[di+1]=bgpic[di+1]; // mov es:[di],eax + framebuffer[di+2]=bgpic[di+2]; + framebuffer[di+3]=bgpic[di+3]; + + bx=pop(); // pop bx + cx=pop(); // pop cx + si=si+SKIP; // add si,16 + cx=cx-SKIP; // loop @@1 + if (cx!=0) goto label1; + goto label0; // jmp @@0 + +} + +static void setpalette(char *pal) { + + int c; + + // push bp + // mov bp,sp + // push si + // push di + // push ds + // mov si,[bp+6] + // mov ds,[bp+8] + // mov dx,3c8h + // mov al,0 + outp(0x3c8,0); //out dx,al + + for(c=0;c<768;c++) outp(0x3c9,pal[c]); + grsim_update(); + // inc dx + //mov cx,768 + //rep outsb + // pop ds + // pop di + // pop si + // pop bp + // ret + +} + +//short face[]={ +// 2248,-2306,0, // from face.inc +// 30000,30000,30000 +//}; + +/* wait for VGA border start */ +static short dis_waitb(void) { + +// descr: Waits for border start +// waitb_1 PROC NEAR +// call checkkeys + +// IFDEF INDEMO +// sti +// mov ax,cs:copperframecount +//@@v: cmp cs:copperframecount,ax +// je @@v +//@@q: mov ax,cs:copperframecount +// mov cs:copperframecount,0 +// ELSE + +// mov dx,3dah +//@@1: in al,dx +// test al,8 +// jnz @@1 +//@@2: in al,dx +// test al,8 + // jz @@2 + + // mov ax,1 ;number of frames taken ;TEMP! + +// ENDIF +// ret +//waitb_1 ENDP + + + /* approximate by 70Hz sleep */ + usleep(14286); + + return 1; +} + +static short dis_exit(void) { + return 0; +} + +static short dis_indemo(void) { + return 0; +} + +//char far *vram=(char far *)0xa0000000L; +static unsigned char *vram=framebuffer; + +static char pal[768]; +static char pal2[768]; + +static short isin(short deg) { + return(sin1024[deg&1023]); +} + +static short icos(short deg) { + return(sin1024[(deg+256)&1023]); +} + +static void setborder(short color) { + + //printf("Setting border to %d\n",color); + + // to write attribute register: + // read/write address to $3c0 + // data written to $3c0, read from $3c1 + // flip flop tracks if it's index/data, you reset that + // by reading $3da + + //mov dx,3dah // input status reg #1 + //in al,dx // resets index/addr flip-flop + + //mov dx,3c0h // attribute access + //mov al,11h+32 // $11=overscan (border color) + // 32 is PAS bit + //out dx,al + + //mov al,color + //out dx,al +} + +static short cols[]={ +0,0,0, +4,25,30, +8,40,45, +16,55,60}; + +static short dottaul[1024]; + +int main(int argc,char **argv) { + +// short timer=30000; + short dropper,repeat; + short frame=0; + short rota=-1*64; +// short fb=0; + short rot=0,rots=0; + short a,b,c,d,i,j=0;//,mode; + short grav,gravd; + short f=0; + int ch; + + //dis_partstart(); + + dotnum=512; + for(a=0;a15) c=15; + c=15-c; + depthtable1[a]=0x202+0x04040404*c; + depthtable2[a]=0x02030302+0x04040404*c; + depthtable3[a]=0x202+0x04040404*c; + //depthtable4[a]=0x02020302+0x04040404*c; + } + + /* make a byte-wise copy of this */ + /* the original code just indexes byte-wise into integer data */ + /* which is a pain */ + for(a=0;a<128;a++) { + depthtable1_bytes[(a*4)+0]=(depthtable1[a]>>0)&0xff; + depthtable1_bytes[(a*4)+1]=(depthtable1[a]>>8)&0xff; + depthtable1_bytes[(a*4)+2]=(depthtable1[a]>>16)&0xff; + depthtable1_bytes[(a*4)+3]=(depthtable1[a]>>24)&0xff; + + depthtable2_bytes[(a*4)+0]=(depthtable2[a]>>0)&0xff; + depthtable2_bytes[(a*4)+1]=(depthtable2[a]>>8)&0xff; + depthtable2_bytes[(a*4)+2]=(depthtable2[a]>>16)&0xff; + depthtable2_bytes[(a*4)+3]=(depthtable2[a]>>24)&0xff; + + depthtable3_bytes[(a*4)+0]=(depthtable3[a]>>0)&0xff; + depthtable3_bytes[(a*4)+1]=(depthtable3[a]>>8)&0xff; + depthtable3_bytes[(a*4)+2]=(depthtable3[a]>>16)&0xff; + depthtable3_bytes[(a*4)+3]=(depthtable3[a]>>24)&0xff; + + + + } + + + /* allocate space for background */ + //bgpic=halloc(64000L,1L); + bgpic=calloc(65536L,1L); + + /* backup background */ + memcpy(bgpic,vram,64000); + + grsim_update(); + + /* Fade back in from black to palette */ + a=0; + for(b=64;b>=0;b--) { + for(c=0;c<768;c++) { + a=pal[c]-b; + if(a<0) a=0; + pal2[c]=a; + } + /* wait for retrace (delay) */ + dis_waitb(); + dis_waitb(); + outp(0x3c8,0); + for(c=0;c<768;c++) outp(0x3c9,pal2[c]); + grsim_update(); + } + + while(!dis_exit() && frame<2450) { + + /* code sets border color */ + /* then waits for it to end, as a timing thing? */ + setborder(0); + + /* when not in demo this defaults to 1? */ + repeat=dis_waitb(); + + if(frame>2300) setpalette(pal2); + + setborder(1); + + if(dis_indemo()) { + /* ?? music synchronization? */ +// a=dis_musplus(); +// if(a>-4 && a<0) break; + } + + repeat=1; + + while(repeat--) { + + frame++; + if(frame==500) f=0; + i=dottaul[j]; + j++; j%=dotnum; + + /* initial spin */ + if(frame<500) { + dot[i].x=isin(f*11)*40; + dot[i].y=icos(f*13)*10-dropper; + dot[i].z=isin(f*17)*40; + dot[i].yadd=0; +// printf("%d: %d,%d,%d,%d\n",i, +// dot[i].x,dot[i].y,dot[i].z,dot[i].yadd); + } + /* bouncing ring */ + else if(frame<900) { + dot[i].x=icos(f*15)*55; + dot[i].y=dropper; + dot[i].z=isin(f*15)*55; + dot[i].yadd=-260; + } + /* fountain */ + else if(frame<1700) { + a=sin1024[frame&1023]/8; + dot[i].x=icos(f*66)*a; + dot[i].y=8000; + dot[i].z=isin(f*66)*a; + dot[i].yadd=-300; + } + /* swirling */ + else if(frame<2360) { + /* + a=rand()/128+32; + dot[i].y=8000-a*80; + b=rand()&1023; + a+=rand()&31; + dot[i].x=sin1024[b]*a/3+(a-50)*7; + dot[i].z=sin1024[(b+256)&1023]*a/3+(a-40)*7; + dot[i].yadd=300; + if(frame>1640 && !(frame&31) && grav>-2) grav--; + */ + dot[i].x=rand()-16384; + dot[i].y=8000-rand()/2; + dot[i].z=rand()-16384; + dot[i].yadd=0; + if(frame>1900 && !(frame&31) && grav>0) grav--; + } + /* palette to white */ + else if(frame<2400) { + a=frame-2360; + for(b=0;b<768;b+=3) { + c=pal[b+0]+a*3; + if(c>63) c=63; + pal2[b+0]=c; + c=pal[b+1]+a*3; + if(c>63) c=63; + pal2[b+1]=c; + c=pal[b+2]+a*4; + if(c>63) c=63; + pal2[b+2]=c; + } + } + /* palette to black */ + else if(frame<2440) { + a=frame-2400; + for(b=0;b<768;b+=3) { + c=63-a*2; + if(c<0) c=0; + pal2[b+0]=c; + pal2[b+1]=c; + pal2[b+2]=c; + } + } + if(dropper>4000) dropper-=100; + + rotcos=icos(rot)*64; rotsin=isin(rot)*64; + rots+=2; + + if(frame>1900) { + rot+=rota/64; + rota--; + } + else rot=isin(rots); + + f++; + gravity=grav; + gravityd=gravd; + + } + + + drawdots(); + + grsim_update(); + +#if 0 + for(i=0;i +#include +#include +#include +#include +#include + +#include "8086_emulator.h" +#include "vga_emulator.h" + +#include "../gr-sim.h" +#include "../tfv_zp.h" + +#include "sin1024.h" + +#define MAXDOTS 1024 + +#define SKIP 2 + +static short gravitybottom; +static short bpmin=30000; +static short bpmax=-30000; +static short gravity=0; +static short dotnum=0; +static short gravityd=16; + +static short rows[200]; + +static struct { + short x; // 0 + short y; // 2 + short z; // 4 + short old1; // 6 oldpos shadow + short old2; // 8 oldpos + short old3; // 10 + short old4; // 12 + short yadd; // 14 +} dot[MAXDOTS]; + +static short rotsin=0; +static short rotcos=0; + +static void drawdots(void) { + int temp32; + int yy; + + cx=dotnum; // mov cx,cs:_dotnum + si=0; // mov si,OFFSET dot + +label1: + push(cx); // push cx + ax=dot[si].x; // mov ax,ds:[si+0] ;X + imul_16(rotsin); // imul ds:_rotsin + ax=ax; // mov ax,ax + cx=dx; // mov cx,dx + ax=dot[si].z; // mov ax,ds:[si+4] ;Z + imul_16(rotcos); // imul ds:_rotcos + ax=ax-bx; // sub ax,bx + dx=dx-cx; // sub dx,cx + bp=dx; // mov bp,dx + bp=bp+9000; // add bp,9000 + + ax=dot[si].x; // mov ax,ds:[si+0] ;X + imul_16(rotcos); // imul ds:_rotcos + bx=ax; // mov bx,ax + cx=dx; // mov cx,dx + ax=dot[si].z; // mov ax,ds:[si+4] ;Z + imul_16(rotsin); // imul ds:_rotsin + + temp32=ax+bx; // add ax,bx + ax=ax+bx; // + dx=dx+cx; // adc dx,cx + if (temp32&(1<<16)) dx=dx+1; + + ax=(ax>>8)|(dx<<8); // shrd ax,dx,8 + dx=sar(dx,8); // sar dx,8 + + bx=ax; // mov bx,ax + cx=dx; // mov cx,dx + ax=(ax>>3)|(dx<<13); // shrd ax,dx,3 + + dx=sar(dx,3); // sar dx,3 + temp32=ax+bx; // add ax,bx + ax=ax+bx; + dx=dx+cx; // adc dx,cx + if (temp32&(1<<16)) dx=dx+1; + + temp32=(dx<<16)|(ax&0xfffff); + idiv_16(bp); // idiv bp + ax=ax+160; // add ax,160 + push(ax); // push ax + + /* if off end of screen, no need for shadow */ + + if (ax>319) goto label2; // cmp ax,319 + + // ja @@2 + /**********/ + /* shadow */ + /**********/ + + ax=0; // xor ax,ax + dx=8; // mov dx,8 + idiv_16(bp); // idiv bp + ax=ax+100; // add ax,100 + + /* if shadow off screen, don't draw */ + if (ax>199) goto label2; // cmp ax,199 + // ja @@2 + bx=ax; // mov bx,ax + + // not needed, it's a C array + //bx=bx<<1; // shl bx,1 + bx=rows[bx]; // mov bx,ds:_rows[bx] + ax=pop(); // pop ax + bx=bx+ax; // add bx,ax + push(ax); // push ax + + + /* draw new shadow (?) */ + +// bx/320 -> 200 200->48 *48/200 + + yy=((bx/320)*48)/200; + color_equals(0); + plot( (bx%320)/8,yy); + + /********/ + /* ball */ + /********/ + + dot[si].yadd+=gravity; + ax=dot[si].y+dot[si].yadd; + + temp32=ax; + if (temp32&0x8000) temp32|=0xffff0000; + if (temp32>10); // shld dx,ax,6 + ax=ax<<6; // shl ax,6 + idiv_16(bp); // idiv bp + ax=ax+100; // add ax,100 + if (ax>199) goto label3; // cmp ax,199 + // ja @@3 + bx=ax; // mov bx,ax + + // not needed, C array + //bx=bx<<1; // shl bx,1 + bx=rows[bx]; // mov bx,ds:_rows[bx] + + ax=pop(); // pop ax + bx=bx+ax; // add bx,ax + bp=bp>>6; // shr bp,6 + bp=bp&(~3L); // and bp,not 3 + + temp32=bp; + if (temp32&0x8000) temp32|=0xffff0000; + if (temp32>=bpmin) goto label_t1; // cmp bp,cs:_bpmin + // jge @@t1 + bpmin=bp; // mov cs:_bpmin,bp +label_t1: + temp32=bp; + if (temp32&0x8000) temp32|=0xffff0000; + if (temp32<=bpmax) goto label_t2; // cmp bp,cs:_bpmax + // jle @@t2 + bpmax=bp; // mov cs:_bpmax,bp +label_t2: + yy=((bx/320)*48)/200; + color_equals(6); + plot( (bx%320)/8,yy); + cx=pop(); // pop cx + si=si+SKIP; // add si,16 point to next dot + cx=cx-SKIP; + if (cx!=0) goto label1; // loop @@1 +label0: + return; + // @@0: CEND + +label2: + /* This is called when we are off the screen */ + /* erases old but didn't draw new */ + bx=pop(); // pop bx + cx=pop(); // pop cx + si=si+SKIP; // add si,16 + cx=cx-SKIP; // loop @@1 + if (cx!=0) goto label1; + goto label0; // jmp @@0 + +label3: + + bx=pop(); // pop bx + cx=pop(); // pop cx + si=si+SKIP; // add si,16 + cx=cx-SKIP; // loop @@1 + if (cx!=0) goto label1; + goto label0; // jmp @@0 + +} + + +/* wait for VGA border start */ +static short dis_waitb(void) { + + /* approximate by 70Hz sleep */ + usleep(14286); + + return 1; +} + + +static char pal[768]; +static char pal2[768]; + +static short isin(short deg) { + return(sin1024[deg&1023]); +} + +static short icos(short deg) { + return(sin1024[(deg+256)&1023]); +} + +static short dottaul[1024]; + +int main(int argc,char **argv) { + + short dropper; + short frame=0; + short rota=-1*64; + short rot=0,rots=0; + short a,b,c,d,i,j=0; + short grav,gravd; + short f=0; + int ch; + + dotnum=512; + for(a=0;a1900 && !(frame&31) && grav>0) grav--; + } + /* palette to white */ + else if(frame<2400) { + a=frame-2360; + for(b=0;b<768;b+=3) { + c=pal[b+0]+a*3; + if(c>63) c=63; + pal2[b+0]=c; + c=pal[b+1]+a*3; + if(c>63) c=63; + pal2[b+1]=c; + c=pal[b+2]+a*4; + if(c>63) c=63; + pal2[b+2]=c; + } + } + /* palette to black */ + else if(frame<2440) { + a=frame-2400; + for(b=0;b<768;b+=3) { + c=63-a*2; + if(c<0) c=0; + pal2[b+0]=c; + pal2[b+1]=c; + pal2[b+2]=c; + } + } + if(dropper>4000) dropper-=100; + + rotcos=icos(rot)*64; rotsin=isin(rot)*64; + rots+=2; + + if(frame>1900) { + rot+=rota/64; + rota--; + } + else rot=isin(rots); + + f++; + gravity=grav; + gravityd=gravd; + + + drawdots(); + + grsim_update(); + + dis_waitb(); + + ch=grsim_input(); + if (ch==27) { + return 0; + } + + } + + return 0; +} diff --git a/utils/gr-sim/dots/dots_play.c b/utils/gr-sim/dots/dots_play.c new file mode 100644 index 00000000..1a4ed699 --- /dev/null +++ b/utils/gr-sim/dots/dots_play.c @@ -0,0 +1,64 @@ +#include +#include + +#include "../gr-sim.h" +#include "../tfv_zp.h" + +int main(int argc, char **argv) { + + int xx,yy,ch; + int current_row=0; + + grsim_init(); + + gr(); + + while(1) { + clear_screens(); + soft_switch(MIXCLR); + + ram[DRAW_PAGE]=0; + + color_equals(5); + for(yy=24;yy<48;yy++) hlin(0,0,40,yy); + + color_equals(0); + + /* parse loop */ + while(1) { + ch=getchar(); + if (ch==0xff) break; + + if (ch==0xfe) { + color_equals(0); + break; + } + if (ch==0xfd) { + color_equals(6); + continue; + } + + if (ch&0x40) { + current_row=ch&0x3f; + ch=getchar(); + } + xx=ch; + plot(xx,current_row); + } + if (ch==0xff) break; + + usleep(14285); + + grsim_update(); + +//again: + ch=grsim_input(); + if (ch==27) { + break; + } +// else if (ch==0) goto again; + + } + + return 0; +}