1*d86ed7fbStbbdev /*
2*d86ed7fbStbbdev     Copyright (c) 2005-2020 Intel Corporation
3*d86ed7fbStbbdev 
4*d86ed7fbStbbdev     Licensed under the Apache License, Version 2.0 (the "License");
5*d86ed7fbStbbdev     you may not use this file except in compliance with the License.
6*d86ed7fbStbbdev     You may obtain a copy of the License at
7*d86ed7fbStbbdev 
8*d86ed7fbStbbdev         http://www.apache.org/licenses/LICENSE-2.0
9*d86ed7fbStbbdev 
10*d86ed7fbStbbdev     Unless required by applicable law or agreed to in writing, software
11*d86ed7fbStbbdev     distributed under the License is distributed on an "AS IS" BASIS,
12*d86ed7fbStbbdev     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*d86ed7fbStbbdev     See the License for the specific language governing permissions and
14*d86ed7fbStbbdev     limitations under the License.
15*d86ed7fbStbbdev */
16*d86ed7fbStbbdev 
17*d86ed7fbStbbdev /*
18*d86ed7fbStbbdev     The original source for this example is
19*d86ed7fbStbbdev     Copyright (c) 1994-2008 John E. Stone
20*d86ed7fbStbbdev     All rights reserved.
21*d86ed7fbStbbdev 
22*d86ed7fbStbbdev     Redistribution and use in source and binary forms, with or without
23*d86ed7fbStbbdev     modification, are permitted provided that the following conditions
24*d86ed7fbStbbdev     are met:
25*d86ed7fbStbbdev     1. Redistributions of source code must retain the above copyright
26*d86ed7fbStbbdev        notice, this list of conditions and the following disclaimer.
27*d86ed7fbStbbdev     2. Redistributions in binary form must reproduce the above copyright
28*d86ed7fbStbbdev        notice, this list of conditions and the following disclaimer in the
29*d86ed7fbStbbdev        documentation and/or other materials provided with the distribution.
30*d86ed7fbStbbdev     3. The name of the author may not be used to endorse or promote products
31*d86ed7fbStbbdev        derived from this software without specific prior written permission.
32*d86ed7fbStbbdev 
33*d86ed7fbStbbdev     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
34*d86ed7fbStbbdev     OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
35*d86ed7fbStbbdev     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36*d86ed7fbStbbdev     ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
37*d86ed7fbStbbdev     DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38*d86ed7fbStbbdev     DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39*d86ed7fbStbbdev     OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40*d86ed7fbStbbdev     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
41*d86ed7fbStbbdev     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
42*d86ed7fbStbbdev     OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43*d86ed7fbStbbdev     SUCH DAMAGE.
44*d86ed7fbStbbdev */
45*d86ed7fbStbbdev 
46*d86ed7fbStbbdev #include <cstdio>
47*d86ed7fbStbbdev #include <cstdlib>
48*d86ed7fbStbbdev #include <cstring>
49*d86ed7fbStbbdev 
50*d86ed7fbStbbdev #include "types.hpp"
51*d86ed7fbStbbdev #include "api.hpp" /* The ray tracing library API */
52*d86ed7fbStbbdev #include "ui.hpp"
53*d86ed7fbStbbdev #include "util.hpp"
54*d86ed7fbStbbdev #include "tachyon_video.hpp"
55*d86ed7fbStbbdev 
56*d86ed7fbStbbdev extern SceneHandle global_scene;
57*d86ed7fbStbbdev extern char *global_window_title;
58*d86ed7fbStbbdev extern bool global_usegraphics;
59*d86ed7fbStbbdev 
60*d86ed7fbStbbdev void tachyon_video::on_process() {
61*d86ed7fbStbbdev     char buf[8192];
62*d86ed7fbStbbdev     flt runtime;
63*d86ed7fbStbbdev     scenedef *scene = (scenedef *)global_scene;
64*d86ed7fbStbbdev     updating_mode = scene->displaymode == RT_DISPLAY_ENABLED;
65*d86ed7fbStbbdev     recycling = false;
66*d86ed7fbStbbdev     pausing = false;
67*d86ed7fbStbbdev     do {
68*d86ed7fbStbbdev         updating = updating_mode;
69*d86ed7fbStbbdev         timer start_timer = gettimer();
70*d86ed7fbStbbdev         rt_renderscene(global_scene);
71*d86ed7fbStbbdev         timer end_timer = gettimer();
72*d86ed7fbStbbdev         runtime = timertime(start_timer, end_timer);
73*d86ed7fbStbbdev         sprintf(buf, "%s: %.3f seconds", global_window_title, runtime);
74*d86ed7fbStbbdev         rt_ui_message(MSG_0, buf);
75*d86ed7fbStbbdev         title = buf;
76*d86ed7fbStbbdev         show_title(); // show time spent for rendering
77*d86ed7fbStbbdev         if (!updating) {
78*d86ed7fbStbbdev             updating = true;
79*d86ed7fbStbbdev             drawing_memory dm = get_drawing_memory();
80*d86ed7fbStbbdev             drawing_area drawing(0, 0, dm.sizex, dm.sizey); // invalidate whole screen
81*d86ed7fbStbbdev         }
82*d86ed7fbStbbdev         rt_finalize();
83*d86ed7fbStbbdev         title = global_window_title;
84*d86ed7fbStbbdev         show_title(); // reset title to default
85*d86ed7fbStbbdev     } while (recycling && running);
86*d86ed7fbStbbdev }
87*d86ed7fbStbbdev 
88*d86ed7fbStbbdev void tachyon_video::on_key(int key) {
89*d86ed7fbStbbdev     key &= 0xff;
90*d86ed7fbStbbdev     recycling = true;
91*d86ed7fbStbbdev     if (key == esc_key)
92*d86ed7fbStbbdev         running = false;
93*d86ed7fbStbbdev     else if (key == ' ') {
94*d86ed7fbStbbdev         if (!updating) {
95*d86ed7fbStbbdev             updating = true;
96*d86ed7fbStbbdev             drawing_memory dm = get_drawing_memory();
97*d86ed7fbStbbdev             drawing_area drawing(0, 0, dm.sizex, dm.sizey); // invalidate whole screen
98*d86ed7fbStbbdev         }
99*d86ed7fbStbbdev         updating = updating_mode = !updating_mode;
100*d86ed7fbStbbdev     }
101*d86ed7fbStbbdev     else if (key == 'p') {
102*d86ed7fbStbbdev         pausing = !pausing;
103*d86ed7fbStbbdev         if (pausing) {
104*d86ed7fbStbbdev             title = "Press ESC to exit or 'p' to continue after rendering completion";
105*d86ed7fbStbbdev             show_title();
106*d86ed7fbStbbdev         }
107*d86ed7fbStbbdev     }
108*d86ed7fbStbbdev }
109*d86ed7fbStbbdev 
110*d86ed7fbStbbdev void rt_finalize(void) {
111*d86ed7fbStbbdev     timer t0, t1;
112*d86ed7fbStbbdev     t0 = gettimer();
113*d86ed7fbStbbdev     if (global_usegraphics)
114*d86ed7fbStbbdev         do {
115*d86ed7fbStbbdev             rt_sleep(1);
116*d86ed7fbStbbdev             t1 = gettimer();
117*d86ed7fbStbbdev         } while ((timertime(t0, t1) < 10 || video->pausing) && video->next_frame());
118*d86ed7fbStbbdev #ifdef _WINDOWS
119*d86ed7fbStbbdev     else
120*d86ed7fbStbbdev         rt_sleep(10000);
121*d86ed7fbStbbdev #endif
122*d86ed7fbStbbdev }
123