#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* Fsck. What are they going to preempt next?! */ #undef setmode #define setmode setmode_ extern const char *__progname; #include "cg6.h" #include "bitmap.h" #include "bitmaps.h" static const char *fbpath = "/dev/cgsix0"; static const char *kbpath = "/dev/kbd1"; static const char *mspath = "/dev/mouse1"; #define how_many(x,y) (((x)+(y)-1)/(y)) #define round_up(x,y) (how_many(x,y)*(y)) static int fbfd; static int kbfd; static int msfd; static volatile struct cg6fb *fb; static volatile struct brooktree *bt; static volatile unsigned char *vram; static int fbmode; static int fbalu; static int fbfg; static int fbpm; #define RPSIZE 64 static unsigned long int randpool[RPSIZE]; static int rp; static int rmp; static volatile unsigned long int hardtime; static unsigned long int softtime; static unsigned long int drawtime; static unsigned long int queuetime; #define EVQ_SIZE 64 /* must be a power of two */ static int evq[EVQ_SIZE]; static int evqh; static int evqt; #define EV_TYPE 0x000f0000 #define EVT_NIL 0x00000000 #define EVT_KBD 0x00010000 #define EVK_CODE 0x0000007f /* must be low bits */ #define EVK_UPDN 0x00000080 #define EVK_UP 0x00000080 #define EVK_DN 0x00000000 #define EVT_TICK 0x00020000 #define EVT_DRAW 0x00030000 #define EVT_MOUSE 0x00040000 #define EVM_TYPE 0x0000c000 #define EVM_T_DX 0x00004000 #define EVM_T_DY 0x00008000 #define EVM_T_BUT 0x0000c000 #define EVM_SIGN 0x00002000 #define EVM_S_NEG 0x00002000 #define EVM_S_POS 0x00000000 #define EVM_DELTA 0x00001fff /* must be low bits */ #define EVM_UPDN 0x00000004 #define EVM_UP 0x00000004 #define EVM_DN 0x00000000 #define EVM_BUTID 0x00000003 #define EVM_BUT_L 0x00000000 #define EVM_BUT_M 0x00000001 #define EVM_BUT_R 0x00000002 #define GRIDX 20 #define GRIDY 28 #define PLAYERZONE 6 #define GRIDWS 5 #define GRIDHS 5 #define GRIDW (1<addr = 0; for (i=0;i<256;i++) { x = (bit ? (i>>3) : i) & 7; if (x) { v = &cmapl[colorscheme][x-1][0]; } else if (i & 0xc0) { v = &cmaph[colorscheme][(i>>6)-1][0]; } else { v = (flash & 1) ? &white[0] : &black[0]; } bt->cmap = *v++ * 0x01000000; bt->cmap = *v++ * 0x01000000; bt->cmap = *v++ * 0x01000000; } } static void drain(void) { while (fb->s & 0x10000000) ; } static void draw(void) { while ((fb->draw & 0xa0000000) == 0xa0000000) ; } static void setpm(int pm) { if (pm != fbpm) { fbpm = pm; fb->pm = pm; } } static void setfg(int fg) { if (fg != fbfg) { fbfg = fg; fb->fg = fg; } } static void setalu(int alu) { if (alu != fbalu) { fbalu = alu; fb->alu = alu; } } static void setmode(int mode) { if (mode != fbmode) { fbmode = mode; fb->mode = mode; } } static void fbrrect(int fg, int x1, int y1, int x2, int y2) { setfg(fg); fb->arecty = y1; fb->arectx = x1; fb->rrecty = y2; fb->rrectx = x2; draw(); } #if 0 static void fbbitmap(int fg, BITMAP *bm, int bmx, int x, int y) { const unsigned long int *bp; int i; bp = bm->bits; if (bm->nvariants > 1) { if (bm->vmap) bmx = bm->vmap[bmx]; bp += bm->h * bmx; } x -= bm->xhot; y -= bm->yhot; fb->fg = fg; fb->x0 = XOFF + x; fb->x1 = XOFF + x + 31; fb->y0 = YOFF + y; fb->incx = 0; fb->incy = 1; for (i=bm->h;i>0;i--) fb->font = *bp++; } #endif static void setupfb(void) { void *mrv; struct fbgattr a; fbfd = open(fbpath,O_RDWR,0); if (fbfd < 0) { fprintf(stderr,"%s: %s: %s\n",__progname,fbpath,strerror(errno)); exit(1); } if ( (ioctl(fbfd,FBIOGATTR,&a) < 0) || (a.fbtype.fb_type != FBTYPE_SUNFAST_COLOR) || (a.fbtype.fb_width != 1152) || (a.fbtype.fb_height != 900) || (a.fbtype.fb_depth != 8) ) { close(fbfd); fprintf(stderr,"%s: %s: not a cg6\n",__progname,fbpath); exit(1); } mrv = mmap(0,0x16000+a.fbtype.fb_size,PROT_READ|PROT_WRITE,MAP_SHARED,fbfd,0x70000000); if (mrv == MAP_FAILED) { fprintf(stderr,"%s: can't mmap %s: %s\n",__progname,fbpath,strerror(errno)); exit(1); } fb = mrv; bt = (void *)(0x2000+(unsigned char *)mrv); vram = 0x16000 + (unsigned char *)mrv; drawbit = 0; fbfg = -1; fbpm = -1; fbalu = -1; fbmode = -1; fb->bg = 0; fb->pixelm = ~0; fb->s = 0; fb->mode = 0x00229540; /* not all bits known */ fb->alu = 0xc0000000 /* GX_PLANE_MASK */ | 0x20000000 /* GX_PIXEL_ONES */ | 0x00800000 /* GX_ATTR_SUPP (?) */ | 0x00000000 /* GX_RAST_BOOL (?) */ | 0x00000000 /* GX_PLOT_PLOT (?) */ | 0x08000000 /* GX_PATTERN_ONES */ | 0x01000000 /* GX_POLYG_OVERLAP */ | 0x0000ff00 /* ALU = set to fg color */ ; fb->clip = 0; fb->offx = 0; fb->offy = 0; fb->clipminx = 0; fb->clipminy = 0; fb->clipmaxx = 1151; fb->clipmaxy = 899; drain(); fb->pm = ~0; fbrrect(0,0,0,1151,899); drain(); fb->clipminx = 0; fb->clipminy = 0; fb->clipmaxx = 1151; fb->clipmaxy = 899; setpm(7); } static void setupkb(void) { int type; int mode; kbfd = open(kbpath,O_RDWR,0); if (kbfd < 0) { fprintf(stderr,"%s: can't open %s: %s\n",__progname,kbpath,strerror(errno)); exit(1); } if ( (ioctl(kbfd,KIOCTYPE,&type) < 0) || (type != KB_SUN3) ) { close(kbfd); fprintf(stderr,"%s: %s isn't a type-3\n",__progname,kbpath); exit(1); } mode = 1; ioctl(kbfd,KIOCSDIRECT,&mode); mode = TR_UNTRANS_EVENT; ioctl(kbfd,KIOCTRANS,&mode); mode = 1; ioctl(kbfd,FIONBIO,&mode); } static void setupms(void) { int mode; msfd = open(mspath,O_RDWR,0); if (msfd < 0) { fprintf(stderr,"%s: can't open %s: %s\n",__progname,mspath,strerror(errno)); exit(1); } mode = 1; ioctl(msfd,FIONBIO,&mode); } static void handle_sigalrm(int sig __attribute__((__unused__))) { if (paused) { if (singlestep) { singlestep --; } else { return; } } hardtime ++; } static void setuptimer(void) { struct itimerval itv; struct sigaction sa; hardtime = 0; softtime = 0; drawtime = 0; queuetime = 0; sa.sa_handler = handle_sigalrm; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; sigaction(SIGALRM,&sa,0); itv.it_value.tv_sec = 0; itv.it_value.tv_usec = 10000; itv.it_interval = itv.it_value; setitimer(ITIMER_REAL,&itv,0); } static void initevq(void) { evqh = 0; evqt = 0; } static unsigned long int rnd(void) { int prp; prp = rp++; if (rp >= RPSIZE) rp = 0; return(randpool[prp]+=randpool[rp]); } static void initrandom(void) { int i; struct timeval tv; void *m; unsigned char h[16]; int nh; gettimeofday(&tv,0); randpool[0] = tv.tv_sec; randpool[1] = tv.tv_usec; randpool[2] = getpid(); randpool[3] = 1; nh = 0; for (i=RPSIZE-1;i>=0;i--) { if (nh < 2) { m = md5_init(); md5_process_bytes(m,&randpool[0],sizeof(randpool)); md5_result(m,&h[0]); nh = 16; } randpool[i] ^= (h[nh-1] << 8) | h[nh-2]; nh -= 2; } randpool[0] |= 1; rp = RPSIZE-3; for (i=0;i<65536;i++) rnd(); rmp = 0; } static void rnd_tweak(const void *data, int len) { int i; unsigned long int v; for (i=0;i> 1) ^ ((v & 1) ? 0xedb88320 : 0); randpool[rmp] = v; rmp ++; if (rmp >= RPSIZE) rmp = 0; } } static void incscore(int pts) { score += pts; while (score > nextlife) { lives ++; nextlife += 12000; } } static void fuse_bubble_up(void) { unsigned int x; unsigned int u; FUSE *fx; FUSE *fu; x = fuses_n - 1; fx = fuses[x]; while (x > 0) { u = (x-1) / 2; fu = fuses[u]; if (fx->when >= fu->when) break; fuses[x] = fu; x = u; } fuses[x] = fx; } static FUSE *add_fuse(int when, void (*fn)(void *), void *arg) { FUSE *f; f = malloc(sizeof(FUSE)); f->when = queuetime + when; f->fn = fn; f->arg = arg; if (fuses_n >= fuses_a) fuses = realloc(fuses,(fuses_a=fuses_n+6)*sizeof(FUSE *)); fuses[fuses_n++] = f; fuse_bubble_up(); return(f); } #if 0 static void cancel_fuse(FUSE *f) { f->fn = 0; f->arg = 0; } #endif static int touches(BITMAP *a, BITMAP *b, int ox, int oy) { int as; int bs; int axo; int bxo; int ay; int by; unsigned long long int av; unsigned long long int bv; int atw; int btw; int n; int x; unsigned long int *atp; unsigned long int *btp; if ((ox >= a->w) || (ox <= -b->w) || (oy >= a->h) || (oy <= -b->h)) return(0); if (ox < 0) { as = 0; bs = (-ox) & 31; axo = (-ox) >> 5; bxo = 0; } else { as = ox & 31; bs = 0; axo = 0; bxo = ox >> 5; } atw = how_many(a->w,32); btw = how_many(b->w,32); n = atw - axo; if (n > btw-bxo) n = btw - bxo; av = 0; bv = 0; atp = a->shadow + axo; btp = b->shadow + bxo; for (x=0;xh)&&(byh);ay++,by++) { av = 0; bv = 0; atp = a->touch + (ay * atw) + axo; btp = b->touch + (by * btw) + bxo; for (x=0;xalu = 0xff00; setpm(0xc0); fbrrect(0,0,0,1151,899); drain(); } static void fixed_bitmap(BITMAP *b, int x, int y) { unsigned char m; int px; int r; unsigned long int *dp; setmode(0x40000); setalu(0xcccc); fb->incx = 0; fb->incy = 1; x = (x * GRIDW) + XOFF; y = (y * GRIDH) + YOFF; dp = b->data; setfg(0xc0); for (m=0x40;m&0xc0;m<<=1) { setpm(m); for (px=0;pxw;px+=32) { fb->x0 = x + px; fb->x1 = x + px + 31; fb->y0 = y; for (r=b->h-1;r>=0;r--) fb->font = *dp++; } } } static BITMAP *mroom_bitmap(int mr) { return(mr_bitmaps[mr]); } static void render_fixed(int x, int y) { BITMAP *b; b = mroom_bitmap(mrooms[x][y]); if (! b) { drain(); setalu(0xff00); setpm(0xc0); fbrrect(0,XOFF+(x*GRIDW),YOFF+(y*GRIDH),GRIDW-1,GRIDH-1); drain(); return; } fixed_bitmap(b,x,y); } static void setup_level(void) { int x; int y; clear_fixed(); pzmush = 0; for (x=0;x= GRIDY-PLAYERZONE) pzmush ++; } } mrooms[x][GRIDY-1] = 0; } reset_playbegin(); } static void fuse_bubble_down(void) { unsigned int x; unsigned int l; unsigned int r; FUSE *fx; FUSE *fl; FUSE *fr; x = 0; fx = fuses[0]; while (x < fuses_n) { l = x + x + 1; r = l + 1; fl = (l < fuses_n) ? fuses[l] : 0; fr = (r < fuses_n) ? fuses[r] : 0; if (fl && (fl->when < fx->when)) { if (fr && (fr->when < fx->when)) { if (fl->when < fr->when) { fuses[x] = fl; x = l; } else { fuses[x] = fr; x = r; } } else { fuses[x] = fl; x = l; } } else { if (fr && (fr->when < fx->when)) { fuses[x] = fr; x = r; } else { break; } } } fuses[x] = fx; } static void initgame(void) { debugk = 0; scorptime = 0; fleay = -1; flash = 0; level = 1; paused = 0; score = 0; nextlife = 12000; lives = 2; setup_level(); } static void queue_event(int ev) { if (((evqh-evqt) & (EVQ_SIZE-1)) == (EVQ_SIZE-1)) { write(1,"evq full\n",9); } else { evq[evqh] = ev; evqh = (evqh+1) & (EVQ_SIZE-1); } } static int checkkb(void) { struct firm_event ev; int r; r = read(kbfd,&ev,sizeof(ev)); if (r == sizeof(ev)) { rnd_tweak(&ev,sizeof(ev)); queue_event(EVT_KBD|(ev.id&0x7f)|((ev.value==VKEY_UP)?EVK_UP:EVK_DN)); return(1); } return(0); } static int checkms(void) { struct firm_event ev; int r; int v; r = read(msfd,&ev,sizeof(ev)); if (r == sizeof(ev)) { rnd_tweak(&ev,sizeof(ev)); switch (ev.id) { case MS_LEFT: v = EVM_BUT_L; if (0) { case MS_MIDDLE: v = EVM_BUT_M; } if (0) { case MS_RIGHT: v = EVM_BUT_R; } queue_event(EVT_MOUSE|EVM_T_BUT|v|((ev.value==VKEY_UP)?EVM_UP:EVM_DN)); break; case LOC_X_DELTA: v = EVM_T_DX; if (0) { case LOC_Y_DELTA: v = EVM_T_DY; } if (ev.value < 0) { queue_event(EVT_MOUSE|v|EVM_S_NEG|(EVM_DELTA&-ev.value)); } else { queue_event(EVT_MOUSE|v|EVM_S_POS|(EVM_DELTA&ev.value)); } break; default: printf("id %#x ignored from mouse\n",ev.id); break; } return(1); } return(0); } static int checktick(void) { int ht; ht = hardtime; if (softtime != ht) { queue_event(EVT_TICK); softtime ++; if ((softtime == ht) && (softtime >= drawtime)) queue_event(EVT_DRAW); return(1); } return(0); } static int dequeue_event(void) { int ev; if (evqh == evqt) return(EVT_NIL); ev = evq[evqt]; evqt = (evqt+1) & (EVQ_SIZE-1); return(ev); } static void check_fuses(void) { FUSE *f; while ((fuses_n > 0) && (fuses[0]->when <= queuetime)) { f = fuses[0]; if (f->fn) (*f->fn)(f->arg); free(f); fuses_n --; if (fuses_n > 0) { fuses[0] = fuses[fuses_n]; fuse_bubble_down(); } } } static void check_shot_hits(void) { int gx; int gy; if (! shot) return; if ( (scorptime > 0) && touches(scorpbm,shotbm,shotx-(shotbm->w/2)-scorpx,shoty-scorpy) ) { scorptime = 0; shot = 0; incscore(0); return; } if ( (fleay >= 0) && touches(&bitmap_flea,shotbm,shotx-(shotbm->w/2)-fleax,shoty-fleay) ) { fleay = -1; shot = 0; incscore(0); return; } gx = shotx >> GRIDWS; gy = shoty >> GRIDHS; if (mrooms[gx][gy]) { if ((MROOM_DAMAGE & --mrooms[gx][gy]) == 0) { mrooms[gx][gy] = 0; if (gy >= GRIDY-PLAYERZONE) pzmush --; incscore(1); } render_fixed(gx,gy); shot = 0; return; } } static void check_hits(void) { check_shot_hits(); } static void togglepause(void) { paused ^= PAUSE_TABKEY; } static void dec_flash(void *arg __attribute__((__unused__))) { flash --; if (flash > 0) add_fuse(4,dec_flash,0); } #if 0 static void startflash(int n) { if (flash == 0) add_fuse(4,dec_flash,0); flash += n; } #endif static void playermove(int dx, int dy) { int px; int py; int v[4][2]; int nv; BITMAP *b; static void foo(int gx, int gy) { int i; if (mrooms[gx][gy] == 0) return; for (i=0;i= MAXX-bitmap_gun.w) { px = MAXX - bitmap_gun.w - 1; } if (py < MAXY-(GRIDH*PLAYERZONE)) { py = MAXY - (GRIDH*PLAYERZONE); } else if (py > MAXY-bitmap_gun.h) { py = MAXY - bitmap_gun.h; } nv = 0; foo( px >>GRIDWS, py >>GRIDHS); foo((px+bitmap_gun.w-1)>>GRIDWS, py >>GRIDHS); foo( px >>GRIDWS,(py+bitmap_gun.h-1)>>GRIDHS); foo((px+bitmap_gun.w-1)>>GRIDWS,(py+bitmap_gun.h-1)>>GRIDHS); for (nv--;nv>=0;nv--) { b = mroom_bitmap(mrooms[v[nv][0]][v[nv][1]]); if (b == 0) continue; if (touches(b,&bitmap_gun,px-(v[nv][0]*GRIDW),py-(v[nv][1]*GRIDH))) return; } playerx = px; playery = py; } static void setshotbm(void) { static BITMAP *shot_bitmaps[4] = { &bitmap_shotA, &bitmap_shotB, &bitmap_shotC, &bitmap_shotD }; shotbm = shot_bitmaps[shot&3]; } static void tick_shot(void) { if (! shot) { if (firing) { shot = 1; shotx = playerx + (bitmap_gun.w / 2); shoty = playery; setshotbm(); } return; } shot ++; shoty -= 2; if (shoty < 0) shot = 0; setshotbm(); } static void sstep(void) { singlestep = 1; } static void scorpion(void) { if (rnd() & 1) { scorpx = MAXX; scorpdx = -1; scorpbm = &bitmap_scorpL; } else { scorpx = -bitmap_scorpR.w; scorpdx = 1; scorpbm = &bitmap_scorpR; } scorpy = GRIDH * (rnd() % (GRIDY-PLAYERZONE)); scorptime = (MAXX + scorpbm->w) + 2; } static void setpoison(int x, int y) { if ((x < 0) || (y < 0) || (x >= GRIDX) || (y >= GRIDY)) return; if (mrooms[x][y]) { mrooms[x][y] |= MROOM_POISON; render_fixed(x,y); } } static void tick_scorpion(void) { if (scorptime < 1) return; if (scorpx >= 0) setpoison(scorpx>>GRIDWS,scorpy>>GRIDHS); setpoison((scorpx+scorpbm->w-1)>>GRIDWS,scorpy>>GRIDHS); scorpx += scorpdx; scorptime --; } static void tick_flea(void) { int gy; if (fleay < 0) { if (pzmush < 5) { fleagx = rnd() % GRIDX; fleax = fleagx << GRIDWS; fleagy = -1; fleay = 0; } return; } fleay += 2; gy = fleay >> GRIDHS; if (gy >= GRIDY) { fleay = -1; return; } if (gy != fleagy) { fleagy = gy; if ((rnd() & 1) && (mrooms[fleagx][gy] == 0) && (gy < GRIDY-1)) { mrooms[fleagx][gy] = 4; if (gy >= GRIDY-PLAYERZONE) pzmush ++; render_fixed(fleagx,gy); } } } static void process_evq(void) { int ev; while (1) { ev = dequeue_event(); switch (ev & EV_TYPE) { case EVT_NIL: return; break; case EVT_KBD: switch (ev & (EVK_CODE|EVK_UPDN)) { case 1|EVK_DN: debugk++; break; /* L1, debugging */ case 1|EVK_UP: break; case 5|EVK_DN: sstep(); break; /* F1, single-step */ case 5|EVK_UP: break; case 21|EVK_DN: scorpion(); break; /* R1 */ case 21|EVK_UP: break; case 22|EVK_DN: break; /* R2 */ case 22|EVK_UP: break; case 23|EVK_DN: break; /* R3 */ case 23|EVK_UP: break; case 29|EVK_DN: exit(0); break; /* ESC */ case 29|EVK_UP: break; case 53|EVK_DN: togglepause(); break; /* TAB */ case 53|EVK_UP: break; default: printf("kbd: %d ",ev&EVK_CODE); switch (ev & EVK_UPDN) { case EVK_UP: printf("up\n"); break; case EVK_DN: printf("dn\n"); break; } break; } break; case EVT_TICK: queuetime ++; tick_shot(); tick_scorpion(); tick_flea(); check_hits(); check_fuses(); break; case EVT_DRAW: wantrender = 1; break; case EVT_MOUSE: switch (ev & EVM_TYPE) { case EVM_T_DX: switch (ev & EVM_SIGN) { case EVM_S_NEG: playermove(-(ev&EVM_DELTA),0); break; case EVM_S_POS: playermove(ev&EVM_DELTA,0); break; } break; case EVM_T_DY: switch (ev & EVM_SIGN) { case EVM_S_NEG: playermove(0,ev&EVM_DELTA); break; case EVM_S_POS: playermove(0,-(ev&EVM_DELTA)); break; } break; case EVM_T_BUT: switch (ev & EVM_UPDN) { case EVM_DN: firing = 1; break; case EVM_UP: firing = 0; break; } break; } break; } } } static void moving_bitmap(BITMAP *b, int x, int y) { unsigned long int *dp; int px; int r; setmode(0x20000); setalu(0xeeee); setpm(drawpm); fb->incx = 0; fb->incy = 1; x += XOFF; y += YOFF; dp = b->data; for (px=0;pxw;px+=4) { fb->x0 = x + px; fb->x1 = x + px + 3; fb->y0 = y; for (r=b->h-1;r>=0;r--) fb->font = *dp++; } } static void render_centipedes(void) { } static void render_player(void) { moving_bitmap(&bitmap_gun,playerx,playery); } static void render_spider(void) { } static void render_flea(void) { if (fleay < 0) return; moving_bitmap(&bitmap_flea,fleax,fleay); } static void render_scorpion(void) { if (scorptime < 1) return; moving_bitmap(scorpbm,scorpx,scorpy); } static void render_shot(void) { if (! shot) return; moving_bitmap(shotbm,shotx-(bitmap_shotA.w/2),shoty); } static void mayberender(void) { if (! wantrender) return; wantrender = 0; drain(); fb->clipminx = 0; fb->clipminy = 0; fb->clipmaxx = 1151; fb->clipmaxy = 899; setmode(0x20000); setalu(0xff00); setpm(drawpm); fbrrect(0,0,0,1151,899); drain(); fb->clipminx = XOFF; fb->clipminy = YOFF; fb->clipmaxx = XOFF + MAXX - 1; fb->clipmaxy = YOFF + MAXY - 1; render_centipedes(); render_player(); render_spider(); render_flea(); render_scorpion(); render_shot(); drain(); setcmap(drawbit); drawbit = ! drawbit; drawpm = drawbit ? 070 : 007; } static void step(void) { struct pollfd pfd[2]; process_evq(); mayberender(); if (checkkb()) return; if (checkms()) return; if (checktick()) return; pfd[0].fd = kbfd; pfd[0].events = POLLIN | POLLRDNORM; pfd[1].fd = msfd; pfd[1].events = POLLIN | POLLRDNORM; if (poll(&pfd[0],2,INFTIM) < 0) { if (errno == EINTR) return; fprintf(stderr,"%s: poll: %s\n",__progname,strerror(errno)); exit(1); } } static void initfuses(void) { fuses = 0; fuses_n = 0; fuses_a = 0; } static void initbitmaps(void) { int bno; BITMAP *b; static unsigned long int *datav = 0; static int datan = 0; unsigned char m; int px; int bx; unsigned long int v; unsigned long int s; unsigned long int *sv; int y; int i; static void need_data(int n) { if (datan < n) { datav = malloc(1000*sizeof(*datav)); datan = 1000; } } for (bno=0;(b=allbitmaps[bno]);bno++) { switch (b->type) { case BM_FIXED: need_data(b->h*2*how_many(b->w,32)); b->data = datav; for (m=0x40;m&0xc0;m<<=1) { for (px=0;pxw;px+=32) { for (y=0;yh;y++) { v = 0; for (bx=0;bx<32;bx++) { if ((px+bx < b->w) && (b->bits[(y*b->w)+px+bx] & m)) { v |= 0x80000000 >> bx; } } *datav++ = v; datan --; } } } break; case BM_MOVING: need_data(b->h*how_many(b->w,4)); b->data = datav; for (px=0;pxw;px+=4) { for (y=0;yh;y++) { v = 0; for (bx=0;bx<4;bx++) { if (px+bx < b->w) { v |= ((b->bits[(y*b->w)+px+bx] & 7) * 011) << (24 - (8 * bx)); } } *datav++ = v; datan --; } } break; } i = how_many(b->w,32); need_data(i); sv = datav; b->shadow = sv; datav += i; datan -= i; need_data(b->h*how_many(b->w,32)); b->touch = datav; for (px=0;pxw;px+=32) { s = 0; for (y=0;yh;y++) { v = 0; for (bx=0;bxw;bx++) { if (b->bits[(y*b->w)+bx]) v |= 0x80000000 >> bx; } *datav++ = v; datan --; s |= v; } *sv++ = s; } } } int main(void); int main(void) { setupfb(); setupkb(); setupms(); setuptimer(); initevq(); initfuses(); initrandom(); initbitmaps(); initgame(); wantrender = 1; while (1) step(); exit(0); }