Abyss2D Graphics …quick preview.

May 27th, 2010 Rashaud Teague No comments

Maris Labs has been working on a graphics engine/framework/library called “Abyss2D”. Abyss2D sits on top of the Simple DirectMedia Layer and it is geared towards small graphic computing trying its best to leave a small footprint on the device it is running on. Abyss2D is being built with C++, with more C style coding in terms of memory management and file i/o… just personal preference.

Right now Abyss2D is in super beta/alpha I should not even be showing you screen shots below of what I’ve done with it in a test space shooter game that uses the basic features of Abyss2D. First I will state some of the features!

  • Interfacing with SDL made easy!
  • Sprite module, to easily blit images to the screen.
  • Sound module, queuing/playing sound affects and music with ease.
  • Portability between Linux (Ubuntu), Windows and Mac OS but sorry Linux first.
  • Safe memory management, you can load objects into the program and we’ll take care of destroying them when no longer needing them.
  • Font module for rendering text to the screen.
  • Animation, create cool animations of an object on the screen.
  • Networking TCP/IP.
  • Frame rate regulation.
  • Much more …

Now here are the screen shots of “Abyss – Spacewars”, a game I created to test some of the features listed above.

Hero [Red colored] Ship fighting their way through “Badies”:

Hero [Red colored] Ship fighting their way through

Game Over:

Game Over

I will try to get more done before the summer ends!

-Rashaud

String Splitting Revisited Part II

May 13th, 2010 Rashaud Teague No comments

In the last part there was a demo of how to split a string by a delimiter, but the delimiter could only be a single character string (i.e. “,”). Now, what if you came across data that was separated by a delimiter that looks to have more than one character (i.e. two dashes “–”)? I guess that means we have to change our function then.

Here is the new function, it is very similar to part one’s function.

char ** split(char *delimiter, char *str) {
    char **elements = (char **) calloc(1, sizeof(char));
    char **_elements = NULL;
   
    /*
     * x to track strpos offset in *str and e for element tick and current delimiter position, i for var
     * start for the start of the substr and stop for the end
     */

    int x = 0, e = 0, d = 0, next_d = -1, start, stop;
    int str_size = (int) strlen(str), delimiter_size = (int) strlen(delimiter);
    while ((d = strpos(delimiter, str, x)) != -1) {
       
        if ((next_d = strpos(delimiter, str, x + 1)) == -1) next_d = str_size;
       
        if (x == 0 && strcmp(substr(str, 0, delimiter_size), delimiter) != 0 && e == 0) {
            /* lets not skip the first group */
            next_d = d, d = 0, start = d, stop = next_d;
        } else if (x == 0 && strcmp(substr(str, 0, delimiter_size), delimiter) == 0 && e == 0) {
            /* this runs if the delimiter is the first character in the search */
            next_d = delimiter_size, start = 0, stop = 0;
        } else {
            /* increment d so that we can start from the proper pos in substr */
            x++, start = d + delimiter_size, stop = (next_d - (d + delimiter_size));
        }
       
        elements[e] = (char *) calloc(next_d - d, sizeof(char));
       
        strcpy(elements[e], substr(str, start, stop));
       
        _elements = realloc(elements, (e + 2) * sizeof(char *));
        elements = _elements;
   
        e++;
    }
   
    return elements;
}

And the example uses:

/********************************************************************
 * Name: test.c
 * Author: rashaud
 * Date: 05/05/2010
 * License: GNU GPL <http://www.gnu.org/licenses/>
 * Description: <description>
 ********************************************************************/


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <xstdlib.h>

int main(void) {
    system("clear");
   
    char *text = "This,is,split,by,a,comma,delimiter!";
    char **s = split(",", text);
    printf("%s %s\n", s[0], s[1]);
   
    printf("\n");
   
    char *text1 = "This--is--split--by--a--two-dash--delimiter!";
    char **t = split("--", text1);
    printf("%s %s\n", s[0], s[1]);
   
    return 0;
}

This has now been added (or re-added) to the eXtended C Standard Library. You would have to get it the most up-to-date code from the SVN repo

Enjoy,
Rashaud

Up next is… “Now we that we split the string, let us rejoin it!”

Categories: C/C++ Tags:

String Splitting Revisited Part I

May 13th, 2010 Rashaud Teague No comments

Here in part one I will go through a way to split a string by a delimiter. This delimiter is a string with a single character.

Headers:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <xstdlib.h>

Prototype:

char ** split(char *delimiter, char *str);

Function code:

