diff --git a/src/app.c b/src/app.c index 2a7aff4..15bc799 100644 --- a/src/app.c +++ b/src/app.c @@ -9,6 +9,11 @@ #include #include +#define GUIDE_BROWSE_STEP_MINUTES 30 +#define GUIDE_BROWSE_MAX_AHEAD_MINUTES (12 * 60) +#define GUIDE_BROWSE_MAX_OFFSET_MINUTES (GUIDE_BROWSE_MAX_AHEAD_MINUTES - ((int) (TIMELINE_VISIBLE_SECONDS / 60.0) - 30)) +#define CHANNEL_BANNER_DURATION_MS 3000 + static void configure_runtime_environment(void) { char runtime_dir[64]; char pulse_socket[96]; @@ -135,6 +140,24 @@ static void tune_relative(App *app, int delta) { destroy_video_texture(app); begin_startup_handoff(app); player_tune(&app->player, next_index); + app->channel_banner_until = SDL_GetTicks() + CHANNEL_BANNER_DURATION_MS; +} + +static void browse_guide_time(App *app, int delta_minutes) { + int next_offset; + + if (!app || app->mode != MODE_GUIDE) { + return; + } + + next_offset = app->guide_time_offset_minutes + delta_minutes; + if (next_offset < 0) { + next_offset = 0; + } + if (next_offset > GUIDE_BROWSE_MAX_OFFSET_MINUTES) { + next_offset = GUIDE_BROWSE_MAX_OFFSET_MINUTES; + } + app->guide_time_offset_minutes = next_offset; } static void toggle_fullscreen(App *app) { @@ -230,6 +253,12 @@ static void handle_event(App *app, const SDL_Event *event) { case SDLK_DOWN: tune_relative(app, 1); break; + case SDLK_LEFT: + browse_guide_time(app, -GUIDE_BROWSE_STEP_MINUTES); + break; + case SDLK_RIGHT: + browse_guide_time(app, GUIDE_BROWSE_STEP_MINUTES); + break; default: break; } @@ -300,6 +329,7 @@ int app_init(App *app) { if (app->channels.count > 0) { begin_startup_handoff(app); player_tune(&app->player, 0); + app->channel_banner_until = SDL_GetTicks() + CHANNEL_BANNER_DURATION_MS; } return 0; @@ -356,9 +386,9 @@ void app_run(App *app) { &app->ui_cache, &app->channels, app->player.current_index, - app->app_start_ticks, - now_ticks, - now_wall); + app->app_start_time, + now_wall, + app->guide_time_offset_minutes); if (app->theme_picker_open) { ui_render_theme_picker(app->renderer, &app->fonts, @@ -383,7 +413,14 @@ void app_run(App *app) { app->texture_width, app->texture_height, output_width, - output_height); + output_height, + &GUIDE_THEMES[app->theme_index], + &app->fonts, + &app->channels, + app->player.current_index, + app->app_start_time, + now_wall, + SDL_GetTicks() < app->channel_banner_until); } SDL_RenderPresent(app->renderer); diff --git a/src/app.h b/src/app.h index 7ad2d10..8e4239b 100644 --- a/src/app.h +++ b/src/app.h @@ -24,8 +24,10 @@ typedef struct App { int startup_handoff_active; int last_blackout_state; Uint32 startup_handoff_until; + Uint32 channel_banner_until; time_t app_start_time; Uint64 app_start_ticks; + int guide_time_offset_minutes; ChannelList channels; Player player; UiFonts fonts; diff --git a/src/app.o b/src/app.o index b3f2dc4..8688f42 100644 Binary files a/src/app.o and b/src/app.o differ diff --git a/src/channel.c b/src/channel.c index 38abc96..34c4f74 100644 --- a/src/channel.c +++ b/src/channel.c @@ -333,6 +333,16 @@ time_t channel_wall_time_from_ticks(time_t app_start_time, Uint64 app_start_tick return app_start_time + (time_t) (elapsed_ticks / 1000); } +double channel_schedule_elapsed_seconds(time_t app_start_time, time_t target_time) { + double elapsed = difftime(target_time, app_start_time); + + if (elapsed < 0.0) { + return 0.0; + } + + return elapsed; +} + double channel_live_position(const Channel *channel, time_t app_start_time, time_t now) { double elapsed; @@ -363,28 +373,33 @@ double channel_live_position_precise(const Channel *channel, Uint64 app_start_ti return fmod(elapsed, channel->total_duration_seconds); } -const ProgramEntry *channel_program_at_index(const Channel *channel, int program_index) { - if (!channel || program_index < 0 || program_index >= channel->program_count) { - return NULL; - } - return &channel->programs[program_index]; -} - -const ProgramEntry *channel_resolve_program(const Channel *channel, - Uint64 app_start_ticks, - Uint64 now_ticks, - double *program_seek_seconds, - int *program_index) { +const ProgramEntry *channel_resolve_program_at_elapsed(const Channel *channel, + double elapsed_seconds, + double *program_seek_seconds, + int *program_index) { double channel_offset; if (!channel || channel->program_count == 0 || channel->total_duration_seconds <= 0.0) { return NULL; } - channel_offset = channel_live_position_precise(channel, app_start_ticks, now_ticks); + if (elapsed_seconds < 0.0) { + elapsed_seconds = 0.0; + } + + channel_offset = fmod(elapsed_seconds, channel->total_duration_seconds); + if (channel_offset < 0.0) { + channel_offset += channel->total_duration_seconds; + } + for (int i = 0; i < channel->program_count; ++i) { const ProgramEntry *program = &channel->programs[i]; double end_offset = program->start_offset_seconds + program->duration_seconds; + + if (program->duration_seconds <= 0.0) { + continue; + } + if (channel_offset < end_offset || i == channel->program_count - 1) { if (program_seek_seconds) { *program_seek_seconds = channel_offset - program->start_offset_seconds; @@ -401,3 +416,29 @@ const ProgramEntry *channel_resolve_program(const Channel *channel, return &channel->programs[0]; } + +const ProgramEntry *channel_program_at_index(const Channel *channel, int program_index) { + if (!channel || program_index < 0 || program_index >= channel->program_count) { + return NULL; + } + return &channel->programs[program_index]; +} + +const ProgramEntry *channel_resolve_program(const Channel *channel, + Uint64 app_start_ticks, + Uint64 now_ticks, + double *program_seek_seconds, + int *program_index) { + double elapsed; + + if (!channel || channel->program_count == 0 || channel->total_duration_seconds <= 0.0) { + return NULL; + } + + if (now_ticks < app_start_ticks) { + now_ticks = app_start_ticks; + } + + elapsed = (double) (now_ticks - app_start_ticks) / 1000.0; + return channel_resolve_program_at_elapsed(channel, elapsed, program_seek_seconds, program_index); +} diff --git a/src/channel.h b/src/channel.h index a85cbb9..ed662b5 100644 --- a/src/channel.h +++ b/src/channel.h @@ -30,8 +30,13 @@ typedef struct ChannelList { int channel_list_load(ChannelList *list, const char *media_dir); void channel_list_destroy(ChannelList *list); time_t channel_wall_time_from_ticks(time_t app_start_time, Uint64 app_start_ticks, Uint64 now_ticks); +double channel_schedule_elapsed_seconds(time_t app_start_time, time_t target_time); double channel_live_position(const Channel *channel, time_t app_start_time, time_t now); double channel_live_position_precise(const Channel *channel, Uint64 app_start_ticks, Uint64 now_ticks); +const ProgramEntry *channel_resolve_program_at_elapsed(const Channel *channel, + double elapsed_seconds, + double *program_seek_seconds, + int *program_index); const ProgramEntry *channel_resolve_program(const Channel *channel, Uint64 app_start_ticks, Uint64 now_ticks, diff --git a/src/channel.o b/src/channel.o index e81015e..1732d04 100644 Binary files a/src/channel.o and b/src/channel.o differ diff --git a/src/ui.c b/src/ui.c index 9e772c3..769ba5e 100644 --- a/src/ui.c +++ b/src/ui.c @@ -12,6 +12,7 @@ static const char *FONT_CANDIDATES[] = { }; static void fill_rect(SDL_Renderer *renderer, const SDL_Rect *rect, SDL_Color color); +static void stroke_rect(SDL_Renderer *renderer, const SDL_Rect *rect, SDL_Color color); static SDL_Texture *text_to_texture(SDL_Renderer *renderer, TTF_Font *font, const char *text, SDL_Color color, int *width, int *height); static void text_texture_destroy(UiTextTexture *text_texture) { @@ -235,6 +236,37 @@ static void draw_beveled_bar(SDL_Renderer *renderer, SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE); } +static void draw_program_block(SDL_Renderer *renderer, + const SDL_Rect *rect, + SDL_Color top, + SDL_Color mid, + SDL_Color bottom, + SDL_Color gloss, + SDL_Color border, + int is_selected, + SDL_Color selection_edge) { + SDL_Rect inner; + + if (!rect || rect->w <= 2 || rect->h <= 2) { + return; + } + + draw_beveled_bar(renderer, rect, top, mid, bottom, gloss, border); + stroke_rect(renderer, rect, border); + + inner = (SDL_Rect){rect->x + 1, rect->y + 1, rect->w - 2, rect->h - 2}; + if (inner.w > 1 && inner.h > 1) { + stroke_rect_alpha(renderer, &inner, color_with_alpha(COLOR_TEXT_LIGHT, is_selected ? 64 : 42)); + fill_rect_alpha(renderer, + &(SDL_Rect){inner.x + 1, inner.y + 1, SDL_max(inner.w - 2, 0), 2}, + color_with_alpha(COLOR_TEXT_LIGHT, is_selected ? 34 : 20)); + } + + if (is_selected) { + draw_selection_glow(renderer, rect, selection_edge); + } +} + static void draw_pill_button(SDL_Renderer *renderer, const GuideTheme *theme, const SDL_Rect *rect, SDL_Color fill, SDL_Color border) { SDL_Rect shadow; @@ -468,9 +500,8 @@ static void draw_info_panel(SDL_Renderer *renderer, const GuideTheme *theme, const Channel *selected_channel, const SDL_Rect *rect, - Uint64 app_start_ticks, - Uint64 now_ticks, - time_t now_wall) { + time_t app_start_time, + time_t guide_focus_time) { SDL_Rect accent; SDL_Rect clip_rect; char time_range[64]; @@ -495,11 +526,14 @@ static void draw_info_panel(SDL_Renderer *renderer, draw_panel_bevel(renderer, rect, theme->gloss); stroke_rect(renderer, rect, theme->panel_border); - program = channel_resolve_program(selected_channel, app_start_ticks, now_ticks, &program_seek, NULL); + program = channel_resolve_program_at_elapsed(selected_channel, + channel_schedule_elapsed_seconds(app_start_time, guide_focus_time), + &program_seek, + NULL); if (!program) { return; } - start_time = now_wall - (time_t) program_seek; + start_time = guide_focus_time - (time_t) program_seek; end_time = start_time + (time_t) program->duration_seconds; format_time_compact(time_range, sizeof(time_range), start_time); format_time_compact(end_text, sizeof(end_text), end_time); @@ -554,7 +588,7 @@ static void draw_footer_legend(SDL_Renderer *renderer, int window_width, int window_height) { SDL_Rect footer = {0, window_height - 54, window_width, 54}; - SDL_Rect chip = {window_width / 2 - 120, window_height - 38, 34, 20}; + SDL_Rect chip = {window_width / 2 - 220, window_height - 38, 34, 20}; SDL_Color footer_text = readable_text_color(theme->footer_mid); fill_three_stop_gradient(renderer, @@ -573,6 +607,11 @@ static void draw_footer_legend(SDL_Renderer *renderer, draw_pill_button(renderer, theme, &chip, theme->block_mid, theme->panel_border); draw_text_clipped(renderer, fonts->small, "B", &footer, chip.x + 11, chip.y + 2, footer_text); draw_text_clipped(renderer, fonts->small, "THEME", &footer, chip.x + 42, chip.y - 1, footer_text); + + chip.x += 160; + draw_pill_button(renderer, theme, &chip, theme->row_mid, theme->panel_border); + draw_text_clipped(renderer, fonts->small, "<>", &footer, chip.x + 5, chip.y + 2, footer_text); + draw_text_clipped(renderer, fonts->small, "TIME", &footer, chip.x + 42, chip.y - 1, footer_text); } static void draw_scanline_overlay(SDL_Renderer *renderer, int width, int height, const GuideTheme *theme) { @@ -582,6 +621,100 @@ static void draw_scanline_overlay(SDL_Renderer *renderer, int width, int height, (void) theme; } +static void draw_channel_status_banner(SDL_Renderer *renderer, + const UiFonts *fonts, + const GuideTheme *theme, + const ChannelList *channels, + int active_channel, + time_t app_start_time, + time_t now_wall, + int window_width, + int window_height) { + SDL_Rect banner; + SDL_Rect channel_pill; + SDL_Rect info_clip; + SDL_Color banner_text; + SDL_Color sub_text; + char channel_text[96]; + char time_range[64]; + char end_text[32]; + time_t start_time; + time_t end_time; + double program_seek = 0.0; + const Channel *channel; + const ProgramEntry *program; + + if (!renderer || !fonts || !theme || !channels || active_channel < 0 || active_channel >= channels->count) { + return; + } + + channel = &channels->items[active_channel]; + program = channel_resolve_program_at_elapsed(channel, + channel_schedule_elapsed_seconds(app_start_time, now_wall), + &program_seek, + NULL); + if (!program) { + return; + } + + banner = (SDL_Rect){window_width / 2 - 360, window_height - 92, 720, 64}; + if (banner.x < 24) { + banner.x = 24; + banner.w = window_width - 48; + } + channel_pill = (SDL_Rect){banner.x + 10, banner.y + 10, 210, banner.h - 20}; + info_clip = (SDL_Rect){channel_pill.x + channel_pill.w + 14, banner.y + 8, banner.w - channel_pill.w - 28, banner.h - 16}; + banner_text = ensure_contrast(theme->ribbon_text, theme->status_mid); + sub_text = ensure_contrast(theme->row_subtext, theme->status_mid); + + start_time = now_wall - (time_t) program_seek; + end_time = start_time + (time_t) program->duration_seconds; + format_time_compact(time_range, sizeof(time_range), start_time); + format_time_compact(end_text, sizeof(end_text), end_time); + strncat(time_range, " - ", sizeof(time_range) - strlen(time_range) - 1); + strncat(time_range, end_text, sizeof(time_range) - strlen(time_range) - 1); + snprintf(channel_text, sizeof(channel_text), "%s %d", channel->name, channel->number); + + draw_panel_shadow(renderer, &banner); + draw_beveled_bar(renderer, + &banner, + blend_color(theme->status_top, theme->status_mid, 220), + theme->status_mid, + blend_color(theme->status_bottom, theme->status_mid, 220), + color_with_alpha(theme->gloss, 42), + theme->panel_border); + stroke_rect(renderer, &banner, theme->panel_border); + draw_pill_button(renderer, theme, &channel_pill, theme->panel_fill, theme->panel_border); + draw_text_shadowed(renderer, + fonts->medium, + channel_text, + &channel_pill, + channel_pill.x + 14, + channel_pill.y + 8, + ensure_contrast(theme->panel_text, theme->panel_fill), + color_with_alpha(COLOR_BLACK, 255)); + set_draw_color(renderer, theme->status_divider); + SDL_RenderDrawLine(renderer, + channel_pill.x + channel_pill.w + 6, + banner.y + 10, + channel_pill.x + channel_pill.w + 6, + banner.y + banner.h - 10); + draw_text_clipped(renderer, + fonts->medium, + program->program_title, + &info_clip, + info_clip.x, + banner.y + 10, + banner_text); + draw_text_clipped(renderer, + fonts->small, + time_range, + &info_clip, + info_clip.x, + banner.y + 36, + sub_text); +} + void ui_render_about_modal(SDL_Renderer *renderer, const UiFonts *fonts, int window_width, @@ -668,10 +801,28 @@ void ui_render_fullscreen(SDL_Renderer *renderer, int texture_width, int texture_height, int window_width, - int window_height) { + int window_height, + const GuideTheme *theme, + const UiFonts *fonts, + const ChannelList *channels, + int active_channel, + time_t app_start_time, + time_t now_wall, + int show_channel_banner) { SDL_Rect window = {0, 0, window_width, window_height}; fill_rect(renderer, &window, COLOR_BLACK); draw_video(renderer, video_texture, texture_width, texture_height, window); + if (show_channel_banner) { + draw_channel_status_banner(renderer, + fonts, + theme, + channels, + active_channel, + app_start_time, + now_wall, + window_width, + window_height); + } } void ui_render_guide(SDL_Renderer *renderer, @@ -685,9 +836,9 @@ void ui_render_guide(SDL_Renderer *renderer, UiCache *cache, const ChannelList *channels, int active_channel, - Uint64 app_start_ticks, - Uint64 now_ticks, - time_t now_wall) { + time_t app_start_time, + time_t now_wall, + int guide_time_offset_minutes) { double scale_x = (double) window_width / WINDOW_WIDTH; double scale_y = (double) window_height / WINDOW_HEIGHT; int guide_x_start = (int) (GUIDE_X_START * scale_x); @@ -703,7 +854,11 @@ void ui_render_guide(SDL_Renderer *renderer, int start_index = active_channel - 2; const Channel *selected_channel = NULL; double pixels_per_minute = timeline_w / 90.0; - time_t guide_view_start_time = now_wall - (30 * 60); + time_t guide_view_start_time = now_wall - (30 * 60) + (guide_time_offset_minutes * 60); + time_t guide_focus_time = guide_view_start_time + (30 * 60); + double guide_view_start_seconds = channel_schedule_elapsed_seconds(app_start_time, guide_view_start_time); + double guide_view_end_seconds = guide_view_start_seconds + TIMELINE_VISIBLE_SECONDS; + double guide_focus_seconds = channel_schedule_elapsed_seconds(app_start_time, guide_focus_time); if (channels && channels->count > 0 && active_channel >= 0 && active_channel < channels->count) { selected_channel = &channels->items[active_channel]; @@ -714,20 +869,20 @@ void ui_render_guide(SDL_Renderer *renderer, theme->background_top, theme->background_mid, theme->background_bottom); - draw_info_panel(renderer, fonts, theme, selected_channel, &info_panel, app_start_ticks, now_ticks, now_wall); + draw_info_panel(renderer, fonts, theme, selected_channel, &info_panel, app_start_time, guide_focus_time); draw_panel_shadow(renderer, &preview); fill_rect(renderer, &preview, COLOR_BLACK); draw_video(renderer, video_texture, texture_width, texture_height, preview); draw_status_bar(renderer, fonts->medium, theme, selected_channel, &status_bar, now_wall); - if (cache->timeline_label_slot != now_wall / 60 || cache->timeline_theme != theme) { + if (cache->timeline_label_slot != guide_view_start_time / 60 || cache->timeline_theme != theme) { char label[32]; for (int i = 0; i < 4; ++i) { format_clock_label(label, sizeof(label), guide_view_start_time, 30 * i); text_texture_destroy(&cache->timeline_labels[i]); text_texture_init(&cache->timeline_labels[i], renderer, fonts->small, label, COLOR_TEXT_LIGHT); } - cache->timeline_label_slot = now_wall / 60; + cache->timeline_label_slot = guide_view_start_time / 60; cache->timeline_theme = theme; } draw_timeline_header_cached(renderer, @@ -778,14 +933,8 @@ void ui_render_guide(SDL_Renderer *renderer, { const Channel *channel = &channels->items[channel_index]; - double program_seek = 0.0; - const ProgramEntry *program = channel_resolve_program(channel, app_start_ticks, now_ticks, &program_seek, NULL); - double guide_view_start_seconds = (double) guide_view_start_time; - double program_start_time = (double) now_wall; - int block_x = guide_x_start; - int block_w = 48; - SDL_Rect block = {guide_x_start, timeline_rect.y + 4, 48, timeline_rect.h - 8}; - SDL_Rect title_rect = {block.x + 8, block.y + 8, block.w - 16, block.h - 16}; + double focus_program_seek = 0.0; + const ProgramEntry *focus_program = channel_resolve_program_at_elapsed(channel, guide_focus_seconds, &focus_program_seek, NULL); char title[128]; SDL_Color row_primary = ensure_contrast(is_selected ? theme->row_active_text : theme->row_text, is_selected ? theme->row_active_mid : theme->row_mid); @@ -797,14 +946,9 @@ void ui_render_guide(SDL_Renderer *renderer, ? color_with_alpha(COLOR_BLACK, 255) : color_with_alpha(COLOR_TEXT_LIGHT, 255); - if (!program) { + if (!focus_program) { continue; } - program_start_time -= program_seek; - block_x = guide_x_start + (int) ((((program_start_time - guide_view_start_seconds) / 60.0) * pixels_per_minute) + 0.5); - block_w = (int) ((program->duration_seconds / 60.0) * pixels_per_minute); - block = (SDL_Rect){block_x, timeline_rect.y + 4, SDL_max(block_w, 48), timeline_rect.h - 8}; - title_rect = (SDL_Rect){block.x + 8, block.y + 8, block.w - 16, block.h - 16}; if (is_selected) { draw_text_shadowed(renderer, fonts->medium, channel->name, &sidebar, 20, row_rect.y + 12, row_primary, color_with_alpha(COLOR_BLACK, 255)); @@ -823,7 +967,7 @@ void ui_render_guide(SDL_Renderer *renderer, } draw_text_shadowed(renderer, fonts->small, - program->file_name, + focus_program->file_name, &sidebar, 20, row_rect.y + 38, @@ -831,26 +975,78 @@ void ui_render_guide(SDL_Renderer *renderer, color_with_alpha(COLOR_BLACK, 255)); SDL_RenderSetClipRect(renderer, &clip); - draw_beveled_bar(renderer, - &block, - is_selected ? theme->block_active_top : theme->block_top, - is_selected ? theme->block_active_mid : theme->block_mid, - is_selected ? theme->block_active_bottom : theme->block_bottom, - is_selected ? theme->selection_edge : theme->gloss, - theme->panel_border); - fit_text_with_ellipsis(is_selected ? fonts->medium : fonts->small, - program->program_title, - title_rect.w, - title, - sizeof(title)); - draw_text_shadowed(renderer, - is_selected ? fonts->medium : fonts->small, - title, - &title_rect, - title_rect.x, - title_rect.y, - block_text, - block_shadow); + + { + double block_cursor_seconds = guide_view_start_seconds; + int block_guard = channel->program_count; + + if (channel->total_duration_seconds > 0.0) { + block_guard *= 1 + (int) (TIMELINE_VISIBLE_SECONDS / channel->total_duration_seconds); + } + block_guard += 8; + if (block_guard < 16) { + block_guard = 16; + } + + while (block_cursor_seconds < guide_view_end_seconds && block_guard-- > 0) { + double program_seek = 0.0; + const ProgramEntry *program = channel_resolve_program_at_elapsed(channel, block_cursor_seconds, &program_seek, NULL); + double program_start_seconds; + double program_end_seconds; + double visible_start_seconds; + double visible_end_seconds; + int block_x; + int block_w; + SDL_Rect block; + SDL_Rect title_rect; + + if (!program || program->duration_seconds <= 0.0) { + break; + } + + program_start_seconds = block_cursor_seconds - program_seek; + program_end_seconds = program_start_seconds + program->duration_seconds; + visible_start_seconds = SDL_max(program_start_seconds, guide_view_start_seconds); + visible_end_seconds = SDL_min(program_end_seconds, guide_view_end_seconds); + + block_cursor_seconds = program_end_seconds; + if (visible_end_seconds <= visible_start_seconds) { + continue; + } + + block_x = guide_x_start + (int) ((((visible_start_seconds - guide_view_start_seconds) / 60.0) * pixels_per_minute) + 0.5); + block_w = (int) ((((visible_end_seconds - visible_start_seconds) / 60.0) * pixels_per_minute) + 0.5); + block = (SDL_Rect){block_x + 1, timeline_rect.y + 4, SDL_max(block_w - 2, 22), timeline_rect.h - 8}; + title_rect = (SDL_Rect){block.x + 8, block.y + 8, block.w - 16, block.h - 16}; + + draw_program_block(renderer, + &block, + is_selected ? theme->block_active_top : theme->block_top, + is_selected ? theme->block_active_mid : theme->block_mid, + is_selected ? theme->block_active_bottom : theme->block_bottom, + theme->gloss, + theme->panel_border, + is_selected, + theme->selection_edge); + + if (title_rect.w > 24) { + fit_text_with_ellipsis(is_selected ? fonts->medium : fonts->small, + program->program_title, + title_rect.w, + title, + sizeof(title)); + draw_text_shadowed(renderer, + is_selected ? fonts->medium : fonts->small, + title, + &title_rect, + title_rect.x, + title_rect.y, + block_text, + block_shadow); + } + } + } + SDL_RenderSetClipRect(renderer, NULL); } } diff --git a/src/ui.h b/src/ui.h index c716f65..61b5547 100644 --- a/src/ui.h +++ b/src/ui.h @@ -52,7 +52,14 @@ void ui_render_fullscreen(SDL_Renderer *renderer, int texture_width, int texture_height, int window_width, - int window_height); + int window_height, + const GuideTheme *theme, + const UiFonts *fonts, + const ChannelList *channels, + int active_channel, + time_t app_start_time, + time_t now_wall, + int show_channel_banner); void ui_render_guide(SDL_Renderer *renderer, SDL_Texture *video_texture, int texture_width, @@ -64,9 +71,9 @@ void ui_render_guide(SDL_Renderer *renderer, UiCache *cache, const ChannelList *channels, int active_channel, - Uint64 app_start_ticks, - Uint64 now_ticks, - time_t now_wall); + time_t app_start_time, + time_t now_wall, + int guide_time_offset_minutes); void ui_render_theme_picker(SDL_Renderer *renderer, const UiFonts *fonts, int window_width, diff --git a/src/ui.o b/src/ui.o index 470287a..b82cf0a 100644 Binary files a/src/ui.o and b/src/ui.o differ