Example #1
0
static int run_map_thread(tribuf *tb)
{
	set_threadname("render");

	struct point_data *pd = new_point_data(opts.rational_julia?4:2);
	unsigned int beats = beat_get_count();
	unsigned int tick0, fps_oldtime, frmcnt=0, last_beat_time = 0;
	tick0 = fps_oldtime = SDL_GetTicks();

	unsigned int fpstimes[40]; for(int i=0; i<40; i++) fpstimes[i] = 0;

	uint16_t *map_src = tribuf_get_read_nolock(tb);
    while(running) {
		frmcnt++;

		if((tick0-SDL_GetTicks())*opts.maxsrc_rate + (maxfrms*1000) > 1000) {
			audio_data ad; audio_get_samples(&ad);
			maxsrc_update(maxsrc, ad.data, ad.len);
			audio_finish_samples();
			maxfrms++;
		}

		uint16_t *map_dest = tribuf_get_write(tb);
		map_func(map_dest, map_src, im_w, im_h, pd);
		maxblend(map_dest, maxsrc_get(maxsrc), im_w, im_h);

		tribuf_finish_write(tb);
		map_src=map_dest;

		unsigned int now = SDL_GetTicks() - tick0;
		float fpsd = (now - fpstimes[frmcnt%40])/1000.0f;
		fpstimes[frmcnt%40] = now;
		map_fps = 40.0f / fpsd;

		unsigned int newbeat = beat_get_count();
		if(newbeat != beats && now - last_beat_time > 1000) {
			last_beat_time = now;
			update_points(pd, now, 1);
		} else update_points(pd, now, 0);
		beats = newbeat;

		if(map_fps > 750)
			SDL_Delay(1); // hard limit ourselves because 1500FPS is just pointless use of CPU (except of course to say that we can do it)
							// also if we run at more that 1000FPS the point motion code might blow up without the microsecond accurate timers...
							// high threshhold because we want it high enough that we don't notice if we jitter back
							// and fourth across it
    }
	return 0;
}
Example #2
0
int main(int argc, char **argv)
{
	optproc(argc, argv, &opts); if(audio_init(&opts) < 0) exit(1);
	SDL_Surface *screen = sdl_setup(&opts, IM_SIZE);
	im_w = screen->w - screen->w%16; im_h = screen->h - screen->h%16;
	printf("running with %dx%d bufs\n", im_w, im_h);

	if(strcmp(opts.map_name, "rational") == 0) {
		map_func = soft_map_rational_interp;
		if(opts.quality >= 1)  map_func = soft_map_rational;
	}
	else if(strcmp(opts.map_name, "butterfly") == 0) {
//		map_func = soft_map_butterfly_interp;
//		if(opts.quality >= 1)
			map_func = soft_map_butterfly;
	}
	else if(opts.quality >= 1)  map_func = soft_map;

	maxsrc = maxsrc_new(im_w, im_h);
	struct pal_ctx *pal_ctx = pal_ctx_new(screen->format->BitsPerPixel == 8);

	uint16_t *map_surf[3];
	void *map_surf_mem = aligned_alloc(64, 3 * im_w * im_h * sizeof(uint16_t));
	for(int i=0; i<3; i++)
		map_surf[i] = map_surf_mem + i * im_w * im_h * sizeof(uint16_t);
	memset(map_surf_mem, 0, 3 * im_w * im_h * sizeof(uint16_t));

	tribuf *map_tb = tribuf_new((void **)map_surf, 1);

	int beats = 0;
	int frmcnt = 0;
	int lastdrawn=0;

	SDL_Thread *map_thread = SDL_CreateThread((void *)&run_map_thread, map_tb);
	SDL_Delay(100);

	uint32_t frametimes[FPS_HIST_LEN]; for(int i=1; i<FPS_HIST_LEN; i++) frametimes[i] = 0;
	uint32_t totframetime = frametimes[0] = MIN(1000/opts.draw_rate, 1);

	Uint32 tick0 = SDL_GetTicks();
	Uint32 lastpalstep, lastupdate, fps_oldtime; fps_oldtime = lastpalstep = lastupdate = tick0;
	SDL_Event event;
	while(SDL_PollEvent(&event) >= 0)
	{
		if(event.type == SDL_QUIT || (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_ESCAPE)) {
			break;
		} else if(tribuf_check_fresh(map_tb)) {
			Uint32 now = SDL_GetTicks();
			if(now - lastpalstep >= 2048/256) { // want pallet switch to take ~2 seconds
				pal_ctx_step(pal_ctx, IMIN((now - lastpalstep)*256/2048, 64));
				lastpalstep = now;
			}

			pallet_blit_SDL(screen, tribuf_get_read(map_tb), im_w, im_h, pal_ctx_get_active(pal_ctx));
			tribuf_finish_read(map_tb);

			char buf[64];
			sprintf(buf,"%6.1f FPS %6.1f UPS %6.1f", map_fps, FPS_HIST_LEN*1000.0f/totframetime, maxfrms*1000.0f/(now-tick0));
			DrawText(screen, buf);
			SDL_Flip(screen);

			int newbeat = beat_get_count();
			if(newbeat != beats) pal_ctx_start_switch(pal_ctx, newbeat);
			beats = newbeat;

			now = SDL_GetTicks();
			int delay =  (tick0 + frmcnt*1000/opts.draw_rate) - now;
			if(delay > 0) SDL_Delay(delay);

			totframetime -= frametimes[frmcnt%FPS_HIST_LEN];
			totframetime += (frametimes[frmcnt%FPS_HIST_LEN] = now - fps_oldtime);
			fps_oldtime = now;
			frmcnt++;
		} else {
			SDL_Delay(1000/opts.draw_rate/2); // wait half a frame and hope we get a new buffer
		}
	}
	running = 0;

	int status;
	SDL_WaitThread(map_thread, &status);
	aligned_free(map_surf_mem);
	audio_shutdown();
	SDL_Quit();
    return 0;
}
Example #3
0
void render_frame(GLboolean debug_maxsrc, GLboolean debug_pal, GLboolean show_mandel, GLboolean show_fps_hist)
{
	static int cnt = 0;
	static uint32_t maxfrms = 0;
	static uint32_t last_beat_time = 0, lastpalstep = 0, fps_oldtime = 0;
	static int beats = 0;
	static uint64_t now = 0, workstart = 0;

	//TODO: move this up to top
	workstart = now = uget_ticks();
	int delay =  (tick0 + cnt*INT64_C(1000000)/opts->draw_rate) - now;
	if(delay > 0) { udodelay(delay); workstart = now = uget_ticks(); }


	// rate limit our maxsrc updates, but run at full frame rate if we're close the opts.maxsrc_rate to avoid choppyness
	if((tick0-now)*opts->maxsrc_rate + (maxfrms*INT64_C(1000000)) > INT64_C(1000000) ) {
//			|| (totframetime + 10*FPS_HIST_LEN > FPS_HIST_LEN*1000/opts->maxsrc_rate ) ) {
		audio_data ad; audio_get_samples(&ad);
		maxsrc_update(glmaxsrc, ad.data, ad.len);
		audio_finish_samples();
		maxfrms++;
	}

	render_fractal(glfract, pd, maxsrc_get_tex(glmaxsrc));

	if(!debug_pal || !debug_maxsrc || !show_mandel) {
		gl_pal_render(glpal, fract_get_tex(glfract));
	} else {
		glPushAttrib(GL_VIEWPORT_BIT);
		setup_viewport(scr_w/2, scr_h/2);
		gl_pal_render(glpal, fract_get_tex(glfract));
		glPopAttrib();
	}

	if(show_mandel) render_mandel(pd); //TODO: enable click to change c

	//TODO: figure out what attrib to push to save color
	if(debug_pal || debug_maxsrc) { glPushAttrib(GL_TEXTURE_BIT); if(packed_intesity_pixels) glColor3f(1.0f, 1.0f, 1.0f); }
	if(debug_pal) {
		glBindTexture(GL_TEXTURE_2D, fract_get_tex(glfract));
		draw_tex_quad(0.5f, 0.5f, -0.5f);
	}
	if(debug_maxsrc) {
		glBindTexture(GL_TEXTURE_2D, maxsrc_get_tex(glmaxsrc));
		draw_tex_quad(0.5f, -0.5f, 0.5f);
	}
	if(debug_pal || debug_maxsrc) { glPopAttrib(); if(packed_intesity_pixels) glColor3f(1.0f, 1.0f, 1.0f); }

	if(show_fps_hist) { DEBUG_CHECK_GL_ERR;
		glPushMatrix();
		glScalef(0.5f, 0.25f, 1);
		glTranslatef(-2, 3, 0);
		draw_hist_array(cnt, FPS_HIST_LEN/(8.0f*totframetime), frametimes, FPS_HIST_LEN);
		glPopMatrix();
		glPushMatrix();
		glScalef(0.5f, 0.25f, 1);
		glTranslatef(1, 3, 0);
		draw_hist_array(cnt, FPS_HIST_LEN/(8.0f*totworktime), worktimes, FPS_HIST_LEN);
		glPopMatrix();
		glColor3f(1.0f, 1.0f, 1.0f);
		char buf[128];
		glRasterPos2f(-1,1 - 20.0f/(scr_h*0.5f));
		sprintf(buf,"%6.1f FPS %6.1f", FPS_HIST_LEN*1000000.0f/totframetime, maxfrms*1000000.0f/(now-tick0));
		draw_string(buf); DEBUG_CHECK_GL_ERR;
		glRasterPos2f(-1,0.75f-20.0f/(scr_h*0.5f));
		sprintf(buf,"%7.1fns frametime\n%7.1fns worktime\n", totframetime/((float)FPS_HIST_LEN), totworktime/((float)FPS_HIST_LEN));
		draw_string(buf); DEBUG_CHECK_GL_ERR;
	} else {
		glRasterPos2f(-1,0.75f-20.0f/(scr_h*0.5f));
	}

	render_debug_overlay();

	swap_buffers(); CHECK_GL_ERR;

	now = uget_ticks();
	if(now - lastpalstep >= 1000*2048/256 && gl_pal_changing(glpal)) { // want pallet switch to take ~2 seconds
		if(gl_pal_step(glpal, IMIN((now - lastpalstep)*256/(2048*1000), 32)))
		lastpalstep = now;
	}
	int newbeat = beat_get_count();
	if(newbeat != beats) {
		gl_pal_start_switch(glpal, newbeat);
	}
	if(newbeat != beats && now - last_beat_time > 1000000) {
		last_beat_time = now;
		update_points(pd, (now - tick0)/1000, 1);
	} else update_points(pd, (now - tick0)/1000, 0);
	beats = newbeat;


	now = uget_ticks();
	totframetime -= frametimes[cnt%FPS_HIST_LEN];
	totframetime += (frametimes[cnt%FPS_HIST_LEN] = now - fps_oldtime);
	fps_oldtime = now;

	totworktime -= worktimes[cnt%FPS_HIST_LEN];
	totworktime += (worktimes[cnt%FPS_HIST_LEN] = now - workstart);

	cnt++;
}