2 This file is part of 3dengfx demosystem.
4 Copyright (c) 2004, 2005 John Tsiombikas <nuclear@siggraph.org>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "3dengfx_config.h"
32 #include "3dengfx/3dengfx.hpp"
33 #include "n3dmath2/n3dmath2.hpp"
34 #include "common/timer.h"
35 #include "common/err_msg.h"
37 #if defined(__unix__) || defined(unix)
45 static int execute_script(DemoScript *ds, unsigned long time);
47 Texture *dsys::tex[4];
48 unsigned int dsys::rtex_size_x, dsys::rtex_size_y;
49 Matrix4x4 dsys::tex_mat[4];
51 typedef map<string, Part*> PartTree;
52 static PartTree parts;
53 static PartTree running;
57 static char script_fname[256];
58 static DemoScript *ds;
60 static bool demo_running = false;
61 static bool seq_render = false;
62 static unsigned long seq_time, seq_dt;
64 static int best_tex_size(int n) {
66 for(i=64; i<2048; i*=2) {
74 int scrx = get_graphics_init_parameters()->x;
75 int scry = get_graphics_init_parameters()->y;
77 int next_size_x, next_size_y;
79 rtex_size_x = best_tex_size(scrx - 1);
80 rtex_size_y = best_tex_size(scry - 1);
82 next_size_x = rtex_size_x * 2;
83 next_size_y = rtex_size_y * 2;
85 info("allocating dsys render targets:");
87 //if (!engfx_state::sys_caps.non_power_of_two_textures)
89 // make a high-res texture and 3 low-res
90 for(int i=0; i<4; i++) {
91 int x = (i > 1) ? rtex_size_x : next_size_x;
92 int y = (i > 1) ? rtex_size_y : next_size_y;
93 tex[i] = new Texture(x, y);
94 info(" %d - %dx%d", i, x, y);
97 tex_mat[0].set_scaling(Vector3((float)scrx / (float)next_size_x, (float)scry / (float)next_size_y, 1));
98 tex_mat[1].set_scaling(Vector3((float)scrx / (float)next_size_x, (float)scry / (float)next_size_y, 1));
100 tex_mat[2] = Matrix4x4::identity_matrix;
101 tex_mat[3] = Matrix4x4::identity_matrix;
105 for (int i=0; i<4; i++)
107 tex[i] = new Texture(scrx, scry);
108 info(" %d - %dx%d", i, scrx, scry);
109 tex_mat[i] = Matrix4x4::identity_matrix;
113 strcpy(script_fname, "demoscript");
115 cmd::register_commands();
120 void dsys::clean_up() {
121 for(int i=0; i<4; i++) {
122 if(tex[i]) delete tex[i];
127 void dsys::use_rt_tex(RenderTarget rt) {
128 set_texture(0, tex[rt]);
129 set_matrix(XFORM_TEXTURE, tex_mat[rt]);
132 void dsys::set_demo_script(const char *fname) {
133 strcpy(script_fname, fname);
137 unsigned long dsys::get_demo_time() {
138 return seq_render ? seq_time : timer_getmsec(&timer);
142 void dsys::add_part(Part *part) {
143 if(!part->get_name()) {
144 error("dsys::add_part - trying to add a nameless part...");
147 parts[string(part->get_name())] = part;
150 void dsys::remove_part(Part *part) {
151 PartTree::iterator iter = parts.find(part->get_name());
155 void dsys::start_part(Part *part) {
156 running[part->get_name()] = part;
160 void dsys::stop_part(Part *part) {
162 PartTree::iterator iter = running.find(part->get_name());
163 if(iter != running.end()) {
166 error("stop_part() called for unknown part: %s\n", part->get_name());
170 Part *dsys::get_part(const char *pname) {
171 PartTree::iterator iter = parts.find(pname);
172 return iter != parts.end() ? iter->second : 0;
175 Part *dsys::get_running(const char *pname) {
176 PartTree::iterator iter = running.find(pname);
177 return iter != running.end() ? iter->second : 0;
181 bool dsys::start_demo() {
182 if(!(ds = open_script(script_fname))) {
191 #define PATH_MAX 2048
192 static char curr_dir[PATH_MAX];
194 bool dsys::render_demo(int fps, const char *out_dir) {
195 if(!(ds = open_script(script_fname))) {
199 #if defined(__unix__) || defined(unix)
200 // change to the specified directory
201 getcwd(curr_dir, PATH_MAX);
204 if(stat(out_dir, &sbuf) == -1) {
205 mkdir(out_dir, 0770);
219 void dsys::end_demo() {
220 #if defined(__unix__) || defined(unix)
228 demo_running = false;
233 static void update_node(const pair<string, Part*> &p) {
234 p.second->update_graphics();
237 int dsys::update_graphics() {
242 unsigned long time = get_demo_time();
245 while((res = execute_script(ds, time)) != 1) {
253 clear(Color(0.0f, 0.0f, 0.0f));
254 clear_zbuffer_stencil(1.0f, 0);
256 for_each(running.begin(), running.end(), update_node);
258 // apply any post effects
259 apply_image_fx(time);
270 static int execute_script(DemoScript *ds, unsigned long time) {
273 int res = get_next_command(ds, &command, time);
274 if(res == EOF || res == 1) {
278 if(!cmd::command(command.type, command.argv[0], command.argv + 1)) {
279 error("error in demoscript command execution!");
281 free_command(&command);
283 return demo_running ? 0 : -1;