texture_2d *text_manager_get_text(const char *font_name, int size, const char *text, rgba *color, int max_width, int text_style, float stroke_width) {

	char buf[256] = {'\0'};
	float scale = device_get_text_scale();
	snprintf(buf, sizeof(buf), "@TEXT%s|%i|%i|%i|%i|%i|%i|%i|%f|%s",
			font_name,(int) (scale * size),
			(int) (255 * color->r),
			(int) (255 * color->g),
			(int) (255 * color->b),
			(int) (255 * color->a),
			(int)(scale * max_width),
			text_style,
			scale * stroke_width,
			text); // text has to go last!

	texture_2d *tex = texture_manager_get_texture(texture_manager_get(), buf);
	if (!tex) {
		tex = texture_manager_load_texture(texture_manager_get(), buf);
		tex->originalWidth /= scale;
		tex->originalHeight /= scale;
		tex->width /= scale;
		tex->height /= scale;
	}
	return tex;
}
/**
 * @name	context_2d_delete
 * @brief	frees the given context
 * @param	ctx - (context_2d *) context to delete
 * @retval	NONE
 */
void context_2d_delete(context_2d *ctx) {
	texture_2d *tex = texture_manager_get_texture(texture_manager_get(), (char *)ctx->url);

	if (tex) {
		texture_manager_free_texture(texture_manager_get(), tex);
	}

	free(ctx->url);
	free(ctx);
}
/**
 * @name	context_2d_drawImage
 * @brief	darws an image to the given context using given options
 * @param	ctx - (context_2d *) context to draw to
 * @param	srcTex - (int) deprecated
 * @param	url - (const char *) name of the texture to draw from
 * @param	srcRect - (const rect_2d *) source rectangle on the texture to draw from
 * @param	destRect - (const rect_2d *) destination rect to draw to
 * @param	composite_op - (int) composite operation to draw with
 * @retval	NONE
 */
void context_2d_drawImage(context_2d *ctx, int srcTex, const char *url, const rect_2d *srcRect, const rect_2d *destRect) {
	context_2d_bind(ctx);
	texture_2d *tex = texture_manager_load_texture(texture_manager_get(), url);

	if (tex && tex->loaded) {
		draw_textures_item(ctx, GET_MODEL_VIEW_MATRIX(ctx), tex->name, tex->width, tex->height, tex->originalWidth, tex->originalHeight, *srcRect, *destRect, * GET_CLIPPING_BOUNDS(ctx), ctx->globalAlpha[ctx->mvp], ctx->globalCompositeOperation[ctx->mvp], &ctx->filter_color, ctx->filter_type);
	}
}
/**
 * @name	context_2d_draw_point_sprites
 * @brief	Draws pointsprites using the given options (in batch along a line)
 * @param	ctx - (context_2d *) context to draw to
 * @param	url - (const char *) name of the texture to draw from
 * @param	point_size - (float) point sprite size
 * @param	step_size - (float) step size to take between drawn pointsprites
 * @param	color - (rgba *) color to draw with
 * @param	x1 - (float) starting x-coordinate to draw along
 * @param	y1 - (float) starting y-coordinate to draw along
 * @param	x2 - (float) ending x-coordinate to draw along
 * @param	y2 - (float) ending y-coordinate to draw along
 * @retval	NONE
 */
