Skip to content

Commit

Permalink
See desc
Browse files Browse the repository at this point in the history
* randomized dirt color
* ttf font renderer
  • Loading branch information
xtreme8000 committed May 17, 2018
1 parent db7337d commit e844770
Show file tree
Hide file tree
Showing 8 changed files with 190 additions and 47 deletions.
Binary file added resources/fonts/Fixedsys.ttf
Binary file not shown.
Binary file added resources/fonts/Terminal.ttf
Binary file not shown.
165 changes: 123 additions & 42 deletions src/font.c
Expand Up @@ -18,94 +18,175 @@
*/

#include "common.h"

struct texture font_fixedsys;
struct texture font_smallfnt;
#include "stb_truetype.h"

short* font_vertex_buffer;
short* font_coords_buffer;
int font_type = FONT_FIXEDSYS;

unsigned char font_init() {
texture_create(&font_fixedsys,"fonts/FixedSys_Bold_36.png");
texture_create(&font_smallfnt,"fonts/smallfnt68.png");
struct font_backed {
stbtt_bakedchar* cdata;
int type;
int texture_id;
int w, h;
float size;
};

struct list font_backed_fonts;

unsigned char font_init() {
font_vertex_buffer = malloc(512*8*sizeof(short));
CHECK_ALLOCATION_ERROR(font_vertex_buffer)
font_coords_buffer = malloc(512*8*sizeof(short));
CHECK_ALLOCATION_ERROR(font_coords_buffer)

list_create(&font_backed_fonts,sizeof(struct font_backed));

return 1;
}

void font_select(char type) {
font_type = type;
}

static struct font_backed* font_find(float h) {
if(font_type==FONT_SMALLFNT)
h *= 1.5F;

for(int k=0;k<list_size(&font_backed_fonts);k++) {
struct font_backed* b = (struct font_backed*)list_get(&font_backed_fonts,k);
if(b->size==h && b->type==font_type)
return (struct font_backed*)list_get(&font_backed_fonts,k);
}

struct font_backed f;
f.w = 64;
f.h = 64;
f.size = h;
f.type = font_type;
f.cdata = malloc(224*sizeof(stbtt_bakedchar));
CHECK_ALLOCATION_ERROR(f.cdata)

void* temp_bitmap = NULL;

int max_size = 0;
glGetIntegerv(GL_MAX_TEXTURE_SIZE,&max_size);

void* file;
switch(font_type) {
case FONT_FIXEDSYS:
file = file_load("fonts/Fixedsys.ttf");
break;
case FONT_SMALLFNT:
file = file_load("fonts/Terminal.ttf");
break;
}

while(1) {
temp_bitmap = realloc(temp_bitmap,f.w*f.h);
CHECK_ALLOCATION_ERROR(temp_bitmap)
int res = 0;
res = stbtt_BakeFontBitmap(file,0,f.size,temp_bitmap,f.w,f.h,31,224,f.cdata);
if(res>0 || (f.w==max_size && f.h==max_size))
break;
if(f.h>f.w)
f.w *= 2;
else
f.h *= 2;
}

printf("texsize: %i:%ipx [size %f] type: %i\n",f.w,f.h,f.size,f.type);

glGenTextures(1,&f.texture_id);
glBindTexture(GL_TEXTURE_2D,f.texture_id);
glTexImage2D(GL_TEXTURE_2D,0,GL_ALPHA,f.w,f.h,0,GL_ALPHA,GL_UNSIGNED_BYTE,temp_bitmap);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glBindTexture(GL_TEXTURE_2D,0);

free(temp_bitmap);
free(file);

return list_add(&font_backed_fonts,&f);
}

float font_length(float h, char* text) {
return strlen(text)*h*((font_type==FONT_SMALLFNT)?0.75F:0.49F);
struct font_backed* font = font_find(h);


stbtt_aligned_quad q;
float y = h*0.75F;
float x = 0.0F;
for(int k=0;k<strlen(text);k++) {
if(text[k]>30) {
stbtt_GetBakedQuad(font->cdata,font->w,font->h,text[k]-31,&x,&y,&q,1);
}
}
return x+h*0.125F;
}

void font_reset() {
for(int k=0;k<list_size(&font_backed_fonts);k++) {
struct font_backed* f = (struct font_backed*)list_get(&font_backed_fonts,k);
glDeleteTextures(1,&f->texture_id);
free(f->cdata);
}
list_clear(&font_backed_fonts);
}

void font_render(float x, float y, float h, char* text) {

struct font_backed* font = font_find(h);

int chars_x = 16;
int chars_y = (font_type==FONT_SMALLFNT)?16:14;
float size_ratio = (font_type==FONT_SMALLFNT)?0.75F:0.49F;

float i = 0.0F;
int k = 0;
float y2 = h*0.75F;
while(*text) {
if(*text>31 || font_type==FONT_SMALLFNT) {
float tx = ((*text-((font_type==FONT_FIXEDSYS)?32:0))%chars_x)/((float)chars_x);
float ty = ((*text-((font_type==FONT_FIXEDSYS)?32:0))/chars_x)/((float)chars_y);
if(*text>31) {
stbtt_aligned_quad q;
stbtt_GetBakedQuad(font->cdata,font->w,font->h,*text-31,&x,&y2,&q,1);
font_coords_buffer[k+0] = q.s0*4096.0F;
font_coords_buffer[k+1] = q.t1*4096.0F;

//vertices
font_vertex_buffer[k+0] = x+i;
font_vertex_buffer[k+1] = y-h;
font_coords_buffer[k+2] = q.s1*4096.0F;
font_coords_buffer[k+3] = q.t1*4096.0F;

font_vertex_buffer[k+2] = x+i+h*size_ratio;
font_vertex_buffer[k+3] = y-h;
font_coords_buffer[k+4] = q.s1*4096.0F;
font_coords_buffer[k+5] = q.t0*4096.0F;

font_vertex_buffer[k+4] = x+i+h*size_ratio;
font_vertex_buffer[k+5] = y;
font_coords_buffer[k+6] = q.s0*4096.0F;
font_coords_buffer[k+7] = q.t0*4096.0F;

font_vertex_buffer[k+6] = x+i;
font_vertex_buffer[k+7] = y;
font_vertex_buffer[k+0] = q.x0;
font_vertex_buffer[k+1] = -q.y1+y;

font_vertex_buffer[k+2] = q.x1;
font_vertex_buffer[k+3] = -q.y1+y;

//texture coordinates
font_coords_buffer[k+0] = tx*8192.0F;
font_coords_buffer[k+1] = (ty+1.0F/((float)chars_y))*8192.0F;
font_vertex_buffer[k+4] = q.x1;
font_vertex_buffer[k+5] = -q.y0+y;

font_coords_buffer[k+2] = (tx+1.0F/((float)chars_x))*8192.0F;
font_coords_buffer[k+3] = (ty+1.0F/((float)chars_y))*8192.0F;

font_coords_buffer[k+4] = (tx+1.0F/((float)chars_x))*8192.0F;
font_coords_buffer[k+5] = ty*8192.0F;

font_coords_buffer[k+6] = tx*8192.0F;
font_coords_buffer[k+7] = ty*8192.0F;
i += h*size_ratio;
font_vertex_buffer[k+6] = q.x0;
font_vertex_buffer[k+7] = -q.y0+y;
k += 8;
} else {
x += h*0.49F;
}
text++;
}

glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glScalef(1.0F/8192.0F,1.0F/8192.0F,1.0F);
glScalef(1.0F/4096.0F,1.0F/4096.0F,1.0F);
glMatrixMode(GL_MODELVIEW);

glEnable(GL_TEXTURE_2D);
switch(font_type) {
case FONT_SMALLFNT:
glBindTexture(GL_TEXTURE_2D,font_smallfnt.texture_id);
break;
case FONT_FIXEDSYS:
glBindTexture(GL_TEXTURE_2D,font_fixedsys.texture_id);
break;
}
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glBindTexture(GL_TEXTURE_2D,font->texture_id);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
glEnable(GL_BLEND);
Expand Down
6 changes: 3 additions & 3 deletions src/font.h
Expand Up @@ -20,14 +20,14 @@
#define FONT_FIXEDSYS 0
#define FONT_SMALLFNT 1

extern struct texture font_fixedsys;
extern struct texture font_smallfnt;

extern short* font_vertex_buffer;
extern short* font_coords_buffer;
extern int font_type;

extern struct list font_backed_fonts;

unsigned char font_init(void);
void font_reset(void);
float font_length(float h, char* text);
void font_render(float x, float y, float h, char* text);
void font_centered(float x, float y, float h, char* text);
Expand Down
2 changes: 1 addition & 1 deletion src/main.c
Expand Up @@ -423,7 +423,7 @@ void init() {
}

void reshape(struct window_instance* window, int width, int height) {
//font_reset();
font_reset();
glViewport(0,0,width,height);
settings.window_width = width;
settings.window_height = height;
Expand Down
38 changes: 37 additions & 1 deletion src/map.c
Expand Up @@ -593,14 +593,50 @@ int map_cube_line(int x1, int y1, int z1, int x2, int y2, int z2, struct Point*
}
}

static int lerp(int a, int b, int amt) { //amt from 0 to 8
return a + (b-a)*amt/8;
}

static int dirt_color_table[] = {
0x506050, 0x605848, 0x705040,
0x804838, 0x704030, 0x603828,
0x503020, 0x402818, 0x302010
};

//thanks to BR_ for deobfuscating this method
int map_dirt_color(int x, int y, int z) {
int vertical_slice = (map_size_y-1-y)/8;
int lerp_amt = (map_size_y-1-y)%8;
int dirt_base_color = dirt_color_table[vertical_slice];
int dirt_next_color = dirt_color_table[vertical_slice+1];

int red = lerp(dirt_base_color&0xFF0000,dirt_next_color&0xFF0000,lerp_amt)>>16;
int green = lerp(dirt_base_color&0x00FF00,dirt_next_color&0x00FF00,lerp_amt)>>8;
int blue = lerp(dirt_base_color&0x0000FF,dirt_next_color&0x0000FF,lerp_amt);

int rng = ms_rand()%8;
red += 4*abs((x%8)-4)+rng;
green += 4*abs((z%8)-4)+rng;
blue += 4*abs(((map_size_y-1-y)%8)-4)+rng;

return rgb(red,green,blue);
}

static int gkrand = 0;
int map_placedblock_color(int color) {
color = color | 0x7F000000;
gkrand = 0x1A4E86D*gkrand+1;
return color^(gkrand&0x70707);
}

void map_vxl_load(unsigned char* v, unsigned int* map) {
for(int k=0;k<map_size_x*map_size_z;k++)
pthread_rwlock_wrlock(&chunk_map_locks[k]);
for(int y=0;y<map_size_z;y++) {
for(int x=0;x<map_size_x;x++) {
int z;
for(z=0;z<map_size_y;z++) {
map_vxl_setgeom(x,y,z,0x273F66,map);
map_vxl_setgeom(x,y,z,map_dirt_color(x,map_size_y-1-z,y),map);
}
z = 0;
while(1) {
Expand Down
2 changes: 2 additions & 0 deletions src/map.h
Expand Up @@ -47,5 +47,7 @@ void map_set(int x, int y, int z, unsigned long long color);
int map_cube_line(int x1, int y1, int z1, int x2, int y2, int z2, struct Point* cube_array);
void map_vxl_setgeom(int x, int y, int z, unsigned int t, unsigned int* map);
void map_vxl_setcolor(int x, int y, int z, unsigned int t, unsigned int* map);
int map_dirt_color(int x, int y, int z);
int map_placedblock_color(int color);
void map_vxl_load(unsigned char* v, unsigned int* map);
void map_collapsing_render(float dt);
24 changes: 24 additions & 0 deletions src/stb_truetype.c
@@ -0,0 +1,24 @@
/*
Copyright (c) 2017-2018 ByteBit
This file is part of BetterSpades.
BetterSpades is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
BetterSpades is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with BetterSpades. If not, see <http://www.gnu.org/licenses/>.
*/

#define STB_TRUETYPE_IMPLEMENTATION
#define STBTT_RASTERIZER_VERSION 1

#include "common.h"
#include "stb_truetype.h"

0 comments on commit e844770

Please sign in to comment.