void Map::draw(int center_x, int center_y, Canvas &canvas) { static ubyte64 start_time = -1; if (start_time == -1) start_time = System::get_time(); int powerup_spr = ((System::get_time()-start_time)/250)%2; int tile_width = get_tile_width()-6; int tile_height = get_tile_height()-6; for (int y=0; y<height; y++) { for (int x=0; x<width; x++) { int scr_x = x*tile_width-6 - center_x; int scr_y = y*tile_height-6 - center_y; int frame = tiles[x + y*width]; if (frame == 2) frame = powerup_spr + 1; // powerup blinking. tile_images.set_frame(frame); tile_images.draw(canvas, scr_x, scr_y); } } }
int add_particle_sys_at_tile (const char *file_name, int x_tile, int y_tile) #endif { float z; z = get_tile_height(x_tile, y_tile); #ifndef MAP_EDITOR return add_particle_sys (file_name, (float) x_tile / 2.0 + 0.25f, (float) y_tile / 2.0 + 0.25f, z, dynamic); #else return add_particle_sys (file_name, (float) x_tile / 2.0 + 0.25f, (float) y_tile / 2.0 + 0.25f, z); #endif }
static INLINE unsigned get_zslice_offset(unsigned tile_mode, unsigned z, unsigned pitch, unsigned nb_h) { unsigned tile_h = get_tile_height(tile_mode); unsigned tile_d = get_tile_depth(tile_mode); /* pitch_2d == to next slice within this volume-tile */ /* pitch_3d == size (in bytes) of a volume-tile */ unsigned pitch_2d = tile_h * 64; unsigned pitch_3d = tile_d * align(nb_h, tile_h) * pitch; return (z % tile_d) * pitch_2d + (z / tile_d) * pitch_3d; }
void display_map_marks(){ actor *me; float x,y,z; int i,ax,ay; float dx = (TILESIZE_X / 6); float dy = (TILESIZE_Y / 6); float fr = mark_z_rot/360; float j,ff=0; me = get_our_actor(); if(!me) return; ax = me->x_pos; ay = me->y_pos; glDisable(GL_TEXTURE_2D); glDisable(GL_LIGHTING); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE); glEnable(GL_ALPHA_TEST); for(i=0;i<max_mark;i++){ x=marks[i].x/2.0; y=marks[i].y/2.0; x += (TILESIZE_X / 2); y += (TILESIZE_Y / 2); if(DST(ax,ay,x,y)>MARK_DIST||marks[i].x<0||!marks_3d) continue; z = get_tile_height(marks[i].x, marks[i].y); for(j=z-fr/5,ff=1;j<z+2;j+=0.1,ff=(2-(j-z))/2) { if(marks[i].server_side) glColor4f(0.0f, 0.0f, 1.0f, 0.9f-(j-z)/3); else glColor4f((float)marks[i].r/255, (float)marks[i].g/255, (float)marks[i].b/255, 0.7f-(j-z)/3); glBegin(GL_QUADS); glVertex3f(x-dx*ff,y-dy*ff,j); glVertex3f(x-dx*ff,y+dy*ff,j); glVertex3f(x+dx*ff,y+dy*ff,j); glVertex3f(x+dx*ff,y-dy*ff,j); glEnd(); } } glDisable(GL_ALPHA_TEST); //glEnable(GL_LIGHTING); glDisable(GL_BLEND); glEnable(GL_TEXTURE_2D); }
void add_teleporters_from_list (const Uint8 *teleport_list) { Uint16 teleporters_no; int i; int teleport_x,teleport_y,my_offset; float x,y,z; teleporters_no=SDL_SwapLE16(*((Uint16 *)(teleport_list))); for (i = 0; i < teleporters_no; i++) { my_offset = i * 5 + 2; teleport_x=SDL_SwapLE16(*((Uint16 *)(teleport_list+my_offset))); teleport_y=SDL_SwapLE16(*((Uint16 *)(teleport_list+my_offset+2))); //later on, maybe we want to have different visual types //now, get the Z position if (!get_tile_valid(teleport_x, teleport_y)) { continue; } z = get_tile_height(teleport_x, teleport_y); //convert from height values to meters x=(float)teleport_x/2; y=(float)teleport_y/2; //center the object x += 0.25f; y += 0.25f; add_particle_sys ("./particles/teleporter.part", x, y, z, 1); engine_add_dynamic_object("./3dobjects/portal1.e3d", x, y, z, 0.0f, 0.0f, 0.0f, 0, 1.0f, 1.0f, 1.0f, engine_get_next_free_dynamic_object_id(), est_detect); //mark the teleporter as an unwalkable so that the pathfinder //won't try to plot a path through it pf_tile_map[teleport_y*tile_map_size_x*6+teleport_x].z = 0; } }
void display_highlight_marker(const highlight_marker *marker) { // (a) varies from 1..0 depending on the age of this marker const float a = ((float)marker->timeleft) / HIGHLIGHT_MARKER_LIFESPAN; float z = get_tile_height(marker->x, marker->y); float x = (float)marker->x/2; float y = (float)marker->y/2; /* The highlighting marker is four polygons like the one below rotated with C as center. A---B---+ | | | D---+---+ | | | +---+---C (polygon is A->B->C->D->A) where C is supposed to be the center of the highlighted tile (offset by center_offset_x, center_offset_y though). Distance A->B is (dx), distance A->D is (dy) */ const float dx = (TILESIZE_X / 6); const float dy = (TILESIZE_Y / 6); //Move the offset of the C point closer to the actual center of the tile depending // on how "old" this marker is. We want the highlighting marker to shrink close to // the center as the marker gets older, and we also want the shrinking to be faster // when the marker is large, and slower as it gets to the center, hence the (a*a) // instead of just (a). const float center_offset_x = ((TILESIZE_X / 2) * (a*a)); const float center_offset_y = ((TILESIZE_X / 2) * (a*a)); //we want the marker to start a bit above ground and move itself closer to the // ground as it gets older. z += a*0.3f; // place x,y in the center of the highlighting tile x += (TILESIZE_X / 2); y += (TILESIZE_Y / 2); switch (marker->type) { case HIGHLIGHT_TYPE_WALKING_DESTINATION: glColor4f(0.0f, 1.0f, 0.0f, a); break; case HIGHLIGHT_TYPE_SPELL_TARGET: glColor4f(0.0f, 0.0f, 1.0f, a); break; case HIGHLIGHT_TYPE_ATTACK_TARGET: glColor4f(1.0f, 0.0f, 0.0f, a); break; case HIGHLIGHT_TYPE_LOCK: glColor4f(1.0f, 1.0f, 0.0f, a); break; case HIGHLIGHT_SOFT_FAIL: glColor4f(1.0f, 0.5f, 0.0f, a); break; } glBegin(GL_POLYGON); glVertex3f(x - 2*dx - center_offset_x, y - 2*dy - center_offset_y, z); glVertex3f(x - 1*dx - center_offset_x, y - 2*dy - center_offset_y, z); glVertex3f(x - 0*dx - center_offset_x, y - 0*dy - center_offset_y, z); glVertex3f(x - 2*dx - center_offset_x, y - 1*dy - center_offset_y, z); glVertex3f(x - 2*dx - center_offset_x, y - 2*dy - center_offset_y, z); glEnd(); glBegin(GL_POLYGON); glVertex3f(x + 2*dx + center_offset_x, y - 2*dy - center_offset_y, z); glVertex3f(x + 1*dx + center_offset_x, y - 2*dy - center_offset_y, z); glVertex3f(x + 0*dx + center_offset_x, y - 0*dy - center_offset_y, z); glVertex3f(x + 2*dx + center_offset_x, y - 1*dy - center_offset_y, z); glVertex3f(x + 2*dx + center_offset_x, y - 2*dy - center_offset_y, z); glEnd(); glBegin(GL_POLYGON); glVertex3f(x + 2*dx + center_offset_x, y + 2*dy + center_offset_y, z); glVertex3f(x + 1*dx + center_offset_x, y + 2*dy + center_offset_y, z); glVertex3f(x + 0*dx + center_offset_x, y + 0*dy + center_offset_y, z); glVertex3f(x + 2*dx + center_offset_x, y + 1*dy + center_offset_y, z); glVertex3f(x + 2*dx + center_offset_x, y + 2*dy + center_offset_y, z); glEnd(); glBegin(GL_POLYGON); glVertex3f(x - 2*dx - center_offset_x, y + 2*dy + center_offset_y, z); glVertex3f(x - 1*dx - center_offset_x, y + 2*dy + center_offset_y, z); glVertex3f(x - 0*dx - center_offset_x, y + 0*dy + center_offset_y, z); glVertex3f(x - 2*dx - center_offset_x, y + 1*dy + center_offset_y, z); glVertex3f(x - 2*dx - center_offset_x, y + 2*dy + center_offset_y, z); glEnd(); }
void display_map_markers() { int ax, ay; float z,x,y; int i; GLdouble model[16],proj[16]; GLint view[4]; GLdouble hx,hy,hz; float banner_width; float font_scale = 1.0f/ALT_INGAME_FONT_X_LEN; float font_size_x=font_scale*SMALL_INGAME_FONT_X_LEN; float font_size_y=font_scale*SMALL_INGAME_FONT_Y_LEN; char tmpb[4]; actor *me; me = get_our_actor(); if(!me) return; ax = me->x_pos; ay = me->y_pos; glGetDoublev(GL_MODELVIEW_MATRIX, model); glGetDoublev(GL_PROJECTION_MATRIX, proj); glGetIntegerv(GL_VIEWPORT, view); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(view[0],view[2]+view[0],view[1],view[3]+view[1],0.0f,-1.0f); glDepthFunc(GL_LEQUAL); glEnable(GL_TEXTURE_2D); glColor4f(1.0,1.0,1.0,1.0); glDisable(GL_LIGHTING); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE); for(i=0;i<max_mark;i++){ x=marks[i].x/2.0; y=marks[i].y/2.0; x += (TILESIZE_X / 2); y += (TILESIZE_Y / 2); if(DST(ax,ay,x,y)>MARK_DIST||marks[i].x<0||!marks_3d) continue; z = get_tile_height(marks[i].x, marks[i].y)+2.3; gluProject(x, y, z, model, proj, view, &hx, &hy, &hz); //shorten text memcpy(tmpb,marks[i].text+MARK_CLIP_POS,4); marks[i].text[MARK_CLIP_POS]=marks[i].text[MARK_CLIP_POS+1]=marks[i].text[MARK_CLIP_POS+2]='.'; marks[i].text[MARK_CLIP_POS+3]=0; banner_width = ((float)get_string_width((unsigned char*)marks[i].text)*(font_size_x*name_zoom))/2.0; draw_ortho_ingame_string(hx-banner_width, hy, hz, (unsigned char*)marks[i].text, 4, font_size_x, font_size_y); //restore text memcpy(marks[i].text+MARK_CLIP_POS,tmpb,4); } glDisable(GL_BLEND); glDisable(GL_TEXTURE_2D); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); //glEnable(GL_LIGHTING); glDepthFunc(GL_LESS); }
int get_3d_objects_from_server (int nr_objs, const Uint8 *data, int len) { int iobj; int obj_x, obj_y; int offset, nb_left; float x = 0.0f, y = 0.0f, z = 0.0f, rx = 0.0f, ry = 0.0f, rz = 0.0f; char obj_name[128]; int name_len, max_name_len; int id = -1; int all_ok = 1; offset = 0; nb_left = len; for (iobj = 0; iobj < nr_objs; iobj++) { int obj_err = 0; if (nb_left < 14) { // Warn about this error! LOG_WARNING("Incomplete 3D objects list!"); all_ok = 0; break; } obj_x = SDL_SwapLE16 (*((Uint16 *)(&data[offset]))); offset += 2; obj_y = SDL_SwapLE16 (*((Uint16 *)(&data[offset]))); offset += 2; if (obj_x > tile_map_size_x * 6 || obj_y > tile_map_size_y * 6) { // Warn about this error! LOG_WARNING("A 3D object was located OUTSIDE the map!"); offset += 8; obj_err = 1; } else { rx = SwapLEFloat (*((float *)(&data[offset]))); offset += 2; ry = SwapLEFloat (*((float *)(&data[offset]))); offset += 2; rz = SwapLEFloat (*((float *)(&data[offset]))); offset += 2; id = SDL_SwapLE16 (*((Uint16 *)(&data[offset]))); offset += 2; x = 0.5f * obj_x + 0.25f; y = 0.5f * obj_y + 0.25f; z = get_tile_height(obj_x, obj_y); } nb_left -= 12; max_name_len = nb_left > sizeof (obj_name) ? sizeof (obj_name) : nb_left; name_len = safe_snprintf (obj_name, max_name_len, "%s", &data[offset]); if (name_len < 0 || name_len >= sizeof (obj_name)) { // Warn about this error! LOG_WARNING("3D object has invalid or too long file name!"); all_ok = 0; break; } offset += name_len + 1; nb_left -= name_len + 1; if (!obj_err) add_e3d_at_id (id, obj_name, x, y, z, rx, ry, rz, 0, 0, 1.0f, 1.0f, 1.0f, 1); else all_ok = 0; } return all_ok; }
void update_camera() { const float c_delta = 0.1f; static int last_update = 0; int time_diff = cur_time - last_update; static float old_camera_x = 0; static float old_camera_y = 0; static float old_camera_z = 0; float adjust; actor *me = get_our_actor(); old_rx=rx; old_rz=rz; new_zoom_level=old_zoom_level=zoom_level; //printf("kludge: %f, hold: %f, rx: %f, rz %f, zoom: %f\n",camera_kludge, hold_camera,rx,rz,zoom_level); if (fol_cam && !fol_cam_behind) rz = hold_camera; if (me) camera_kludge = -me->z_rot; /* This is a BIG hack to not polluate the code but if this feature * is accepted and the flag is removed, all the code that * follows will have to be changed in order to get rid of * camera_rotation_duration and camera_tilt_duration. */ camera_rotation_duration = camera_rotation_speed != 0.0 ? time_diff : 0.0; camera_tilt_duration = camera_tilt_speed != 0.0 ? time_diff : 0.0; if(camera_rotation_duration > 0){ if (time_diff <= camera_rotation_duration) rz+=camera_rotation_speed*time_diff; else rz+=camera_rotation_speed*camera_rotation_duration; camera_rotation_duration-=time_diff; adjust_view++; } if(camera_x_duration > 0){ if(camera_x_speed>1E-4 || camera_x_speed<-1E-4){ if (time_diff <= camera_x_duration) camera_x-=camera_x_speed*time_diff; else camera_x-=camera_x_speed*camera_x_duration; if(fabs(camera_x-old_camera_x) >= c_delta){ adjust_view++; } } camera_x_duration-=time_diff; } if(camera_y_duration > 0){ if(camera_y_speed>1E-4 || camera_y_speed<-1E-4){ if (time_diff <= camera_y_duration) camera_y-=camera_y_speed*time_diff; else camera_y-=camera_y_speed*camera_y_duration; if(fabs(camera_y-old_camera_y) >= c_delta){ adjust_view++; } } camera_y_duration-=time_diff; } if(camera_z_duration > 0){ if(camera_z_speed>1E-4 || camera_z_speed<-1E-4){ if (time_diff <= camera_z_duration) camera_z-=camera_z_speed*time_diff; else camera_z-=camera_z_speed*camera_z_duration; if(fabs(camera_z-old_camera_z) >= c_delta){ adjust_view++; } } camera_z_duration-=time_diff; } if(camera_tilt_duration > 0) { if (time_diff <= camera_tilt_duration) rx+=camera_tilt_speed*time_diff; else rx+=camera_tilt_speed*camera_tilt_duration; camera_tilt_duration-=time_diff; adjust_view++; } if(camera_zoom_duration > 0) { if (time_diff <= camera_zoom_duration) new_zoom_level += camera_zoom_speed*(camera_zoom_dir==1?0.003f:-0.003f)*time_diff; else new_zoom_level += camera_zoom_speed*(camera_zoom_dir==1?0.003f:-0.003f)*camera_zoom_duration; camera_zoom_duration-=time_diff; adjust_view++; } else camera_zoom_speed = 1; if (camera_rotation_speed > 0.0) { camera_rotation_speed -= time_diff * camera_rotation_deceleration; if (camera_rotation_speed < 0.0) camera_rotation_speed = 0.0; } else if (camera_rotation_speed < 0.0) { camera_rotation_speed += time_diff * camera_rotation_deceleration; if (camera_rotation_speed > 0.0) camera_rotation_speed = 0.0; } if (camera_tilt_speed > 0.0) { camera_tilt_speed -= time_diff * camera_tilt_deceleration; if (camera_tilt_speed < 0.0) camera_tilt_speed = 0.0; } else if (camera_tilt_speed < 0.0) { camera_tilt_speed += time_diff * camera_tilt_deceleration; if (camera_tilt_speed > 0.0) camera_tilt_speed = 0.0; } clamp_camera(); if (ext_cam && !first_person && me && rx <= -min_tilt_angle && rx >= -max_tilt_angle) { float rot_x[9], rot_z[9], rot[9], dir[3]; float vect[3] = {0.0, 0.0, new_zoom_level*camera_distance}; int tx, ty; float tz; // we compute the camera position MAT3_ROT_X(rot_x, -rx*M_PI/180.0); MAT3_ROT_Z(rot_z, -rz*M_PI/180.0); MAT3_MULT(rot, rot_z, rot_x); MAT3_VECT3_MULT(dir, rot, vect); // we take the tile where the camera is tx = (int)((dir[0] - camera_x)*2); ty = (int)((dir[1] - camera_y)*2); if (get_tile_walkable(tx, ty)) { tz = get_tile_height(tx, ty); } else { // if the tile is outside the map, we take the height at the actor position tz = get_tile_height(me->x_tile_pos, me->y_tile_pos); } // here we use a shift of 0.2 to avoid to be too close to the ground if (tz + 0.2 > dir[2] - camera_z) { if (ext_cam_auto_zoom) // new behaviour { // if the camera is under the ground, we change the zoom level if (fabsf(dir[2]) > 1E-4) new_zoom_level *= (tz + camera_z + 0.2) / dir[2]; else new_zoom_level = 0.0; if (new_zoom_level < 1.0) { new_zoom_level = 1.0; camera_tilt_duration = camera_zoom_duration = 0; camera_tilt_speed = 0.0; if (fabsf(tz + camera_z + 0.2f) < fabsf(vect[2]) - 0.01) rx = -90.0 + 180.0 * asinf((tz + camera_z + 0.2) / vect[2]) / M_PI; } else if (new_zoom_level > old_zoom_level) { new_zoom_level = old_zoom_level; camera_tilt_duration = camera_zoom_duration = 0; camera_tilt_speed = 0.0; } } else // old freecam behaviour { new_zoom_level = old_zoom_level; camera_tilt_duration = camera_zoom_duration = 0; camera_tilt_speed = 0.0; if (fabsf(tz + camera_z + 0.2f) < fabsf(vect[2]) - 0.01) rx = -90.0 + 180.0 * asinf((tz + camera_z + 0.2) / vect[2]) / M_PI; } } } if(adjust_view){ set_all_intersect_update_needed(main_bbox_tree); old_camera_x= camera_x; old_camera_y= camera_y; old_camera_z= camera_z; } hold_camera = rz; if (fol_cam) { static int fol_cam_stop = 0; if ((SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(2)) || camera_rotation_speed != 0) fol_cam_stop = 1; else if (me && me->moving && fol_cam_stop) fol_cam_stop = 0; if (last_kludge != camera_kludge && !fol_cam_stop) { set_all_intersect_update_needed(main_bbox_tree); adjust = (camera_kludge-last_kludge); //without this the camera will zip the wrong way when camera_kludge //flips from 180 <-> -180 if (adjust >= 180) adjust -= 360.0; else if (adjust <= -180) adjust += 360.0; if (fabs(adjust) < fol_strn) { last_kludge=camera_kludge; } else { last_kludge += fol_strn*( adjust*(fol_quad*fol_strn + fol_lin)+ fol_con*(adjust>0?1:-1))/ (fol_quad+fol_lin+fol_con+.000001f);//cheap no/0 } } if (fol_cam_behind) { if (!fol_cam_stop) rz = -last_kludge; else last_kludge = -rz; } else rz -= last_kludge; } //Make Character Turn with Camera if (have_mouse && !on_the_move (get_our_actor ())) { adjust = rz; //without this the character will turn the wrong way when camera_kludge //and character are in certain positions if (adjust >= 180) adjust -= 360.0; else if (adjust <= -180) adjust += 360.0; adjust+=camera_kludge; if (adjust >= 180) adjust -= 360.0; else if (adjust <= -180) adjust += 360.0; if (adjust > 35){ Uint8 str[2]; str[0] = TURN_LEFT; my_tcp_send (my_socket, str, 1); } else if (adjust < -35){ Uint8 str[2]; str[0] = TURN_RIGHT; my_tcp_send (my_socket, str, 1); } } adjust_view = 0; last_update = cur_time; }
void move_camera () { float x, y, z; // float head_pos[3]; float follow_speed; actor *me = get_our_actor (); if(!me){ return; } x = (float)me->x_pos+0.25f; y = (float)me->y_pos+0.25f; // cal_get_actor_bone_local_position(me, get_actor_bone_id(me, head_bone), NULL, head_pos); /* Schmurk: I've commented this out because I don't see why the position of * the camera should be different from the head position in ext cam and fpv */ /* if (first_person){ */ /* z = (ext_cam?-1.7f:-2.1f) + height_map[me->y_tile_pos*tile_map_size_x*6+me->x_tile_pos]*0.2f + head_pos[2]; */ /* } else if (ext_cam){ */ /* z = -1.6f + height_map[me->y_tile_pos*tile_map_size_x*6+me->x_tile_pos]*0.2f + head_pos[2]; */ if (first_person || ext_cam) { // the camera position corresponds to the head position z = get_tile_height(me->x_tile_pos, me->y_tile_pos); // z += (head_pos[2]+0.1)*get_actor_scale(me); //attachment_props *att_props = get_attachment_props_if_held(me); //z += (me->sitting ? 0.7 : 1.5) * get_actor_scale(me); if (me->attached_actor>=0) z+=me->z_pos + me->attachment_shift[Z]+2.0*get_actor_scale(me); else z += (me->sitting ? 0.7 : 1.5) * get_actor_scale(me); } else { z = get_tile_height(me->x_tile_pos, me->y_tile_pos) + sitting; } if(first_person||ext_cam){ follow_speed = 150.0f; } else { follow_speed = 300.0f; } if(reset_camera_at_next_update){ camera_x = -x; camera_y = -y; camera_z = -z; camera_x_duration=0; camera_y_duration=0; camera_z_duration=0; reset_camera_at_next_update = 0; set_all_intersect_update_needed(main_bbox_tree); } else { //move near the actor, but smoothly camera_x_speed=(x+camera_x)/follow_speed; camera_x_duration=follow_speed; camera_y_speed=(y+camera_y)/follow_speed; camera_y_duration=follow_speed; camera_z_speed=(z+camera_z)/follow_speed; camera_z_duration=follow_speed; } if (first_person){ // glTranslatef(head_pos[0], head_pos[1], 0.0); } else { glTranslatef(0.0f, 0.0f, -zoom_level*camera_distance); } glRotatef(rx, 1.0f, 0.0f, 0.0f); glRotatef(rz, 0.0f, 0.0f, 1.0f); glTranslatef(camera_x, camera_y, camera_z); }
void get_old_world_x_y (short *scene_x, short *scene_y) { AABBOX box; float t, x, y, z, t1, t2, tx, ty, dx, dy, h, len, h1, h2, h3, h4; int i, j, h_max, h_min, sx, sy, zx, zy, i_min, i_max, j_min, j_max; x = click_line.center[X]; y = click_line.center[Y]; z = click_line.center[Z]; dx = click_line.direction[X]; dy = click_line.direction[Y]; t = min2f(4.0f, max2f(-2.2f, z)); if (t != z) { t = (t-z)/click_line.direction[Z]; x += t*dx; y += t*dy; } t = 6.2f / click_line.direction[Z]; len = min2f(max2f(t, -t), click_line.length); len = click_line.length; if (max2f(dx, -dx) < 0.000001f) { zx = 1; sx = 0; } else { zx = 0; if (dx < 0.0f) sx = -1; else sx = 1; } if (max2f(dy, -dy) < 0.000001f) { zy = 1; sy = 0; } else { zy = 0; if (dy < 0.0f) sy = -1; else sy = 1; } i = x*2.0f; j = y*2.0f; i_min = min2f(x, x+dx*len)*2.0f; i_max = max2f(x, x+dx*len)*2.0f; j_min = min2f(y, y+dy*len)*2.0f; j_max = max2f(y, y+dy*len)*2.0f; i_min = max2i(min2i(i_min, tile_map_size_x*6), 0); i_max = max2i(min2i(i_max, tile_map_size_x*6-1), 0); j_min = max2i(min2i(j_min, tile_map_size_y*6), 0); j_max = max2i(min2i(j_max, tile_map_size_y*6-1), 0); i = min2i(max2i(i, i_min), i_max-1); j = min2i(max2i(j, j_min), j_max-1); h = 0.0f; while ((i >= i_min) && (j >= j_min) && (i < i_max) && (j < j_max)) { h1 = get_tile_height(i, j); h2 = get_tile_height(i + 1, j); h3 = get_tile_height(i, j + 1); h4 = get_tile_height(i + 1, j + 1); h_max = max2f(max2f(h1, h2), max2f(h3, h4)); h_min = min2f(min2f(h1, h2), min2f(h3, h4)); tx = i*0.5f; ty = j*0.5f; box.bbmin[X] = tx; box.bbmin[Y] = ty; box.bbmin[Z] = h_min; box.bbmax[X] = tx+1.0f; box.bbmax[Y] = ty+1.0f; box.bbmax[Z] = h_max; if (click_line_bbox_intersection(box)) { box.bbmin[X] = tx+0.0f; box.bbmin[Y] = ty+0.0f; box.bbmin[Z] = h1; box.bbmax[X] = tx+0.5f; box.bbmax[Y] = ty+0.5f; box.bbmax[Z] = h1; if (click_line_bbox_intersection(box)) { h = h1; break; } box.bbmin[X] = tx+0.5f; box.bbmin[Y] = ty+0.0f; box.bbmin[Z] = h2; box.bbmax[X] = tx+1.0f; box.bbmax[Y] = ty+0.5f; box.bbmax[Z] = h2; if (click_line_bbox_intersection(box)) { h = h2; break; } box.bbmin[X] = tx+0.0f; box.bbmin[Y] = ty+0.5f; box.bbmin[Z] = h3; box.bbmax[X] = tx+0.5f; box.bbmax[Y] = ty+1.0f; box.bbmax[Z] = h3; if (click_line_bbox_intersection(box)) { h = h3; break; } box.bbmin[X] = tx+0.5f; box.bbmin[Y] = ty+0.5f; box.bbmin[Z] = h4; box.bbmax[X] = tx+1.0f; box.bbmax[Y] = ty+1.0f; box.bbmax[Z] = h4; if (click_line_bbox_intersection(box)) { h = h4; break; } } if ((zx == 1) && (zy == 1)) break; if (zx == 0) t1 = (tx+sx-x)/dx; else t1 = 10e30; if (zx == 0) t2 = (ty+sy-y)/dy; else t2 = -10e30; if (t1 < t2) i += 2*sx; else j += 2*sy; t = min2f(t1, t2); x += dx*t; y += dy*t; } t = (h-click_line.center[Z])/click_line.direction[Z]; *scene_x = (click_line.center[X]+click_line.direction[X]*t) / 0.5; *scene_y = (click_line.center[Y]+click_line.direction[Y]*t) / 0.5; }
void add_bags_from_list (const Uint8 *data) { Uint16 bags_no; int i; int bag_x,bag_y,my_offset; //bag_type unused? float x,y,z; int obj_3d_id, bag_id; bags_no=data[0]; if(bags_no > NUM_BAGS) { return;//something nasty happened } for(i=0;i<bags_no;i++) { my_offset=i*5+1; bag_x=SDL_SwapLE16(*((Uint16 *)(data+my_offset))); bag_y=SDL_SwapLE16(*((Uint16 *)(data+my_offset+2))); bag_id=*((Uint8 *)(data+my_offset+4)); if(bag_id >= NUM_BAGS) { continue; } //now, get the Z position if (!get_tile_valid(bag_x, bag_y)) { //Warn about this error! LOG_WARNING("A bag was located OUTSIDE the map!\n"); continue; } z = get_tile_height(bag_x, bag_y); //convert from height values to meters x=(float)bag_x/2; y=(float)bag_y/2; //center the object (slightly randomized) x = x + 0.25f; // + get_bag_offset_x(bag_x, bag_y, bag_id, tile_map_size_x, tile_map_size_y); y = y + 0.25f; // + get_bag_offset_y(bag_x, bag_y, bag_id, tile_map_size_x, tile_map_size_y); // DEBUG LOG_DEBUG_VERBOSE("bag <%i> (%f,%f) rot %f tilt %f\n", bag_id, x, y, get_bag_rotation(bag_x, bag_y, bag_id, tile_map_size_x, tile_map_size_y), get_bag_tilt(bag_x, bag_y, bag_id, tile_map_size_x, tile_map_size_y)); if (use_eye_candy) { #ifdef ONGOING_BAG_EFFECT // start an ongoing effect until the ongoing bag effect is coded bag_list[bag_id].ongoing_bag_effect_reference = ec_create_lamp(x, y, z, 0.0, 1.0, 0.75, (poor_man ? 6 : 10)); #endif // ONGOING_BAG_EFFECT } // Now, find a place into the bags list, so we can destroy the bag properly if (bag_list[bag_id].obj_3d_id != -1) { char buf[256]; // oops, slot already taken! safe_snprintf(buf, sizeof(buf), "Oops, trying to add an existing bag! id=%d\n", bag_id); LOG_ERROR(buf); return; } #ifdef OLD_MISC_OBJ_DIR obj_3d_id = add_e3d("./3dobjects/misc_objects/bag1.e3d", x, y, z, #else obj_3d_id = add_e3d("./3dobjects/bag1.e3d", x, y, z, #endif get_bag_tilt(bag_x, bag_y, bag_id, tile_map_size_x, tile_map_size_y), 0, get_bag_rotation(bag_x, bag_y, bag_id, tile_map_size_x, tile_map_size_y), 1, 0, 1.0f, 1.0f, 1.0f, 1); bag_list[bag_id].x=bag_x; bag_list[bag_id].y=bag_y; bag_list[bag_id].obj_3d_id=obj_3d_id; } }
void put_bag_on_ground(int bag_x,int bag_y,int bag_id) { float x,y,z; int obj_3d_id; #ifdef NEW_SOUND int snd; #endif // NEW_SOUND //now, get the Z position if (!get_tile_valid(bag_x, bag_y)) { //Warn about this error: LOG_WARNING("A bag was placed OUTSIDE the map!\n"); return; } z = get_tile_height(bag_x, bag_y); //convert from height values to meters x=(float)bag_x/2; y=(float)bag_y/2; //center the object (slightly randomized) x = x + 0.25f; // + get_bag_offset_x(bag_x, bag_y, bag_id, tile_map_size_x, tile_map_size_y); y = y + 0.25f; // + get_bag_offset_y(bag_x, bag_y, bag_id, tile_map_size_x, tile_map_size_y); // DEBUG // printf("bag <%i> (%f,%f) rot %f tilt %f\n", bag_id, x, y, // get_bag_rotation(bag_x, bag_y, bag_id, tile_map_size_x, tile_map_size_y), // get_bag_tilt(bag_x, bag_y, bag_id, tile_map_size_x, tile_map_size_y)); //Launch the animation if (use_eye_candy) { ec_create_bag_drop(x, y, z, (poor_man ? 6 : 10)); #ifdef ONGOING_BAG_EFFECT // start an ongoing effect until the ongoing bag effect is coded bag_list[bag_id].ongoing_bag_effect_reference = ec_create_lamp(x, y, z, 0.0, 1.0, 0.75, (poor_man ? 6 : 10)); #endif // ONGOING_BAG_EFFECT } #ifdef NEW_SOUND if (your_actor && bag_x == your_actor->x_pos * 2 && bag_y == your_actor->y_pos * 2) { snd = get_sound_index_for_particle_file_name("./particles/bag_in.part"); if (snd >= 0) { add_sound_object (snd, bag_x, bag_y, 0); } } #endif // NEW_SOUND #ifdef OLD_MISC_OBJ_DIR obj_3d_id=add_e3d("./3dobjects/misc_objects/bag1.e3d", x, y, z, #else obj_3d_id=add_e3d("./3dobjects/bag1.e3d", x, y, z, #endif get_bag_tilt(bag_x, bag_y, bag_id, tile_map_size_x, tile_map_size_y), 0, get_bag_rotation(bag_x, bag_y, bag_id, tile_map_size_x, tile_map_size_y), 1 ,0 ,1.0f ,1.0f, 1.0f, 1); //now, find a place into the bags list, so we can destroy the bag properly bag_list[bag_id].x=bag_x; bag_list[bag_id].y=bag_y; bag_list[bag_id].obj_3d_id=obj_3d_id; }
static struct pipe_texture * nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp) { struct nouveau_device *dev = nouveau_screen(pscreen)->device; struct nv50_miptree *mt = CALLOC_STRUCT(nv50_miptree); struct pipe_texture *pt = &mt->base.base; unsigned width = tmp->width0, height = tmp->height0; unsigned depth = tmp->depth0, image_alignment; uint32_t tile_flags; int ret, i, l; *pt = *tmp; pipe_reference_init(&pt->reference, 1); pt->screen = pscreen; switch (pt->format) { case PIPE_FORMAT_Z32_FLOAT: tile_flags = 0x4800; break; case PIPE_FORMAT_S8Z24_UNORM: tile_flags = 0x1800; break; case PIPE_FORMAT_Z16_UNORM: tile_flags = 0x6c00; break; case PIPE_FORMAT_Z24X8_UNORM: case PIPE_FORMAT_Z24S8_UNORM: tile_flags = 0x2800; break; case PIPE_FORMAT_R32G32B32A32_FLOAT: case PIPE_FORMAT_R32G32B32_FLOAT: tile_flags = 0x7400; break; default: if ((pt->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY) && util_format_get_blocksizebits(pt->format) == 32) tile_flags = 0x7a00; else tile_flags = 0x7000; break; } /* XXX: texture arrays */ mt->image_nr = (pt->target == PIPE_TEXTURE_CUBE) ? 6 : 1; for (l = 0; l <= pt->last_level; l++) { struct nv50_miptree_level *lvl = &mt->level[l]; unsigned nblocksy = util_format_get_nblocksy(pt->format, height); lvl->image_offset = CALLOC(mt->image_nr, sizeof(int)); lvl->pitch = align(util_format_get_stride(pt->format, width), 64); lvl->tile_mode = get_tile_mode(nblocksy, depth); width = u_minify(width, 1); height = u_minify(height, 1); depth = u_minify(depth, 1); } image_alignment = get_tile_height(mt->level[0].tile_mode) * 64; image_alignment *= get_tile_depth(mt->level[0].tile_mode); /* NOTE the distinction between arrays of mip-mapped 2D textures and * mip-mapped 3D textures. We can't use image_nr == depth for 3D mip. */ for (i = 0; i < mt->image_nr; i++) { for (l = 0; l <= pt->last_level; l++) { struct nv50_miptree_level *lvl = &mt->level[l]; int size; unsigned tile_h = get_tile_height(lvl->tile_mode); unsigned tile_d = get_tile_depth(lvl->tile_mode); size = lvl->pitch; size *= align(util_format_get_nblocksy(pt->format, u_minify(pt->height0, l)), tile_h); size *= align(u_minify(pt->depth0, l), tile_d); lvl->image_offset[i] = mt->total_size; mt->total_size += size; } mt->total_size = align(mt->total_size, image_alignment); } ret = nouveau_bo_new_tile(dev, NOUVEAU_BO_VRAM, 256, mt->total_size, mt->level[0].tile_mode, tile_flags, &mt->base.bo); if (ret) { for (l = 0; l <= pt->last_level; ++l) FREE(mt->level[l].image_offset); FREE(mt); return NULL; } return pt; }