void context_2d_draw_point_sprites(context_2d *ctx, const char *url, float point_size, float step_size, rgba *color, float x1, float y1, float x2, float y2) {
	draw_textures_flush();
	context_2d_bind(ctx);
	texture_2d *tex = texture_manager_load_texture(texture_manager_get(), url);

	// If texture is not finished loading,
	if (!tex || !tex->loaded) {
		return;
	}

	static GLfloat     *vertex_buffer = NULL;
	static unsigned int vertex_max = 64;
	tealeaf_shaders_bind(DRAWING_SHADER);
	matrix_3x3_multiply_m_f_f_f_f(GET_MODEL_VIEW_MATRIX(ctx), x1, y1, &x1, &y1);
	matrix_3x3_multiply_m_f_f_f_f(GET_MODEL_VIEW_MATRIX(ctx), x2, y2, &x2, &y2);

	// Allocate vertex array buffer
	if (vertex_buffer == NULL) {
		vertex_buffer = malloc(vertex_max * 2 * sizeof(GLfloat));
	}

	// Add points to the buffer so there are drawing points every X pixels
	unsigned int count = ceilf(sqrtf((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) / step_size);

	if (count < 1) {
		count = 1;
	}

	unsigned int vertex_count = 0;
	unsigned int i;

	for (i = 0; i < count; ++i) {
		if (vertex_count == vertex_max) {
			vertex_max = 2 * vertex_max;
			vertex_buffer = realloc(vertex_buffer, vertex_max * 2 * sizeof(GLfloat));
		}

		vertex_buffer[2 * vertex_count + 0] = x1 + (x2 - x1) * ((GLfloat)i / (GLfloat)count);
		vertex_buffer[2 * vertex_count + 1] = y1 + (y2 - y1) * ((GLfloat)i / (GLfloat)count);
		vertex_count += 1;
	}

	GLTRACE(glActiveTexture(GL_TEXTURE0));
	GLTRACE(glBindTexture(GL_TEXTURE_2D, tex->name));
	GLTRACE(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
	GLTRACE(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
	GLTRACE(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
	GLTRACE(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
	GLTRACE(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
	// Render the vertex array
	GLTRACE(glUniform1f(global_shaders[DRAWING_SHADER].point_size, point_size));
	GLTRACE(glVertexAttribPointer(global_shaders[DRAWING_SHADER].vertex_coords, 2, GL_FLOAT, GL_FALSE, 0, (float *) vertex_buffer));
	float alpha = color->a * ctx->globalAlpha[ctx->mvp];
	GLTRACE(glUniform4f(global_shaders[DRAWING_SHADER].draw_color, alpha * color->r, alpha * color->g, alpha * color->b, alpha));
	GLTRACE(glDrawArrays(GL_POINTS, 0, vertex_count));
	tealeaf_shaders_bind(PRIMARY_SHADER);
}
Beispiel #5
0
/**
 * @name	core_tick
 * @brief	moves the game forward by a single tick, defined by a time delta of
 *			last tick to this tick
 * @param	dt - (int) elapsed time from last tick to this tick in milliseconds
 * @retval	NONE
 */
void core_tick(int dt) {
	if (js_ready) {
		core_timer_tick(dt);
		js_tick(dt);
	}

	// Tick the texture manager (load pending textures)
	texture_manager_tick(texture_manager_get());
	/*
	 * we need to wait 2 frames before removing the preloader after we get the
	 * core_hide_preloader call from JS.  Only on the second frame after the
	 * callback are the images that were preloaded actually drawn.
	 */

	if (show_preload || preload_hide_frame_count < 2) {
		//if we've gotten the core_hide_preloader cb, start counting frames
		if (!show_preload) {
			preload_hide_frame_count++;
		}

		texture_2d *tex = texture_manager_get_texture(texture_manager_get(), "loading.png");

		if (tex && tex->loaded) {
			if (do_sizing) {
				calculate_size(tex);
				do_sizing = false;
			}

			context_2d *ctx = context_2d_get_onscreen(tealeaf_canvas_get());
			context_2d_loadIdentity(ctx);
			context_2d_clear(ctx);
			context_2d_drawImage(ctx, 0, "loading.png", &tex_size, &size, 0);
			// we're the first, last, and only thing to draw, so flush the buffer
			context_2d_flush(ctx);
		}
	}

    // check the gl error and send it to java to be logged
    if (js_ready) {
        core_check_gl_error();
    }
}
/**
 * @name	tealeaf_canvas_bind_texture_buffer
 * @brief	binds the given context's texture backing to gl to draw to
 * @param	ctx - (context_2d *) pointer to the context to bind
 * @retval	NONE
 */
void tealeaf_canvas_bind_texture_buffer(context_2d *ctx) {
    texture_2d *tex = texture_manager_get_texture(texture_manager_get(), ctx->url);

    if (!tex) {
        return;
    }

    GLTRACE(glBindTexture(GL_TEXTURE_2D, tex->name));
    GLTRACE(glFinish());
    GLTRACE(glBindFramebuffer(GL_FRAMEBUFFER, canvas.offscreen_framebuffer));
    GLTRACE(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex->name, 0));
    canvas.framebuffer_width = tex->originalWidth;
    canvas.framebuffer_height = tex->originalHeight;
    canvas.framebuffer_offset_bottom = tex->height - tex->originalHeight;
}
/**
 * @name	context_2d_init
 * @brief	init's and returns a context_2d pointer with the given options
 * @param	canvas - (tealeaf_canvas *) canvas to use as the context's canvas
 * @param	url - (const char *) name of the canvas
 * @param	dest_tex - (int)
 * @param	on_screen - (bool) whether this should be an onscreen or offscreen context
 * @retval	context_2d* - pointer to the created context
 */
context_2d *context_2d_init(tealeaf_canvas *canvas, const char *url, int dest_tex, bool on_screen) {
	context_2d *ctx = (context_2d *) malloc(sizeof(context_2d));
	ctx->mvp = 0;
	ctx->globalAlpha[0] = 1;
	ctx->globalCompositeOperation[0] = 0;
	ctx->destTex = dest_tex;
	ctx->on_screen = on_screen;
	ctx->filter_color.r = 0.0;
	ctx->filter_color.g = 0.0;
	ctx->filter_color.b = 0.0;
	ctx->filter_color.a = 0.0;
	ctx->filter_type = FILTER_NONE;

	if (!on_screen) {
		texture_2d *tex = texture_manager_get_texture(texture_manager_get(), url);

		if (tex) {
			ctx->backing_width = tex->width;
			ctx->backing_height = tex->height;
			ctx->width = tex->originalWidth;
			ctx->height = tex->originalHeight;
			tealeaf_context_set_proj_matrix(ctx);
			tex->ctx = ctx;
		}
	} else {
		ctx->width = 0;
		ctx->height = 0;
	}

	ctx->canvas = canvas;
	int len = strlen(url);
	ctx->url = (char *)malloc(sizeof(char) * (len + 1));
	strlcpy(ctx->url, url, len + 1);
	ctx->clipStack[0].x = 0;
	ctx->clipStack[0].y = 0;
	ctx->clipStack[0].width = -1;
	ctx->clipStack[0].height = -1;
	matrix_3x3_identity(&ctx->modelView[0]);
	context_2d_clear(ctx);
	return ctx;
}
Beispiel #8
0
/**
 * @name	core_init
 * @brief	initilizes the config object with given options
 *			See config.c for examples for options
 * @param	entry_point - (const char*) entry point
 * @param	tcp_host - (const char*) tcp host
 * @param	code_host - (const char*) code host
 * @param	tcp_port - (int) representing the tcp port
 * @param	code_port - (int) representing the code port
 * @param	source_dir - (const char*) representing where the source directory is located
 * @param	width - (int) representing the width of the screen
 * @param	height - (int) representing the height of the screen
 * @param	remote_loading - (bool) representing whether remote loading is on / orr
 * @param	splash - (const char*) splash screen path
 * @param	simulate_id - (const char*) representing the id of the game to be simulated
 * @retval	NONE
 */
void core_init(const char *entry_point,
               const char *tcp_host,
               const char *code_host,
               int tcp_port,
               int code_port,
               const char *source_dir,
               int width,
               int height,
               bool remote_loading,
               const char *splash,
			   const char *simulate_id) {
	config_set_remote_loading(remote_loading);
	config_set_entry_point(entry_point);
	config_set_tcp_host(tcp_host);
	config_set_code_host(code_host);
	config_set_tcp_port(tcp_port);
	config_set_code_port(code_port);
	config_set_screen_width(width);
	config_set_screen_height(height);
	config_set_splash(splash);
	config_set_simulate_id(simulate_id);
	// http_init();
	// register default HTML color names
	rgba_init();
	//make checks for halfsized images
	resource_loader_initialize(source_dir);
	//default halfsized textures to false
	use_halfsized_textures = false;

	if (width <= MIN_SIZE_TO_HALFSIZE || height <= MIN_SIZE_TO_HALFSIZE) {
		use_halfsized_textures = true;
		//set halfsized textures setting to true here or else java will overwrite with
		//a potentially wrong value
		set_halfsized_textures(true);
	}

	texture_manager_set_use_halfsized_textures();
	texture_manager_load_texture(texture_manager_get(), config_get_splash());

	LOG("{core} Initialization complete");
}
Beispiel #9
0
/**
 * @name	core_destroy
 * @brief	destroys the running js and the texture manager
 * @retval	NONE
 */
void core_destroy() {
	destroy_js();
	texture_manager_destroy(texture_manager_get());
	sound_manager_halt();
}
Beispiel #10
0
/**
 * @name	core_tick
 * @brief	moves the game forward by a single tick, defined by a time delta of
 *			last tick to this tick
 * @param	dt - (int) elapsed time from last tick to this tick in milliseconds
 * @retval	NONE
 */
void core_tick(int dt) {
	if (js_ready) {
		core_timer_tick(dt);
		js_tick(dt);
	}

	// Tick the texture manager (load pending textures)
	texture_manager_tick(texture_manager_get());
	/*
	 * we need to wait 2 frames before removing the preloader after we get the
	 * core_hide_preloader call from JS.  Only on the second frame after the
	 * callback are the images that were preloaded actually drawn.
	 */

	if (show_preload || preload_hide_frame_count < 2) {
		//if we've gotten the core_hide_preloader cb, start counting frames
		if (!show_preload) {
			preload_hide_frame_count++;

			// May have never loaded the splash image, so hide splash here too
			device_hide_splash();
		}

		// If splash is defined,
		const char *splash = config_get_splash();
		if (splash) {
			texture_2d *tex = texture_manager_get_texture(texture_manager_get(), splash);
			if (!tex) {
				tex = texture_manager_load_texture(texture_manager_get(), splash);
			}

			if (tex && tex->loaded) {
				if (do_sizing) {
					// Calculate rotation
					tealeaf_canvas *canvas = tealeaf_canvas_get();
					int canvas_width = canvas->framebuffer_width;
					int canvas_height = canvas->framebuffer_height;
					rotate = canvas_width > canvas_height;
					rotate ^= tex->originalWidth > tex->originalHeight;

					calculate_size(tex, rotate);
					do_sizing = false;
				}

				context_2d *ctx = context_2d_get_onscreen(tealeaf_canvas_get());
				context_2d_loadIdentity(ctx);
				context_2d_clear(ctx);
				if (rotate) {
					context_2d_save(ctx);
					context_2d_translate(ctx, size.y + (size.height)/2.f/tex->scale, size.x + (size.width)/2.f/tex->scale);
					context_2d_rotate(ctx, (tex->originalWidth > tex->originalHeight)? -3.14f/2.f : 3.14f/2.f);
					context_2d_translate(ctx, -size.x -(size.width)/2.f/tex->scale, -size.y - (size.height)/2.f/tex->scale);
				}
				context_2d_setGlobalCompositeOperation(ctx, source_over);
				context_2d_drawImage(ctx, 0, splash, &tex_size, &size);
				if (rotate) {
					context_2d_restore(ctx);
				}
				// we're the first, last, and only thing to draw, so flush the buffer
				context_2d_flush(ctx);

				device_hide_splash();
			}
		}
	}

    // check the gl error and send it to java to be logged
    if (js_ready) {
        core_check_gl_error();
    }
}
Beispiel #11
0
SDL_Texture* textures_get(const char* name) { return texture_manager_get(&globals.textures, name); }