Jump to content

  • Log In with Google      Sign In   
  • Create Account

TheComet

Member Since 02 Oct 2013
Offline Last Active Yesterday, 07:05 PM

#5295997 Wannabe

Posted by TheComet on 10 June 2016 - 11:29 AM

It's never too late to pursue anything. There are a million ways to get into game programming, you just have to find one that is easy enough for beginners and offers to you the freedom and features you expect to have. Some immediate products that come to mind are: DarkBASIC, Unity, pygame, etc.

 

I personally started making games with DarkBASIC when I was about 14. It's a very simple language to pick up quickly and the results are immediate. It's also a lot of fun to play around in. I wrote games for about 5 years using only that product.




#5295995 Do you keep a collection of handles in your game for your components

Posted by TheComet on 10 June 2016 - 11:21 AM

This is perhaps a shameless plug, but when I first learned about ECS I tried writing my own framework, and I implemented a way for the user to specify execution dependencies:

https://github.com/thecomet93/ontology#execution-order-of-systems

 

In my project, the dependency tree is resolved and flattened into a linear ordered list of systems to execute. Thus, when calling world.update(), I only have to iterate through the list and call system->update(). This sounds like the exact thing you need. It might also be a possibility to flatten the dependency tree into multiple lists of systems, where each list contains systems that can be executed in parallel. Just a thought.




#5294975 What is the output?

Posted by TheComet on 04 June 2016 - 10:15 AM

Just a tip to ensure the success of your future career: Don't ever write code like that.




#5293976 Animated Cursor: how get frame delay?

Posted by TheComet on 28 May 2016 - 04:48 PM

I don't understand this.

 

First of all, your code won't even compile because "i" is undeclared.

 

Your while loop will probably never exit, so your program will just get stuck once you call GetAniFrameCount().

Even if this somehow worked, it would not return the frame rate of your app. You'd just be timing how fast DrawIconEx() is, which has nothing to do with frame rate.

 

And lastly, Windows applications don't have a "frame rate" per se. They are only redrawn when they need to be redrawn (e.g. when you rescale the window), so the concept of "frame rate" doesn't exist.




#5293962 Some people just want to watch the world burn

Posted by TheComet on 28 May 2016 - 02:29 PM

x can go to zero even faster in opposite direction

int x = 10;

while( 0 <---- x )
{
    printf("%d ", x);
}
8 6 4 2

You can control speed with an arrow!

int x = 100;

while( 0 <-------------------- x )
{
    printf("%d ", x);
}
90 80 70 60 50 40 30 20 10

Sad thing is, this actually compiles.  :unsure:




#5265522 Why didn't somebody tell me?

Posted by TheComet on 08 December 2015 - 07:52 PM

Cats. They are not dogs.

1) Dogs have four legs
2) Cats have four legs
3) Therefore, cats are dogs.

Checkmate atheists.


#5262674 Question about type, and displaying the bits of a char

Posted by TheComet on 18 November 2015 - 07:32 PM

God damn it, I had a super long post typed up and chrome crashed because I hit CTRL+S.
 
You don't really see bitfields in desktop applications because there's no need to conserve memory. You'll find them in code that makes heavy use if bit masking (crypto?) or memory conservation (networking code?). I program micro controllers for my day job and we make heavy use of bitfields.

[EDIT] Just to be clear and as mentioned in the coming posts: This is not portable.
 
Here's an example. Imagine you had to pack a "move" instruction of a chess piece in a game of chess into as little space as possible. Reasons being you want to transmit the move over a network and save space. You could encode this by using a "to" and "from" coordinate. Seeing as a chess board is 8x8, a coordinate can be packed into 6 bits. You could write:
u16 move = 0;
move |= (current_x << 0);
move |= (current_y << 3);
move |= (new_x << 6);
move |= (new_y << 9);
/* 4 bits reserved for whatever */
Using bitfields makes this much more readable:
struct chess_move_t {
    union {
        struct {
            unsigned current_x : 3;
            unsigned current_y : 3;
            unsigned new_x : 3;
            unsigned new_y : 3;
            unsigned :4; /* unused */
        };
        u16 data;
    };
};
The following code does the same thing as the first example.
struct chess_move_t move;
move.current_x = current_x;
move.current_y = current_y;
move.new_x = new_x;
move.new_y = new_y;
 



