Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support for special characters in gfx.text; added scrolling to the de…
…fault shell; updated sftdlib. There is a known bug with different text size in sftdlib.
- Loading branch information
Reuh
committed
Aug 22, 2015
1 parent
56b4715
commit 2a55134
Showing
10 changed files
with
516 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#ifndef BIN_PACKING_2D_H | ||
#define BIN_PACKING_2D_H | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
typedef struct bp2d_position { | ||
int x, y; | ||
} bp2d_position; | ||
|
||
typedef struct bp2d_size { | ||
int w, h; | ||
} bp2d_size; | ||
|
||
typedef struct bp2d_rectangle { | ||
int x, y, w, h; | ||
} bp2d_rectangle; | ||
|
||
typedef struct bp2d_node { | ||
struct bp2d_node *left; | ||
struct bp2d_node *right; | ||
bp2d_rectangle rect; | ||
int filled; | ||
} bp2d_node; | ||
|
||
bp2d_node *bp2d_create(const bp2d_rectangle *rect); | ||
void bp2d_free(bp2d_node *node); | ||
// 1 success, 0 failure | ||
int bp2d_insert(bp2d_node *node, const bp2d_size *in_size, bp2d_position *out_pos); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#ifndef INT_HTAB_H | ||
#define INT_HTAB_H | ||
|
||
#include <stddef.h> | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
#define INT_HTAB_MAX_LOAD (70) // over 100 | ||
|
||
typedef struct int_htab_entry { | ||
unsigned int key; | ||
void *value; | ||
} int_htab_entry; | ||
|
||
typedef struct int_htab { | ||
size_t size; | ||
size_t used; | ||
int_htab_entry *entries; | ||
} int_htab; | ||
|
||
int_htab *int_htab_create(size_t size); | ||
void int_htab_free(int_htab *htab); | ||
int int_htab_insert(int_htab *htab, unsigned int key, void *value); | ||
void *int_htab_find(const int_htab *htab, unsigned int key); | ||
int int_htab_erase(const int_htab *htab, unsigned int key); | ||
|
||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#ifndef TEXTURE_ATLAS_H | ||
#define TEXTURE_ATLAS_H | ||
|
||
#include "sf2d.h" | ||
#include "bin_packing_2d.h" | ||
#include "int_htab.h" | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
typedef struct atlas_htab_entry { | ||
bp2d_rectangle rect; | ||
int bitmap_left; | ||
int bitmap_top; | ||
int advance_x; | ||
int advance_y; | ||
} atlas_htab_entry; | ||
|
||
typedef struct texture_atlas { | ||
sf2d_texture *tex; | ||
bp2d_node *bp_root; | ||
int_htab *htab; | ||
} texture_atlas; | ||
|
||
texture_atlas *texture_atlas_create(int width, int height, sf2d_texfmt format, sf2d_place place); | ||
void texture_atlas_free(texture_atlas *atlas); | ||
int texture_atlas_insert(texture_atlas *atlas, unsigned int character, const void *image, int width, int height, int bitmap_left, int bitmap_top, int advance_x, int advance_y); | ||
int texture_atlas_exists(texture_atlas *atlas, unsigned int character); | ||
void texture_atlas_get(texture_atlas *atlas, unsigned int character, bp2d_rectangle *rect, int *bitmap_left, int *bitmap_top, int *advance_x, int *advance_y); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
#include <stdlib.h> | ||
#include "bin_packing_2d.h" | ||
|
||
bp2d_node *bp2d_create(const bp2d_rectangle *rect) | ||
{ | ||
bp2d_node *node = malloc(sizeof(*node)); | ||
if (!node) | ||
return NULL; | ||
|
||
node->left = NULL; | ||
node->right = NULL; | ||
node->rect.x = rect->x; | ||
node->rect.y = rect->y; | ||
node->rect.w = rect->w; | ||
node->rect.h = rect->h; | ||
node->filled = 0; | ||
|
||
return node; | ||
} | ||
|
||
void bp2d_free(bp2d_node *node) | ||
{ | ||
if (node->left) { | ||
bp2d_free(node->left); | ||
} | ||
if (node->right) { | ||
bp2d_free(node->right); | ||
} | ||
free(node); | ||
} | ||
|
||
int bp2d_insert(bp2d_node *node, const bp2d_size *in_size, bp2d_position *out_pos) | ||
{ | ||
if (node->left != NULL || node->right != NULL) { | ||
int ret = bp2d_insert(node->left, in_size, out_pos); | ||
if (ret == 0) { | ||
return bp2d_insert(node->right, in_size, out_pos); | ||
} | ||
return ret; | ||
} else { | ||
if (node->filled) | ||
return 0; | ||
|
||
if (in_size->w > node->rect.w || in_size->h > node->rect.h) | ||
return 0; | ||
|
||
if (in_size->w == node->rect.w && in_size->h == node->rect.h) { | ||
out_pos->x = node->rect.x; | ||
out_pos->y = node->rect.y; | ||
node->filled = 1; | ||
return 1; | ||
} | ||
|
||
int dw = node->rect.w - in_size->w; | ||
int dh = node->rect.h - in_size->h; | ||
|
||
bp2d_rectangle left_rect, right_rect; | ||
|
||
if (dw > dh) { | ||
left_rect.x = node->rect.x; | ||
left_rect.y = node->rect.y; | ||
left_rect.w = in_size->w; | ||
left_rect.h = node->rect.h; | ||
|
||
right_rect.x = node->rect.x + in_size->w; | ||
right_rect.y = node->rect.y; | ||
right_rect.w = node->rect.w - in_size->w; | ||
right_rect.h = node->rect.h; | ||
} else { | ||
left_rect.x = node->rect.x; | ||
left_rect.y = node->rect.y; | ||
left_rect.w = node->rect.w; | ||
left_rect.h = in_size->h; | ||
|
||
right_rect.x = node->rect.x; | ||
right_rect.y = node->rect.y + in_size->h; | ||
right_rect.w = node->rect.w; | ||
right_rect.h = node->rect.h - in_size->h; | ||
} | ||
|
||
node->left = bp2d_create(&left_rect); | ||
node->right = bp2d_create(&right_rect); | ||
|
||
return bp2d_insert(node->left, in_size, out_pos); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include "int_htab.h" | ||
|
||
static inline unsigned int FNV_1a(unsigned int key) | ||
{ | ||
unsigned char *bytes = (unsigned char *)&key; | ||
unsigned int hash = 2166136261U; | ||
hash = (16777619U * hash) ^ bytes[0]; | ||
hash = (16777619U * hash) ^ bytes[1]; | ||
hash = (16777619U * hash) ^ bytes[2]; | ||
hash = (16777619U * hash) ^ bytes[3]; | ||
return hash; | ||
} | ||
|
||
int_htab *int_htab_create(size_t size) | ||
{ | ||
int_htab *htab = malloc(sizeof(*htab)); | ||
if (!htab) | ||
return NULL; | ||
|
||
htab->size = size; | ||
htab->used = 0; | ||
|
||
htab->entries = malloc(htab->size * sizeof(*htab->entries)); | ||
memset(htab->entries, 0, htab->size * sizeof(*htab->entries)); | ||
|
||
return htab; | ||
} | ||
|
||
void int_htab_free(int_htab *htab) | ||
{ | ||
int i; | ||
for (i = 0; i < htab->size; i++) { | ||
if (htab->entries[i].value != NULL) | ||
free(htab->entries[i].value); | ||
} | ||
free(htab); | ||
} | ||
|
||
void int_htab_resize(int_htab *htab, unsigned int new_size) | ||
{ | ||
int i; | ||
int_htab_entry *old_entries; | ||
unsigned int old_size; | ||
|
||
old_entries = htab->entries; | ||
old_size = htab->size; | ||
|
||
htab->size = new_size; | ||
htab->used = 0; | ||
htab->entries = malloc(new_size * sizeof(*htab->entries)); | ||
memset(htab->entries, 0, new_size * sizeof(*htab->entries)); | ||
|
||
for (i = 0; i < old_size; i++) { | ||
if (old_entries[i].value != NULL) { | ||
int_htab_insert(htab, old_entries[i].key, old_entries[i].value); | ||
} | ||
} | ||
|
||
free(old_entries); | ||
} | ||
|
||
int int_htab_insert(int_htab *htab, unsigned int key, void *value) | ||
{ | ||
if (value == NULL) | ||
return 0; | ||
|
||
/* Calculate the current load factor */ | ||
if (((htab->used + 1)*100)/htab->size > INT_HTAB_MAX_LOAD) { | ||
int_htab_resize(htab, 2*htab->size); | ||
} | ||
|
||
unsigned int mask = htab->size - 1; | ||
unsigned int idx = FNV_1a(key) & mask; | ||
|
||
/* Open addressing, linear probing */ | ||
while (htab->entries[idx].value != NULL) { | ||
idx = (idx + 1) & mask; | ||
} | ||
|
||
htab->entries[idx].key = key; | ||
htab->entries[idx].value = value; | ||
htab->used++; | ||
|
||
return 1; | ||
} | ||
|
||
void *int_htab_find(const int_htab *htab, unsigned int key) | ||
{ | ||
unsigned int mask = htab->size - 1; | ||
unsigned int idx = FNV_1a(key) & mask; | ||
|
||
/* Open addressing, linear probing */ | ||
while (htab->entries[idx].key != key && htab->entries[idx].value != NULL) { | ||
idx = (idx + 1) & mask; | ||
} | ||
|
||
/* Found the key */ | ||
if (htab->entries[idx].key == key) { | ||
return htab->entries[idx].value; | ||
} | ||
|
||
return NULL; | ||
} | ||
|
||
int int_htab_erase(const int_htab *htab, unsigned int key) | ||
{ | ||
unsigned int mask = htab->size - 1; | ||
unsigned int idx = FNV_1a(key) & mask; | ||
|
||
/* Open addressing, linear probing */ | ||
while (htab->entries[idx].key != key && htab->entries[idx].value != NULL) { | ||
idx = (idx + 1) & mask; | ||
} | ||
|
||
/* Found the key */ | ||
if (htab->entries[idx].key == key) { | ||
htab->entries[idx].value = NULL; | ||
return 1; | ||
} | ||
|
||
return 0; | ||
} |
Oops, something went wrong.