Thread: Help porting two console functions?

  1. #1
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708

    Exclamation Help porting two console functions?

    Hello all, I have two console-related functions that need to be supported "across the board", but I'm a little short on time, unfortunately. So far I've only got the MSWindows version coded. Any help or advice would be greatly appreciated!

    Code:
    #include "stdlib.h" // for size_t
    #if defined( WIN32 ) || defined( MSWIN )
    #include "windows.h"
    // zero-based indexing
    void set_row_and_column_character( size_t row, size_t column, unsigned char character )
    {
        COORD 
            position;
        position.X = column;
        position.Y = row;
        SetConsoleCursorPosition( GetStdHandle( STD_OUTPUT_HANDLE ), position );
        putchar( character );
    }
    // for resizeable screens, calculation should be done dynamically
    void get_screen_height_and_width( size_t* height, size_t* width )
    {
        CONSOLE_SCREEN_BUFFER_INFO 
            info;
        GetConsoleScreenBufferInfo( GetStdHandle( STD_OUTPUT_HANDLE ), &info );
        *width = info.srWindow.Right;
        *height = info.srWindow.Bottom - info.srWindow.Top;
    }
    #else
    #if defined( NextPlatformNamePlaceHolder_ )
    // platform implementation
    #else
    #error Console platform not specified 
    #endif
    Last edited by Sebastiani; 04-20-2010 at 10:17 AM. Reason: naming convention, inclusion for size_t, function signature
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    You're gonna have to pick an API on linux. ncurses, obviously, also there is "slang".

    Since both of them can be ported to windows, you might want to just write one version. I haven't look at slang but I fear ncurses is not as simple as the windows API so you may have to re-think "short on time". For a tough guy like you I think maybe a few hours will get you somewhere.

    http://tldp.org/HOWTO/NCURSES-Programming-HOWTO/
    Last edited by MK27; 04-20-2010 at 09:43 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #3
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Quote Originally Posted by MK27 View Post
    You're gonna have to pick an API on linux. ncurses, obviously, also there is "slang".

    Since both of them can be ported to windows, you might want to just write one version. I haven't look at slang but I fear ncurses is not as simple as the windows API so you may have to re-think "short on time". For a tough guy like you I think maybe a few hours will get you somewhere.

    NCURSES Programming HOWTO
    Yeah, you were right, actually. Does the ncurses code look correct, btw?

    Code:
    #include "stdlib.h" // for size_t
    #if defined( WIN32 ) || defined( MSWIN )
    #include "windows.h"
    // zero-based indexing
    void set_row_and_column_character( size_t row, size_t column, unsigned char character )
    {
        COORD
            position;
        position.X = column;
        position.Y = row;
        SetConsoleCursorPosition( GetStdHandle( STD_OUTPUT_HANDLE ), position );
        putchar( character );
    }
    // for resizeable screens, calculation should be done dynamically
    void get_screen_height_and_width( size_t* height, size_t* width )
    {
        CONSOLE_SCREEN_BUFFER_INFO
            info;
        GetConsoleScreenBufferInfo( GetStdHandle( STD_OUTPUT_HANDLE ), &info );
        *width = info.srWindow.Right;
        *height = info.srWindow.Bottom - info.srWindow.Top;
    }
    #elif defined( NCURSES )
    #include "curses.h"
    void set_row_and_column_character( size_t row, size_t column, unsigned char character )
    {
        mvaddch( row, column, character );
    }
    void get_screen_height_and_width( size_t* height, size_t* width )
    {
        getmaxyx( initscr( ), *height, *width );
    }
    #elif defined( NextPlatformNamePlaceHolder_ )
    // platform implementation
    #else
    #error Console platform not specified
    #endif
    Last edited by Sebastiani; 04-20-2010 at 12:30 PM. Reason: spacing, ncurses fix removed (too confusing)
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  4. #4
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Sebastiani View Post
    Yeah, you were right, actually. Does the ncurses code look correct, btw?
    Does it work?
    I actually don't use ncurses that much, and usually via the perl API, so I keep getting object notation flashing in my mind. Using the return value of initscr() in getmaxyx() seems a little unorthodox to me, unless you are planning to call get_screen_height_and_width() BEFORE set_row_and_column_character(), since I would guess calling mvaddch() BEFORE initscr() will be a problem. And if that's all you are doing, you don't need to keep the return value of initscr(), so probably all this is fine.

    Looking thru some old code you don't need to keep the initscr() return normally either, there is the predefined "stdscr":

    Code:
    getmaxyx(stdscr,maxy,maxx);
    Again, I assume initscr() must be called first.

    I still haven't found a nice indexed version of the C API beyond the man pages.
    Last edited by MK27; 04-20-2010 at 11:11 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  5. #5
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Quote Originally Posted by MK27 View Post
    Does it work?
    I actually don't use ncurses that much, and usually via the perl API, so I keep getting object notation flashing in my mind. Using the return value of initscr() in getmaxyx() seems a little unorthodox to me, unless you are planning to call get_screen_height_and_width() BEFORE set_row_and_column_character(), since I would guess calling mvaddch() BEFORE initscr() will be a problem. And if that's all you are doing, you don't need to keep the return value of initscr(), so probably all this is fine.

    Looking thru some old code you don't need to keep the initscr() return normally either, there is the predefined "stdscr":

    Code:
    getmaxyx(stdscr,maxy,maxx);
    Again, I assume initscr() must be called first.

    I still haven't found a nice indexed version of the C API beyond the man pages.
    Ah, okay, thanks. So something like this then:

    Code:
    #include "stdlib.h" // for size_t
    #if defined( WIN32 ) || defined( MSWIN )
    #include "windows.h"
    // zero-based indexing
    void set_row_and_column_character( size_t row, size_t column, unsigned char character )
    {
        COORD
            position;
        position.X = column;
        position.Y = row;
        SetConsoleCursorPosition( GetStdHandle( STD_OUTPUT_HANDLE ), position );
        putchar( character );
    }
    // for resizeable screens, calculation should be done dynamically
    void get_screen_height_and_width( size_t* height, size_t* width )
    {
        CONSOLE_SCREEN_BUFFER_INFO
            info;
        GetConsoleScreenBufferInfo( GetStdHandle( STD_OUTPUT_HANDLE ), &info );
        *width = info.srWindow.Right;
        *height = info.srWindow.Bottom - info.srWindow.Top;
    }
    #elif defined( NCURSES )
    #include "curses.h"
    void initscr_helper_( void )
    {
        static WINDOW*
            unused = initscr( );	
    }
    void set_row_and_column_character( size_t row, size_t column, unsigned char character )
    {
        initscr_helper_( );
        mvaddch( row, column, character );
    }
    void get_screen_height_and_width( size_t* height, size_t* width )
    { 
        initscr_helper_( );
        getmaxyx( stdscr, *height, *width );
    }
    #elif defined( NextPlatformNamePlaceHolder_ )
    // platform implementation
    #else
    #error Console platform not specified
    #endif
    Last edited by Sebastiani; 04-20-2010 at 01:06 PM. Reason: ncurses fix
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  6. #6
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    No, I meant more that the mvaddch() might not work if initscr() is not called first.

    Generally the first thing you do in a program ncurses wise is call initscr() to create a window object. The commands which don't require a pointer to a WINDOW (such as mvaddch()) operate on stdscr, and I would guess stdscr won't exist until initscr() is called.

    So your get_screen_height_and_width() was fine, as long as you only call it ONCE. I don't think initscr() should be called repeatedly.

    The issue would be if you call set_row_and_column_character() first, before initscr() is called in the other function, you'll have a problem.

    So, IMO (this is sort of conjecture, you'll have to try yourself), as long as you call get_screen_height_and_width() before you do anything else and don't call it again, you should be able to use set_row_and_column_character() as much as you like.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  7. #7
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Quote Originally Posted by MK27 View Post
    No, I meant more that the mvaddch() might not work if initscr() is not called first.

    Generally the first thing you do in a program ncurses wise is call initscr() to create a window object. The commands which don't require a pointer to a WINDOW (such as mvaddch()) operate on stdscr, and I would guess stdscr won't exist until initscr() is called.

    So your get_screen_height_and_width() was fine, as long as you only call it ONCE. I don't think initscr() should be called repeatedly.

    The issue would be if you call set_row_and_column_character() first, before initscr() is called in the other function, you'll have a problem.

    So, IMO (this is sort of conjecture, you'll have to try yourself), as long as you call get_screen_height_and_width() before you do anything else and don't call it again, you should be able to use set_row_and_column_character() as much as you like.
    I see what you mean. I fixed it to where both functions call the initialization routine (which in turn creates a static WINDOW object). Thanks for the help!
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. exchange functions demo code
    By kryptkat in forum C++ Programming
    Replies: 0
    Last Post: 04-05-2009, 02:06 PM
  2. An array of macro functions?
    By someprogr in forum C Programming
    Replies: 6
    Last Post: 01-28-2009, 07:05 PM
  3. Passing pointers between functions
    By heygirls_uk in forum C Programming
    Replies: 5
    Last Post: 01-09-2004, 06:58 PM
  4. Attaching functions to a class/struct
    By VirtualAce in forum Tech Board
    Replies: 2
    Last Post: 08-04-2003, 10:56 AM
  5. Console Functions
    By unanimous in forum C++ Programming
    Replies: 1
    Last Post: 12-28-2001, 08:09 PM