// 2nd pass: which roi would this operation need as input to fill the given output region? void modify_roi_in(dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const dt_iop_roi_t *const roi_out, dt_iop_roi_t *roi_in) { *roi_in = *roi_out; const float scale = roi_in->scale / piece->iscale; float aabb[4] = { roi_out->x, roi_out->y, roi_out->x + roi_out->width, roi_out->y + roi_out->height }; float aabb_in[4] = { INFINITY, INFINITY, -INFINITY, -INFINITY }; for(int c = 0; c < 4; c++) { float p[2], o[2]; // get corner points of roi_out get_corner(aabb, c, p); backtransform(piece, scale, p, o); // transform to roi_in space, get aabb. adjust_aabb(o, aabb_in); } const struct dt_interpolation *interpolation = dt_interpolation_new(DT_INTERPOLATION_USERPREF); const float IW = interpolation->width * scale; // adjust roi_in to minimally needed region roi_in->x = aabb_in[0] - IW; roi_in->y = aabb_in[1] - IW; roi_in->width = aabb_in[2] - roi_in->x + IW; roi_in->height = aabb_in[3] - roi_in->y + IW; }
// Return cached corner with the given lattice Location bloomenthal_polygonizer::Corner* bloomenthal_polygonizer::get_cached_corner(const Location& L) { Corner* c = get_corner(L); if(!c) { c = new Corner(L); c->p = location_vertex(L); c->value = m_FieldFunctor.implicit_value(c->p); m_Corners.insert(L, c); } return c; }
// 2nd pass: which roi would this operation need as input to fill the given output region? void modify_roi_in(dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const dt_iop_roi_t *const roi_out, dt_iop_roi_t *roi_in) { *roi_in = *roi_out; const float scale = roi_in->scale / piece->iscale; float aabb[4] = { roi_out->x, roi_out->y, roi_out->x + roi_out->width, roi_out->y + roi_out->height }; float aabb_in[4] = { INFINITY, INFINITY, -INFINITY, -INFINITY }; for(int c = 0; c < 4; c++) { float p[2], o[2]; // get corner points of roi_out get_corner(aabb, c, p); backtransform(piece, scale, p, o); // transform to roi_in space, get aabb. adjust_aabb(o, aabb_in); } const struct dt_interpolation *interpolation = dt_interpolation_new(DT_INTERPOLATION_USERPREF); const float IW = (float)interpolation->width * scale; const float orig_w = roi_in->scale * piece->buf_in.width, orig_h = roi_in->scale * piece->buf_in.height; // adjust roi_in to minimally needed region roi_in->x = fmaxf(0.0f, aabb_in[0] - IW); roi_in->y = fmaxf(0.0f, aabb_in[1] - IW); roi_in->width = fminf(orig_w - roi_in->x, aabb_in[2] - roi_in->x + IW); roi_in->height = fminf(orig_h - roi_in->y, aabb_in[3] - roi_in->y + IW); // sanity check. roi_in->x = CLAMP(roi_in->x, 0, (int)floorf(orig_w)); roi_in->y = CLAMP(roi_in->y, 0, (int)floorf(orig_h)); roi_in->width = CLAMP(roi_in->width, 1, (int)ceilf(orig_w) - roi_in->x); roi_in->height = CLAMP(roi_in->height, 1, (int)ceilf(orig_h) - roi_in->y); }
void World::set_tera_height(Plasma &plasma) { memset(corner_matrix, 0, sizeof(Corner)*(max_x_loc+1)*(max_y_loc+1)); // short seaHeight = TerrainRes::max_height(TERRAIN_OCEAN); short seaHeight = 0; // no more sea int y; int x; for(y = 0; y <= max_y_loc; ++y ) { for(x = 0; x <= max_x_loc; ++x) { Corner *cornerPtr = get_corner(x,y); cornerPtr->set_altitude(plasma.get_pix(x,y)); cornerPtr->set_sea_altitude(seaHeight); // set gradient_x float gradientX; if(x <= 0) { err_when(x < 0); gradientX = float(4*plasma.get_pix(x+1,y) - plasma.get_pix(x+2,y) - 3*plasma.get_pix(x,y)) / (2 * LOCATE_WIDTH); } else if( x >= max_x_loc ) { err_when(x > max_x_loc); gradientX = float(plasma.get_pix(x-2,y) - 4*plasma.get_pix(x-1,y) + 3*plasma.get_pix(x,y)) / (2 * LOCATE_WIDTH); } else { gradientX = float(plasma.get_pix(x+1,y) - plasma.get_pix(x-1,y)) / (2 * LOCATE_WIDTH); } // if( gradientX >= 0.0f && gradientX <= 0.25f ) // gradientX += 0.15f; // else if( gradientX < 0.0f && gradientX >= -0.25f ) // gradientX -= 0.15f; cornerPtr->set_gradient_x( gradientX ); // set gradient_y float gradientY; if(y <= 0) { err_when(y < 0); gradientY = float(4*plasma.get_pix(x,y+1) - plasma.get_pix(x,y+2) - 3*plasma.get_pix(x,y)) / (2 * LOCATE_HEIGHT); } else if( y >= max_y_loc ) { err_when(y > max_y_loc); gradientY = float(plasma.get_pix(x,y-2) - 4*plasma.get_pix(x,y-1) + 3*plasma.get_pix(x,y)) / (2 * LOCATE_HEIGHT); } else { gradientY = float(plasma.get_pix(x,y+1) - plasma.get_pix(x,y-1)) / (2 * LOCATE_HEIGHT); } // if( gradientY >= 0.0f && gradientY <= 0.25f ) // gradientY += 0.15f; // else if( gradientY < 0.0f && gradientY >= -0.25f ) // gradientY -= 0.15f; cornerPtr->set_gradient_y( gradientY ); } } // calculate polynomial coefficient for(y = 0; y < max_y_loc; ++y ) { for(x = 0; x < max_x_loc; ++x) { LocationCorners lc; get_loc_corner(x,y, &lc); short &z0 = lc.top_left->altitude; short &z1 = lc.top_right->altitude; short &z2 = lc.bottom_left->altitude; short &z3 = lc.bottom_right->altitude; short &duz0w = lc.top_left->gradient_x; // du/dz * LOCATE_WIDTH short &dvz0h = lc.top_left->gradient_y; short &duz1w = lc.top_right->gradient_x; short &dvz1h = lc.top_right->gradient_y; short &duz2w = lc.bottom_left->gradient_x; short &dvz2h = lc.bottom_left->gradient_y; short &duz3w = lc.bottom_right->gradient_x; short &dvz3h = lc.bottom_right->gradient_y; lc.loc_ptr->c30 = (duz1w + duz0w - (z1-z0) * 2) << (C_MULTIPLIER_SHIFT - LOCATE_WIDTH_SHIFT - LOCATE_WIDTH_SHIFT - LOCATE_WIDTH_SHIFT); lc.loc_ptr->c21 = (duz3w + duz0w - duz1w - duz2w) << (C_MULTIPLIER_SHIFT - 1 - LOCATE_WIDTH_SHIFT - LOCATE_WIDTH_SHIFT - LOCATE_HEIGHT_SHIFT); lc.loc_ptr->c12 = (dvz3h + dvz0h - dvz1h - dvz2h) << (C_MULTIPLIER_SHIFT - 1 - LOCATE_WIDTH_SHIFT - LOCATE_HEIGHT_SHIFT - LOCATE_HEIGHT_SHIFT); lc.loc_ptr->c03 = (dvz2h + dvz0h - (z2-z0) * 2) << (C_MULTIPLIER_SHIFT - LOCATE_HEIGHT_SHIFT - LOCATE_HEIGHT_SHIFT - LOCATE_HEIGHT_SHIFT); lc.loc_ptr->c20 = ( (z1-z0) * 3 - duz1w - duz0w * 2 ) << (C_MULTIPLIER_SHIFT - LOCATE_WIDTH_SHIFT - LOCATE_WIDTH_SHIFT); lc.loc_ptr->c11 = (( z3 + z0 - z1 - z2 ) << (C_MULTIPLIER_SHIFT - LOCATE_WIDTH_SHIFT - LOCATE_HEIGHT_SHIFT)) - (lc.loc_ptr->c21 << LOCATE_WIDTH_SHIFT) - (lc.loc_ptr->c12 << LOCATE_HEIGHT_SHIFT); lc.loc_ptr->c02 = ( (z2-z0) * 3 - dvz2h - dvz0h * 2 ) << (C_MULTIPLIER_SHIFT - LOCATE_HEIGHT_SHIFT - LOCATE_HEIGHT_SHIFT); lc.loc_ptr->c00 = z0 << C_MULTIPLIER_SHIFT; lc.loc_ptr->c10 = duz0w << (C_MULTIPLIER_SHIFT - LOCATE_WIDTH_SHIFT); lc.loc_ptr->c01 = dvz0h << (C_MULTIPLIER_SHIFT - LOCATE_HEIGHT_SHIFT); // find the height of the rendered bitmap { lc.loc_ptr->min_y = 0; lc.loc_ptr->max_y = 0; int seaLevel = 0; if( lc.top_left->is_sea() ) seaLevel = lc.top_left->sea_altitude; if( lc.top_right->is_sea() ) seaLevel = lc.top_right->sea_altitude; if( lc.bottom_left->is_sea() ) seaLevel = lc.bottom_left->sea_altitude; if( lc.bottom_right->is_sea() ) seaLevel = lc.bottom_right->sea_altitude; if( seaLevel ) lc.loc_ptr->loc_flag |= LOCATE_SEA_COAST; else lc.loc_ptr->loc_flag &= ~LOCATE_SEA_COAST; // height relative to top left corner // int refHeight = ZoomMatrix::calc_abs_y(0, 0, lc.loc_ptr->evaluate_z(0, 0)); int refHeight = ZoomMatrix::calc_abs_y(0, 0, lc.loc_ptr->c00 >> C_MULTIPLIER_SHIFT); // include LOCATE_WIDTH, LOCATE_HEIGHT for wider min_y, max_y for(int v = 0; v <= LOCATE_HEIGHT; v+=LOCATE_HEIGHT/4 ) { for( int u = 0; u <= LOCATE_WIDTH; u+=LOCATE_WIDTH/4 ) { long z = lc.loc_ptr->evaluate_z(u, v); // if cover by sea if( seaLevel && z < seaLevel ) z = seaLevel; int pointY = ZoomMatrix::calc_abs_y(u, v, z) - refHeight; //(z - z0) * ZOOM_Z_HEIGHT //+ (u * ZOOM_LOC_X_HEIGHT * LOCATE_HEIGHT //+ v * ZOOM_LOC_Y_HEIGHT * LOCATE_WIDTH ) //>> (LOCATE_WIDTH_SHIFT + LOCATE_HEIGHT_SHIFT); if( pointY < lc.loc_ptr->min_y) lc.loc_ptr->min_y = pointY; if( pointY > lc.loc_ptr->max_y) lc.loc_ptr->max_y = pointY; } } lc.loc_ptr->min_y -= 8; // -4 for more space lc.loc_ptr->max_y += 8; // +4 for more space } } } }
//---------- Begin of function MapMatrix::draw_map ------------// // see also World::explore // void MapMatrix::draw_map() { //----------- draw map now ------------// sys.yield(); short fireColor = vga_back.translate_color(FIRE_COLOR); short plantColor = vga_back.translate_color(plant_res.plant_map_color); short seaColor = vga_back.translate_color(0x32); short rockColor = vga_back.translate_color( 0x59 ); short mapModeColor = vga_back.translate_color( VGA_GRAY+10 ); short unexploredColor = vga_back.translate_color(UNEXPLORED_COLOR); short shadowColor = vga_back.translate_color( VGA_GRAY+2 ); short roadColor = vga_back.translate_color( VGA_GRAY+12 ); short nationColorArray[MAX_NATION+2]; for( int n = 0; n < MAX_NATION+2; ++n ) nationColorArray[n] = vga_back.translate_color(nation_array.nation_power_color_array[n]); // #### begin Ban 8/12 #######// int temp3 = vga_back.buf_true_pitch() -2; short *temp6 = vga_back.buf_ptr((image_x1 + image_x2)/2, image_y1); #ifdef ASM_FOR_MSVC _asm { MOV AX , DS MOV ES , AX MOV EDX, temp3 MOV EDI, temp6 CLD MOV AX, word ptr UNEXPLORED_COLOR MOV CX, AX // processing the color for drawing SHL EAX, 16 MOV AX, CX MOV EBX, 100 XOR ECX, ECX PutLineUpper: // draw upper triangle INC ECX REP STOSD MOV ECX, 101 // restore ECX after STOSD for updating EDI SUB ECX, EBX ADD EDI, EDX // updating EDI to start point of next line SUB EDI, ECX SUB EDI, ECX SUB EDI, ECX SUB EDI, ECX DEC EBX // decrease the remain height JNZ PutLineUpper // loop MOV EBX, 99 // ready parameters for drawing lower triangle ADD EDX, 4 ADD EDI, 4 PutLineLower: // draw lower triangle MOV ECX, EBX REP STOSD ADD EDI, EDX // updating EDI to start point of next line SUB EDI, EBX SUB EDI, EBX SUB EDI, EBX SUB EDI, EBX DEC EBX // decrease the remain height JNZ PutLineLower // loop } #else int lineDiff = temp3 / 2; int lineLength = 2; // Blacken upper half of minimap. for ( int i = 0; i < 100; ++i ) { for ( int j = 0; j < lineLength; ++j ) { *temp6 = UNEXPLORED_COLOR; ++temp6; } temp6 += lineDiff - lineLength; lineLength += 2; } // Blacken lower half of minimap. lineLength = 99 * 2; lineDiff += 2; temp6 += 2; for ( int i = 0; i < 99; ++i ) { for ( int j = 0; j < lineLength; ++j ) { *temp6 = UNEXPLORED_COLOR; ++temp6; } temp6 += lineDiff - lineLength; lineLength -= 2; } #endif // #### end Ban 8/12 #######// // { // traversal of location in MapMatrix // int pixelX = (image_x1 + image_x2 + 1) / 2; // int pixelY = image_y1; // int xLoc, yLoc; // int writePtrInc = vga_back.buf_pitch() + 1; // for( yLoc = 0; yLoc < max_y_loc; (yLoc&1?++pixelY:--pixelX) , ++yLoc ) // { // short* writePtr = vga_back.buf_ptr(pixelX, pixelY); // xLoc = 0; // Location *locPtr = get_loc( xLoc, yLoc ); // for( xLoc = 0; xLoc < max_x_loc; (xLoc += 2), (writePtr += writePtrInc), (locPtr+=2) ) // { // } // } // } switch(map_mode) { case MAP_MODE_TERRAIN: { int pixelX = (image_x1 + image_x2 + 1) / 2; int pixelY = image_y1; int xLoc, yLoc; int writePtrInc = vga_back.buf_pitch() + 1; for( yLoc = 0; yLoc < max_y_loc; (yLoc&1?++pixelY:--pixelX) , ++yLoc ) { short* writePtr = vga_back.buf_ptr(pixelX, pixelY); int tileYOffset = (yLoc & TERRAIN_TILE_Y_MASK) * TERRAIN_TILE_WIDTH; xLoc = 0; Location* locPtr = get_loc( xLoc, yLoc ); for( ; xLoc < max_x_loc; (xLoc += 2), (locPtr += 2), (writePtr += writePtrInc) ) { if( locPtr->explored() ) { // ##### begin Gilbert 10/2 #######// if( filter_object_flag || filter_nation_flag ) // do not anything except filtered objects when filters are on *writePtr = mapModeColor; else if( locPtr->fire_str() > 0) // ##### end Gilbert 10/2 #######// *writePtr = fireColor; else if( locPtr->is_plant() || xLoc+1<max_x_loc && locPtr[1].is_plant() ) *writePtr = plantColor; else if( locPtr->is_rock() ) *writePtr = rockColor; else if( locPtr->has_dirt() ) { Rock *dirtPtr = dirt_array[locPtr->dirt_recno()]; RockInfo *dirtInfo = rock_res.get_rock_info(dirtPtr->rock_recno); if (dirtInfo->rock_type == 'P') *writePtr = seaColor; else *writePtr = rockColor; } else if( locPtr->is_road() ) *writePtr = vga_back.translate_color(terrain_res.get_map_tile(locPtr->road_terrain_id)[tileYOffset + (xLoc & TERRAIN_TILE_X_MASK)]); else { if( xLoc < 2 || terrain_res[locPtr->terrain_id]->average_type >= terrain_res[(locPtr-2)->terrain_id]->average_type ) { // get terrain pixel from terrain_res *writePtr = vga_back.translate_color(terrain_res.get_map_tile(locPtr->terrain_id)[tileYOffset + (xLoc & TERRAIN_TILE_X_MASK)]); } else { *writePtr = shadowColor; } } } //else // not needed because filled black already //{ // *writePtr = unexploredColor; //} } } } break; // ##### begin Gilbert 2/11 #####// case MAP_MODE_TRADE: // ##### end Gilbert 2/11 #####// case MAP_MODE_SPOT: { // traversal of location in MapMatrix int pixelX = (image_x1 + image_x2 + 1) / 2; int pixelY = image_y1; int xLoc, yLoc; int writePtrInc = vga_back.buf_pitch() + 1; for( yLoc = 0; yLoc < max_y_loc; (yLoc&1?++pixelY:--pixelX) , ++yLoc ) { short* writePtr = vga_back.buf_ptr(pixelX, pixelY); xLoc = 0; Location* locPtr = get_loc( xLoc, yLoc ); for( ; xLoc < max_x_loc; (xLoc += 2), (locPtr +=2), (writePtr += writePtrInc) ) { if( locPtr->explored() ) { *writePtr = mapModeColor; } } } } break; case MAP_MODE_POWER: { int pixelX = (image_x1 + image_x2 + 1) / 2; int pixelY = image_y1; int xLoc, yLoc; int writePtrInc = vga_back.buf_pitch() + 1; for( yLoc = 0; yLoc < max_y_loc; (yLoc&1?++pixelY:--pixelX) , ++yLoc ) { short* writePtr = vga_back.buf_ptr(pixelX, pixelY); xLoc = 0; Location *locPtr = get_loc( xLoc, yLoc ); for( xLoc = 0; xLoc < max_x_loc; (xLoc += 2), (locPtr +=2), (writePtr += writePtrInc) ) { if( locPtr->explored() ) { // ####### begin Gilbert 10/2 #########// if( filter_object_flag || filter_nation_flag ) // do not anything except filtered objects when filters are on *writePtr = mapModeColor; else if( locPtr->sailable() ) // ####### end Gilbert 10/2 #########// *writePtr = seaColor; else if( locPtr->is_rock() || locPtr[1].is_rock() ) *writePtr = rockColor; /* else if( locPtr->has_dirt() ) { Rock *dirtPtr = dirt_array[locPtr->dirt_recno()]; RockInfo *dirtInfo = rock_res.get_rock_info(dirtPtr->rock_recno); if (dirtInfo->rock_type == 'P') *writePtr = seaColor; else *writePtr = rockColor; } else if( locPtr->is_plant() || xLoc+1<max_x_loc && locPtr[1].is_plant() ) *writePtr = plantColor; */ else // ###### begin Gilbert 21/12 ########// { if( power_mode ) *writePtr = nationColorArray[locPtr->power_nation_recno]; else *writePtr = nationColorArray[0]; } // ###### end Gilbert 21/12 ########// } } } } break; case MAP_MODE_ALTITUDE: { int pixelX = (image_x1 + image_x2 + 1) / 2; int pixelY = image_y1; int xLoc, yLoc; int writePtrInc = vga_back.buf_pitch() + 1; for( yLoc = 0; yLoc < max_y_loc; (yLoc&1?++pixelY:--pixelX) , ++yLoc ) { short* writePtr = vga_back.buf_ptr(pixelX, pixelY); xLoc = 0; for( xLoc = 0; xLoc < max_x_loc; (xLoc += 2), (writePtr += writePtrInc) ) { Corner *cornerPtr = get_corner( xLoc, yLoc ); short alt = cornerPtr->get_altitude(); if( alt > 255 ) alt = 255; else if( alt < 0 ) alt = 0; *writePtr = vga.make_pixel((BYTE)alt, 128, 32); } } } break; } sys.yield(); }