Here's a real world example of some micro controller code, just in case you were wondering.
void timer_init(void)
{
    /*
     * Target interrupt frequency is 100Hz
     * 
     * Fcy = 7.37 * 65 / 8 = 59.88125 MHz
     * Prescale 1:64 ~ 936 kHz
     * Using 16-bit timer type B: count to 9356 for 100 Hz
     * 
     * We'll be using a timer type B, specifically timer 4, so we don't
     * clash with the timer required for ADC conversions.
     * 
     * Notes on config:
     *  + Clock source select by default is Fosc / 2
     *  + Default mode is 16-bit mode
     */
    T4CONbits.TON = 0;      /* disable timer during config */
    T4CONbits.TCKPS = 0x02; /* prescale 1:64 */
    PR4 = 9356;             /* period match, divide the 936 kHz by 9356 to 
                             * reach 10ms */
    IFS1bits.T4IF = 0;      /* clear interrupt flag */
    IEC1bits.T4IE = 1;      /* enable timer 4 interrupts */
    
    T4CONbits.TON = 1;      /* start timer */
}
The relevant bitfield declarations are the following (this is found in a header file provided by Microchip)
#define T4CON T4CON
extern volatile unsigned int  T4CON __attribute__((__sfr__));
__extension__ typedef struct tagT4CONBITS {
  union {
    struct {
      unsigned :1;
      unsigned TCS:1;
      unsigned :1;
      unsigned T32:1;
      unsigned TCKPS:2;
      unsigned TGATE:1;
      unsigned :6;
      unsigned TSIDL:1;
      unsigned :1;
      unsigned TON:1;
    };
    struct {
      unsigned :4;
      unsigned TCKPS0:1;
      unsigned TCKPS1:1;
    };
  };
} T4CONBITS;
extern volatile T4CONBITS T4CONbits __attribute__((__sfr__));



#5260334 Idea about game engine for Linux

Posted by TheComet on 03 November 2015 - 09:57 AM

Why not help improve an existing engine rather than trying to create yet another engine? Urho3D comes to mind...




#5252690 How to use small datatypes efficiently

Posted by TheComet on 17 September 2015 - 11:00 AM


Once that 64 byte buffer is loaded, anything you do within that 64 byte buffer is very nearly free.  Thanks to the magic of the Out Of Order core and processor caches, doing one operation on one item in that block is very nearly the same clock time as doing one operation on sixteen items in that block.

Would it actually be beneficial to pack our variables more tightly together (use char/short where possible) in order to reduce block loads?




#5251721 Is there a language like Python but without the tab requirement?

Posted by TheComet on 11 September 2015 - 08:27 AM

 


but aligning code is pretty silly as well IMO.

 

Umm... what?

 

l0calh05st obviously writes all of his programs on a single line, didn't you know? It saves disk space.




#5251537 Convincing AntiVirsus, im not a virus

Posted by TheComet on 10 September 2015 - 08:15 AM

Get someone else to compile your code using Visual Studio 2013 (CE) and send the binary to you.




#5251310 Convincing AntiVirsus, im not a virus

Posted by TheComet on 09 September 2015 - 04:41 AM

Have you tried using the C library?

#include <stdio.h>

int main(int argc, char* argv[])
{
    FILE* fp;
    if(!(fp = fopen("test.txt", "w")))
    {
        fprintf(stderr, "oh oh (failed to open file)");
        return -1;
    }

    fprintf(fp, "hello world!");
    fclose(fp);

    return 0;
}

It's a silly suggestion. As you've been saying over and over, it works fine with VS8 but not with VS10. Seeing as I know nothing of VS I can only suggest to try disabling/enabling options until it starts working.




#5250983 C++11 lambda, modifying copied value

Posted by TheComet on 07 September 2015 - 07:49 AM

It makes sense if you want to do something like:

int counter = 10;
std::function<void()> fooFunction = [=]() {
    while(counter--) {
        // do important things
    }
}



#5250559 Best comment ever

Posted by TheComet on 04 September 2015 - 06:22 AM


IMO if you can't properly read a simple function pointer declaration like that you have no business writing C or C++.

This.

 

The comment doesn't contribute in any way to what can already clearly be extracted from reading the code. It's just as dumb as

int a = 6; // set a to 6

A useful comment would have been to explain what VFunc is and how it is used.




#5250129 C++ cross platform resolve hostname to ip library

Posted by TheComet on 01 September 2015 - 09:53 AM

As SeanMiddleditch pointed out, getaddrinfo() is probably your best bet. The following is a great guide on socket programming. I used it extensively as a reference when I was learning about sockets.

http://beej.us/guide/bgnet/output/print/bgnet_A4.pdf

 

If you scroll down to page 20 (16) (Chapter 5.1. getaddrinfo()) there's a complete example which does exactly what you asked for.

 

You may have to adjust a few things here and there to get it working on Windows (e.g. call WSAStartup() and WSACleanup() and include the right headers), but by and large it works the same way on Windows.

 


anyone who considers compiling on MingW to be "ported to Windows" should be thrown out of a window