char ** split(char *delimiter, char *str) {
    char **elements = (char **) calloc(1, sizeof(char));
    char **_elements = NULL;
   
    /*
     * x to track strpos offset in *str and e for element tick and current delimiter position, i for var
     * start for the start of the substr and stop for the end
     */

    int x = 0, e = 0, d = 0, next_d = -1, start, stop, str_size = (int) strlen(str);
    while ((d = strpos(delimiter, str, x)) != -1) {
       
        if ((next_d = strpos(delimiter, str, x + 1)) == -1) next_d = str_size;
       
        if (x == 0 && str[0] != str[d] && e == 0) {
            /* lets not skip the first group */
            next_d = d, d = 0, start = d, stop = next_d;
        } else if (x == 0 && str[0] == str[d] && e == 0) {
            /* this runs if the delimiter is the first character in the search */
            next_d = 1, start = 0, stop = 0;
        } else {
            /* increment d so that we can start from the proper pos in substr */
            x++, start = d + 1, stop = (next_d - d) - 1;
        }
       
        elements[e] = (char *) calloc(next_d - d, sizeof(char));
       
        strcpy(elements[e], substr(str, start, stop));
       
        /* debugging information */
        //printf("%s\n", elements[e]);
       
        _elements = realloc(elements, (e + 2) * sizeof(char *));
        elements = _elements;
       
        e++;
    }
   
    return elements;
}

Example use:

int main(void) {
    system("clear");
   
    char *text = "This,is,split,by,a,comma,delimiter!";
    char **s = split(",", text);
   
    return 0;
}

From that example you would just have to loop through char **s and print your results. In part 2 I will show you how to split a string using a delimiter that has more than one character. The code is a bit different but it will make the function above more powerful.

Enjoy,
Rashaud

Categories: C/C++ Tags:

Number Formatting in C

May 11th, 2010 Rashaud Teague No comments

I was in a need to format numbers in human readable presentation one day, so I spent a while on coming with a way to make a function for number formatting in the C Programming Language. I’ve based it off PHP’s number_format.

Here is my prototype:

char * number_format(long double n, int decimals, char *dec_point, char *thousands_sep);

For use of the parameter “n”, must be a long double, the number of decimals can be 0 or n (n = number of decimal places), dec_point can be set to NULL or a string decimal point identifier (i.e. “.”) and thousands_sep can be an empty string “” or a thousandths place identifier “,”. All depends on what notation you use for example the French decimal presentation looks different from a United States presentation reference.

Now here is the code I wrote for the function prototype:

char * number_format(long double n, int decimals, char *dec_point, char *thousands_sep) {
    /* declare/initialize a place holder text */
    char *text = (char *) calloc(256, sizeof(char));
    if (text == NULL) return NULL;
   
    if (decimals > 0) {
        sprintf(text, "%.10Lf", n);
    } else {
        sprintf(text, "%ld", (long int)n);
    }
   
    /*
     * find the "." decimcal placement position
     * from there its the string length
     */

    int dot = strpos(".", text, 0);
    /* check to see if its even there */
    if (dot == -1) { dot = strlen(text); }
   
    int num_thousands = 0;
   
    if (thousands_sep != NULL && strcmp(thousands_sep, "") != 0) {
        if (dot > 3) {
            /* get the number of thousands seperators */
            if (!(n < 0 && dot < 5)) num_thousands = (thousands_sep != NULL) ? ((int)ceil(((float)dot / 3))) - 1 : 0;
            if (n < 0 && dot > 5 && (int)strlen(substr(text, 1, dot)) % 3 == 0) num_thousands--;
        }
    }
   
    /* start new string */
    int new_s_size = dot + num_thousands;
    char *new_s = (char *) calloc(new_s_size + 1, sizeof(char));
   
    int i, c, k;
    for (i = new_s_size - 1, c = 0, k = dot - 1; i >= 0; i--) {
        if (c == 3 && num_thousands > 0) {
            /* add the thousands seperator if is set */
            new_s[i] = *(thousands_sep);
            num_thousands--;
            c = 0;
        } else {
            new_s[i] = text[k];
            k--, c++;
        }
    }
   
    /* now add on the decimal points */
    if (decimals > 0) {
        char *decimals_s = substr(text, dot + 1, decimals);
       
        if (dec_point != NULL) {
            strcat(new_s, dec_point);
        } else {
            strcat(new_s, " ");
        }
       
        strcat(new_s, decimals_s);
    }
   
    free(text);
   
    return new_s;
}

NOTE: You see functions used in that code such as substr() and strpos() which are apart of Maris Labs’ “mess around” eXtended C Standard Library “xstdlib”.

