Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Topics - FutureCow

#21
Anyone have any ideas?
I'm trying to query an NTP server with the following (see page http://www.kloth.net/software/timesrv1.php for example code)

Code (glbasic) Select
LOCAL server$, ok%, sock%, rv%
ok%=SOCK_INIT()
sock% = SOCK_TCPCONNECT("0.pool.ntp.org", 37)
rv = SOCK_TCPSEND (sock, "\n")
LOCAL Done = 0

WHILE Done = 0
rv = SOCK_RECV(sock%, msg$, 1024)
IF rv = -2
SLEEP 1
ENDIF

IF KEY(1) = 1
Done = 1
ENDIF
WEND


The code gets as far as the SOCK_TCPCONNECT and locks up. Is there a problem doing a socket connection to a server you didn't start?
#22
I'm writing a program that I want people to be able to run, but a certain part won't work until a given date (their birthday).
I'm going to do a date check ( PLATFORMINFO$("TIME") ) but want to protect against them being clever and changing the system clock.

I thought I'd do a NETWEBGET to grab the date off an internet site (timeanddate.com) - but the date there (and similar sites I've looked at) is implemented via javacode, so a NETWEBGET will get the code and not the time (at least that's what I assume, I can't test at the moment as I'm behind a proxy server and NETWEBGET doesn't work for proxies where you have to type in a username and password).

Does anyone know of anywhere online that statically update their page with a date that will be easy to parse with NETWEBGET? The ones I've found that have a static date (like my local news site) have too much data to sift through.
This is only for a small app that will be run a few times for family over the next couple of months, so it's not putting any load on anyone's internet server.

If anyone has any ideas on a better way to do it too I'd love to hear it.
#23
Please allow the number of bytes to be retrieved by NETWEBGET to be specified when used with a proxy.

Also, can there be a way to specify the username and password for the proxy server?

When testing a NETWEBGET through my proxy server here (requires username and password) I get a access denied error as username and password were not supplied.
#24
GLBasic - en / Clipboard
2010-Mar-08
Does anyone know how to push/pull text to/from the windows clipboard? I don't have a need to work with images, but if someone knows how to copy images to the clipboard too, that may help others in the future.
#25
Math / Car Physics
2010-Feb-19
Many times I've had people on the street stop and ask me "Hey FutureCow - how do I do car physics in GLBasic?" My reply is always "I don't know, leave me alone - I'm on my lunchbreak!"  8)

