screenin(char (* pic)[160], char *text) { int a,x,y,yy,v; tw_setsplit(400); tw_clrscr(); tw_setstart(160*200); dis_waitb(); tw_setpalette(&pic[0][16]); pic=&pic[0][784]; y=16;while(*(text=prtc(160,y,text))) y+=FONAY+10; for(x=0;x<160;x++) for(y=0;y<100;y++) tw_putpixel(400+x,400+y*2,pic[y][x]+16); for(y=200*128;y>0;y=y*12L/13) { dis_waitb(); tw_setsplit(y/128+200); yy=320-y/80; for(a=0;a<10000;a++); tw_setstart(160*200+(yy/4)); asm { mov dx, 0x3c0 mov al, 0x33 out dx, al mov ax, yy and ax, 3 shl ax, 1 out dx, al } } for(a=0;a<200 && !dis_exit();a++) dis_waitb(); for(y=0,v=0;y<128*200;y=y+v,v+=15) { dis_waitb(); tw_setsplit(y/128+200); yy=320+y/80; for(a=0;a<10000;a++); tw_setstart(160*200+(yy/4)); asm { mov dx, 0x3c0 mov al, 0x33 out dx, al mov ax, yy and ax, 3 shl ax, 1 out dx, al } } }
void blit_singlecolor(BITMAP *src, BITMAP *dest, int copycolor) { STACKTRACE; if ( src->w != dest->w || src->h != dest->h ) tw_error("error in copying color in shpysr2"); for ( int iy = 0; iy < src->h; ++iy ) { for ( int ix = 0; ix < src->w; ++ix ) { int color = getpixel(src, ix, iy); if ( color == copycolor ) tw_putpixel(dest, ix, iy, color); } } }
prt(int x,int y,char *txt) { int x2w,x2,y2,y2w=y+FONAY,sx,d; while(*txt) { x2w=fonaw[*txt]+x; sx=fonap[*txt]; for(x2=x;x2<x2w;x2++) { for(y2=y;y2<y2w;y2++) { d=font[y2-y][sx]; tw_putpixel(x2,y2,d); } sx++; } x=x2+2; txt++; } }
void KaboHaze::animate(Frame *space) { STACKTRACE; // IMPORTANT: physics must not be changed, that is, NON-LOCAL variable must not // be changed in this subroutine ! // Reason: the TimeWarp engine can decide to skip animations in case of low // frame-rate, thus, leading to a desynch between computers! /* Aaaaah, lots of work to do for a simple job, namely, create a transparent overlay of the shield onto the host: - Init (see constructor): Take the host-ship picture. Create a (blurred) mask image of it. Draw the shield and Overlay the mask. - Animate: Scale and draw the masked shield, Rotate and Draw transparent onto the screen. */ if (!host) return; //if ( state == 0 ) // return; // the host can die in-between calculate and animate, therefore I use this; it's // not allowed to change state of this presence though; that's done only in // calculate(). // Create a rotated copy of the shield sprite ... but only, if such a thing // does not exist, yet ! The purpose of this is, to spread the amount of // calculations over different frames, and to limit them to when they're // needed. int wshield = shield_bmp[0]->w; int hshield = shield_bmp[0]->h; if ( !shield_bmp[shield_sprite_index] ) { shield_bmp[shield_sprite_index] = create_bitmap(wshield, hshield); // important otherwise it contains artefacts clear_to_color(shield_bmp[shield_sprite_index], 0); rotate_sprite(shield_bmp[shield_sprite_index], shield_bmp[0], 0, 0, iround((1<<24)*(host->angle + 0.5*PI)/PI2) ); // result is in sprite_bmp[sprite_index] ( nice conventions, huh !) } //sprite_index = 0; // also needed - for collision detection?? // note, I've turned the collision of, since collide_flag_anyone = 0, but // otherwise, the collision detector would use this sprite_index to access // a ship sprite that doesnt exist !! // next, animate ... // first, reserve space for the target image, but ... how big should it be? // well, as big as the ship_bmp, but then, zoomed in space: int wfinal = int(wshield * space_zoom); int hfinal = int(hshield * space_zoom); BITMAP *final_bmp; final_bmp = create_bitmap(wfinal, hfinal); // scale/draw a shield: stretch_blit(shield_bmp[shield_sprite_index], final_bmp, 0, 0, wshield, hshield, 0, 0, wfinal, hfinal ); // result is in final_bmp // I need to calculate screen coordinates (using the original bmp size). // double xhost = host->normal_pos().x; // double yhost = host->normal_pos().y; Vector2 Vcorner; Vcorner = corner(host->normal_pos(), Vector2(wshield, hshield) ); //wcorner(xhost, wshield); int xplot = iround(Vcorner.x); //hcorner(yhost, hshield); int yplot = iround(Vcorner.y); // these routines are the standard way to calculate screen coordinates ! // local double power_scaled = power / 10.0; if ( power_scaled > 1.0 ) power_scaled = 1.0; // max brightness. // change the brightness of the shield: int brightness = int(255 * power_scaled); set_add_blender(0, 0, 0, brightness); draw_trans_sprite(space->surface, final_bmp, xplot, yplot); space->add_box(xplot, yplot, wshield, hshield); // also, draw a (few) flashes, at twice the brightness: brightness = 255; for ( int i = 0; i < int(power); ++i ) { int dx, dy; dx = wshield; dy = hshield; int icheck = 0; for (;;) { ++icheck; if (icheck > 100) break; // too bad !! //graphics dy = rand() % hshield; if (edge_left[dy] == -1) continue; if ( !(rand() % 2) ) //graphics dx = edge_left[dy]; else dx = edge_right[dy]; } dx -= wshield / 2; dy -= hshield / 2; double a = host->angle + 0.5*PI; // rotated around the center int dx2 = iround(wshield/2 + dx * cos(a) - dy * sin(a)); int dy2 = iround(hshield/2 + dy * cos(a) + dx * sin(a)); dx = iround( dx2 * space_zoom); dy = iround( dy2 * space_zoom); int x = xplot + dx; int y = yplot + dy; tw_putpixel(space->surface, x, y, tw_makecol(brightness,brightness,0) ); space->add_pixel(x, y); } // release the temporary bitmap: destroy_bitmap(final_bmp); }
// WHY DOES THIS TAKE SO LONG ?!?! // an image of 100x100 pixels means, // there's 10,000 calculations involved ! // no wonder. void blit_blur(BITMAP *src, int R) { STACKTRACE; int *blurmap; if ( R <= 2 ) return; // first, create a sinusoid blur template blurmap = new int [R*R]; double radius = R / 2.0; double xmid = radius; double ymid = radius; int ix, iy, k; k = 0; for ( iy = 0; iy < R; ++iy ) { for ( ix = 0; ix < R; ++ix ) { // 0.5, so that you're in the center of the pixel double x = ix+0.5 - xmid; double y = iy+0.5 - ymid; double range = sqrt(x*x + y*y); if (range > radius) range = radius; blurmap[k] = int(255 * cos(0.5*PI * range/R)); ++k; } } // next, create a copy of the picture to which we write the result BITMAP *temp_bmp = create_bitmap(src->w, src->h); // next, apply the blur for ( iy = 0; iy < src->h; ++iy ) { for ( ix = 0; ix < src->w; ++ix ) { // create a new pixel at this position: int xblur, yblur; int newcolorR = 0; int newcolorG = 0; int newcolorB = 0; int totweight = 0; k = 0; for ( yblur = 0; yblur < R; ++yblur ) { for ( xblur = 0; xblur < R; ++xblur ) { int color = getpixel(src, ix+xblur-R/2, iy+yblur-R/2); if ( color != -1 ) { int weight = blurmap[k]; ++k; newcolorR += getr(color) * weight; newcolorG += getg(color) * weight; newcolorB += getb(color) * weight; totweight += weight; } } } newcolorR /= totweight; newcolorG /= totweight; newcolorB /= totweight; int newcolor = tw_makecol(newcolorR, newcolorG, newcolorB); tw_putpixel(temp_bmp, ix, iy, newcolor); } } // and then, copy the blurred image on top of the old one, so that becomes blurred. blit(temp_bmp, src, 0, 0, 0, 0, src->w, src->h); destroy_bitmap(temp_bmp); delete[] blurmap; }