Here is the full code in test:

/********************************************************************
 * Name: test.c
 * Author: rashaud
 * Date: 05/05/2010
 * License: GNU GPL <http://www.gnu.org/licenses/>
 * Description: <description>
 ********************************************************************/


#include <stdio.h>
#include <string.h>
#include <math.h>
#include <xstdlib.h>

char * number_format(long double n, int decimals, char *dec_point, char *thousands_sep) {
    /* declare/initialize a place holder text */
    char *text = (char *) calloc(256, sizeof(char));
    if (text == NULL) return NULL;
   
    if (decimals > 0) {
        sprintf(text, "%.10Lf", n);
    } else {
        sprintf(text, "%ld", (long int)n);
    }
   
    /*
     * find the "." decimcal placement position
     * from there its the string length
     */

    int dot = strpos(".", text, 0);
    /* check to see if its even there */
    if (dot == -1) { dot = strlen(text); }
   
    int num_thousands = 0;
   
    if (thousands_sep != NULL && strcmp(thousands_sep, "") != 0) {
        if (dot > 3) {
            /* get the number of thousands seperators */
            if (!(n < 0 && dot < 5)) num_thousands = (thousands_sep != NULL) ? ((int)ceil(((float)dot / 3))) - 1 : 0;
            if (n < 0 && dot > 5 && (int)strlen(substr(text, 1, dot)) % 3 == 0) num_thousands--;
        }
    }
   
    /* start new string */
    int new_s_size = dot + num_thousands;
    char *new_s = (char *) calloc(new_s_size + 1, sizeof(char));
   
    int i, c, k;
    for (i = new_s_size - 1, c = 0, k = dot - 1; i >= 0; i--) {
        if (c == 3 && num_thousands > 0) {
            /* add the thousands seperator if is set */
            new_s[i] = *(thousands_sep);
            num_thousands--;
            c = 0;
        } else {
            new_s[i] = text[k];
            k--, c++;
        }
    }
   
    /* now add on the decimal points */
    if (decimals > 0) {
        char *decimals_s = substr(text, dot + 1, decimals);
       
        if (dec_point != NULL) {
            strcat(new_s, dec_point);
        } else {
            strcat(new_s, " ");
        }
       
        strcat(new_s, decimals_s);
    }
   
    free(text);
   
    return new_s;
}

int main(void) {
   
    printf("%s\n", number_format(-5.1223, 0, NULL, ","));
    printf("%s\n", number_format(-50.1223, 0, NULL, ","));
    printf("%s\n", number_format(-500.1223, 0, NULL, ","));
    printf("%s\n", number_format(-5000.1223, 0, NULL, ","));
    printf("%s\n", number_format(-50000.1223, 0, NULL, ","));
    printf("%s\n", number_format(-500000.1223, 0, NULL, ","));
    printf("%s\n", number_format(-5000000.1223, 0, NULL, ","));
    printf("%s\n", number_format(-50000000.1223, 0, NULL, ","));
    printf("%s\n", number_format(-500000000.1223, 0, NULL, ","));
    printf("%s\n", number_format(-5000000000.1223, 0, NULL, ","));
    printf("%s\n", number_format(-50000000000.1223, 0, NULL, ","));
    printf("%s\n", number_format(-500000000000.1223, 0, NULL, ","));
    printf("%s\n", number_format(-5000000000000.1223, 0, NULL, ","));
    printf("%s\n", number_format(-50000000000000.1223, 0, NULL, ","));
    printf("%s\n", number_format(-500000000000000.1223, 0, NULL, ","));
    printf("%s\n", number_format(-5000000000000000.1223, 0, NULL, ","));
    printf("%s\n", number_format(-50000000000000000.1223, 0, NULL, ","));
    printf("%s\n", number_format(-500000000000000000.1223, 0, NULL, ","));
    printf("%s\n", number_format(-5000000000000000000.1223, 0, NULL, ","));
   
    printf("%s\n", number_format(5000000000000000000.1223, 0, NULL, ","));
    printf("%s\n", number_format(500000000000000000.1223, 0, NULL, ","));
    printf("%s\n", number_format(50000000000000000.1223, 0, NULL, ","));
    printf("%s\n", number_format(5000000000000000.1223, 0, NULL, ","));
    printf("%s\n", number_format(500000000000000.1223, 0, NULL, ","));
    printf("%s\n", number_format(50000000000000.1223, 0, NULL, ","));
    printf("%s\n", number_format(5000000000000.1223, 0, NULL, ","));
    printf("%s\n", number_format(500000000000.1223, 0, NULL, ","));
    printf("%s\n", number_format(50000000000.1223, 0, NULL, ","));
    printf("%s\n", number_format(5000000000.1223, 0, NULL, ","));
    printf("%s\n", number_format(500000000.1223, 0, NULL, ","));
    printf("%s\n", number_format(50000000.1223, 0, NULL, ","));
    printf("%s\n", number_format(5000000.1223, 0, NULL, ","));
    printf("%s\n", number_format(500000.1223, 0, NULL, ","));
    printf("%s\n", number_format(50000.1223, 0, NULL, ","));
    printf("%s\n", number_format(5000.1223, 0, NULL, ","));
    printf("%s\n", number_format(500.1223, 0, NULL, ","));
    printf("%s\n", number_format(50.1223, 0, NULL, ","));
    printf("%s\n", number_format(5.1223, 0, NULL, ","));
   
    /* different tests */
    printf("\n\n%s\n", number_format(5000.1223, 4, ".", ","));
    printf("\n\n%s\n", number_format(5000.1223, 2, ".", ","));
    printf("\n\n%s\n", number_format(5000.1223, 4, NULL, ","));
    printf("\n\n%s\n", number_format(5000.1223, 2, ",", " "));
   
    return 0;
}

