Jump to content

  • Log In with Google      Sign In   
  • Create Account

TheComet

Member Since 02 Oct 2013
Online Last Active Today, 02:55 PM

#5293976 Animated Cursor: how get frame delay?

Posted by TheComet on Yesterday, 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 Yesterday, 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;
}



#5248981 Outputting to a file

Posted by TheComet on 26 August 2015 - 07:40 AM

Reminds me of the time my antivirus decided to delete all DLL files in my python site-packages while I was debugging. "Unable to call function: Function was deleted from your computer"




#5245705 Worst Hotfixes

Posted by TheComet on 11 August 2015 - 05:26 AM

In this thread we share stories of some of the worst hotfixes we've seen and/or applied.

 

In a game I had to present I was experiencing an extremely obscure bug where after some time pointers would randomly point to garbage values, crashing the game. I had an hour to get it working before the presentation.

 

I spent 45 minutes trying to reproduce it with no success. It happened at seemingly random times, but for some reason it was always the same two pointers that were modified.

 

Seeing as I was running out of time, I ended up inserting checks which would replace the garbage value (when it occurred) with the correct value again - the correct value I knew because I saw it in the debugger and it seemed to remain consistent.

if(game->settings_doc != 0x63e1b0)
    game->settings_doc = 0x63e1b0; /* from debugger */

After the presentation I sat down with valgrind and found the problem. A buffer overrun was writing into memory it wasn't supposed to.




#5245674 Can someome please tell me why this crashes?

Posted by TheComet on 11 August 2015 - 02:01 AM

If you happen to have a cygwin shell installed (e.g. if you installed git) you could also just use:

find /c/Users/admin/Documents -name "*.mp4" -exec basename {} \; > video_filenames.txt

Maybe someone can translate that to the Windows cmd equivalent.






PARTNERS