Mercurial > hg > forks > 3x666-SDL
diff oxl.c @ 0:0e4f2da58161
Initial import.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 15 Mar 2013 05:00:01 +0200 |
parents | |
children |
line wrap: on
line diff
--- /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;i<GLASTMODE;i++){ + if(vga_hasmode(i)){ + inf=vga_getmodeinfo(i); + if((inf->colors==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<a.fragstotal/2) break; + + {register int i,*s=(*player)(); /* output 8bit */ + int lgt=*s++;char*d=audiobuf; + for(i=lgt;i;i--){ + int x=*s++>>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;y<y0+BUFH;y++){vga_drawscansegment(s,x0,y,BUFW);s+=BUFW;} + } +#endif + +#if VIDEO==X11 + oxl_im->data=vscr; + XPutImage(oxl_disp,oxl_win,oxl_gc,oxl_im,-1,-1,0,0,BUFW,BUFH); + XSync(oxl_disp,False); +#endif +}