/* Copyright (C) 1995-2002 FSGames. Ported by Sean Ford and Yan Shosh * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //radar.cpp /* ChangeLog buffers: 7/31/02: *include cleanup */ #include "graph.h" #include "colors.h" #define RADAR_X 60 // These are the dimensions of the radar #define RADAR_Y 44 // viewport // ************************************************************ // RADAR -- It's nothing like pixie, it just looks like it // ************************************************************ /* radar(char,short,short,screen) - initializes the radar data (pix = char) short draw() short on_screen() */ // Radar -- this initializes the graphics data for the radar, // as well as its graphics x and y size. In addition, it informs // the radar of the screen object it is linked to. radar::radar(viewscreen * myview, screen * myscreen, short whatnum) { screenp = myscreen; viewscreenp = myview; mynum = whatnum; //what number viewscreen we are, to get control's position bmp = NULL; } void radar::start() { sizex = (unsigned short) screenp->maxx; sizey = (unsigned short) screenp->maxy; size = (unsigned short) (((unsigned short) sizex)*((unsigned short) sizey)); xview = RADAR_X; yview = RADAR_Y; radarx = 0; radary = 0; if (xview > sizex) xview = sizex; if (yview > sizey) yview = sizey; xloc = (short) ( ((viewscreenp->endx - xview) - 4) ); yloc = (short) ( ((viewscreenp->endy - yview) - 4) ); bmp = (unsigned char *) new unsigned char[size]; update(); } // Destruct the radar and its variables radar::~radar() { if (bmp) { delete bmp; bmp = NULL; } } short radar::draw() { oblink * here; long tempx, tempy, tempz; unsigned char tempcolor; short oborder, obfamily, obteam; short can_see = 0, do_show = 0; long listtype = 0; radarx = 0; radary = 0; if (!viewscreenp || !screenp) return 0; //shouldn't be needed???? if (!viewscreenp->radarstart) { start(); viewscreenp->radarstart = 1; } if (viewscreenp->control) { radarx = (short) (viewscreenp->control->xpos/GRID_SIZE - xview/2); radary = (short) (viewscreenp->control->ypos/GRID_SIZE - yview/2); if (viewscreenp->control->view_all > 0) can_see = 1; obteam = viewscreenp->control->team_num; } else { radarx = (short) (screenp->topx/GRID_SIZE - xview/2); radary = (short) (screenp->topy/GRID_SIZE - yview/2); obteam = 0; } if (radarx > (sizex - xview)) radarx = (short) (sizex - xview); if (radary > (sizey - yview)) radary = (short) (sizey - yview); if (radarx < 0) radarx = 0; if (radary < 0) radary = 0; screenp->putbuffer(xloc, yloc, sizex,sizey, xloc,yloc,xloc + xview,yloc + yview, &bmp[radarx + (radary * sizex)]); // Now determine what objects are visible on the radar .. while (listtype <= 1) { if (listtype == 0) // do oblist, standard { here = screenp->oblist; listtype++; } else if (listtype == 1) // do weapons { here = screenp->weaplist; listtype++; } else continue; while (here) { if (here->ob) oborder = here->ob->query_order(); do_show = 0; // don't show, by default if (here->ob && (oborder == ORDER_LIVING || oborder == ORDER_WEAPON || (oborder == ORDER_TREASURE && (here->ob->query_family() == FAMILY_LIFE_GEM)) || (oborder == ORDER_TREASURE && (here->ob->query_family() == FAMILY_EXIT)) || (oborder == ORDER_GENERATOR && can_see) ) && (obteam==here->ob->team_num || here->ob->invisibility_left < 1 || can_see) && on_screen( (short) ((here->ob->xpos+1)/GRID_SIZE), (short) ((here->ob->ypos+1)/GRID_SIZE), radarx, radary) ) do_show = 1; if (do_show) { tempx = xloc + ((here->ob->xpos+1)/GRID_SIZE - radarx); tempy = yloc + ((here->ob->ypos+1)/GRID_SIZE - radary); if ( (tempx < xloc) || (tempx > (xloc + xview)) ) {} //do nothing else if ( (tempy < yloc) || (tempy > (yloc + yview)) ) {} //also do nothing else { tempz = (tempx+(tempy*320)); //this may need fixing if (tempz > 64000 || tempz < 0) { printf("bad radar, bad\n"); return 1; } tempcolor = (here->ob->query_team_color()); if (viewscreenp->control == here->ob) { tempcolor = (unsigned char) (random(256)); if (tempx >= (xloc + xview - 1) && tempy < (yloc+yview) ) { //buffers: PORT: screenp->videobuffer[tempz-1] = tempcolor; //buffers: PORT: screenp->videobuffer[tempz] = tempcolor; //buffers: PORT: screenp->videobuffer[tempz+319] = tempcolor; //buffers: PORT: screenp->videobuffer[tempz+320] = tempcolor; screenp->pointb(tempx-1,tempy,tempcolor); screenp->pointb(tempx,tempy,tempcolor); screenp->pointb(tempx-1,tempy+1,tempcolor); screenp->pointb(tempx,tempy+1,tempcolor); } else if (tempx >= (xloc + xview -1) ) { //buffers: PORT: screenp->videobuffer[tempz] = tempcolor; //buffers: PORT: screenp->videobuffer[tempz-1] = tempcolor; //buffers: PORT: screenp->videobuffer[tempz-320] = tempcolor; //buffers: PORT: screenp->videobuffer[tempz-321] = tempcolor; screenp->pointb(tempx,tempy,tempcolor); screenp->pointb(tempx-1,tempy,tempcolor); screenp->pointb(tempx,tempy-1,tempcolor); screenp->pointb(tempx-1,tempy-1,tempcolor); } else if (tempy >= (yloc + yview -1) && tempx < (xloc+xview) ) { //buffers: PORT: screenp->videobuffer[tempz] = tempcolor; //buffers: PORT: screenp->videobuffer[tempz+1] = tempcolor; //buffers: PORT: screenp->videobuffer[tempz-320] = tempcolor; //buffers: PORT: screenp->videobuffer[tempz-319] = tempcolor; screenp->pointb(tempx,tempy,tempcolor); screenp->pointb(tempx+1,tempy,tempcolor); screenp->pointb(tempx,tempy-1,tempcolor); screenp->pointb(tempx+1,tempy-1,tempcolor); } else { //buffers: PORT: screenp->videobuffer[tempz] = tempcolor; //buffers: PORT: screenp->videobuffer[tempz+1] = tempcolor; //buffers: PORT: screenp->videobuffer[tempz+320] = tempcolor; //buffers: PORT: screenp->videobuffer[tempz+321] = tempcolor; screenp->pointb(tempx,tempy,tempcolor); screenp->pointb(tempx+1,tempy,tempcolor); screenp->pointb(tempx,tempy+1,tempcolor); screenp->pointb(tempx+1,tempy+1,tempcolor); } } else if (oborder == ORDER_LIVING) //buffers: PORT: screenp->videobuffer[tempz] = tempcolor; screenp->pointb(tempx,tempy,tempcolor); else if (oborder == ORDER_GENERATOR) //buffers: PORT: screenp->videobuffer[tempz] = (char) (tempcolor+1); screenp->pointb(tempx,tempy,(char)(tempcolor+1)); else if (oborder == ORDER_TREASURE) // currently life gems //buffers: PORT: screenp->videobuffer[tempz] = COLOR_FIRE; screenp->pointb(tempx,tempy,COLOR_FIRE); else //buffers: PORT: screenp->videobuffer[tempz] = COLOR_WHITE; screenp->pointb(tempx,tempy,COLOR_WHITE); }//draw the blob onto the radar } here = here->next; } } // go back to new screen lists (weapons, etc.) here = screenp->fxlist; while (here) { if (here->ob && !here->ob->dead) { oborder = here->ob->query_order(); obfamily = here->ob->query_family(); do_show = 0; // don't show, by default if (oborder == ORDER_TREASURE) { if (can_see) { switch (obfamily) { case FAMILY_GOLD_BAR: do_show = (short) (YELLOW + random(5)); break; case FAMILY_SILVER_BAR: do_show = (short) (GREY + random(5)); break; case FAMILY_DRUMSTICK: do_show = (short) (COLOR_BROWN + random(2)); break; case FAMILY_MAGIC_POTION: case FAMILY_INVIS_POTION: case FAMILY_INVULNERABLE_POTION: case FAMILY_FLIGHT_POTION: do_show = (short) (COLOR_BLUE + random(5)); break; default: do_show = 0; break; } } if (obfamily == FAMILY_EXIT || obfamily == FAMILY_TELEPORTER) do_show = (short) LIGHT_BLUE + random(7); } if (!on_screen( (short) ((here->ob->xpos+1)/GRID_SIZE), (short) ((here->ob->ypos+1)/GRID_SIZE), radarx, radary) ) do_show = 0; if (do_show) { tempx = xloc + ((here->ob->xpos+1)/GRID_SIZE - radarx); tempy = yloc + ((here->ob->ypos+1)/GRID_SIZE - radary); if ( (tempx < xloc) || (tempx > (xloc + xview)) ) {} //do nothing else if ( (tempy < yloc) || (tempy > (yloc + yview)) ) {} //also do nothing else { tempz = (tempx+(tempy*320)); //this may need fixing if (tempz > 64000 || tempz < 0) { printf("bad radar, bad\n"); return 1; } //buffers: PORT: screenp->videobuffer[tempz] = (char) do_show; screenp->pointb(tempx,tempy,(char)do_show); }//draw the blob onto the radar } // end of valid do_show } // end of if here->ob here = here->next; } // end of while (here) return 1; } //short radar::refresh() //{ // The first two values are screwy... I don't know why // screenp->buffer_to_screen(xloc, yloc, xview, yview); // return 1; //} // In theory the above function will NOT be required short radar::on_screen(short whatx, short whaty, short hor, short ver) { // Return 0 if off radar. // These measurements are grid coords, not pixels. if (whatx < hor || whatx >= (hor+xview) || whaty < ver || whaty >= (ver+yview) ) { return 0; } else { return 1; } } // This function re-initializes the radar map data. Do not // call it often, as it is very slow .. void radar::update() { short temp, i, j; for (i = 0; i < sizex; i++) for (j = 0; j < sizey; j++) { // Check if item in background grid switch (screenp->grid[i+sizex*j]) { case PIX_GRASS1: // grass is green case PIX_GRASS_DARK_1: case PIX_GRASS_DARK_B1: case PIX_GRASS_DARK_BR: temp = COLOR_GREEN+3; break; case PIX_GRASS2: case PIX_GRASS_DARK_2: case PIX_GRASS_DARK_B2: case PIX_WALL_ARROW_GRASS: temp = COLOR_GREEN+4; break; case PIX_GRASS3: case PIX_GRASS_DARK_3: case PIX_GRASS_DARK_R1: case PIX_WALL_ARROW_GRASS_DARK: temp = COLOR_GREEN+5; break; case PIX_GRASS4: case PIX_GRASS_DARK_4: case PIX_GRASS_DARK_R2: temp = COLOR_GREEN+5; break; case PIX_GRASS_DARK_LL: case PIX_GRASS_DARK_UR: case PIX_GRASS_RUBBLE: case PIX_GRASS_LIGHT_1: // lighter grass case PIX_GRASS_LIGHT_TOP: case PIX_GRASS_LIGHT_RIGHT_TOP: case PIX_GRASS_LIGHT_RIGHT: case PIX_GRASS_LIGHT_RIGHT_BOTTOM: case PIX_GRASS_LIGHT_BOTTOM: case PIX_GRASS_LIGHT_LEFT_BOTTOM: case PIX_GRASS_LIGHT_LEFT: case PIX_GRASS_LIGHT_LEFT_TOP: temp = (short) (COLOR_GREEN + random(3) + 3); break; case PIX_TREE_M1: // Trees are green case PIX_TREE_ML: case PIX_TREE_T1: case PIX_TREE_MR: case PIX_TREE_MT: temp = (short) (COLOR_TREES + random(3)); break; case PIX_TREE_B1: // Trunks are brown temp = COLOR_BROWN + 6; break; case PIX_PAVEMENT1: // pavement dark grey case PIX_PAVEMENT2: case PIX_PAVEMENT3: case PIX_PAVESTEPS1: case PIX_PAVESTEPS2: case PIX_PAVESTEPS2L: case PIX_PAVESTEPS2R: case PIX_COBBLE_1: case PIX_COBBLE_2: case PIX_COBBLE_3: case PIX_COBBLE_4: temp = 17; break; case PIX_FLOOR_PAVEL: // wood is brown case PIX_FLOOR_PAVER: case PIX_FLOOR_PAVEU: case PIX_FLOOR_PAVED: case PIX_FLOOR1: case PIX_WALL_ARROW_FLOOR: temp = COLOR_BROWN+4; break; case PIX_DIRT_1: // path is brown case PIX_DIRTGRASS_UL1: case PIX_DIRTGRASS_UR1: case PIX_DIRTGRASS_LL1: case PIX_DIRTGRASS_LR1: case PIX_DIRT_DARK_1: case PIX_DIRTGRASS_DARK_UL1: case PIX_DIRTGRASS_DARK_UR1: case PIX_DIRTGRASS_DARK_LL1: case PIX_DIRTGRASS_DARK_LR1: temp = COLOR_BROWN+5; break; case PIX_JAGGED_GROUND_1: case PIX_JAGGED_GROUND_2: case PIX_JAGGED_GROUND_3: case PIX_JAGGED_GROUND_4: temp = COLOR_BROWN+5; break; case PIX_CLIFF_BOTTOM: // slightly darker case PIX_CLIFF_TOP: case PIX_CLIFF_LEFT: case PIX_CLIFF_RIGHT: case PIX_CLIFF_BACK_1: case PIX_CLIFF_BACK_2: case PIX_CLIFF_BACK_L: case PIX_CLIFF_BACK_R: case PIX_CLIFF_TOP_L: case PIX_CLIFF_TOP_R: temp = COLOR_BROWN+6; break; case PIX_CARPET_LL: // carpet is purple case PIX_CARPET_B: case PIX_CARPET_LR: case PIX_CARPET_UR: case PIX_CARPET_U: case PIX_CARPET_UL: case PIX_CARPET_L: case PIX_CARPET_M: case PIX_CARPET_M2: case PIX_CARPET_R: case PIX_CARPET_SMALL_HOR: case PIX_CARPET_SMALL_VER: case PIX_CARPET_SMALL_CUP: case PIX_CARPET_SMALL_CAP: case PIX_CARPET_SMALL_LEFT: case PIX_CARPET_SMALL_RIGHT: case PIX_CARPET_SMALL_TINY: temp = COLOR_PURPLE+4; break; case PIX_H_WALL1: // walls are light grey case PIX_WALL2: case PIX_WALL3: case PIX_WALL_LL: case PIX_WALLTOP_H: case PIX_WALL4: case PIX_WALL5: case PIX_BOULDER_1: case PIX_BOULDER_2: case PIX_BOULDER_3: case PIX_BOULDER_4: case PIX_PATH_1: // sparser cobblestone/grass case PIX_PATH_2: case PIX_PATH_3: case PIX_PATH_4: temp = 24; break; case PIX_WATER1: // Water is dark blue case PIX_WATER2: case PIX_WATER3: case PIX_WATERGRASS_LL: case PIX_WATERGRASS_LR: case PIX_WATERGRASS_UL: case PIX_WATERGRASS_UR: case PIX_GRASSWATER_LL: case PIX_GRASSWATER_LR: case PIX_GRASSWATER_UL: case PIX_GRASSWATER_UR: temp = COLOR_BLUE+2; break; case PIX_WALLSIDE_L: // White, maybe? case PIX_WALLSIDE1: case PIX_WALLSIDE_R: case PIX_WALLSIDE_C: case PIX_WALLSIDE_CRACK_C1: temp = COLOR_WHITE-1; break; case PIX_TORCH1: case PIX_TORCH2: case PIX_TORCH3: case PIX_BRAZIER1: temp = COLOR_FIRE; break; default: temp = 0; } bmp[i+sizex*j] = (unsigned char) temp; } }