time_of_day tod_manager::time_of_day_at(const unit_map& units,const map_location& loc, const gamemap& map) const { int lighten = std::max<int>(map.get_terrain_info(map.get_terrain(loc)).light_modification() , 0); int darken = std::min<int>(map.get_terrain_info(map.get_terrain(loc)).light_modification() , 0); time_of_day tod = get_time_of_day(lighten + darken,loc); if(loc.valid()) { map_location locs[7]; locs[0] = loc; get_adjacent_tiles(loc,locs+1); for(int i = 0; i != 7; ++i) { const unit_map::const_iterator itor = units.find(locs[i]); if(itor != units.end() && itor->second.get_ability_bool("illuminates") && !itor->second.incapacitated()) { unit_ability_list illum = itor->second.get_abilities("illuminates"); unit_abilities::effect illum_effect(illum,lighten,false); int mod = illum_effect.get_composite_value(); if(mod + tod.lawful_bonus > illum.highest("max_value").first) { mod = illum.highest("max_value").first - tod.lawful_bonus; } lighten = std::max<int>(mod, lighten); darken = std::min<int>(mod, darken); } } } tod = get_time_of_day(lighten + darken,loc); return tod; }
/* * rtp_periodic - called from the player media rtp task. This basically just * checks for the end of the range. */ void CRtpByteStreamBase::rtp_periodic (void) { if (m_buffering != 0) { if (m_recvd_pak == false) { if (m_recvd_pak_timeout == false) { m_recvd_pak_timeout_time = get_time_of_day(); #if 0 rtp_message(LOG_DEBUG, "%s Starting timeout at "U64, m_name, m_recvd_pak_timeout_time); #endif } else { uint64_t timeout; if (m_eof == 0) { timeout = get_time_of_day() - m_recvd_pak_timeout_time; if (m_stream_ondemand && get_max_playtime() != 0.0) { uint64_t range_end = (uint64_t)(get_max_playtime() * 1000.0); if (m_last_realtime + timeout >= range_end) { rtp_message(LOG_DEBUG, "%s Timedout at range end - last "U64" range end "U64" "U64, m_name, m_last_realtime, range_end, timeout); m_eof = 1; } } else { // broadcast - perhaps if we time out for a second or 2, we // should re-init rtp ? We definately need to put some timing // checks here. session_desc_t *sptr = m_fmt->media->parent; if (sptr->time_desc != NULL && sptr->time_desc->end_time != 0) { time_t this_time; this_time = time(NULL); if (this_time > sptr->time_desc->end_time && timeout >= TO_U64(1000)) { m_eof = 1; } } } } } m_recvd_pak_timeout = true; } else { m_recvd_pak = false; m_recvd_pak_timeout = false; } } }
/* * audio_is_ready - when the audio indicates that it's ready, it will * send a latency number, and a play time */ void CPlayerSession::audio_is_ready (uint64_t latency, uint64_t time) { m_start = get_time_of_day(); sync_message(LOG_DEBUG, "Aisready "U64, m_start); m_start -= time; m_latency = latency; sync_message(LOG_DEBUG, "Audio is ready "U64" - latency "U64, time, latency); sync_message(LOG_DEBUG, "m_start is "X64, m_start); m_waiting_for_audio = 0; SDL_SemPost(m_sync_sem); }
/* * get_current_time. Gets the time of day, subtracts off the start time * to get the current play time. */ uint64_t CPlayerSession::get_current_time (void) { uint64_t current_time; if (m_waiting_for_audio != 0) { return 0; } current_time = get_time_of_day(); //if (current_time < m_start) return 0; m_current_time = current_time - m_start; if (m_current_time >= m_latency) m_current_time -= m_latency; return(m_current_time); }
const time_of_day tod_manager::get_illuminated_time_of_day(const map_location& loc, int for_turn) const { // get ToD ignoring illumination time_of_day tod = get_time_of_day(loc, for_turn); // now add illumination const gamemap& map = *resources::game_map; const unit_map& units = *resources::units; int light_modif = map.get_terrain_info(map.get_terrain(loc)).light_modification(); int light = tod.lawful_bonus + light_modif; int illum_light = light; if(loc.valid()) { map_location locs[7]; locs[0] = loc; get_adjacent_tiles(loc,locs+1); for(int i = 0; i != 7; ++i) { const unit_map::const_iterator itor = units.find(locs[i]); if(itor != units.end() && itor->get_ability_bool("illuminates") && !itor->incapacitated()) { unit_ability_list illum = itor->get_abilities("illuminates"); unit_abilities::effect illum_effect(illum, light, false); illum_light = light + illum_effect.get_composite_value(); //max_value and min_value control the final result //unless ToD + terrain effect is stronger int max = std::max(light, illum.highest("max_value").first); int min = std::min(light, illum.lowest("min_value").first); if(illum_light > max) { illum_light = max; } else if (illum_light < min) { illum_light = min; } } } } tod.bonus_modified = illum_light - tod.lawful_bonus; tod.lawful_bonus = illum_light; return tod; }
/** * @brief Initializes phase 3 of the title screen. * * The title screen will be shown. */ void TitleScreen::init_phase_title() { static const std::string time_of_day_strings[] = { "daylight", "sunset", "night" }; static Color text_colors[] = { Color(0, 0, 92), Color(0, 0, 92), Color(255, 128, 0) }; TimeOfDay time_of_day = get_time_of_day(); current_phase = PHASE_TITLE; Music::play("title_screen.spc"); const std::string &time_of_day_name = time_of_day_strings[time_of_day]; std::string background_img_name = (std::string) "menus/title_" + time_of_day_name + "_background.png"; std::string clouds_img_name = (std::string) "menus/title_" + time_of_day_name + "_clouds.png"; background_img = new Surface(background_img_name); clouds_img = new Surface(clouds_img_name); logo_img = new Surface("menus/title_logo.png"); dx_img = new Surface("menus/title_dx.png"); star_img = new Surface("menus/title_star.png"); website_img = new TextSurface(160, 220, TextSurface::ALIGN_CENTER, TextSurface::ALIGN_MIDDLE); website_img->set_font("dialog"); website_img->set_rendering_mode(TextSurface::TEXT_BLENDED); website_img->set_text_color(text_colors[time_of_day]); website_img->set_text(StringResource::get_string("title_screen.website")); press_space_img = new TextSurface(160, 190, TextSurface::ALIGN_CENTER, TextSurface::ALIGN_MIDDLE); press_space_img->set_font("dialog_big"); press_space_img->set_rendering_mode(TextSurface::TEXT_BLENDED); press_space_img->set_text_color(text_colors[time_of_day]); press_space_img->set_text(StringResource::get_string("title_screen.press_space")); title_surface = new Surface(320, 240); clouds_position.set_xy(320, 30); uint32_t now = System::now(); next_clouds_move_date = now; counter = 0; next_image_date = System::now() + 5000; transition_in = new TransitionFade(Transition::IN); transition_in->set_delay(30); transition_in->start(); transition_out = new TransitionFade(Transition::OUT); }
const time_of_day tod_manager::get_illuminated_time_of_day(const unit_map & units, const gamemap & map, const map_location& loc, int for_turn) const { // get ToD ignoring illumination time_of_day tod = get_time_of_day(loc, for_turn); if ( map.on_board_with_border(loc) ) { // Now add terrain illumination. const int terrain_light = map.get_terrain_info(loc).light_bonus(tod.lawful_bonus); std::vector<int> mod_list; std::vector<int> max_list; std::vector<int> min_list; int most_add = 0; int most_sub = 0; // Find the "illuminates" effects from units that can affect loc. map_location locs[7]; locs[0] = loc; get_adjacent_tiles(loc,locs+1); for ( size_t i = 0; i != 7; ++i ) { const unit_map::const_iterator itor = units.find(locs[i]); if (itor != units.end() && itor->get_ability_bool("illuminates") && !itor->incapacitated()) { unit_ability_list illum = itor->get_abilities("illuminates"); unit_abilities::effect illum_effect(illum, terrain_light, false); const int unit_mod = illum_effect.get_composite_value(); // Record this value. mod_list.push_back(unit_mod); max_list.push_back(illum.highest("max_value").first); min_list.push_back(illum.lowest("min_value").first); if ( unit_mod > most_add ) most_add = unit_mod; else if ( unit_mod < most_sub ) most_sub = unit_mod; } } const bool net_darker = most_add < -most_sub; // Apply each unit's effect, tracking the best result. int best_result = terrain_light; const int base_light = terrain_light + (net_darker ? most_add : most_sub); for ( size_t i = 0; i != mod_list.size(); ++i ) { int result = bounded_add(base_light, mod_list[i], max_list[i], min_list[i]); if ( net_darker && result < best_result ) best_result = result; else if ( !net_darker && result > best_result ) best_result = result; } // Update the object we will return. tod.bonus_modified = best_result - tod.lawful_bonus; tod.lawful_bonus = best_result; } return tod; }
/* * sync_thread_wait_sync - wait until all decoding threads have put * data into the sync classes. */ int CPlayerSession::sync_thread_wait_sync (void) { int state; state = process_msg_queue(SYNC_STATE_WAIT_SYNC); if (state == SYNC_STATE_WAIT_SYNC) { // We're not synced. See if the video is ready, and if the audio // is ready. Then start them going... bool vsynced = true; int asynced = 1; uint64_t astart = 0, vstart = MAX_UINT64; for (CTimedSync *ts = m_timed_sync_list; ts != NULL; ts = ts->GetNext()) { uint64_t cmp; if (ts->active_at_start()) { if (ts->is_ready(cmp)) { vstart = MIN(cmp, vstart); } else { vsynced = false; } } } if (m_audio_sync) { asynced = m_audio_sync->is_audio_ready(astart); } if (vsynced && asynced == 1) { /* * Audio and video are synced. */ if (m_audio_sync) { /* * If we have audio, we use that for syncing. Start it up */ m_first_time_played = astart; m_current_time = astart; sync_message(LOG_DEBUG, "Astart is "U64, astart); if (m_timed_sync_list) sync_message(LOG_DEBUG, "Vstart is "U64, vstart); m_waiting_for_audio = 1; state = SYNC_STATE_WAIT_AUDIO; m_audio_sync->play_audio(); } else if (m_timed_sync_list) { /* * Video only - set up the start time based on the video time * returned */ m_first_time_played = vstart; m_current_time = vstart; m_waiting_for_audio = 0; m_start = get_time_of_day(); m_start -= m_current_time; state = SYNC_STATE_PLAYING; } sync_message(LOG_DEBUG, "Resynced at time "U64 " "U64, m_current_time, vstart); } else { SDL_Delay(10); } } return (state); }
/* * recv_callback - callback for when bytestream is active - basically, * put things on the queue */ int CRtpByteStreamBase::recv_callback (struct rtp *session, rtp_event *e) { switch (e->type) { case RX_RTP: rtp_packet *rpak; rpak = (rtp_packet *)e->data; if (rpak->rtp_data_len == 0) { xfree(rpak); } else { // need to add lock/unlock of mutex here if (m_have_recv_last_ts) { int32_t diff = rpak->rtp_pak_ts - m_recv_last_ts; int32_t ts, nts; ts = m_timescale * 2; nts = 0 - ts; if (diff > ts || diff < nts) { rtp_message(LOG_INFO, "%s - rtp timestamp diff %d last %u now %u", m_name, diff, m_recv_last_ts, rpak->rtp_pak_ts); flush_rtp_packets(); reset(); } } m_have_recv_last_ts = true; m_recv_last_ts = rpak->rtp_pak_ts; if (m_buffering == 0) { rpak->pd.rtp_pd_timestamp = get_time_of_day(); rpak->pd.rtp_pd_have_timestamp = 1; } if (SDL_mutexP(m_rtp_packet_mutex) == -1) { rtp_message(LOG_CRIT, "SDL Lock mutex failure in rtp bytestream recv"); break; } add_rtp_packet_to_queue(rpak, &m_head, &m_tail, m_name); if (SDL_mutexV(m_rtp_packet_mutex) == -1) { rtp_message(LOG_CRIT, "SDL Lock mutex failure in rtp bytestream recv"); break; } m_recvd_pak = true; check_buffering(); } break; case RX_SR: rtcp_sr *srpak; srpak = (rtcp_sr *)e->data; if (rtp_my_ssrc(session) != e->ssrc) { //rtp_message(LOG_DEBUG, "%s received rtcp", m_name); calculate_wallclock_offset_from_rtcp(srpak->ntp_frac, srpak->ntp_sec, srpak->rtp_ts); } break; case RX_APP: free(e->data); break; default: #if 0 rtp_message(LOG_DEBUG, "Thread %u - Callback from rtp with %d %p", SDL_ThreadID(),e->type, e->rtp_data); #endif break; } return m_buffering; }
time_of_day tod_manager::get_time_of_day(int illuminated, const map_location& loc) const { return get_time_of_day(illuminated, loc, turn()); }
int RecvMsg(int sock, address &from, address &to, uint8_t *buffer, int buflen, int &ttl, uint64_t &ts) { int len; struct msghdr msg; struct iovec iov; uint8_t ctlbuf[64]; from.set_family(beaconUnicastAddr.family()); msg.msg_name = (char *)from.saddr(); msg.msg_namelen = from.addrlen(); msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = (char *)ctlbuf; msg.msg_controllen = sizeof(ctlbuf); msg.msg_flags = 0; iov.iov_base = (char *)buffer; iov.iov_len = buflen; len = recvmsg(sock, &msg, 0); if (len < 0) return len; ts = 0; ttl = 127; to = beaconUnicastAddr; if (msg.msg_controllen > 0) { for (cmsghdr *hdr = CMSG_FIRSTHDR(&msg); hdr; hdr = CMSG_NXTHDR(&msg, hdr)) { if (hdr->cmsg_level == IPPROTO_IPV6 && hdr->cmsg_type == IPV6_HOPLIMIT) { ttl = *(int *)CMSG_DATA(hdr); #ifdef IPV6_PKTINFO } else if (hdr->cmsg_level == IPPROTO_IPV6 && hdr->cmsg_type == IPV6_PKTINFO) { if (hdr->cmsg_len == CMSG_LEN(sizeof(in6_pktinfo))) { in6_pktinfo *pktinfo = (in6_pktinfo *)CMSG_DATA(hdr); to.set_family(AF_INET6); to.v6()->sin6_addr = pktinfo->ipi6_addr; } #endif #ifdef IP_RECVTTL } else if (hdr->cmsg_level == IPPROTO_IP && hdr->cmsg_type == IP_RECVTTL) { ttl = *(uint8_t *)CMSG_DATA(hdr); #endif } else if (hdr->cmsg_level == IPPROTO_IP && hdr->cmsg_type == IP_TTL) { ttl = *(int *)CMSG_DATA(hdr); #ifdef SO_TIMESTAMP } else if (hdr->cmsg_level == SOL_SOCKET && hdr->cmsg_type == SO_TIMESTAMP) { timeval *tv = (timeval *)CMSG_DATA(hdr); ts = tv->tv_sec; ts *= 1000; ts += tv->tv_usec / 1000; #endif } } } if (!ts) { ts = get_time_of_day(); } return len; }
/* * CPlayerMedia::recv_callback - callback from RTP with valid data */ void CPlayerMedia::recv_callback (struct rtp *session, rtp_event *e) { if (e == NULL) return; /* * If we're paused, just dump the packet. Multicast case */ if (m_paused) { if (e->type == RX_RTP) { media_message(LOG_DEBUG, "%s dropping pak", get_name()); xfree(e->data); return; } } #if DROP_PAKS if (e->type == RX_RTP && dropcount >= 50) { xfree((rtp_packet *)e->data); dropcount = 0; return; } else { dropcount++; } #endif if (m_rtp_byte_stream != NULL) { if ((m_rtp_byte_stream->recv_callback(session, e) > 0) && (e->type == RX_RTP)) { // indicates they are done buffering. if (m_rtp_buffering == 0) { m_rtp_buffering = 1; start_decoding(); } else { // we're not buffering, but the decode thread might be waiting; if so, // tweak it if we have a complete frame. if (m_decode_thread_waiting) { if (m_rtp_byte_stream->check_rtp_frame_complete_for_payload_type()) { bytestream_primed(); } } } } return; } // we only get here if there is not a valid rtp bytestream yet. switch (e->type) { case RX_RTP: /* regular rtp packet - add it to the queue */ rtp_packet *rpak; rpak = (rtp_packet *)e->data; if (rpak->rtp_data_len == 0) { xfree(rpak); } else { rpak->pd.rtp_pd_timestamp = get_time_of_day(); rpak->pd.rtp_pd_have_timestamp = true; add_rtp_packet_to_queue(rpak, &m_head, &m_tail, get_name()); m_rtp_queue_len++; rtp_check_payload(); } break; case RX_SR: rtcp_sr *srpak; srpak = (rtcp_sr *)e->data; m_rtcp_ntp_frac = srpak->ntp_frac; m_rtcp_ntp_sec = srpak->ntp_sec; m_rtcp_rtp_ts = srpak->rtp_ts; m_rtcp_received = 1; break; case RX_APP: free(e->data); break; default: case RX_RR: case RX_SDES: case RX_BYE: case SOURCE_CREATED: case SOURCE_DELETED: case RX_RR_EMPTY: case RX_RTCP_START: case RX_RTCP_FINISH: case RR_TIMEOUT: #if 0 media_message(LOG_DEBUG, "Thread %u - Callback from rtp with %d %p", SDL_ThreadID(),e->type, e->data); #endif break; } }