This is just a simple way to show thousandths place when printing a number to the screen. The bottom half of the full code snippet are tests with the number format function. This example is intended for a beginner trying to figure this out.

Enjoy,
-Rashaud

Next up: char ** split(const char *delimeter, const char *str); and char * join(const char *delimiter, const char **e); Revisited

Categories: C/C++ Tags:

Converting integers to strings in C

February 13th, 2010 Rashaud Teague No comments

I found a simple way to convert integers into strings the safe and easy way. I used the power of the C Standard Library to help me out (calloc, malloc, memcpy, sprintf).

Here is the source:

/********************************************************************
 * Name: inttostr.c
 * Author: Rashaud Teague
 * Date: 02/13/2010
 * License: GNU LGPL <http://www.gnu.org/licenses/>
 * Description: <description>
 ********************************************************************/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char * itoa(int i) {
    /* declare/initialize a place holder text */
    char *text = (char *) calloc(256, sizeof(char));
    if (text == NULL) return NULL;
   
    /* declare a return text */
    void *rtext;
   
    /* use sprintf to format the integer into a string */
    sprintf(text, "%d", i);
   
    /*
     * allocate the correct size for the return text (rtext)
     * then copy the block of memory from text to rtext
     * and free text
     */

    if ((rtext = malloc(strlen(text))) == NULL) return NULL;
    memcpy(rtext, (void *)text, strlen(text));
    free(text);
   
    return (char *)rtext;
}

int main(void) {
   
    char *str = itoa(2010);
   
    printf("My string integer: %s\n", str);
   
    return 0;
}

Have fun,
Rashaud

Categories: C/C++ Tags: ,

Basic Data Trees

August 16th, 2009 Rashaud Teague No comments

Displaying data in data trees showing parent/child relationships can be important to your application for when users are looking for data. You have been seeing this all along, since you have been using computers with file browsing in directory trees showing a directory(which in fact is a file) and all of its children in one big tree starting with a the ‘/’ root path.

Here I will be showing you (most likely a beginner programmer) how to display data from a database (MySQL) using PHP.

In the this example I’m using the data from Maris SimpleDocu, a “simple” documentation system which in fact has document pages that have parent/child relationships we want to be displayed in a large tree (that depends on how many pages are in the database).

You can download the source files here!

Lets take a look at the `pages` table schema:

CREATE TABLE IF NOT EXISTS `pages` (
  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `title` varchar(50) NOT NULL DEFAULT '',
  `content` text NOT NULL DEFAULT '',
  `post_date` int(10) UNSIGNED NOT NULL DEFAULT '0',
  `last_update` int(10) UNSIGNED NOT NULL DEFAULT '0',
  `parent` int(10) UNSIGNED NOT NULL DEFAULT '0',
  `last_ip` varchar(100) NOT NULL DEFAULT '',
  `p_order` int(5) UNSIGNED NOT NULL DEFAULT '0',
  `hidden` tinyint(1) UNSIGNED NOT NULL DEFAULT '0',
  `views` int(10) UNSIGNED NOT NULL DEFAULT '0',
  `locked` tinyint(1) UNSIGNED NOT NULL DEFAULT '0',
  UNIQUE KEY `id` (`id`),
  KEY `parent` (`parent`)
) ENGINE=MyISAM;

