# HG changeset patch # User Matti Hamalainen # Date 1363316401 -7200 # Node ID 0e4f2da5816158689962b4e3be0930e31e0f969a Initial import. diff -r 000000000000 -r 0e4f2da58161 3x666.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3x666.c Fri Mar 15 05:00:01 2013 +0200 @@ -0,0 +1,871 @@ +#include "math.h" +#include "stdio.h" +#include "stdlib.h" +#include "fcntl.h" +#include "unistd.h" +#include "malloc.h" +#include "time.h" +#include "sys/time.h" + +#include "config.h" +#include "oxl.h" +#include "3xfont.h" + +#ifdef __linux__ +#include "linux/string.h" +#else +#include "string.h" +#endif + +extern int TIKLGT; + +/** typedefs **/ + +typedef struct { signed int x,y,z; } vec3d; + +/**/ + +char *ruutu; +int *mxbuf; + +int *ballz; + +/**************** tEXT dRAWiNG rOUTiNES ********** + +bitmaps are for lamers :) let's use a little 12-segment calculator font... +ascii chars 32..90, 16 bits per char unpacked -> 114 bytes for the whole +font ;) let's credit karl/nooon for the original idea. */ + +void drawseg(int y,int x,int w,int h) +{ + /* clip clip clip */ + if(x+w>BUFW)w=BUFW-x; + if(x<0){w+=x;x=0;} + if(y+h>BUFH)h=BUFH-y; + if(y<0){h+=y;y=0;} + if(w>0)if(h>0){ + char *b=ruutu+y*BUFW+x; + for(;h;h--){memset(b,122,w);b+=BUFW;} +} } + +void drawchar(int x,int y,int c,int xunit,int yunit) +{ x-=xunit*2; + y-=yunit*3; + for(;;){ + if(!c)break; + + if(c&1)drawseg(y,x+1, xunit*2-2,yunit); + if(c&2)drawseg(y,x+1+xunit*2,xunit*2-2,yunit); + y++; + + c>>=2; + if(!c)break; + + if(c&1)drawseg(y,x, xunit,yunit*3-2); + if(c&2)drawseg(y,x+((xunit*3)>>1),xunit,yunit*3-2); + if(c&4)drawseg(y,x+xunit*3,xunit,yunit*3-2); + + y+=yunit*2; + c>>=3; +}} + +void drawtxtscr(char*z) +{ + int x=BUFW>>4,y=BUFH>>3; + while(*z){ + if(*z>=32){ + drawchar(x,y,phont[*z-32],BUFW/50,BUFW/80); + x+=BUFW/10; + }else{x=BUFW>>4;y+=BUFW/10;} + z++; +} } + + +void flashtxt(char*txt) +{ + int x=(BUFW>>1)-(strlen(txt)+1)*3*BUFW/80; + while(*txt){ + drawchar(x,BUFH>>1,phont[*txt++-32],BUFW/50,BUFW/80); + x+=BUFW/10;} +} + +/*************************** DA PHONGBALL HEAVEN ************** + +A short course on phongball theory! + +A sphere: x^2+y^2+z^2=R^2 + +Diffuse shading: intensity = dotproduct(surfacenormal,lightvector) + +(doing this for every drawn point of the surface is sometimes called +phong shading even if the normals aren't actually interpolated) + +For a sphere, a normal vector at a point of the surface == constant * +the coordinates of the point (if center == origo). + +Thus, the function for the intensity of a 2d-projected phongball can be +stated as + +intensity(x,y) = l.x*x + l.y*y + l.z*z, z = sqrt(R^2-x^2-y^2) + +The first two muls can be eliminated easily. (and will be eliminated by +a good compiler even if you are lazy) + +The third mul can be eliminated by approximating l.z*z with a function +of the form f(x)=a*x^2+c. This approximation makes the ball look a bit +"twisty" but who cares, it just looks damn cool ;) + +***/ + +#if BUFH>1) +#else + #define maxR (BUFW>>1) +#endif + +struct{int *tab;signed int R;}balltab[50]; + +void preball() +{ + unsigned int rR; signed int R; + + for(rR=0;rR<48;rR++){ + int R2,*d;signed int y; + R=(maxR*(rR+4))/52; + if(R<2)R=2; + R2=R*R; + balltab[rR].R=R; + d=balltab[rR].tab=malloc(R*2*sizeof(int)); + for(y=-R+1;y>16;} + +#endif +} + +void drawball(char *d,vec3d *l,int relR) +{ + int R=balltab[relR].R,*s=balltab[relR].tab; + + signed int doty=(-(R-1)*l->y); + signed int y=R*2-2; + + d+=(BUFW>>1)-R+((BUFH>>1)-R)*BUFW; + + if(y)for(;y;y--){ + int halfw=*s++; + if(halfw) + drawball_inloop( + d+R-halfw, + (doty-(l->x*halfw))<<8, + (l->x+l->z)<<8, + 0-((l->z<<8)/halfw), + halfw<<1); + d+=BUFW; + doty+=l->y; +} } + +/* some extra for freaks: a plasma made with the phongball innerloop :) + looks ugly. + +void drawplasma(char *d,float t) +{ + int y=BUFH; float u=0,du=500/BUFH; + + for(;y;y--){ + drawball_inloop(d, + sin(t*0.02+0+u*0.033)*65536*256, + cos(t*0.04+1+u*0.022)*65536*4096/BUFW, + -2*cos(t*0.04+1+u*0.022)*65536*4096/(BUFW*BUFW), BUFW); + d+=BUFW; + u+=du; + } +} +*/ + +/************************ oTHA FX ***************/ + +void rotochess(char *d,int du,int dv,int iu,int iv) +{ + int hu=iu-(dv*(BUFH>>1))-(du*(BUFW>>1)), + hv=iv+(du*(BUFH>>1))-(dv*(BUFW>>1)); + +#if (ASMLOOPS==386) && (!(BUFW&3)) + +__asm__(" + + movl %%eax,%%ebp + +1: pushl %%ecx + pushl %%ebx + pushl %%edx + + movl %0,%%ecx + jmp 0f + + .align 4 + +0: addl %%ebp,%%ebx + movb %%bh,%%al + addl %%esi,%%edx + xorb %%dh,%%al + + addl %%ebp,%%ebx + movb %%bh,%%ah + addl %%esi,%%edx + xorb %%dh,%%ah + + addl %%ebp,%%ebx + andl $0xb1b1,%%eax + stosw + movb %%bh,%%al + addl %%esi,%%edx + xorb %%dh,%%al + + addl %%ebp,%%ebx + movb %%bh,%%ah + addl %%esi,%%edx + xorb %%dh,%%ah + andl $0xb1b1,%%eax + + decl %%ecx + stosw + jne 0b + + popl %%edx + popl %%ebx + popl %%ecx + + subl %%ebp,%%edx + addl %%esi,%%ebx + + decl %%ecx + jne 1b +" +:: "m"(BUFW/4), + + "c"(BUFH), // ecx == x + "D"(d), // edi == *d + + "b"(hu),"a"(du), + "d"(hv),"S"(dv) + +: "ax","bx","cx","dx","si","di","bp"); + d+=BUFW; +#else + int y; + for(y=BUFH;y;y--){ + {register int u=hu,v=hv,x=BUFW; + for(;x;x--){ + u+=du;v+=dv;*d++=((u^v)>>8)&0xb1;}} + hu+=dv;hv-=du;} +#endif +} + +/***************************************************************/ + +rgb pal[256],pal2[256]; +void setpal() +{ + int i,a=3,b=0; + for(i=255;i;i--){ + rgb*d=&pal[(i+128)&255]; + d->r=(abs(i-140)>>a)&255; + d->g=((abs(i-128)>>b)&255)^1; + d->b=(abs(i-96)>>b)&255; + if(i==128){a=0;b=1;} + } + oxl_setpalette(pal); +} + +void unitvec(vec3d *v,float a,float b,float c,float m) +{ + float cam=cos(a)*m,sam=sin(a)*m,sbcam=sin(b)*cam; + + v->x=cos(b)*cam; + v->y=cos(c)*sam-sin(c)*sbcam; + v->z=cos(c)*sbcam+sin(c)*sam; +} + +/************************* MUSiC cODE **************************/ + +#if AUDIO + +/* This table was ripped (and reduced and rudely integerized) from the + Maube tracker by K .. keep on the good work man! ;) */ + +const int noterate[3*12] = { + 1000, 1059, 1122, 1189, 1259, 1334, + 1414, 1498, 1587, 1681, 1781, 1887, + + 2000, 2118, 2244, 2378, 2519, 2669, + 2828, 2996, 3174, 3363, 3563, 3775, + + 4000, 4237, 4489, 4756, 5039, 5339, + 5656, 5993, 6349, 6727, 7127, 7550 +}; + +/* 64 bytes of pure musical power ;) + Originally composed with Scream Tracker. */ + +const char basstrak[32]={ + 12,0, 24,12, + 12,24,12,24, + 12,0, 24,12, + 12,24,12,24, + 15,0, 27,15, + 15,27,15,27, + 14,0, 26,14, + 15,27,17,29}; + +const char melody[32]={ + 24,12,19,15, + 24,0, 19,0, + 24,12,19,15, + 24,0, 15,19, + 15,19,15,19, + 22,0, 15,19, + 14,17,21,14, + 22,17,17,22}; + +signed int*drum0,*drum1; + +void audio_precalcs() +/* sampling sucks! */ +{ + int drumlgt=TIKLGT*ROWTIX*4; + int *d=drum0=malloc(drumlgt*sizeof(int)), + *e=drum1=malloc(drumlgt*sizeof(int)),i, + vol=24680,dvol=35000/(float)drumlgt; + int o=0,oo=0;float a=0,da=386/(float)drumlgt,dda=da/(float)drumlgt; + + printf("aCtIvATiNg 303 eMuLAtOR\n"); + + for(i=drumlgt;i;i--){ + int u; + + o=(o>>1)+(rand()%vol)-(rand()%vol); + oo=(oo*2+((rand()%vol)-(rand()%vol)))/3; + + o*=sin(a);oo*=sin(a); + + u=o*2;if(u<-65535)u=-65535;if(u>65535)u=65535; + *d++=(vol*sin((a/2)+((float)u)/80000)); + *e++=(vol*sin(a+((float)oo)/60000)); + + a+=da;da-=dda;vol-=dvol; +} } + +int*audio_mix(void) +/* mixes the next row of music into b */ +{ + static int rowno=0; + static signed int delta=-5; + static char ismelody=0,silend=0; + + int rowlgt=TIKLGT*ROWTIX,i; + int *d=mxbuf,note; + + /* BASS (sawtooth ofcoz) */ + + *d++=rowlgt; + + note=basstrak[(rowno>>1)&31]; + + if(!note)note=basstrak[((rowno>>1)&31)-1]; + else if(rowno&1)note=0; + if((rowno&3)==3)note=0; + if(note){ + int ps=16384,dps; + note+=delta; + dps=((noterate[note]<<10)/AUFREQ); + for(i=rowlgt;i;i--){ + *d++=ps;ps=(ps+dps)&32767; } + }else + for(i=rowlgt;i;i--)*d++=16384; + + /* MELODY (sawtooth as well :) */ + + if(!(silend&&((rowno&63)>47))){ + + if(ismelody){ + d=mxbuf+1; + if(rowno&1)note=0;else note=melody[(rowno>>1)&31]; + if(note){ + int ps=16384,dps; /* this loop is different */ + note+=delta; + dps=((noterate[note]<<12)/AUFREQ); + for(i=rowlgt;i;i--){ + *d+++=ps;ps=(ps+dps)&32767;} + }} + /* DRUMS (rave on!!!) */ + + { + int *s=drum1;d=mxbuf+1; + if(rowno&4)s=drum0; + s+=(rowno&3)*rowlgt; + + for(i=rowlgt;i;i--)*d+++=*s++; + } + } + /* PATTERN SHIFT */ + + rowno++; + + /* no switch+case? just check out how gcc handles them! + it's 1024+ bytes for every phukken switch statement! + in this case we can prefer size to speed, can't we? */ + + if(!(rowno&63)){ + int r=rowno>>6; + if(r==2)delta=0; + if(r==4)ismelody=1; + if((r==6)||(r==10))delta=5; + if((r==7)||(r==11))silend=1; + if(r==8)delta=silend=0; + if(r==12){rowno=ismelody=silend=0;delta=-5;} + } + return mxbuf; +} + +#endif + +/**************** tEXT gENERATORS eTC ***************/ + +char skrtxt[]={ +" HI THERE ! THIS IS THE FIRST OCSA RELEASE FOR LINUX ! " +"IT'S A STUPID INTRO CALLED 3X666 ! " }; + +void plainscroll(int t) +#define CHTIME 16 +#define CHPSCR 8 +{ + int chno=t/CHTIME; + int x=0-((t%CHTIME)*(BUFW/CHPSCR))/CHTIME; + int h=(abs((t%48)-24)*BUFH)/256,i; + char*c=skrtxt+chno; + + for(i=0;i=0-(BUFH/8))if(y=*dez)&&(!(flagz&DEMOEND))) + {dez++;flagz=*dez++; + if(flagz&FLASHTXT)flixtim=*(dez-2); + if(flagz&TXTSCR)dizainword=dotxtscr(); + } + if(flagz&FLASHTXT) + while((t/ROWTIX)>=flixtim){phiword=lyrix();flixtim+=4;} + + if(flagz&DEMOEND)break; + + if(flagz&BLACKBG)memset(ruutu,0,BUFH*BUFW);else + if(flagz&FLASHBG) + { unsigned char col=130+(t%48)*2; + #if ASMLOOPS==386 + /* the original asm/string.h by linus does this with stosb, so */ + __asm__("rep;stosl"::"D"(ruutu),"c"((BUFH*BUFW)>>2), + "a"(col|(col<<8)|(col<<16)|(col<<24)):"ax","cx","di"); + #else + memset(ruutu,col,BUFH*BUFW); + #endif + } + + if(flagz&CHESSBG){int zoom=((10+abs(((t>>1)%96)-48))*4096/BUFW); + rotochess(ruutu, + sin(t*0.03)*zoom,cos(t*0.03)*zoom,0,0);} + +/* if(flagz&PLASMABG) drawplasma(ruutu,t); */ + + if(flagz&OCSALOGO){ + #define U (BUFW/40) + drawchar(U*6,U*4,phont['O'-32],U+U*sin(t*0.10+3),U); + drawchar(U*14,U*4,phont['C'-32],U,U+U*sin(t*0.11+3)); + drawchar(U*22,U*4,phont['S'-32],U,U+U*sin(t*0.12+3)); + drawchar(U*30,U*4,phont['A'-32],U+U*sin(t*0.13+3),U); + #undef U + } + + if(flagz&SCROLL0)plainscroll(t); + + if(flagz&BALLIE){ + int zoom; + if(flagz&BALLJUMPS)zoom=abs((t%96)-48);else zoom=47; + if(zoom<0)zoom=0;else if(zoom>47)zoom=47; + + unitvec(&joo,0.038*t,0.023*t,0.011*t,32000/balltab[zoom].R); + joo.z<<=1; + + drawball(ruutu,&joo,zoom); + } + + if(flagz&FLASHTXT)flashtxt(phiword); + if(flagz&TXTSCR)if((t/ROWTIX)&2)drawtxtscr(dizainword); + + if(flagz&ENDSCR)doendscroll(t-1024*ROWTIX); + + #define U (BUFW/40) + if(flagz&COUNTAH) + {int n=((t*50/48)-256*6); + int dis=(rand()%U)>>1; + if(n>666)n=666; + if(n>600){ + drawchar(U*12+dis,(BUFH>>1)+dis+U*6,phont['X'-32],U,U); + drawchar(U*22+dis,(BUFH>>1)+dis+U*6,phont['3'-32],U,U);} + drawchar(U*28+dis,BUFH>>1,phont[16+(n%10)],U,U);n/=10; + drawchar(U*18+dis,BUFH>>1,phont[16+(n%10)],U,U);n/=10; + drawchar(U*8+dis,BUFH>>1,phont[16+(n%10)],U,U);n/=10; + } + #undef U + + /* blitzz */ + + oxl_doframe(ruutu); + #if AUDIO!=0 + oxl_doaudio(audio_mix); + #endif + while(t==oxl_timer()){ + #if SLEEPY + usleep(250000/DEMOHZ); + #endif + } + } + oxl_end(); +} diff -r 000000000000 -r 0e4f2da58161 3xfont.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3xfont.h Fri Mar 15 05:00:01 2013 +0200 @@ -0,0 +1,434 @@ +/* +The font structure: think it out as a segmented lcd display: + + aa bb + c d e + c d e + ff gg + h i j + h i j + kk ll +*/ + +#define Q(a,b,c,d,e,f,g,h,i,j,k,l) \ + a+(b<<1)+(c<<2)+(d<<3)+(e<<4)+(f<<5)+(g<<6)+ \ + (h<<7)+(i<<8)+(j<<9)+(k<<10)+(l<<11) + +short phont[]={ + +Q( /* space 32 */ + 0,0, +0,0,0, + 0,0, +0,0,0, + 0,0 ), + +Q( /* ! 33 */ + 1,1, + 1,0,1, + 1,1, + 0,0,0, + 1,1 ), + +Q( /* " 34 */ + 0,0, +1,0,1, + 0,0, +0,0,0, + 0,0 ), + +Q( /* # 35 .. let's give up :) */ + 1,1, +1,1,1, + 1,1, +1,1,1, + 1,1 ), + +Q( /* $ 36 */ + 1,1, +1,1,0, + 1,1, +0,1,1, + 1,1 ), + +Q( /* % 37 */ + 1,0, +0,0,1, + 1,1, +1,0,0, + 0,1 ), + +Q( /* ~ 38 not ascii */ + 0,1, +1,0,1, + 1,0, +0,0,0, + 0,0 ), + +Q( /* ' 39 */ + 0,0, +0,0,1, + 0,1, +0,0,0, + 0,0 ), + +Q( /* ( 40 */ + 1,1, +1,0,0, + 0,0, +1,0,0, + 1,1 ), + +Q( /* ) 41 */ + 1,1, +0,0,1, + 0,0, +0,0,1, + 1,1 ), + +Q( /* * 42 */ + 0,0, +1,1,1, + 1,1, +1,1,1, + 0,0 ), + +Q( /* + 43 */ + 0,0, +0,1,0, + 1,1, +0,1,0, + 0,0 ), + +Q( /* , 44 */ + 0,0, +0,0,0, + 0,0, +0,0,1, + 0,1 ), + +Q( /* - 45 */ + 0,0, +0,0,0, + 1,1, +0,0,0, + 0,0 ), + +Q( /* . 46 */ + 0,0, +0,0,0, + 0,0, +0,0,0, + 1,1 ), + +Q( /* / 47 */ + 0,0, +0,0,1, + 1,1, +1,0,0, + 0,0 ), + +Q( /* 0 48 */ + 1,1, +1,0,1, + 0,0, +1,0,1, + 1,1 ), + +Q( /* 1 49 */ + 0,0, +0,1,0, + 0,0, +0,1,0, + 0,0 ), + +Q( /* 2 50 */ + 1,1, +0,0,1, + 1,1, +1,0,0, + 1,1 ), + +Q( /* 3 51 */ + 1,1, +0,0,1, + 0,1, +0,0,1, + 1,1 ), + +Q( /* 4 52 */ + 0,0, +1,0,1, + 1,1, +0,0,1, + 0,0 ), + +Q( /* 5 53 */ + 1,1, +1,0,0, + 1,1, +0,0,1, + 1,1 ), + +Q( /* 6 54 */ + 1,1, +1,0,0, + 1,1, +1,0,1, + 1,1 ), + +Q( /* 7 55 */ + 1,1, +1,0,1, + 0,0, +0,0,1, + 0,0 ), + +Q( /* 8 56 */ + 1,1, +1,0,1, + 1,1, +1,0,1, + 1,1 ), + +Q( /* 9 57 */ + 1,1, +1,0,1, + 1,1, +0,0,1, + 1,1 ), + +Q( /* : 58 */ + 1,1, +0,0,0, + 0,0, +0,0,0, + 1,1 ), + +Q( /* ; 59 */ + 1,1, +0,0,0, + 0,0, +0,0,1, + 0,1 ), + +Q( /* < 60 */ + 0,1, +0,1,0, + 1,0, +0,1,0, + 0,1 ), + +Q( /* = 61 */ + 1,1, +0,0,0, + 0,0, +0,0,0, + 1,1 ), + +Q( /* > 62 */ + 1,0, +0,1,0, + 0,1, +0,1,0, + 1,0 ), + +Q( /* ? 63 */ + 1,1, +0,0,1, + 1,1, +0,0,0, + 1,1 ), + +Q( /* @ 64 */ + 1,1, +1,1,1, + 0,1, +1,1,1, + 1,0 ), + +Q( /* A 65 */ + 1,1, +1,0,1, + 1,1, +1,0,1, + 0,0 ), + +Q( /* B 66 */ + 1,0, +1,1,0, + 1,1, +1,0,1, + 1,1 ), + +Q( /* C 67 */ + 1,1, +1,0,1, + 0,0, +1,0,0, + 1,1 ), + +Q( /* D 68 */ + 0,0, +0,0,1, + 1,1, +1,0,1, + 1,1 ), + +Q( /* E 69 */ + 1,1, +1,0,0, + 1,0, +1,0,0, + 1,1 ), + +Q( /* F 70 */ + 1,1, +1,0,0, + 1,0, +1,0,0, + 0,0 ), + +Q( /* G 71 */ + 1,1, +1,0,0, + 0,1, +1,0,1, + 1,1 ), + +Q( /* H 72 */ + 0,0, +1,0,1, + 1,1, +1,0,1, + 0,0 ), + +Q( /* I 73 */ + 1,1, +0,1,0, + 0,0, +0,1,0, + 1,1 ), + +Q( /* J 74 */ + 0,0, +0,0,1, + 0,0, +1,0,1, + 1,1 ), + +Q( /* K 75 */ + 0,1, +1,1,0, + 1,1, +1,0,1, + 0,0 ), + +Q( /* L 76 */ + 1,0, +1,0,0, + 0,0, +1,0,0, + 1,1 ), + +Q( /* M 77 */ + 1,1, +1,1,1, + 0,0, +1,0,1, + 0,0 ), + +Q( /* N 78 */ + 1,1, +1,0,1, + 0,0, +1,0,1, + 0,0 ), + +Q( /* O 79 */ + 1,1, +1,0,1, + 0,0, +1,0,1, + 1,1 ), + +Q( /* P 80 */ + 1,1, +1,0,1, + 1,1, +1,0,0, + 0,0 ), + +Q( /* Q 81 */ + 1,1, +1,0,1, + 0,0, +1,1,1, + 1,1 ), + +Q( /* R 82 */ + 1,1, +1,0,1, + 1,1, +1,1,0, + 0,1 ), + +Q( /* S 83 */ + 1,1, +1,0,0, + 1,1, +0,0,1, + 1,1 ), + +Q( /* T 84 */ + 1,1, +1,1,1, + 0,0, +0,1,0, + 0,0 ), + +Q( /* U 85 */ + 0,0, +1,0,1, + 0,0, +1,0,1, + 1,1 ), + +Q( /* V 86 */ + 0,0, +1,0,1, + 1,0, +0,1,1, + 0,1 ), + +Q( /* W 87 */ + 0,0, +1,0,1, + 0,0, +1,1,1, + 1,1 ), + +Q( /* X 88 */ + 0,0, +0,1,1, + 1,1, +1,1,0, + 0,0 ), + +Q( /* Y 89 */ + 0,0, +1,0,1, + 1,1, +0,1,0, + 0,0 ), + +Q( /* Z 90 */ + 1,1, +0,0,1, + 1,1, +1,0,0, + 1,1 ), + +}; + +#undef Q diff -r 000000000000 -r 0e4f2da58161 Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Makefile Fri Mar 15 05:00:01 2013 +0200 @@ -0,0 +1,41 @@ +# mAKEFiLE fOR 3x666 bY oCSA + +# Choose either vga or X11 +VIDEO = X11 + +# 1 = /dev/dsp a.k.a OpenSoundSystem; 0 = nosound +AUDIO = 0 + +# Ok, next check out config.h! + +## ## ## ## + +CC = gcc + +COPT = -O9 -funroll-loops -fomit-frame-pointer + +# If you prefer size to speed, use of the below COPTs: +# i386 size +#COPT = -O2 -m386 -fomit-frame-pointer -malign-functions=0 -malign-loops=0 -malign-jumps=0 +# generic size +#COPT = -O2 + +CFLAGS = -g -Wall -DVIDEO=$(VIDEO) -DAUDIO=$(AUDIO) +LIBS = -l$(VIDEO) -lm + +# You may want to check out if these dirs are right. +INCDIR = +LIBDIR = -L/usr/X11R6/lib + +# These are for sun. +#INCDIR = -I/usr/openwin/include +#LIBDIR = -L/usr/openwin/lib + +3x666: 3x666.o oxl.o + $(CC) 3x666.o oxl.o -s -o 3x666 $(LIBDIR) $(LIBS) + +oxl.o: oxl.c config.h + $(CC) oxl.c -c -o oxl.o $(COPT) $(CFLAGS) $(INCDIR) + +3x666.o: 3x666.c oxl.h config.h 3xfont.h + $(CC) 3x666.c -c -o 3x666.o $(COPT) $(CFLAGS) $(INCDIR) diff -r 000000000000 -r 0e4f2da58161 README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README Fri Mar 15 05:00:01 2013 +0200 @@ -0,0 +1,57 @@ +*************************** +* +** How do I compile this??? + +Check out the makefile (VIDEO and AUDIO) and config.h (BUFW and BUFH) +and change the values appropriately :) Then type make. + +You need an X window system or svgalib, 8 bits per pixel. You may need +to change the lib setting in the makefile to point to your Xlib dir. + +Tested on i386linux, aix (ibm rs/6000) and sun. Audio only works on linux, +freebsd etc. + +********************************************************************** +* +** I only have an Alpha, is it enough for watching this demo??? + +This phukken multimedia show runs reasonably smoothly on an 386 machine +(about 20x faster than most of today's msdos intros ;) in a 320x200 +window. + +The palette is ugly, the effects lousy. Hope you still enjoy it :) + +************* +* +** Credits ** + +Almost everything done by Viznut this time. Greetings to all +betatesters etc :) + +******************* +* +** To contact ocsa + +vheikkil@hytti.uku.fi +www.hytti.uku.fi/~vheikkil/ + +Member applications are not forbidden :) + +*************** +* +** The binary + +The packet also contains a precompiled executable for dummies only. +(Linux i386 shared elf svgalib devdsp 320x200x256, run as root) + +You should know it is very rude to spread suidroot binaries like this +so if you care about the security of your system, just delete the bin +and forget it! + +**************** +* +** Copyright?? + +Who cares. Use it in the spirit of gnu. But we'd hope you credit us if +you take pieces out of it :) + diff -r 000000000000 -r 0e4f2da58161 config.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/config.h Fri Mar 15 05:00:01 2013 +0200 @@ -0,0 +1,80 @@ +/******************************o. + +Here are some settings you may want to fix :) +VIDEO and AUDIO are set in the makefile. +*/ + +#define BUFW 320 +#define BUFH 200 +/* + The size (width&height) of the display buffer. + + 320x200 is smooth on a 386. + + Svgalib: the best-fitting 256 color mode will be searched + automatically. +*/ + +#define VGARETRACE 0 +/* + 1 = Svgalib waits for the vertical retrace before dumping the + framebuffer. +*/ + +#define ASMLOOPS 0 +/* + 386 = use the i386-optimized asm loops (slightly buggy) + 0 = pure c source (recommended for non-pc machines :) +*/ + +#define OUTFREQ 22050 +/* + Audio output frequency. +*/ + +#define FRAGSIZE 10 /* size = 2^n, n=7..17 */ +#define NUMFRAGS 40 /* somewhere between 2..255, i think */ +/* + The number and size of the audio buffers. + + If your machine has problems in keeping the mixbuffer filled, you + an try to increase these values. However those 10,40 are quite ok + for a 386dx/25 with an old soundblaster. + + Prefer increasing NUMFRAGS unless you want an action-halt- + action-halt style multimedia performance a la windows. + + We still have problems in keeping the audio up in all + circumstances.. such as leaving the svgalib console or while + performing some window manager functions. +*/ + +#define WINNAME "3x666" +/* + The name for the x window. +*/ + +#define SLEEPY 0 +/* + 1 = sleep between frames if there's nothing to do + originally implemented for a better cpu usage + but i don't think it is of any relevant use here + + 0 = use dummyloop + + */ +/* All right! Now save the file and type make ("em ay kee ee") +/ \ + +.o*************/ + +/* don't touch these: */ + +#define DEMOHZ 100 + +/* maybe these shouldn't be here */ +#define ROWTIX 6 +#define MAXROWLGT TIKLGT*ROWTIX + +#define vga 0 +#define X11 1 diff -r 000000000000 -r 0e4f2da58161 file_id.diz --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/file_id.diz Fri Mar 15 05:00:01 2013 +0200 @@ -0,0 +1,6 @@ +ocsa presents : 3x666 : da linux demo. +--.---.---.---:---.---^---.---.---.--' +system: unix/linux, gcc, not many mips +video : X11/vga, any*any*8bit__ __ +audio : devdsp/nosnd, mono8b (______) +disk :::bin size abt 10..20k (o .. o) diff -r 000000000000 -r 0e4f2da58161 oxl.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/oxl.c Fri Mar 15 05:00:01 2013 +0200 @@ -0,0 +1,298 @@ +/*** OCSALiB 0.0.1alpha -- see oxl.h ***/ + +#include "config.h" + +#if VIDEO==vga + #include "vga.h" +#endif +#if VIDEO==X11 + #include "X11/Xlib.h" + #include "X11/Xutil.h" +#endif + +#if AUDIO + #include "sys/soundcard.h" + #include "sys/ioctl.h" +#endif + +#include "stdio.h" +#include "stdlib.h" +#include "fcntl.h" +#include "unistd.h" +#include "malloc.h" +#include "time.h" +#include "sys/time.h" + +#ifdef __linux__ +#include "linux/string.h" +#else +#include "string.h" +#endif + +#define DEMOHZ 100 + +int TIKLGT; + +typedef struct { int r,g,b; } rgb; + +/*** gLOBAL vARS ***/ + +int AUFREQ=OUTFREQ; + +#if AUDIO==1 + int devdsp; + char *audiobuf; +#else + int baseclock; +#endif + +#if VIDEO==vga + int SCRH,SCRW; +#endif + +#if VIDEO==X11 + Display *oxl_disp; + Visual *oxl_vis; + GC oxl_gc; + int oxl_win,oxl_scr; + Colormap oxl_pal; + XImage *oxl_im; + XColor oxl_col[256]; +#endif + +void oxl_init_video() +{ + printf("oxl: buffer size = %ix%ix8bit\n",BUFW,BUFH); + +#if VIDEO==vga +{ int i,fit=0,fitw=9999,fith=9999; + vga_modeinfo*inf; + + if(vga_init()){printf("oxl: can't init svgalib!\n");exit(0);} + + /* Finds the best-fitting 256-color videomode */ + for(i=0;icolors==256)&& + (inf->width >=BUFW)&&(inf->height>=BUFH)&& + (inf->width <=fitw)&&(inf->height<=fith)){ + fith=SCRH=inf->height; + fitw=SCRW=inf->width; + fit=i; + } } } + + if(!fit){ + printf("oxl: no suitable modes found.\n");exit(0);} + else{ + printf("oxl: using %s\n",vga_getmodename(fit)); + vga_setmode(fit); + } +} +#endif + +#if VIDEO==X11 +{ XSetWindowAttributes att; + Window rtwin; + + /* get some pointers'n'stuff */ + if(!(oxl_disp=XOpenDisplay(NULL))){ + perror("oxl: can't open X display!\n");exit(0);} + oxl_scr=DefaultScreen(oxl_disp); + oxl_gc=DefaultGC(oxl_disp,oxl_scr); + oxl_vis=DefaultVisual(oxl_disp,oxl_scr); + + rtwin=DefaultRootWindow(oxl_disp); + + /* don't store the contents */ + att.backing_store=NotUseful; + + /* allocate a private colormap */ + oxl_pal=XCreateColormap(oxl_disp,rtwin,oxl_vis,AllocAll); + att.colormap=oxl_pal; + + /* a black emptiness replaces the cursor */ + {XColor blk;Pixmap e; + blk.red=blk.green=blk.blue=0; + blk.flags=DoRed+DoGreen+DoBlue; + e=XCreatePixmap(oxl_disp,rtwin,2,2,1); + att.cursor=XCreatePixmapCursor(oxl_disp,e,e,&blk,&blk,0,0);} + + oxl_win=XCreateWindow( + oxl_disp,rtwin, + 0,0,BUFW,BUFH,4, + 8, /* colordepth */ + InputOutput, + oxl_vis, + CWBackingStore+CWColormap+CWCursor,&att); + + /* tell the wm you can't resize it */ + {XSizeHints shints; + shints.min_width= shints.max_width= BUFW; + shints.min_height=shints.max_height=BUFH; + shints.flags=PMinSize+PMaxSize; + + /* set the names etc */ + XSetStandardProperties( + oxl_disp,oxl_win, + WINNAME,WINNAME, + None,NULL,0, + &shints); + } + + /* and draw the window */ + XMapWindow(oxl_disp,oxl_win); + XSync(oxl_disp,False); + + /* create the ximage to be hooked on the frame buffer */ + oxl_im=XCreateImage(oxl_disp,oxl_vis, + 8,ZPixmap, /* depth, format */ + 0,NULL, /* offset, data */ + BUFW,BUFH, /* width, height */ + 32,BUFW); /* align bits, bytes per scanline */ + oxl_im->bitmap_unit=32; + + /* some values for the palette */ + {int i; + for(i=0;i<256;i++){ + oxl_col[i].flags=DoRed|DoGreen|DoBlue; + oxl_col[i].pixel=i; + oxl_col[i].pad=0; + }} +} +#endif +} + +void oxl_init_audio(int rowtix) +{ +#if AUDIO==1 + int tmp; + printf("oxl: initing oss..\n"); + + devdsp=open("/dev/dsp",O_WRONLY|O_NDELAY,0); + ioctl(devdsp,SNDCTL_DSP_SPEED,&AUFREQ); + + tmp=(NUMFRAGS<<16)|FRAGSIZE; + ioctl(devdsp,SNDCTL_DSP_SETFRAGMENT,&tmp); + ioctl(devdsp,SNDCTL_DSP_SYNC,0); + + tmp=0;ioctl(devdsp,SNDCTL_DSP_STEREO,&tmp); /* mono */ + tmp=8;ioctl(devdsp,SNDCTL_DSP_SAMPLESIZE,&tmp); /* 8*/ + + audiobuf=malloc((rowtix*AUFREQ/DEMOHZ)*sizeof(char)); +#endif +} + +#if AUDIO==0 +int klok() /* just an internal clumsie */ +{ + struct timeval tym; + gettimeofday(&tym,NULL); + return (tym.tv_sec*DEMOHZ)+(tym.tv_usec*DEMOHZ/1000000); +} +#endif + +void oxl_init_timer() +{ +#if AUDIO==0 + baseclock=klok(); +#endif +} + +void oxl_end() +{ +/* These things should be done automatically on exit but + let's put them here anyway :) */ + +#if AUDIO==1 + close(devdsp); +#endif + +#if VIDEO==vga + vga_setmode(TEXT); +#endif + +#if VIDEO==X11 + XCloseDisplay(oxl_disp); +#endif +} + +int oxl_timer() +{ +#if AUDIO==1 + count_info p; + ioctl(devdsp,SNDCTL_DSP_GETOPTR,&p); + return p.bytes/TIKLGT; +#else + return (klok()-baseclock); +#endif +} + +void oxl_doaudio(int*(*player)(void)) +{ +#if AUDIO==1 + audio_buf_info a; + + for(;;){ + ioctl(devdsp,SNDCTL_DSP_GETOSPACE,&a); + if(a.fragments>8; + if(x<0)x=0;else if(x>255)x=255; + *d++=x; + } + write(devdsp,audiobuf,lgt); + } + } +#endif +} + +void oxl_setpalette(rgb*pal) +{ +#if VIDEO==vga + int *p=(int*)pal,*c;int pp[256*3],i;c=pp; + for(i=256*3;i;i--)*c++=*p++>>2; + vga_setpalvec(0,256,pp); +#endif + +#if VIDEO==X11 +{ int i; + rgb*p=pal;XColor *c=oxl_col; + for(i=256;i;i--){ + c->red=(p->r<<8); + c->green=(p->g<<8); + c->blue=(p->b<<8); + c++;p++; + } + XStoreColors(oxl_disp,oxl_pal,oxl_col,256); +} +#endif +} + +void oxl_doframe(char *vscr) +{ +#if VIDEO==vga + int y0=(SCRH-BUFH)>>1; + + #if VGARETRACE==1 + vga_waitretrace(); + #endif + + if(SCRW==BUFW) + vga_drawscansegment(vscr,0,y0,BUFW*BUFH); + else + { + int y;char *s=vscr;int x0=(SCRW-BUFW)>>1; + for(y=y0;ydata=vscr; + XPutImage(oxl_disp,oxl_win,oxl_gc,oxl_im,-1,-1,0,0,BUFW,BUFH); + XSync(oxl_disp,False); +#endif +} diff -r 000000000000 -r 0e4f2da58161 oxl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/oxl.h Fri Mar 15 05:00:01 2013 +0200 @@ -0,0 +1,127 @@ +/******************** + + OCSALiB, the revolutionary -- version 0.0.1alpha + + (c) viznut/ocsa '98 vheikkil@hytti.uku.fi + + use it the way you like, i don't care :) + +***************/ + +typedef struct {int r,g,b; } rgb; + +extern void oxl_setpalette(rgb *pal); +extern void oxl_doframe(char *vscr); +extern int oxl_timer(void); +extern void oxl_doaudio(int*(player())); +extern void oxl_init_video(void); +extern void oxl_init_audio(int rowtix); +extern void oxl_init_timer(void); +extern void oxl_end(void); + +extern int AUFREQ, TIKLGT; + +/*x. + + Just in case you _may_ want to use this in your own proggie (urgh) + let's put some documentation here :) + +** FUNCTIONS ** + +void oxl_setpalette(rgb *pal) + + pal is a table containing three ints (r,g,b) for every color. + the values vary 0..255. + +void oxl_doframe(char *vscr) + + blits the contents of the offscreen buffer to the screen. + the size of the buffer is BUFW * BUFH * 8 bits. + +int oxl_timer(void) + + the current timer value. the number of timer ticks per second is + defined by the DEMOHZ constant. + +void oxl_doaudio(int*(player())); + + fills the audio output buffers up to 50%. + + player is a user-specified function returning a pointer to some raw + audio data (e.g. the mixer output for the next row of a pattern) + + the first int of the data is the length of the rest (in ints). + + the buffer is int* but the data is 16bit unsigned. values going out + of the range 0..65535 will be clipped. + + AUFREQ specifies the output frequency. + +void oxl_init_video(void); + + adjusts the display for the demo. + oxl_doframe and oxl_setpalette need this. + +void oxl_init_audio(int rowtix); + + inits the audio stuff, possibly changing the value of AUFREQ. + rowtix is the maximum length (in ticks) of an audio chunk produced + by int*(player()). (the 'physical length' in samples is therefore + rowtix*AUFREQ/DEMOHZ) + + oxl_doaudio needs this. does nothing if nosound. + +void oxl_init_timer(void); + + starts the timer. oxl_timer needs this. + + with sounds on, the timing is actually based on the byte counter of + the sound device but put this in your code anyway. + +void oxl_end(void); + + closes the multimedia subsystems. these things should be done + automatically when the program terminates, so you really don't need + this function. + +** CONSTANTS REQUIRED ** + + AUDIO (0/1) + VIDEO (vga/X11) + BUFW, BUFH (buffer size) + DEMOHZ (timer ticks per second) + +** THINGS TO DO ** + + - A guard process that tries to keep up the audio even if the main + loop is frozen. (e.g. if the svgalib screen is not active or if + you move the window in X) + + - Make sure the window start address is properly aligned for the + maximum performance. + + - Do not calculate the contents of the buffer if the screen/window + is not visible. + + - A variable palette size: if the palette fits in the end of the + default colormap, we have to be able to use it instead of rudely + using a private map. + + - Support for visual depths other than 8bpp. + + - Support for 16-bit multimedia sound systems. Stereo? + + - mSDoS support (for dummies) + + - AAlib support + + - An automatical reselection of X11 gfx mode to best fit the size of + the buffer. + + - X fullscreen mode + + - X rootwindow mode + + - Etc etc... but still trying to keep it in a relevant size ;) + +.x*/