# frame.ludic - what the camera sees right now: the game offers each subject and tag, and the frame # takes the best subject's grade - which is what a photographer would say about it export function photo_frame_begin(photo_st: mut PhotoState) -> void { photo_st.pht_pending_tags = "" sb_clear(photo_st.pht_tag_sb) photo_st.pht_pending_mask = 0 photo_st.pht_pending_legend = 0 photo_st.pht_pending_grade = 0 photo_st.pht_pending_why = PHOTO_WHY_NONE photo_st.pht_pending_sign = -1 photo_st.pht_pending_stars = false } # A subject `sp` (0..31) named `name`, h metres tall, standing at (x, y, z) and doing something worth # `moment`. True when the lens sees it within its range: it is tagged (once a kind, every legend) and # scored, and the best score is the frame's. export function photo_frame_subject(photo_st: mut PhotoState, sp: int, name: string, x: float, y: float, z: float, h: float, legend: bool, moment: int) -> bool { if not photo_in_view(x, y + 0.8, z, PhotoLens.range()) { return false } if (photo_st.pht_pending_mask & (1 << sp)) == 0 or legend { photo_frame_tag(photo_st, name) } photo_st.pht_pending_mask = photo_st.pht_pending_mask | (1 << sp) if legend { photo_st.pht_pending_legend = photo_st.pht_pending_legend | (1 << sp) } let g = photo_score(photo_st, x, y, z, h, moment) if g > photo_st.pht_pending_grade { photo_st.pht_pending_grade = g photo_st.pht_pending_why = photo_why_of_comp(photo_st) } return true } # anything else in the picture worth naming: a landmark, the water, a sign # (a viewfinder composes every frame: the text is written into a kept buffer and interned) export function photo_frame_tag(photo_st: mut PhotoState, text: string) -> void { if len(text) == 0 { return } let sb = photo_st.pht_tag_sb if sb_len(sb) > 0 { sb_add(sb, ", ") } sb_add(sb, text) photo_st.pht_pending_tags = pht_tags_text(photo_st) } # past the table's most, a copy only when the text changed - never one a frame @alloc_ok("a tag text past 4096 distinct ones: one copy per change") function pht_tags_text(photo_st: PhotoState) -> string { let sb = photo_st.pht_tag_sb let tb = photo_st.pht_tag_tb if strs_count(tb) < tb.most { return sb_intern(sb, tb) } if pht_same(sb, photo_st.pht_pending_tags) { return photo_st.pht_pending_tags } return keep(text_of(sb.b, sb_len(sb))) } function pht_same(sb: StrBuf, s: string) -> bool { if len(s) != sb_len(sb) { return false } for i in 0 .. sb_len(sb) { if s[i] != sb.b[i] { return false } } return true } export function photo_frame_sign(photo_st: mut PhotoState, sign: int) -> void { photo_st.pht_pending_sign = sign } export function photo_frame_stars(photo_st: mut PhotoState) -> void { photo_st.pht_pending_stars = true }