The key table fields you want to pay attention to are `id` `parent` and `p_order` (page order on that parent level).

I created this file and code in the SimpleDocu source for testing, called “test.php” here is the code:

<?php

include 'common.php';

$result = array();
$level = 1;
function tree(&$res, &$lvl, $pid = 0) {
    global $pc;
    $sql = "SELECT id, title, parent, p_order FROM pages WHERE parent = '$pid' ORDER BY p_order";
    $res[] = mysql_query($sql) or die(mysql_error());
   
    $i = sizeof($res)-1;
    while ($row = mysql_fetch_array($res[$i])) {
        if ($pc->has_children($row['title'])) {
            print str_repeat('-', $lvl).$row['title']. '<br />';
            $lvl++;
            tree($res, $lvl, $row['id']);
        } else {
            print str_repeat('-', $lvl).$row['title']. '<br />';
        }
    }
    $lvl = 1;
}

tree($result, $level);

?>

The Run Down:
I included the file called “common.php” because it holds most of the common small functions, variables and constants, but most importantly the database connection.

Next you’ll see I’ve declared a variable $result with an array type to hold multiple data resources and then $level integer so we can trace what level we are in the tree.

include 'common.php';

$result = array();
$level = 1;

Now we begin making our function: function tree(&$res, &$lvl, $pid = 0) … the arguments &$res and &$lvl take in variables passed by reference and work with the $result and $level variables. $pid is the variable used to get the last parent ID, you will see it used for when the tree function is used in recursion.

First section of tree():

global $pc;
$sql = "SELECT id, title, parent, p_order FROM pages WHERE parent = '$pid' ORDER BY p_order";
$res[] = mysql_query($sql) or die(mysql_error());

The global $pc variable that instantiates a class called Pages and we use one of its methods called has_children($title) to determine if the current page in the loop has any children.

Second section of tree():

$i = sizeof($res)-1;
while ($row = mysql_fetch_array($res[$i])) {
    if ($pc->has_children($row['title'])) {
        print str_repeat('-', $lvl).$row['title']. '<br />';
        $lvl++;
        tree($res, $lvl, $row['id']);
    } else {
        print str_repeat('-', $lvl).$row['title']. '<br />';
    }
}

The variable $i get the last element in the $res array which holds the last database resource id in that script. Then we start the while loop notice that mysql_fetch_array($res[$i]) does that instead of just mysql_fetch_array($res). In the loop we first determine if the current page has any children with $pc->has_children($row['title']), if so we print the title then we call the tree() function from within (recursion) else just print the title and move on to the next section of the function.

Last section of tree():
We just set $lvl = 1;

Now we can call the tree function to see our results:

tree($result, $level);

And here is my ouput: (NOTE: Output will vary because we all may not have the same pages created!)
-Introduction
–Test Child
–More
—And More
—-Wait there is more!!
-Chapt Two
–Section 1
-RSURL Test
-Another Test

Notice the dashes to mark how deep each page is for each level.

And thats all!

———————-[ EDITED 2009-08-22 ]——————–

Because of me not thinking of “scale” and people posting the comments below …Here is a more efficient way of doing this with using one query against the database!

<?php

include 'common.php';

class Tree {
    public $lvl = 1;
    public $nodes = array();
   
    public function __construct() {
        $this->fill_nodes();
    }
   
    public function fill_nodes() {
        $sql = "SELECT id, title, parent, p_order FROM pages ORDER BY p_order";
        $result = mysql_query($sql) or die(mysql_error());
        while ($row = mysql_fetch_array($result)) {
            $vals = array();
            $vals['id'] = $row['id'];
            $vals['title'] = $row['title'];
            $vals['parent'] = $row['parent'];
            $vals['p_order'] = $row['p_order'];
            $this->nodes[] = $vals;
        }
    }
   
    public function has_children($id) {
        foreach ($this->nodes as $row)
            if ($row['parent'] == $id) return true;
        return false;
    }
   
    public function tree($pid = 0) {
        foreach ($this->nodes as $row) {
            if ($row['parent'] == $pid) {
                if ($this->has_children($row['id'])) {
                    print str_repeat('-', $this->lvl).$row['title']. '<br />';
                    $this->lvl++;
                    $this->tree($row['id']);
                } else {
                    print str_repeat('-', $this->lvl).$row['title']. '<br />';
                }
            }
        }
        $this->lvl = 1;
    }
}

$tree = new Tree();
$tree->tree();

?>
Categories: PHP Tags:

Finally

July 21st, 2009 Rashaud Teague No comments

Finally got my personal blog set up.

Categories: Uncategorized Tags: