Jump to content

  • Log In with Google      Sign In   
  • Create Account


Lith

Member Since 19 Oct 2009
Offline Last Active Yesterday, 04:35 PM
-----

#5162393 Should I break_the_build?

Posted by Lith on 23 June 2014 - 01:53 PM

I'm going to preface this topic with the fact that I've only every worked alone on projects.

 

In the project I'm working on, I have got to a stage where I've finally decided to refactor one of the systems that a lot of the total code depends on. Refactoring this would probably mean refactoring a lot of other code afterwards. Now I realise that I've got to this scenario through a horrible combination of bad design choices and lack of forethought, but my question is what to do when I find myself in this situation.

 

Because I'm working alone on this project, it doesn't really matter if I just make a new branch, completely refactor the system and then all of the other code afterwards. This could mean that the project won't actually build for days. Again, not too much of a problem considering that I'm working by my self.

 

What would be your advice if I encounter this when I'm working with a team of programmers? Assuming that the refactoring work HAS to be done, how can I approach this problem so that I cause minimum disruption to the other programmers?

 

Thanks for your time.




#5160569 Int Size, Endianness and Serialisation

Posted by Lith on 14 June 2014 - 06:39 PM

Thanks for your speedy reply Samith, lots of good info.

Typically, when you need to deal with unknown endianness you would write a byte order marking at the top of the file, which when read back by another machine can indicate if the content of the file needs to be endian swapped. A common byte order marking is the 16 bit integer 0xfeff. If you read a byte order mark from a file and it comes out as 0xfffe, then you have to reverse the endianness of the contents of that file. If it gets read in as 0xfeff, then you won't need to perform any endian swapping.

This in particular was very enlightening. I'll use a byte order marking to check weather to swap all other numbers read.

 

You don't need to worry about endian-ness unless you are switching machine families or using Java.

It's nice to know that pretty much all conventional PCs use little endain. But I did a bit of searching and found that vc++ has some built in functions for swapping byte order (I think they're quite well optimised as well). With all this info I found that it really wasn't much effort to support big and little endian (unless I've overlooked something) even if it's not likely to be necessary. Good practice I guess.

 

This is what I managed to come up with so far:

It still needs to be cleaned up, but I think I've not overlooked anything important (other than a load function..)

bool save_as_image( std::string argFilename, std::vector<ggCell>& argCells )
{
    // saves a vector of cells as an image.

    // could pack more into each pixel but it's not necessary

    // calculate the image size needed
    unsigned int dimWidth = 128;
    unsigned int hlpBytesNeeded = GG_BYTES_PER_CELL*argCells.size();
    unsigned int dimHeight = 17 + (hlpBytesNeeded/4)/128;
    out("height is " + uint_to_string(dimHeight));

    // load template header
    sf::Image imgHeader;
    if ( !imgHeader.loadFromFile("data/pattern_header.png") ) {
        return false;
    }

    // create new image with header
    sf::Image imgPattern;
    imgPattern.create( dimWidth, dimHeight, sf::Color(0,0,0));
    imgPattern.copy( imgHeader, 0, 0 );

    // write all pixels
    unsigned int x = 0;
    unsigned int y = 16;
    for ( unsigned int index=0; index<argCells.size(); ++index ) {
        // gen colours
        sf::Color colX, colY, colType;
        colX = int_to_pixel( argCells[index].x );
        colY = int_to_pixel( argCells[index].y );
        colType = int_to_pixel( argCells[index].type );
        // write to image
        imgPattern.setPixel( x, y, colX );
        increment(x,y);
        imgPattern.setPixel( x, y, colY );
        increment(x,y);
        imgPattern.setPixel( x, y, colType );
        increment(x,y);
        // output colours used
        out("[" + std::to_string(index) + "] ");
        out("X: ( " + std::to_string(colX.r) + ", " + std::to_string(colX.g) + ", " + std::to_string(colX.b) + ", " + std::to_string(colX.a) + " )\n");
        out("[" + std::to_string(index) + "] ");
        out("X: ( " + std::to_string(colY.r) + ", " + std::to_string(colY.g) + ", " + std::to_string(colY.b) + ", " + std::to_string(colY.a) + " )\n");
        out("[" + std::to_string(index) + "] ");
        out("X: ( " + std::to_string(colType.r) + ", " + std::to_string(colType.g) + ", " + std::to_string(colType.b) + ", " + std::to_string(colType.a) + " )\n");
    }

    // save image
    imgPattern.saveToFile( argFilename );
    return true;

}

sf::Color int_to_pixel( int number ) {
    // code number to look better as an image
    number += GG_INT_CODE;
    // convert to pixel
    int r_single = number & 0xff000000;
    int g_single = number & 0x00ff0000;
    int b_single = number & 0x0000ff00;
    int a_single = number & 0x000000ff;
    int r = r_single >> 24;
    int g = g_single >> 16;
    int b = b_single >> 8;
    int a = a_single;
    sf::Color colour((unsigned char)r,(unsigned char)g,(unsigned char)b,(unsigned char)a);
    return colour;
}