I've just converted the code off the Blitz forums by Vorderman for car physics. I don't claim to be an expert in it. It needs tweaking before it could be used in a game (well, you could use it as is, but you'd have a lot of very slow moving cars...)

The original work doesn't have any licencing agreement listed, so to be on the safe side, it's probably best to credit Vorderman (James Kett) if you use it.

Arrows to move, space for handbrake.
Code (glbasic) Select

// --------------------------------- //
// Project: car physics
// Start: Friday, February 19, 2010
// IDE Version: 7.230

// Car Physics by Vorderman (James Kett) on the BlitzBasic forums.
// Translated to GLBasic by FutureCow (Shane Hockings)
//
// There are two versions of FUNC_do_physics included.
// original listing from Marco Monster's code. Use AS is AND retrieve CAR position x,y TO position car IN-game.
// second listing : tidied up physics routine with variable front/rear/4 wheel drive option and thus the ability to maintain drifts / slides.
//NOTE : FUNC_do_physics includes screen boundary checking AND looping right at the bottom of the function. You'll need TO change this FOR a 2D screen res other THEN 800,600 OR remove IF FOR 3d game.
//


//physics variables
GLOBAL delta_t# = 0.01
GLOBAL M_PI# = 3.1415926
GLOBAL DRAG# = 5.0
GLOBAL RESISTANCE# = 30.0
GLOBAL CA_R# = -5.20
GLOBAL CA_F# = -5.0
GLOBAL MAX_GRIP# = 2.0   
GLOBAL MULT# = 57
GLOBAL MULT2# = 0.01745

GLOBAL CAR1_cartype = 1
GLOBAL CAR1_cartype_b# = 1.0
GLOBAL CAR1_cartype_c# = 1.0
GLOBAL CAR1_cartype_wheelbase# = CAR1_cartype_b# + CAR1_cartype_c#
GLOBAL CAR1_cartype_h# = 1.0
GLOBAL CAR1_cartype_mass# = 1500
GLOBAL CAR1_cartype_inertia# = 1500
GLOBAL CAR1_cartype_width# = 1.5
GLOBAL CAR1_cartype_length# = 3.0
GLOBAL CAR1_cartype_wheellength# = 0.7
GLOBAL CAR1_cartype_wheelwidth# = 0.3
GLOBAL CAR1_car_position_wc_x# = 400.0
GLOBAL CAR1_car_position_wc_y# = 300.0
GLOBAL CAR1_car_velocity_wc_x# = 0
GLOBAL CAR1_car_velocity_wc_y# = 0
GLOBAL CAR1_car_angle# = 0
GLOBAL CAR1_car_angularvelocity# = 0
GLOBAL CAR1_car_steerangle# = 0
GLOBAL CAR1_car_throttle# = 0
GLOBAL CAR1_car_brake# = 0

GLOBAL front_slip = 0
GLOBAL rear_slip = 0

GLOBAL velocity_x#
GLOBAL velocity_y#
GLOBAL yawspeed#
GLOBAL sn#, cs#
GLOBAL xpos#, ypos#
GLOBAL rot_angle#
GLOBAL sideslip#
GLOBAL slipanglefront#
GLOBAL slipanglerear#
GLOBAL flatf_x#, flatf_y#
GLOBAL flatr_x#, flatr_y#
GLOBAL weight#
GLOBAL ftraction_x#, ftraction_y#
GLOBAL resistance_x#, resistance_y#
GLOBAL force_x#, force_y#
GLOBAL torque#
GLOBAL acceleration_x#, acceleration_y#, angular_acceleration#
GLOBAL acceleration_wc_x#, acceleration_wc_y#


//TYPE of car - 1=rear 2=front 3=four
GLOBAL CAR1_car_drivetype = 3

GOSUB Main

//######################################################################################################

SUB Main:
//Main loop
LOCAL Quit = 0
// WHILE ( KeyHit(1)=0 )
WHILE Quit = 0
//     Cls
IF KEY(1) = 1
Quit = 1
ENDIF

    FUNC_do_input()
   
    FUNC_do_physics()
       
//     Flip
SHOWSCREEN    
WEND
ENDSUB


//######################################################################################################


//INPUT routine from joystick/pad/wheel
FUNCTION FUNC_do_input:
//IF ( JoyYDir() = -1 )
IF KEY(200) = 1
CAR1_car_throttle# = 2000.0
ELSE
CAR1_car_throttle# = 0.0
ENDIF

//IF ( JoyYDir() = 0 )
// CAR1_car_throttle# = 0.0
// ENDIF

// IF ( JoyYDir() = 1 )
IF KEY(208) = 1
    CAR1_car_throttle# = 0.0
    CAR1_car_brake# = 100.0
ELSE
    CAR1_car_brake# = 0.0
ENDIF

CAR1_car_steerangle# = 0.0
// IF ( JoyXDir() = 1 )
IF KEY(205) = 1
CAR1_car_steerangle# = (-M_PI# / 4.0) * 0.15 //* MULT2#
ENDIF

// IF ( JoyXDir() = -1 )
IF KEY(203) = 1
CAR1_car_steerangle# = (M_PI# / 4.0) * 0.15 // MULT2#
ENDIF

rear_slip = 0
// IF ( JoyDown(1) )
IF KEY(57) = 1
rear_slip = 1
ENDIF

//temp display of vars
PRINT (CAR1_car_position_wc_x#),0,0
PRINT (CAR1_car_position_wc_y#),0,12
PRINT (CAR1_car_steerangle#),0,24

CAR1_car_angle#=CAR1_car_angle#+(CAR1_car_steerangle# * 0.25)

xpos# = CAR1_car_position_wc_x#
ypos# = CAR1_car_position_wc_y#

//render a small moving car rep.
renda1# =( -CAR1_car_angle# * MULT# ) - 60
IF (renda1#<0.0) THEN renda1#=360.0+renda1#
renda2# =( -CAR1_car_angle# * MULT# ) + 60
IF (renda2#>359.0) THEN renda2#=renda2#-360.0
renda3# =( -CAR1_car_angle# * MULT# ) - 120
IF (renda3#<0.0) THEN renda3#=360.0+renda3#
renda4# =( -CAR1_car_angle# * MULT# ) + 120
IF (renda4#>359.0) THEN renda4#=renda4#-360.0

rendx1#=25*COS(renda1#)
rendy1#=25*SIN(renda1#)

rendx2#=25*COS(renda2#)
rendy2#=25*SIN(renda2#)

rendx3#=25*COS(renda3#)
rendy3#=25*SIN(renda3#)

rendx4#=25*COS(renda4#)
rendy4#=25*SIN(renda4#)

DRAWLINE rendx1#+xpos#,rendy1#+ypos#,rendx2#+xpos#,rendy2#+ypos#,RGB(255,255,255)
DRAWLINE rendx2#+xpos#,rendy2#+ypos#,rendx4#+xpos#,rendy4#+ypos#,RGB(255,255,255)
DRAWLINE rendx4#+xpos#,rendy4#+ypos#,rendx3#+xpos#,rendy3#+ypos#,RGB(255,255,255)
DRAWLINE rendx3#+xpos#,rendy3#+ypos#,rendx1#+xpos#,rendy1#+ypos#,RGB(255,255,255)

ENDFUNCTION


//######################################################################################################

// Original FUNC_do_physics code

//
//FUNCTION FUNC_do_physics()
//
//    sn# = SIN(CAR1_car_angle# * MULT#) * MULT2#
//    cs# = COS(CAR1_car_angle# * MULT#) * MULT2#
//
//    Text 400,0,"sn="+Str(sn#)+" cs="+Str(cs#)
//
//     SAE convention: x is TO the front of the car, y is TO the Right, z is down
//     transform velocity IN world reference frame TO velocity IN car reference frame
//    velocity_x# = cs# * CAR1_car_velocity_wc_y# + sn# * CAR1_car_velocity_wc_x#
//    velocity_y# = -sn# * CAR1_car_velocity_wc_y# + cs# * CAR1_car_velocity_wc_x#
//
//     Lateral force on wheels
//     Resulting velocity of the wheels AS result of the yaw rate of the car body
//     v = yawrate * r where r is distance of wheel TO CG (approx. half wheel base)
//     yawrate (ang.velocity) must be IN rad/s
//    yawspeed# = CAR1_cartype_wheelbase# * 0.5 * CAR1_car_angularvelocity#
//
//    IF( velocity_x# = 0 )
//        rot_angle# = 0
//    ELSE
//        rot_angle# = ATan2( (yawspeed# * MULT#) , (velocity_x# * MULT#) )
//        rot_angle# = ATan2( (yawspeed# ) , (velocity_x#) ) * MULT2#
//    ENDIF
//
//     Calculate the side slip angle of the car (a.k.a. beta)
//    IF( velocity_x# = 0 )
//        sideslip# = 0.0
//    ELSE
//        sideslip# = ATan2( (velocity_y# * MULT#) , (velocity_x# * MULT#) )       
//        sideslip# = ATan2( (velocity_y# ) , (velocity_x#) )    * MULT2#   
//    ENDIF
//
//     Calculate slip angles FOR front AND rear wheels (a.k.a. alpha)
//    slipanglefront# = sideslip# + rot_angle# - CAR1_car_steerangle#
//    slipanglerear# = sideslip# - rot_angle#
//
//     weight per axle = half car mass times 1G (=9.8m/s^2)
//    weight# = CAR1_cartype_mass# * 9.8 * 0.5
//   
//     lateral force on front wheels = (Ca * slip angle) capped TO friction circle * load
//    flatf_x# = 0.0
//    flatf_y# = CA_F# * slipanglefront#
//
//    IF ( flatf_y# > MAX_GRIP# ) flatf_y# = MAX_GRIP#
//    IF ( flatf_y# < -MAX_GRIP# ) flatf_y# = -MAX_GRIP#
//
//    flatf_y# = flatf_y# * weight#
//   
//     allow front wheels TO slip
//    IF(front_slip=1) flatf_y# = flatf_y# * 0.5
//
//     lateral force on rear wheels
//    flatr_x# = 0.0
//    flatr_y# = CA_R# * slipanglerear#
//
//    IF ( flatr_y# > MAX_GRIP# ) flatr_y# = MAX_GRIP#
//    IF ( flatr_y# < -MAX_GRIP# ) flatr_y# = -MAX_GRIP#
//
//    flatr_y# = flatr_y# * weight#
//   
//    IF(rear_slip = 1) flatr_y# = flatr_y# * 0.5
//
//     longtitudinal force on rear wheels - very simple traction model
//    ftraction_x# = 100.0 * (CAR1_car_throttle# - CAR1_car_brake# * SGN(velocity_x#))
//    ftraction_y# = 0.0
//
//    IF(rear_slip = 1) ftraction_x# = ftraction_x# * 0.5
//
//     Forces AND torque on body
//     drag AND rolling resistance
//    resistance_x# = -( RESISTANCE# * velocity_x# + DRAG# * velocity_x# * ABS( velocity_x# ) )
//    resistance_y# = -( RESISTANCE# * velocity_y# + DRAG# * velocity_y# * ABS( velocity_y# ) )
//
//     sum forces
//    force_x# = ftraction_x# + (SIN( CAR1_car_steerangle# * MULT# )) * flatf_x# + flatr_x# + resistance_x#
//    force_y# = ftraction_y# + (COS( CAR1_car_steerangle# * MULT# )) * flatf_y# + flatr_y# + resistance_y#   
//
//     torque on body from lateral forces
//    torque# = CAR1_cartype_b# * flatf_y# - CAR1_cartype_c# * flatr_y#
//
//     Acceleration
//     Newton F = m.a, therefore a = F/m
//    acceleration_x# = force_x# / CAR1_cartype_mass#
//    acceleration_y# = force_y# / CAR1_cartype_mass#
//   
//    angular_acceleration# = torque# / CAR1_cartype_inertia#
//
//     Velocity AND position
//     transform acceleration from car reference frame TO world reference frame
//    acceleration_wc_x# = cs# * acceleration_y# + sn# * acceleration_x#
//    acceleration_wc_y# = -sn# * acceleration_y# + cs# * acceleration_x#
//
//     velocity is integrated acceleration
//    CAR1_car_velocity_wc_x# = CAR1_car_velocity_wc_x# + (delta_t# * acceleration_wc_x#)
//    CAR1_car_velocity_wc_y# = CAR1_car_velocity_wc_y# + (delta_t# * acceleration_wc_y#)
//
//     position is integrated velocity
//    CAR1_car_position_wc_x# = CAR1_car_position_wc_x# + (delta_t# * CAR1_car_velocity_wc_x#)
//    CAR1_car_position_wc_y# = CAR1_car_position_wc_y# + (delta_t# * CAR1_car_velocity_wc_y#)
//
//     Angular velocity AND heading
//     integrate angular acceleration TO get angular velocity
//    CAR1_car_angularvelocity# = CAR1_car_angularvelocity# + (delta_t# * angular_acceleration#)
//
//     integrate angular velocity TO get angular orientation
//    CAR1_car_angle# = CAR1_car_angle# + (delta_t# * CAR1_car_angularvelocity#)
//
//    IF ( CAR1_car_position_wc_x# < 0.0 ) CAR1_car_position_wc_x# = 800.0
//    IF ( CAR1_car_position_wc_x# > 800.0 ) CAR1_car_position_wc_x# = 0.0
//    IF ( CAR1_car_position_wc_y# < 0.0 ) CAR1_car_position_wc_y# = 600.0
//    IF ( CAR1_car_position_wc_y# > 600.0 ) CAR1_car_position_wc_y# = 0.0
//   
//END FUNCTION
//








FUNCTION FUNC_do_physics:
    // SAE convention: x is TO the front of the car, y is TO the Right, z is down
    //--------------------------
    // TRANSFORM VELOCITY
    //--------------------------
        // transform velocity IN world reference frame TO velocity IN car reference frame
        sn# = SIN(CAR1_car_angle# * MULT#)// * MULT2#
        cs# = COS(CAR1_car_angle# * MULT#) //* MULT2#
        velocity_x# = cs# * CAR1_car_velocity_wc_y# + sn# * CAR1_car_velocity_wc_x#
        velocity_y# = -sn# * CAR1_car_velocity_wc_y# + cs# * CAR1_car_velocity_wc_x#


    //--------------------------
    // LATERAL FORCES ON WHEELS
    //--------------------------
        // Resulting velocity of the wheels AS result of the yaw rate of the car body
        // v = yawrate * r where r is distance of wheel TO CG (approx. half wheel base)
        // yawrate (ang.velocity) must be IN rad/s

        // 0.5 IN this line becomes front/rear pos of COG - alter this later
        yawspeed# = CAR1_cartype_wheelbase# * 0.5 * CAR1_car_angularvelocity#
        IF( velocity_x# = 0 )
            rot_angle# = 0
        ELSE
//            rot_angle# = ATan2( (yawspeed# ) , (velocity_x#) ) * MULT2#
            rot_angle# = ATAN( (yawspeed# ) , (velocity_x#) ) * MULT2#
        ENDIF


    //-------------------------
    // SIDESLIP ANGLE
    //-------------------------
        // Calculate the side slip angle of the car (a.k.a. beta)
        IF( velocity_x# = 0 )
            sideslip# = 0.0
        ELSE
//            sideslip# = ATan2( (velocity_y# ) , (velocity_x#) )    * MULT2#   
            sideslip# = ATAN( (velocity_y# ) , (velocity_x#) )    * MULT2#   
        ENDIF


    //-------------------------
    // SLIP ANGLES FRONT/REAR
    //-------------------------
        // Calculate slip angles FOR front AND rear wheels (a.k.a. alpha)
        slipanglefront# = sideslip# + rot_angle# - CAR1_car_steerangle#
        slipanglerear# = (sideslip# - rot_angle#)


    //-------------------------
    // WEIGHT PER AXLE
    //-------------------------
        // weight per axle = half car mass times 1G (=9.8m/s^2)
        // need TO split this into front AND rear masses - according TO position of COG
        weight# = CAR1_cartype_mass# * 9.8 * 0.5


    //--------------------------
    // LATERAL FORCES ON WHEELS
    //--------------------------
        // (Ca * slip angle) capped TO friction circle * load
        flatf_x# = 0.0
        flatr_x# = 0.0

        //check FOR front / rear / 4 wheel drive
        IF ( CAR1_car_drivetype = 1 )

            //rear wheel drive
            flatr_y# = CA_R# * slipanglerear# / ((CAR1_car_throttle# / 5000.0)+1)
            flatf_y# = CA_F# * slipanglefront#

        ELSEIF ( CAR1_car_drivetype = 2 )

            //front wheel drive
            flatr_y# = CA_R# * slipanglerear#
            flatf_y# = CA_F# * slipanglefront# / ((CAR1_car_throttle# / 5000.0)+1)

        ELSEIF ( CAR1_car_drivetype = 3 )
   
            //4 wheel drive
            flatr_y# = CA_R# * slipanglerear# / ((CAR1_car_throttle# / 5000.0)+1)
            flatf_y# = CA_F# * slipanglefront# / ((CAR1_car_throttle# / 5000.0)+1)
       
        ENDIF
           
        flatf_y# = flatf_y# * weight#
        flatr_y# = flatr_y# * weight#

        // allow FOR handbrake / reduced grip levels - use this FOR different surfaces later   
        IF (front_slip=1)
        flatf_y# = flatf_y# * 0.5
        ENDIF
       
        IF (rear_slip = 1)
        flatr_y# = flatr_y# * 0.5
        ENDIF


    //-----------------------------
    // LONGITUDINAL FORCES
    //-----------------------------
        // longtitudinal force on rear wheels - very simple traction model
        ftraction_x# = 100.0 * (CAR1_car_throttle# - CAR1_car_brake# * SGN(velocity_x#))
        ftraction_y# = 0.0

        // allow FOR handbrake
        IF (rear_slip = 1)
        ftraction_x# = ftraction_x# * 0.5
        ENDIF



    //-------------------------------
    // SUM FORCES AND TORQUE ON BODY
    //-------------------------------
        // drag AND rolling resistance
        resistance_x# = -( RESISTANCE# * velocity_x# + DRAG# * velocity_x# * ABS( velocity_x# ) )
        resistance_y# = -( RESISTANCE# * velocity_y# + DRAG# * velocity_y# * ABS( velocity_y# ) )

        // sum forces
        force_x# = ftraction_x# + (SIN( CAR1_car_steerangle# * MULT# )) * flatf_x# + flatr_x# + resistance_x#
        force_y# = ftraction_y# + (COS( CAR1_car_steerangle# * MULT# )) * flatf_y# + flatr_y# + resistance_y#   

       
        // torque on body from lateral forces
        torque# = CAR1_cartype_b# * flatf_y# - CAR1_cartype_c# * flatr_y#

        // Acceleration - Newton F = m.a, therefore a = F/m
        acceleration_x# = force_x# / CAR1_cartype_mass#
        acceleration_y# = force_y# / CAR1_cartype_mass#
   
        // angular acceleration around COG
        angular_acceleration# = torque# / CAR1_cartype_inertia#

        // Velocity AND position
        // transform acceleration from car reference frame TO world reference frame
        acceleration_wc_x# = cs# * acceleration_y# + sn# * acceleration_x#
        acceleration_wc_y# = -sn# * acceleration_y# + cs# * acceleration_x#

        // velocity is integrated acceleration
        CAR1_car_velocity_wc_x# = CAR1_car_velocity_wc_x# + (delta_t# * acceleration_wc_x#)
        CAR1_car_velocity_wc_y# = CAR1_car_velocity_wc_y# + (delta_t# * acceleration_wc_y#)

        // position is integrated velocity
        CAR1_car_position_wc_x# = CAR1_car_position_wc_x# + (delta_t# * CAR1_car_velocity_wc_x#)
        CAR1_car_position_wc_y# = CAR1_car_position_wc_y# + (delta_t# * CAR1_car_velocity_wc_y#)

        // Angular velocity AND heading
        // integrate angular acceleration TO get angular velocity
        CAR1_car_angularvelocity# = CAR1_car_angularvelocity# + (delta_t# * angular_acceleration#)

        // move COG left / right according TO body's angular rotation
        CAR1_car_COGx# = (CAR1_car_angularvelocity# * 10.0)
        CAR1_car_COGy# = CAR1_car_throttle# / 100.0
       
        // integrate angular velocity TO get angular orientation
        CAR1_car_angle# = CAR1_car_angle# + (delta_t# * CAR1_car_angularvelocity#)






    //TEMP - SCREEN LIMITS
    IF ( CAR1_car_position_wc_x# < 0.0 )
    CAR1_car_position_wc_x# = 800.0
    ENDIF
    IF ( CAR1_car_position_wc_x# > 800.0 )
    CAR1_car_position_wc_x# = 0.0
    ENDIF
    IF ( CAR1_car_position_wc_y# < 0.0 )
    CAR1_car_position_wc_y# = 600.0
    ENDIF
    IF ( CAR1_car_position_wc_y# > 600.0 )
    CAR1_car_position_wc_y# = 0.0
    ENDIF
ENDFUNCTION

#26
I've only just started playing around with it, but early indications are that it's very good!
http://sourceforge.net/projects/camstudio/

From their website (so people don't have to go looking  :) )
QuoteCamStudio can also add high-quality, anti-aliased (no jagged edges) screen captions to your recordings in seconds and with the unique Video Annotation feature you can even personalise your videos by including a webcam movie of yourself "picture-in-picture" over your desktop.

And if all that wasn't enough, CamStudio also comes with its own Lossless Codec that produces crystal clear results with a much smaller filesize compared with other more popular codecs, like Microsoft Video 1.

You have total control over the output of your video: you can choose to use custom cursors, to record the whole screen or just a section of it and can reduce or increase the quality of the recording depending on if you want smaller videos (for emailing to people, for instance) or you can have "best quality" ones for burning onto CD/DVD.

My early tests aren't shopping any of the lag I've seen people comment about here when they've done recordings.
#27
As per my earlier post (http://www.glbasic.com/forum/index.php?topic=4152.0), I'm classing this as a bug.

I have a client and server app which get connected by a TCP socket. If one side has a failure of some description, both sides close their sockets. If I then try to recreate the socket without restarting my application, it refuses to do so - the Server's SOCK_TCPACCEPT returns "10035 A non-blocking socket operation could not be completed immediately."
There's also a bug in that the following SOCK_TCPCONNECT on the Client manages to connect to the broken socket, but then constantly returns a -2 return code (a non-blocking socket operation could not be completed immediately).

Here's a test program which is as simple as I could make it while checking each command for an error return code. It's a console application so make sure you compile it as such.
Run two copies side by side, one as the server, one as the client. Here's the code, results follow
Code (glbasic) Select
GLOBAL Net_ServerIP$
GLOBAL EstablishedConnection
GLOBAL Net_PortNumber
GLOBAL Done

Net_PortNumber=1234
Net_ServerIP$="127.0.0.1"

SOCK_INIT()

GLOBAL XLOC,YLOC
// MAIN
//-------------------------------------------------------------------------
Done=0
YLOC=0
XLOC=0
LOCAL Result$

STDOUT "Press s to be server\n"
STDOUT "Press c to be client\n"

WHILE Done=0
Result$=INKEY$()
IF Result$ = "s" // pressed 1
STDOUT "Server\n"
DEBUG "Server-debug\n"
GOSUB server
Done=1
ELSEIF Result$= "c" // pressed 2
STDOUT "Client\n"
DEBUG "Client-debug\n"
GOSUB Client
Done=1
ENDIF
WEND
//-------------------------------------------------------------------------


//-------------------------------------------------------------------------
SUB server:
LOCAL Done=0,RV=0
LOCAL ClientIPAddress%
LOCAL Sock%


Sock=SOCK_TCPLISTEN(Net_PortNumber) // Listen for connections on our socket
IF Sock=-1
STDOUT "Server : SOCK_TCPLISTEN error. TCPLISTEN returned "+Sock+"\n"
STDOUT "Error was : " + NETGETLASTERROR$() + "\n"
SLEEP 4000
END
ENDIF

STDOUT "Server : Waiting for connection with TCPACCEPT...\n"
// STDOUT "'1' to exit.\n"
WHILE Done=0
EstablishedConnection=SOCK_TCPACCEPT(Sock,ClientIPAddress) // Check for established client connection
IF EstablishedConnection <> -1
Done=1 // If a connection was successful
ENDIF

// IF INKEY$() = "1" // quit
// STDOUT "Exiting...\n"
// SLEEP 1000
// END
// ENDIF
WEND

// We now have a connection
STDOUT "\nServer : Sending message '1'\n"
RV = SOCK_TCPSEND(EstablishedConnection,"1")
STDOUT "Server : TCPSEND Return value = " + RV + "\n"
IF RV=-1
STDOUT "Error occurred using TCPSEND to send data.\n"
STDOUT "Error was : " + NETGETLASTERROR$() + "\n"
SLEEP 4000
END
ENDIF

STDOUT "When message has been received by client, press '2' to break connection\n"
Done=0
WHILE Done=0
IF INKEY$() = "2"
RV=SOCK_CLOSE(EstablishedConnection)
IF RV <> TRUE
STDOUT "Server : Error breaking connection : RV = " + RV + "\n"
STDOUT "Error was : " + NETGETLASTERROR$() + "\n"
SLEEP 4000
END
ELSE
STDOUT "Server : Connection broken : RV = " + RV + "\n"
STDOUT "Sleeping for 2 seconds.\n\n\n\n"
Done=1
ENDIF
ENDIF
WEND
SLEEP 2000

STDOUT "Server Waiting for connection again with TCPACCEPT...\n"
// STDOUT "'3' to exit.\n"

Sock=SOCK_TCPLISTEN(Net_PortNumber) // Listen for connections on our socket
Done=0
WHILE Done=0
EstablishedConnection=SOCK_TCPACCEPT(Sock,ClientIPAddress) // Check for established client connection
IF EstablishedConnection > 0 THEN Done=1 // If a connection was successful
IF EstablishedConnection = -1
STDOUT "Server : SOCK_TCPACCEPT error\n"
STDOUT "Error was : " + NETGETLASTERROR$() + "\n"
SLEEP 4000
END
ENDIF
// IF INKEY$() = "3" // esc
// SLEEP 4000
// END
// ENDIF
WEND

// We now have a second connection
STDOUT "Server : Sending message '2'\n"
RV=SOCK_TCPSEND(EstablishedConnection,"2")
STDOUT "Server : TCPSEND Return value = " + RV + "\n"
IF RV=-1
STDOUT "Error occurred - error was : " + NETGETLASTERROR$() + "\n"
SLEEP 4000
END
ENDIF

STDOUT "When message received by client, press '4' to break connection\n"
Done=0
WHILE Done=0
IF INKEY$()="4"
RV=SOCK_CLOSE(EstablishedConnection)
IF RV <> TRUE
STDOUT "Server : Error breaking connection : RV = " + RV + "\n"
STDOUT "Error was : " + NETGETLASTERROR$() + "\n"
SLEEP 4000
END
ELSE
STDOUT "Server : Connection broken : RV = " + RV + "\n"
STDOUT "Sleeping for 2 seconds.\n"
Done=1
ENDIF
ENDIF
WEND

DEBUG ("Server Done\n")
SLEEP 4000
ENDSUB

//-------------------------------------------------------------------------
SUB Client:
LOCAL Done=0
LOCAL RV
LOCAL ReceivedMessage$
LOCAL YLoc=50

STDOUT "Client : Establishing connection with "+Net_ServerIP$+" on port "+Net_PortNumber+"...\n"
EstablishedConnection=SOCK_TCPCONNECT(Net_ServerIP$,Net_PortNumber) // Try to connect to server
IF EstablishedConnection = -1 // Failure
STDOUT "Client : Network error : client failed to create connection"
STDOUT "Client : Error was : " + NETGETLASTERROR$() + "\n"
SLEEP 4000
END
ELSE
STDOUT "Connection Established. EstablishedConnection variable = " + EstablishedConnection + "\n"
ENDIF

STDOUT "Waiting for first message\n"
SLEEP 1000 // allow messages to cache
LOCAL Done=0
WHILE Done=0
RV=SOCK_RECV(EstablishedConnection, ReceivedMessage$, 1023) // Get first message
IF RV=0 // Error
STDOUT "Client : Remote end has disconnected : RV = " + RV + "\n"
STDOUT "Client : Error was : " + NETGETLASTERROR$() + "\n"
STDOUT "Closing socket...\n\n"
SOCK_CLOSE(EstablishedConnection)
STDOUT "Sleeping for 4 seconds....\n"
SLEEP 4000
Done=1
ELSEIF RV = -1 // Error
STDOUT "Client : Network error has occurred : RV = " + RV + "\n"
STDOUT "Client : Error was : " + NETGETLASTERROR$() + "\n"
STDOUT "Closing socket...\n\n"
SOCK_CLOSE(EstablishedConnection)
STDOUT "Sleeping for 4 seconds....\n"
SLEEP 4000
Done=1
ELSEIF RV=-2 // Nothing waiting in the queue
STDOUT "Client : Socket not ready (returned -2). Sleeping for 1 second.\n"
SLEEP 1000
// ELSEIF KEY(1)=1 // ESC
// SLEEP 4000
// END
ELSE
STDOUT "Client : Message length received : "+ RV +"   Message recieved = " + ReceivedMessage$ + "\n"
ENDIF
WEND


// END OF FIRST MESSAGE ----------------------------------------------------------

STDOUT "Client : Reestablishing connection with "+Net_ServerIP$+" on port "+Net_PortNumber+"...\n"
EstablishedConnection=SOCK_TCPCONNECT(Net_ServerIP$,Net_PortNumber) // Try to connect to server
IF EstablishedConnection = -1 // Failure
STDOUT "Client : Network error : client failed to create connection"
STDOUT "Client : Error was : " + NETGETLASTERROR$() + "\n"
SLEEP 4000
END
ELSE
STDOUT "Connection Established. EstablishedConnection variable = " + EstablishedConnection + "\n"
ENDIF

STDOUT "Waiting for second message\n"
Done=0
WHILE Done=0
RV=SOCK_RECV(EstablishedConnection, ReceivedMessage$, 1023) // Get second message
IF RV=0 // Error
STDOUT "Client : Remote end has disconnected : RV = " + RV + "\n"
STDOUT "Client : Error was : " + NETGETLASTERROR$() + "\n"
SLEEP 4000
END
ELSEIF RV = -1 // Error
STDOUT "Client : Network error has occurred : RV = " + RV + "\n"
STDOUT "Client : Error was : " + NETGETLASTERROR$() + "\n"
SLEEP 4000
END
ELSEIF RV=-2 // Nothing waiting in the queue
STDOUT "Client : Socket not ready (returned -2). Sleeping for 1 second.\n"
SLEEP 1000
ELSE
STDOUT "Client : Message length received : "+ RV +"   Message recieved = " + ReceivedMessage$ + "\n"
ENDIF
WEND

STDOUT "When message received from server , press 1 to break connection\n"
Done=0
WHILE Done=0
IF KEY(2)=1
RV=SOCK_CLOSE(EstablishedConnection)
IF RV <> TRUE
STDOUT "Client : Error breaking connection : RV = " + RV + "\n"
STDOUT "Client : Error was : " + NETGETLASTERROR$() + "\n"
SLEEP 4000
END
ELSE
STDOUT "Client : Connection broken : RV = " + RV + "\n"
STDOUT "Client : Sleeping for 2 seconds.\n"
Done=1
ENDIF
ENDIF
WEND
SLEEP 4000

ENDSUB




Results
(I've copied the output in the order you'll see it from the two application windows)

I start the application and choose "s" to run the Server. It runs a SOCK_TCPLISTEN then loops with a SOCK_TCPACCEPT :
QuotePress s to be server
Press c to be client
Server
Server : Waiting for connection with TCPACCEPT...

I run the second copy choosing "c" to run the Client. It runs a SOCK_TCPCONNECT, establishes the connection, then loops on a SOCK_RECV waiting for data.
Quote
Press s to be server
Press c to be client
Client
Client : Establishing connection with 127.0.0.1 on port 1234...
Connection Established. EstablishedConnection variable = 0
Waiting for first message

The Server sends a 1 character string - "1" with SOCK_TCPSEND:
QuoteServer : Sending message '1'
Server : TCPSEND Return value = 1
When message has been received by client, press '2' to break connection

The Client receives the 1 character string "1":
QuoteClient : Message length received : 1   Message recieved = 1

Server : I press the "2" key which runs a SOCK_CLOSE and breaks the connection.
QuoteServer : Connection broken : RV = 1
Sleeping for 2 seconds.

Client : The client's looping SOCK_RECV gets a return value of 0 and determines that the link has closed. It runs a SOCK_CLOSE (so both sides now have shut down the link) and sleeps for 4 seconds.
QuoteClient : Remote end has disconnected : RV = 0
Client : Error was : 0 The operation completed successfully.

Closing socket...

Sleeping for 4 seconds....

Server : This is where the problem is. The server then runs the TCPLISTEN (doesn't return -1 which is the only error code listed in the manual). It then tries to recreate the connection with a SOCK_TCPACCEPT. This returns -1, the error is a non-blocking socket error.
Quote
Recreating connection with TCPLISTEN
Server Waiting for connection again with TCPACCEPT...
Server : SOCK_TCPACCEPT error
Error was : 10035 A non-blocking socket operation could not be completed immediately.

Client : And the other half of the problem The client then runs a SOCK_TCPCONNECT (which doesn't fail even though the server isn't listening).  The SOCK_RECV's that run afterwards all return a -2 return value (socket not ready)
QuoteClient : Reestablishing connection with 127.0.0.1 on port 1234...
Connection Established. EstablishedConnection variable = 0
Waiting for second message
Client : Socket not ready (returned -2). Sleeping for 1 second.
Client : Socket not ready (returned -2). Sleeping for 1 second.

The client then dies as the server program dies (breaking the faulty network link).
Quote
Client : Remote end has disconnected : RV = 0
Client : Error was : 10054 An existing connection was forcibly closed by the remote host.
#28
I'll write a test program for this tomorrow but here's what I've seen in my program. If I can reproduce it in a very small test program I'll list it as a bug.

If I have a network error (due to a bug in my code  ;) ) both my client and server do a sock_close on the connection.
If, without restarting my program, I try and start the game again, the SOCK_TCPCONNECT returns -2 (a non-blocking socket operation could not be completed immediately).

So I tried putting a sock_close at the top of my client and server functions, just before they do the SOCK_TCPCONNECT and SOCK_TCPACCEPT. This didn't help.

I tried debugging it and put a breakpoint on my SOCK_TCPCONNECT line. After breaking the first connection, I started the server then the client. With the breakpoint it now established the connection. I try that a second time and now (and every time after) it returns -2 again.

Thoughts?
#29
This is just for interest reasons. I'm wondering why the following doesn't work (assuming all you typed was the enter key)
Code (glbasic) Select
input string$,0,0
if mid$(string$,0,1) = CHR$(0)

...

but the following will work
Code (glbasic) Select
input string$,0,0
if mid$(string$,0,1) = "\0"


The second option is fine for my code, but I'm curious as to why the first one won't work as well.
#30
The DeleD 3D software modeller that was previously about $80 US (from memory) to purchase has just gone open source. It's not the best modeller in the world,  but it isn't too bad either - it's a lot more intuitive to use than Blender. Hopefully it will improve quickly now it's open sourced (they're hoping for a 3 week release cycle on updates) so fingers crossed it'll soon be the best free 3D modeller around.

http://www.delgine.com/
#31
I can't find it documented anywhere that it shouldn't work, nor can I find any posts about it.
Trying the following code (compiling it as a console program) you'll see that the key() commands aren't working

Console version

Code (glbasic) Select
STDOUT "Press 1 to be server\n"
STDOUT "Press 2 to be client\n"

WHILE Done=0
IF KEY(02) = 1 // pressed 1
STDOUT "Server\n"
DEBUG "Server-debug\n"
ELSEIF KEY(03) = 1 // pressed 2
STDOUT "Client\n"
DEBUG "Client-debug\n"
ENDIF
WEND


Non console version to compare it to
Code (glbasic) Select

WHILE Done=0
PRINT "Press 1 to be server\n",0,0
PRINT "Press 2 to be client\n",0,20

IF KEY(02) = 1 // pressed 1
PRINT "Server\n",0,30
DEBUG "Server-debug\n"
ELSEIF KEY(03) = 1 // pressed 2
PRINT "Client\n",0,40
DEBUG "Client-debug\n"
ENDIF
SHOWSCREEN
WEND
#32
I'm putting this here in case someone has the same problem at some point.

I have been running two copies of my program simultaneously - one a client, the other a server. Once I started the client, the server would seem to freeze and the screen would be blank when I swapped back to it. To close it I had to force close the program (it. it went into "this program is not responding" status).
Similarly if I swapped to running the client then the server, the client would "freeze".
The problem was a actually rather obvious - the code was looping waiting for a particular response from the other program, and wasn't doing a SHOWSCREEN (as I had stupidly assumed the screen would still populated from the previous SHOWSCREEN when I wrote that bit of code). As I found in another post, SHOWSCREEN does more than just show the inactive buffer, and without it you have trouble closing windows.

So if you have this problem, check you're updating the screen with SHOWSCREEN's even when you don't think you need to.
#33
The original SOCK_RECV() would chop your messages up nicely by stopping reading when a '\0' was read.
This was changed after I found I couldn't transmit binary files due to \0 characters through them.

Now I've found I could really do with two versions of the SOCK_RECV command.
1) The current one that will read \0 as part of the stream (for binary transfers)
2) One that terminates at \0 for non-binary transfers (i.e. the way SOCK_RECV used to work)

Currently if you send something like
Code (glbasic) Select
SOCK_TCPSEND([socket],"SetLives=1")
SOCK_TCPSEND([socket],"SetLevel=14")
SOCK_TCPSEND([socket],"ResetHighScoreTable")


then do a
Code (glbasic) Select

SOCK_RECV([socket],LivesString$,1023)
SOCK_RECV([socket],LevelString$,1023)
SOCK_RECV([socket],ResetString$,1023)

InputString will contain "SetLives=1SetLevel=14ResetHighScoreTable" and LevelString$/ResetString$ will probably be empty. And it's not always consistent that all the output will be in the first SOCK_RECV() output as it depends on the timing when you run the SOCK_RECV command.

Having a new command that terminates on the '\0' means I could do 3 separate SOCK_RECV() calls and get each parameter and its setting separately for processing. Without it, I'm currently having to do something similar to the following (this is just an example, mines slightly more efficient)
Code (glbasic) Select

Server
=======
SOCK_TCPSEND([socket],"SetLives=1")

Client
======
while Message$=""
    SOCK_RECV([sock],Message$,1023)
wend
if Message$="SetLives"
    SOCK_TCPSEND([socket],"Acknowledged")

Server
=======
while Message$=""
    SOCK_RECV([sock],Message$,1023)
wend
if Message$="Acknowledged"
    SOCK_TCPSEND([socket],"SetLevel=14")

[...]

and so on which wastes time waiting for acknowledgements and causes excess network chatter, or some really annoying string manipulations to strip each different length string off the network stream.
#34
I'm currently testing my board game's network mode and I'm trying to get all the bugs out of my code.

I'm running the "server" version of the app on one pc (no GLBasic, just running the .exe), and the "client" on the pc running GLBasic in debug mode.

The server stops after a couple of seconds if it doesn't get the right responses from the client (I've set up challenge/response communication to tell the client when to progress). Once the server has stopped executing though, my client (currently) sits in a loop checking for network messages and attempting to process them. After the server has stopped itself, any time the client runs a SOCK_RECV it is not returning a -1 length for error. Instead it's returning 0, and a GETLASTERROR command straight after the SOCK_RECV is returning Error : 0000 success.

My understanding is that SOCK_RECV should return -1 if there's a problem reading from the socket - and I think the socket closing would count as an error  :)

It's getting too late to write a test program here, but I'll try to write one tomorrow if noone has replied with a solution to catching the network dropout.
#35
I can't figure out a way to know what my IP address is. Can you please provide a command to return it? (assuming I'm not overlooking some easy way to do it).

#36
Very limited time birthday sale : pay what you want (as little as $0.01US) for crayon physics deluxe (winner 2008 Independant Games Festival). Normal price $19.95US
http://www.crayonphysics.com
#37
I've found that with a project with multiple files in it, if I try to remove several one after the other, I can only remove one or two then I can't remove any more. If I then go and open one of the source files in the project, I can remove another one or two before I can't get rid of them again.

I had just had a crash (http://www.glbasic.com/forum/index.php?topic=4052.new#new) which may have corrupted something in GLBasic though other than just my gbap file.
I've tried it on two projects and found the same problem.

I just found it may only happen if you right click the file to delete then click delete it. If you left click to select the file, then right click to bring up the menu it works.
#38
I never used to have problems prior to 7.230, but now I'm finding I'll be intermittantly running my code in debug and get a "program has done something unexpected and needs to close" type error.
The last one just corrupted my gbap file (it's looking for all my files in "d:\game projects" rather than "d:\game projects\battleship" and as a result can't find any files).
It's not frequent enough to pinpoint an exact problem so far, but I'll be interested to hear if anyone else is having issues.
#39
I have a 32x32 texture (right hand side of the image - resized to make it easily visible). It's saved as a 24bit png, but there's no alpha data, it's just a plain 3 colours.

I've created a 3D object (just a quad) as follows
Code (glbasic) Select
O_GridHitMiss=GENX_OBJ()
X_OBJSTART O_GridHitMiss
X_OBJADDVERTEX   0, 0, 1, 1, 0, RGB(255,255,255) // Create quad
X_OBJADDVERTEX   0, 0, 0, 1, 1, RGB(255,255,255)
X_OBJADDVERTEX   1, 0, 1, 0, 0, RGB(255,255,255)
X_OBJADDVERTEX   1, 0, 0, 0, 1, RGB(255,255,255)
X_OBJEND


When I texture it with the image, and display it on screen
Code (glbasic) Select
X_SETTEXTURE T_GridHit2, -1
X_MOVEMENT XLoop, 0, YLoop
X_DRAWOBJ O_GridHitMiss,0


I get the awful greeny colour around the edges of the "2". Anyone have any ideas how I stop that happening?

[attachment deleted by admin]
#40
If your program ends successfully (for example you hit ESC to quit it), the debug tab's information isn't updated to show whatever values the variables contained on the program's end.

Also on an error, the information isn't updated - if your code hits an "Out of DIM array" error, the information in the debug tab doesn't get updated.
e.g.
Code (glbasic) Select
GLOBAL b[]
LOCAL a

a=4
DIMDATA b[],1,2,3

DEBUG "b[a] = "+b[a]+"\n"


This is a pain if, in the above example, you were setting the value of "a" via a loop and wanted to know what value it was hitting when it exceeded the array bounds.