Can you elaborate some more on why you take this stance?

 

I've come to the conclusion that writing cross platform software is a lot easier for everyone if you drop support for the MSVC compiler. It's non-compliant in many areas and is a pain to configure properly. As such it only causes headaches and additional overhead when writing your build scripts.

 

I find it disappointing that porting an entire POSIX compliant environment and toolchain to Windows is easier to do than supporting the MSVC compiler, but that's how it is.

 

EDIT:

Just got the code from the PDF file I linked to work using MSVC:

#include <stdio.h>
#include <string.h>
#include <WinSock2.h>
#include <WS2tcpip.h>  // INET6_ADDRSTRLEN

static WSADATA g_wsa_data;

char net_init(void)
{
    return (WSAStartup(MAKEWORD(2, 2), &g_wsa_data) == NO_ERROR);
}

void net_deinit(void)
{
    WSACleanup();
}

void net_dns_resolve(const char* hostname)
{
    struct addrinfo hints, *results, *item;
    int status;
    char ipstr[INET6_ADDRSTRLEN];

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;  /* AF_INET6 to force version */
    hints.ai_socktype = SOCK_STREAM;

    if((status = getaddrinfo(hostname, NULL, &hints, &results)) != 0)
    {
        fprintf(stderr, "failed to resolve hostname \"%s\": %s", hostname, gai_strerror(status));
        return;
    }

    printf("IP addresses for %s:\n\n", hostname);

    for(item = results; item != NULL; item = item->ai_next)
    {
        void* addr;
        char* ipver;

        /* get pointer to the address itself */
        /* different fields in IPv4 and IPv6 */
        if(item->ai_family == AF_INET)  /* address is IPv4 */
        {
            struct sockaddr_in* ipv4 = (struct sockaddr_in*)item->ai_addr;
            addr = &(ipv4->sin_addr);
            ipver = "IPv4";
        }
        else  /* address is IPv6 */
        {
            struct sockaddr_in6* ipv6 = (struct sockaddr_in6*)item->ai_addr;
            addr = &(ipv6->sin6_addr);
            ipver = "IPv6";
        }

        /* convert IP to a string and print it */
        inet_ntop(item->ai_family, addr, ipstr, sizeof ipstr);
        printf("  %s: %s\n", ipver, ipstr);
    }

    freeaddrinfo(results);
}

int main(int argc, char* argv[])
{
    if(argc != 2)
    {
        fprintf(stderr, "usage: %s <hostname>\n", argv[0]);
        return -1;
    }

    net_init();
    net_dns_resolve(argv[1]);
    net_deinit();

    return 0;
}

Don't forget to link Ws2_32.lib under Configuration Properties->Linker->Input.

 

Here's the code ported to Linux:

#include <stdio.h>
#include <string.h>
#include <sys/socket.h> 
#include <netdb.h>




char net_init(void)
{
    return 1; /* nothing to do */
}


void net_deinit(void)
{
    /* nothing to do */
}


void net_dns_resolve(const char* hostname)
{
    struct addrinfo hints, *results, *item;
    int status;
    char ipstr[INET6_ADDRSTRLEN];


    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;  /* AF_INET6 to force version */
    hints.ai_socktype = SOCK_STREAM;


    if((status = getaddrinfo(hostname, NULL, &hints, &results)) != 0)
    {
        fprintf(stderr, "failed to resolve hostname \"%s\": %s", hostname, gai_strerror(status));
        return;
    }


    printf("IP addresses for %s:\n\n", hostname);


    for(item = results; item != NULL; item = item->ai_next)
    {
        void* addr;
        char* ipver;


        /* get pointer to the address itself */
        /* different fields in IPv4 and IPv6 */
        if(item->ai_family == AF_INET)  /* address is IPv4 */
        {
            struct sockaddr_in* ipv4 = (struct sockaddr_in*)item->ai_addr;
            addr = &(ipv4->sin_addr);
            ipver = "IPv4";
        }
        else  /* address is IPv6 */
        {
            struct sockaddr_in6* ipv6 = (struct sockaddr_in6*)item->ai_addr;
            addr = &(ipv6->sin6_addr);
            ipver = "IPv6";
        }


        /* convert IP to a string and print it */
        inet_ntop(item->ai_family, addr, ipstr, sizeof ipstr);
        printf("  %s: %s\n", ipver, ipstr);
    }


    freeaddrinfo(results);
}


int main(int argc, char* argv[])
{
    if(argc != 2)
    {
        fprintf(stderr, "usage: %s <hostname>\n", argv[0]);
        return -1;
    }


    net_init();
    net_dns_resolve(argv[1]);
    net_deinit();


    return 0;
}





PARTNERS