int pixel_to_int( sf::Color colour, bool swap ) {
    int r = (int) colour.r;
    int g = (int) colour.g;
    int b = (int) colour.b;
    int a = (int) colour.a;
    int number = r << 24;
    number = number | g << 16;
    number = number | b << 8;
    number = number | a;
    if ( swap ) {
        number = (int)_byteswap_ulong( number );
    }
    // decode
    number -= GG_INT_CODE;
    return number;
}

void increment( unsigned int& x, unsigned int& y ) {
    ++x;
    if ( x >= 128 ) {
        x = 0;
        ++y;
    }
}



#5157878 Javascript #include implemented in Python

Posted by Lith on 03 June 2014 - 11:27 AM

So I was learning and messing around with javascript and html5 canvas when I found out that javascript has no include or import.

you either have to include extra files through the html or do some funky asynchronous loading or get Jquery to do it for you.

 

So a few hours later I produce this:

# compile.py

# command line utility that takes a javascript file (any text file really)
# as input, goes though it and replaces #include with
# the appropriate js files. Also minimises the resulting 
# large file and saves it.

# minimising and saving not yet implemented

# usage: compile.py file.js

# options:
# -m  minimised the resulting file.
# -o specify output filename
# NOTE - none of these implemented yet

import sys
import argparse

# handle arguments
parser = argparse.ArgumentParser( description="update this later pls" )
parser.add_argument( "filename" )
parser.add_argument( "-m", "--minimise", help="minimises the resultant file", action="store_true" )
parser.add_argument( "-o", "--output", help="filename of the resultant file" )
args = parser.parse_args()

# set options
optInputfile = args.filename
optMinimise = True if args.minimise else False
optOutputfile = args.output if args.output else "COMPILED_" + optInputfile

# extracts the next filename in double or single quotes from a position
def extract_filename ( string, position ):
    curPos = position
    curString = ""
    done = False
    inName = False
    while not done:
        if not inName:
            if string[curPos] == '"' or string[curPos] == "'":
                inName = True
        else:
            if string[curPos] != '"' and string[curPos] != "'":
                curString += string[curPos]
            else:
                done = True
        curPos += 1
        if curPos-position >= 40:
            # probably a missing " or '
            print( "COMPILE ERROR: #include filename too long. You've probably missed a ' or \"" )
            break
    return curString

# replaces everything with spaces in 'string' from 'position' until 2 ' or " are found
def replace_include_line ( string, position ):
    curPos = position
    done = False
    quoteCount = 0
    curLen = 0
    while not done:
        curLen += 1
        if string[curPos] == '"' or string[curPos] == "'":
            quoteCount += 1
        if quoteCount >= 2:
            done = True
        curPos += 1
    newString = string[:position-1] + string[position+curLen:]
    return newString

# inserts string 'b' into string 'a' at position 'pos'
def string_insert ( a, b, pos ):
    return a[:pos] + b + a[pos:]

# recursive file parsing function
def parse_file ( filename ):
    file = open( filename, 'r' )
    fileStr = file.read()
    count = 0
    pos = 0
    while True:
        # find the next include
        pos = fileStr.find( "#include", pos )
        if pos == -1: break
        # read the filename
        includeFilename = extract_filename( fileStr, pos )
        # remove the #include from file
        fileStr = replace_include_line( fileStr, pos )
        # insert the included file
        fileStr = string_insert( fileStr, parse_file( includeFilename ), pos ) # woah here's where the magic happens
    return fileStr
    

print( parse_file( optInputfile ) )

It's a command line utility written in Python that parses text files for #include statements and inserts the appropriate files.

It's far from elegant and most of the extra features aren't done yet, at the moment it just prints out the resulting superfile. But the basic functionality of recursively replacing #include with the contents of a file is done.

 

So in any file that's parsed you can write:

#include "file.ext"

Thoughts? Am I crazy? Wasting my time? Has this been done/solved before?




#5157424 Is working in terminal/console really a waste of time?

Posted by Lith on 01 June 2014 - 04:15 PM

 

Terminal window coding in preparation of learning game programming is only a way to trim cruft and focus on more digestible bits here-and-there, but the problem is that it doesn’t serve any one dish better than the alternatives do. Even as a complete package, most alternatives trump it, as they overall offer basically everything terminal programming does and more. Modding will still hold your hand over looping and logic but also give you a more motivating experience related to actual games.


It may not be useless, but there is no reason to ever do it.

 

I agree with you but there are some alarm bells going off, I fear your advice may be misunderstood.

 

Notice what I highlighted. If the person is learning game programming, then yeah, I completely agree. But it seems to me like this advice already assumes the person knows a language already. If a person wants to learn a new language, say C++, then I feel that they should get some console/terminal experience before they move on.

 

Better learn how to #include and cout before you try linking graphics libraries and allocating memory.




PARTNERS