Navigation Menu

Skip to content

Commit

Permalink
Support for special characters in gfx.text; added scrolling to the de…
Browse files Browse the repository at this point in the history
…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
Show file tree
Hide file tree
Showing 10 changed files with 516 additions and 39 deletions.
36 changes: 36 additions & 0 deletions libs/sftdlib/libsftd/include/bin_packing_2d.h
@@ -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
34 changes: 34 additions & 0 deletions libs/sftdlib/libsftd/include/int_htab.h
@@ -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
36 changes: 36 additions & 0 deletions libs/sftdlib/libsftd/include/texture_atlas.h
@@ -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
86 changes: 86 additions & 0 deletions libs/sftdlib/libsftd/source/bin_packing_2d.c
@@ -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);
}
}
124 changes: 124 additions & 0 deletions libs/sftdlib/libsftd/source/int_htab.c
@@ -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;
}

0 comments on commit 2a55134

Please sign in to comment.