2015-03-10 04:08:51

Hi.
Well I am working on learning python but I also need to learn pure basic. So I was wondering has anyone tried to learn 2 languages at once and if so is this possible?
Pure basic is my priority right now so I might end up dropping python for a while but I really don't want to do that because I'm really enjoying python.

Guitarman.
What has been created in the laws of nature holds true in the laws of magic as well. Where there is light, there is darkness,  and where there is life, there is also death.
Aerodyne: first of the wizard order

2015-03-10 04:59:37

Possible? yes.  But really it depends on you.  If you know one language well, new languages are something like a few hours.  If you've never mastered one, it might be a struggle because you're trying to master programming at the same time.
In this case, be aware that purebasic is essentially C made pretty.  Not even C made more sane, just C with some nicer syntaxes, a less powerful optimizer, and some good built-in libraries.  This is about as different from Python as one can get without going into what is known as functional programming.  To that end, maybe you can.  But it's harder than, say, Python and Ruby.  Or Python and C#.  Or even Python and BGT.  The combination in question is about as diametrically opposite as you can get.
I'd not try unless you don't have a choice.  Learn programming, then learn languages.  Do not fall into the trap of "Danny used Purebasic for DMNB, so it must be the most amazing thing ever".  The statement here does not reflect on the language.  The statement here reflects on the programmer.
But the more interesting question, can you program in two languages at once?  And the answer is yes, It's not super desirable, but I nevertheless do it all the time.  And I don't mean switching back and forth every half hour.  There are days I have Python in one window and C++ in another window and they're in the same project.  Reasoning about program logic is pretty language-neutral, the rest is just details.  The real problem is that you learn how to reason about program logic by mastering a programming language in the first place, so until you've done that picking up more can be a challenge.

My Blog
Twitter: @ajhicks1992

2015-03-10 05:21:57

Hello Camlorn.
I sent you a pm it explains everything.

Guitarman.
What has been created in the laws of nature holds true in the laws of magic as well. Where there is light, there is darkness,  and where there is life, there is also death.
Aerodyne: first of the wizard order

2015-03-10 14:45:10

I pretty much learned Javascript and Java at the same time, but it helps that they're syntactically quite similar (though they're incredibly different when you get to the details. I didn't get to read my Java text for the first loop assignment, so filled in what I didn't know with Javascript; the only issue was that I stuck "var" in where it didn't belong.)

看過來!
"If you want utopia but reality gives you Lovecraft, you don't give up, you carve your utopia out of the corpses of dead gods."
MaxAngor wrote:
    George... Don't do that.

2015-03-10 14:59:48

It is indeed possible. You just have to know one programming language while attempting to learn another. Basically, if you put your mind to it, you can do it. If your easily distracted, though, it becomes a problem.

"On two occasions I have been asked [by members of Parliament!]: 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out ?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question."    — Charles Babbage.
My Github

2015-03-11 02:01:39

Hmm, interesting topic.
  I've never tried to accomplish this task before, however I believe it could be possible. However, as Camlorn said, you should probably know programming. Personally, I had to learn pure basic before I even downloaded BGT. I'm not quite sure why, but I was able to learn the concepts of programming by way of learning pure basic, rather than bgt. The main reason for this, though, is that I prefer to learn by experimenting and trying things out, whereas BGT's manual explains what a variable is, what a function is etc, and hearing the technical explanations of what variables are and the types and functions and all of that just confuses me.

If you have issues with Scramble, please contact support at the link below. I check here at least once a day, so this is the best avenue for submitting your issues and bug reports.
https://stevend.net/scramble/support

2015-03-11 06:05:15

Hi Severestormsteve.
I learn the same way sort of. I've had a look at the pb reference where I've been looking up things I'm interested in like playing and panning a sound and creating a menu. I was really surprised it's really easy to find exactly what I want instead of learning something I'm not interested in. I understand the basic concepts of variables and what do and I can understand things like loops.
I believe camlorn might be right learning pb may not be the risest choice but I think right now I will focus on pb. I believe that whatever knowledge that I lose learning pb I can always gain when I have developed some programming skills.
And severestormsteve I don't know if your religious or not but just in case you are can you pray that I will be able to learn programming. It's all I've wanted to do for years.

Guitarman.
What has been created in the laws of nature holds true in the laws of magic as well. Where there is light, there is darkness,  and where there is life, there is also death.
Aerodyne: first of the wizard order

2015-03-11 11:13:11

If you want my advice on this ishue, I started initially out with bgt, but moved on to pure basic after I had completely done my limits with bgt itself, I know their are a bit of things I skipt but as far as I caired, I was ready to move on. Though i've tried to keep both in mined as I do have a few friends who use bgt, over time i've slowly forgotten half the basic skills needed to use the thing. I can do a bit of classes, but if you ask me about serialization you may as well ask a tree instead for the help I can give. As camlorn said though, it really depends on the programmer as well. Keep in mined, pure basic is my personal choice of language, but by no means is it the best, nore is it always perfect. The story of dmnb's development has been riddled with constant dips and climbs, but if you have the desire and you really push yourself, the project will continue. By all means, their's still a lot of complaints I have about pure basic, somethings I just wish the developer would fix, such as  being able to easyly remove an element from an array that would really help a lot! Over all, choose the one that you feel most cumffy with and stick with it, if you let other people try to make you change to their language of choice all the time, very soon your gonna wind up worce off. I've had several people tell me pure basic stinks, why don't I use something like bgt, or migrate to c++, and the simpple answer is, i'm cumffy and setteled in with pure basic, and I won't be ready to move any time soon.

Check out the new reality software site. http://realitysoftware.noip.us

2015-03-11 15:46:59

I tried to just answer the question, but this thread is now perpetuating the outright myth that Purebasic is in any way a good thing.  At all.
Purebasic is not like C.  Purebasic is C.  They are almost one-for-one the same in terms of features, just Purebasic gives you some nice syntax and built-in libraries.  In every thread that talks about Purebasic, you can safely mentally replace it with C.  You can get the Purebasic features by just installing C libraries.
You have written an online game in C.  Congratulations.  But you're not going to be fixing the core problems with it.  Security and lag must be fixed in the code on day one or it's too late.
And you're not only going to keep writing your stuff in C, you're suggesting that everyone else should too.  All those crashes you have?  I'd be willing to bet over half of them are what's called an invalid pointer.  Invalid pointers are a C problem.  Other languages at least tell you what really happened and don't let you accidentally clobber the stack because you incremented a variable once too many times.  But you've also given up actually being in C, which lets you use the world of C libraries.  So yeah, good luck with that.
If you are thinking about using Purebasic, then go learn about why people consider C to be a liability and stop.  Everything there applies to Purebasic too.  Everything.

My Blog
Twitter: @ajhicks1992

2015-03-11 20:09:11

If I were you, I would go on with python and look into learning pyglet.
python has the nice ability that it can connect with C and C++, so that is why camlorn has 2 windows open.
In c++ it takes over twice the number of lines than it does in python to do anything.
The classic example is hello world:
python:
print("Hello world")
c++
#include <iostream>
int main()
{
std::cout << "Hello world" << std::endl;
return 0;
}


Then you need a compiler and all kinds of things where as with python, you don't need to worry about that till you know the language and have a game you wish to distribute.
But in pyglet, it is super fast to create a screen:
import pyglet
window = pyglet.window.Window(caption="My window")
pyglet.app.run()


As for learning 2 languages at once:
I always compare languages to python, so when I work on the backend of my website in PHP, I always am thinking how much better python is. Same goes for javascript.
C++ is a little different because my goal is to do things fast in C++ then return the results to python. But also, I can see python in C++, it is very very clear.
I think one may get a little lost if they tried to learn javascript and python together, but something syntactically different like c and python should be fine.
But learning French and Italian at the same time is almost impossible as I found to my dismay!

2015-03-11 23:00:06 (edited by Ethin 2015-03-11 23:02:30)

In C, creating a window on windows using the windows API goes something like:
#if defined(UNICODE) && !defined(_UNICODE)
    #define _UNICODE
#elif defined(_UNICODE) && !defined(UNICODE)
    #define UNICODE
#endif

#include <tchar.h>
#include <windows.h>

/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/*  Make the class name into a global variable  */
TCHAR szClassName[ ] = _T("Test");

int WINAPI WinMain (HINSTANCE hThisInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszArgument,
                     int nCmdShow)
{
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */

    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default colour as the background of the window */
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;

    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
           _T("Test"),       /* Title Text */
           WS_OVERLAPPEDWINDOW, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           544,                 /* The programs width */
           375,                 /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           hThisInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
           );

    /* Make the window visible on the screen */
    ShowWindow (hwnd, nCmdShow);

    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 0, 0))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }

    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam;
}


/*  This function is called by the Windows function DispatchMessage()  */

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)                  /* handle the messages */
    {
        case WM_DESTROY:
            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
            break;
        default:                      /* for messages that we don't deal with */
            return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}
Of course, I do like languages that make creating windows easier. That code was 94 lines of code, and I don't like typing that. I should read the Pyglet documentation to learn how it works. The windows API, in my opinion, is useless, overcomplicated, and quite stupid.

"On two occasions I have been asked [by members of Parliament!]: 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out ?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question."    — Charles Babbage.
My Github

2015-03-11 23:37:00

I wasn't suggesting everyone use pure basic, I was meerly saying pick which ever suits you, I didn't know that listing down my personal opinion on pb was such a bad thing. For the record, I do not think pure basic is perfect, their are still plenty of ishues with it. The crashes you speak of are not invalid memory pointers, they are errors on my part with the network code, and while this is partly my falt, I had difficulty in testing that bit because most of my testers were not online people or didn't come online to help test very much. Also, pure basic is not c, it is basic, their's a difference.

Check out the new reality software site. http://realitysoftware.noip.us

2015-03-12 03:54:19 (edited by The Dwarfer 2015-03-12 05:20:32)

I'm same as Danny: I've adjusted to purebasic, and won't be going anyware soon. Perhaps, when I finish my game, I'll check out BGT, or perhaps pyaudiogame, though the latter is highly unlikely because again, I don't like the indentions facter.
  However, though purebasic suits me well, I can point a few flaws out with it: the array thing as danny said. As far as I know it's impossible to pack files into an executable, which can be rather bothersome in applications that utilize files that can, but preferably shouldn't, be modified.
@guitarman working with arrays in pb can get cumbersome at times. Look at this example where I try to access a random element in the array:
players(random(ArraySize(players()), 1)). In other words, when you really start working with arrays like that, you'll have to be very careful. Also, the clipboard can come in handy, especially if you have to write similar lines of code repeatedly.
Another hard examples of arrays, where I access a piece of the race track that corresponds with a player's Y coordinate.
Track(players(1)\y)
will access track array index 0 if the player's y is 0, 1 if it's 1, etc.
Also, depending on the way you program your game or whatever, you could just as well end up with 5 nested if statements: it's happened to me before.
However, please note that when you perform errors in your code, the debugger is very helpful at diagnosing app crashes and the compiler will give you relatively English-like explanations of your error.
  If anything, wouldn't purebasic be similar to things like vb, free basic, or something? Those are basic languages.
At Danny yes it's a basic language, but pb might be similar to C as far as features and libraries goes, that doesn't necessarily mean sintax.
PS. It's funny you mention the Christian thing, guitarman. I was saved on January 4, 2015... so yeah I am! It's only been for 2 months though. Anyways I'll pray for you

If you have issues with Scramble, please contact support at the link below. I check here at least once a day, so this is the best avenue for submitting your issues and bug reports.
https://stevend.net/scramble/support

2015-03-12 06:06:44 (edited by Ethin 2015-03-12 06:14:50)

@Camlorn, please read exactly what others post about programming languages before you go on rants like you did in post 9. You did not realize what Danny was saying. He did not say that everyone should use PB. He just said he's comfortable with it. Again, I ask you nicely to re-read Danny's posts.
Edit:
PB is not C in any way, shape or form. It does not have the syntax that C has; it does not use any C libraries whatsoever; and it does not generate C code and then use another compiler to accomplish its goal. It, in fact, uses pure assembly. Every single library is written in assembly and converted to binary code using the Flat Assembler (fasm.exe on Windows, fasm on Linux, and Yasm on OS X). When you compile something, it translates your code to assembly and then assembles and links the code.
As an example, I'll demonstrate this in practice:
In PB, asking the user for input is as simple as doing:
PrintN ("Enter a message.")
Input()
When compiling PB code, the compiler takes this code and translates it into the following:
;
; PureBasic 5.31 (Windows - x86) generated code
;
; (c) 2014 Fantaisie Software
;
; The header must remain intact for Re-Assembly
;
; Console
; :System
; KERNEL32
; :Import
;
format MS COFF
;
;
extrn _PB_Input
extrn _PB_PrintN
extrn _ExitProcess@4
extrn _GetModuleHandleA@4
extrn _HeapCreate@12
extrn _HeapDestroy@4
extrn _memset
extrn PB_StringBase
extrn _SYS_InitString@0
extrn _SYS_FreeStrings@0
;
extrn _PB_StringBasePosition
public _PB_Instance
public _PB_ExecutableType
public _PB_OpenGLSubsystem
public _PB_MemoryBase
public PB_Instance
public PB_MemoryBase
public _PB_EndFunctions

macro pb_public symbol
{
  public  _#symbol
  public symbol
_#symbol:
symbol:
}

macro    pb_align value { rb (value-1) - ($-_PB_DataSection + value-1) mod value }
macro pb_bssalign value { rb (value-1) - ($-_PB_BSSSection  + value-1) mod value }

public PureBasicStart
;
section '.code' code readable executable align 4096
;
;
PureBasicStart:
;
  PUSH   dword I_BSSEnd-I_BSSStart
  PUSH   dword 0
  PUSH   dword I_BSSStart
  CALL  _memset
  ADD    esp,12
  PUSH   dword 0
  CALL  _GetModuleHandleA@4
  MOV    [_PB_Instance],eax
  PUSH   dword 0
  PUSH   dword 4096
  PUSH   dword 0
  CALL  _HeapCreate@12
  MOV    [PB_MemoryBase],eax
  CALL  _SYS_InitString@0
; PrintN ("Enter a message.")
  PUSH   dword _S1
  CALL   dword [_PB_PrintN]
; Input()
  MOV    edx,[_PB_StringBasePosition]
  PUSH   edx
  PUSH   edx
  CALL   dword [_PB_Input]
  POP    dword [_PB_StringBasePosition]
_PB_EOP_NoValue:
  PUSH   dword 0
_PB_EOP:
  CALL  _PB_EndFunctions
  CALL  _SYS_FreeStrings@0
  PUSH   dword [PB_MemoryBase]
  CALL  _HeapDestroy@4
  CALL  _ExitProcess@4
_PB_EndFunctions:
  RET
;
;
section '.data' data readable writeable
;
_PB_DataSection:
_PB_OpenGLSubsystem: db 0
pb_public PB_DEBUGGER_LineNumber
  dd     -1
pb_public PB_DEBUGGER_IncludedFiles
  dd     0
pb_public PB_DEBUGGER_FileName
  db     0
pb_public PB_Compiler_Unicode
  dd     0
pb_public PB_Compiler_Thread
  dd     0
pb_public PB_Compiler_Purifier
  dd     0
pb_public PB_Compiler_Debugger
  dd     0
_PB_ExecutableType: dd 0
public _SYS_StaticStringStart
_SYS_StaticStringStart:
_S1: db "Enter a message.",0
pb_public PB_NullString
  db     0
public _SYS_StaticStringEnd
_SYS_StaticStringEnd:
align 4
align 4
align 4
s_s:
  dd     0
  dd     -1
align 4
;
section '.bss' readable writeable
_PB_BSSSection:
align 4
;
I_BSSStart:
_PB_MemoryBase:
PB_MemoryBase: rd 1
_PB_Instance:
PB_Instance: rd 1
;
align 4
PB_DataPointer rd 1
align 4
align 4
align 4
align 4
I_BSSEnd:
section '.code' code readable executable align 4096
section '.data' data readable writeable
SYS_EndDataSection:

That is what happends during compilation: Write PB code, check the sntax, covert the code to ASM, check the ASM code with FASM, assemble it, and link it to produce an executable program.

"On two occasions I have been asked [by members of Parliament!]: 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out ?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question."    — Charles Babbage.
My Github

2015-03-12 19:02:49 (edited by The Dwarfer 2015-03-12 19:06:42)

I agree with Ethin here. Contrary to Danny trying to get everyone to use purebasic, it seems, Camlorn, that you're trying to get people to not use it.

  I'm just saying, I'm sick of when people so mutch as mention pure basic, it's "oh noooooo! That's so bad!" when did you use pure basic, Camlorn? What exact version did you use? What were the features?
But unless you develop or have in the very near past with purebasic, and no, not C, Pure, Basic, please don't try and tell those who actually have experience with more recent versions of the language what liability issues it has. We had Death Match, Snow Race, and now the game I'm working on... all were successes. So can you provide a recent example of the horridness of purebasic and quit just winning people away from it? Please? And while you're at it, I'd kindly ask with respect that you provide links to at least 2 articles from credible sources that back up your statements, that is, unless you've recently used pb.

If you have issues with Scramble, please contact support at the link below. I check here at least once a day, so this is the best avenue for submitting your issues and bug reports.
https://stevend.net/scramble/support

2015-03-12 19:56:19

Also, Camlorn, I would like to know where you found out that PB was C. What pot were you smoking - or what alcohol were you drinking when you wrote that post? It sounds like you were drunk or jacked up because I know that you wouldn't write a retort like that if you were in a normal state or normal mindset.
Now, I'm going to add to Steve's post by saying this: I know that all of PB's libraries are not C. Here's how:
The PB library maker says so. I quote this from its documentation:

PureBasic is a complete programming language which uses third party libraries (called 'PureLibraries' to avoid conflit with systems  libraries) to ease the programmer's life. These libraries can be wrote in ASM (with NAsm, FAsm etc.) or in C (with VisualC++, etc.).

Now, that said ASM or C. I can probably bet you 100 percent that every PureLibrary to date has been written in ASM. Some of them might be written in C, but that still doesn't mean you are writing something using C. This situation is just like any programming situation: Everything goes all the way back to C/C++. Every language does some sort of source-to-souce translation - from that language to another language and then to executable code - but that still doesn't mean you wrote it in C. When you write these things, please back them up.
As an example, let's examine some of the examples.
I'll start with the Visual C PureLibs, the SampleGadget one:
/*
*/

#include "ListIconSampleGadget.h"


/* Usage of the Data fields in the Gadget Structure:
*  [0] length of largest string in the Gadget
*  [1] pointer to PB_GadgetImageList for this gadget (0 if no images yet)
*  [2] GridLine Color
*  [3] internal flags (not Gadget flags), to know if custom colors are set etc
*/
#define DATA_MaxString  0
#define DATA_ImageList  1
#define DATA_GridColor  2
#define DATA_InternalFlags 3

// values for the InternalFlags field
//
#define FLAG_FrontColorSet     (1)
#define FLAG_BackColorSet      (1 << 1)
#define FLAG_DisplayGrid       (1 << 2)
#define FLAG_ThreeStateMode    (1 << 3) // 3state mode is on
#define FLAG_ThreeStateBlocked (1 << 4) // block state change in 3state mode

/* Storage of individual cell colors + user data for each item.
* This data is stored in a memoryblock which is stored in lParam of each item struct.
* It is only allocated when needed, so always check the lParam for 0!
* If the memory exists though, it has the number of cells inside as there are columns in the gadget.
*/
typedef struct
{
  int FrontColor; // colors are stored as (ColorValue+1), so 0 means no color stored yet
  int BackColor;
} PB_ListIconCell;

typedef struct
{
  integer UserData;
  PB_ListIconCell Cells[];
} PB_ListIconItem;
// only the base struct, not the following cells
#define SIZEOF_ListIconItem sizeof(integer)

static PB_GadgetVT ListIconVT;
static int         Initialized;
static int         OriginalFrontColor, OriginalBackColor;
static WNDPROC     StandardListIconCallback;

// -----------------------------------------------------------------------------------------

static M_GADGETVIRTUAL(integer) ListIcon_Callback(PB_Gadget *Gadget, HWND Window, UINT Message, WPARAM wParam, LPARAM lParam)
{
  integer Result = PB_EventNotProcessed;

  if (Message == WM_NOTIFY) // Handle any message here
  {
    Result = 0; // set Result to 0, if you don't want the event to be populated to next handlers
  }

  return Result;
}

// ---------------------------------------------------------------------------------------

static M_GADGETVIRTUAL(void) ListIcon_SetGadgetColor(PB_Gadget *Gadget, int ColorType, int Color)
{
}

// ---------------------------------------------------------------------------------------

static M_GADGETVIRTUAL(integer)  ListIcon_GetGadgetColor(PB_Gadget *Gadget, int ColorType)
{
  return 0;
}

// ---------------------------------------------------------------------------------------

static M_GADGETVIRTUAL(void) ListIcon_SetGadgetItemColor2(PB_Gadget *Gadget, int Item, int ColorType, int Color, int Column)
{
}

// ---------------------------------------------------------------------------------------

static M_GADGETVIRTUAL(int)  ListIcon_GetGadgetItemColor2(PB_Gadget *Gadget, int Item, int ColorType, int Column)
{
  return 0;
}

// ---------------------------------------------------------------------------------------

static M_GADGETVIRTUAL(void) ListIcon_FreeGadget(PB_Gadget *Gadget)
{
}

// ---------------------------------------------------------------------------------------

static M_GADGETVIRTUAL(void) ListIcon_FillColumns(PB_Gadget *Gadget, int Position, TCHAR *Cursor)
{
}

// ---------------------------------------------------------------------------------------

static M_GADGETVIRTUAL(integer) ListIcon_AddGadgetItem2(PB_Gadget *Gadget, int Position, const TCHAR *Text, int *Image)
{
  return 0;
}


// ---------------------------------------------------------------------------------------

static M_GADGETVIRTUAL(int) ListIcon_CountGadgetItems(PB_Gadget *Gadget)
{
  return 0;
}

// ---------------------------------------------------------------------------------------

static M_GADGETVIRTUAL(void) ListIcon_ClearGadgetItems(PB_Gadget *Gadget)
{
}

// ---------------------------------------------------------------------------------------

static M_GADGETVIRTUAL(void) ListIcon_RemoveGadgetItem(PB_Gadget *Gadget, int Position)
{
}

// ---------------------------------------------------------------------------------------

static M_GADGETVIRTUAL(void) ListIcon_SetGadgetState(PB_Gadget *Gadget, integer Index)
{
}

// ---------------------------------------------------------------------------------------

static M_GADGETVIRTUAL(void) ListIcon_GetGadgetItemText(PB_Gadget *Gadget, int ItemID, int ColumnID, int PreviousStringPosition)
{
}

// ---------------------------------------------------------------------------------------

static M_GADGETVIRTUAL(integer) ListIcon_GetGadgetState(PB_Gadget *Gadget)
{
  return 0;
}

// ---------------------------------------------------------------------------------------

static M_GADGETVIRTUAL(void) ListIcon_GetGadgetText(PB_Gadget *Gadget, int PreviousStringPosition)
{
}

// ---------------------------------------------------------------------------------------

static M_GADGETVIRTUAL(void) ListIcon_SetGadgetText(PB_Gadget *Gadget, const TCHAR *Text)
{
}

// ---------------------------------------------------------------------------------------

static M_GADGETVIRTUAL(int) ListIcon_GetGadgetItemState(PB_Gadget *Gadget, int ItemID)
{
  return 0;
}

// ---------------------------------------------------------------------------------------

static M_GADGETVIRTUAL(void) ListIcon_SetGadgetItemState(PB_Gadget *Gadget, int ItemID, int State)
{
}

// ---------------------------------------------------------------------------------------

static M_GADGETVIRTUAL(void) ListIcon_SetGadgetItemText(PB_Gadget *Gadget, int ItemID, const TCHAR *Text, int ColumnID)
{
}

// ---------------------------------------------------------------------------------------

static M_GADGETVIRTUAL(void) ListIcon_AddGadgetColumn(PB_Gadget *Gadget, int Position, const TCHAR *Text, int Width)
{
}

// ---------------------------------------------------------------------------------------

static M_GADGETVIRTUAL(void) ListIcon_RemoveGadgetColumn(PB_Gadget *Gadget, int Position)
{
}

// -----------------------------------------------------------------------------

static M_GADGETVIRTUAL(void) ListIcon_SetGadgetItemData(PB_Gadget *Gadget, int Item, integer Value)
{
}

// -----------------------------------------------------------------------------

static M_GADGETVIRTUAL(integer)  ListIcon_GetGadgetItemData(PB_Gadget *Gadget, int Item)
{
  return 0;
}

// -----------------------------------------------------------------------------

static M_GADGETVIRTUAL(void) ListIcon_SetGadgetItemAttribute2(PB_Gadget *Gadget, int Item, int Attribute, int Value, int Column)
{
}

// -----------------------------------------------------------------------------

static M_GADGETVIRTUAL(int)  ListIcon_GetGadgetItemAttribute2(PB_Gadget *Gadget, int Item, int Attribute, int Column)
{
  return 0;
}

// -----------------------------------------------------------------------------

static M_GADGETVIRTUAL(integer)  ListIcon_GetGadgetAttribute(PB_Gadget *Gadget, int Attribute)
{
  return 0;
}

// -----------------------------------------------------------------------------

static M_GADGETVIRTUAL(void) ListIcon_SetGadgetAttribute(PB_Gadget *Gadget, int Attribute, int Value)
{
}

// -----------------------------------------------------------------------------

static LRESULT CALLBACK CustomCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
  {
    case WM_NCDESTROY:
      RemoveProp(hWnd, PB_RectTopProperty);
      RemoveProp(hWnd, PB_RectBottomProperty);
        break;


        case WM_SETFONT:
      RemoveProp(hWnd, PB_RectTopProperty); // It's this one which triggers the new measure for the empty list grid
      break;
  }

  return CallWindowProc(StandardListIconCallback, hWnd, message, wParam, lParam);
}

// -----------------------------------------------------------------------------

M_PBFUNCTION(HWND) PB_ListIconSampleGadget2(integer GadgetID, int x, int y, int Width, int Height, const TCHAR *Title, int ColumnWidth, int Flags)
{
  PB_GadgetGlobals *Globals = PB_Object_GetThreadMemory(PB_Gadget_Globals);
  HWND Result;
  PB_Gadget *Gadget;
  int Mask    = WS_TABSTOP | WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SHAREIMAGELISTS | Flags;
  int ExMask = LVS_EX_DOUBLEBUFFER; // We do use double buffered listview (needs XP or above, but will be ignored on previous Windows)
  HIMAGELIST ImageList;

  if ((Flags & LVS_SINGLESEL) == 0)  // Multiselection emulation
    Mask |= LVS_SINGLESEL;
  else
    Mask &= ~LVS_SINGLESEL;

  // We don't use 'LVS_EX_GRIDLINES' flags because of this nasty Windows bug: http://support.microsoft.com/kb/813791 (http://www.purebasic.fr/english/viewtopic.php?t=32912)
  // As we have our own ownerdraw line routine, use it all the time.
  //
  // if (Flags & WS_TABSTOP)
  //   ExMask |= LVS_EX_GRIDLINES;

  if (Flags & WS_CHILD)
    ExMask |= LVS_EX_FULLROWSELECT;

  if (Flags & WS_VISIBLE)
    ExMask |= LVS_EX_HEADERDRAGDROP;

  if (Flags & LVS_REPORT)
    ExMask |= LVS_EX_CHECKBOXES;

  // Useful: LVS_NOSORTHEADER (no clickable titles)
  //
  if (Result = CreateWindowEx(WS_EX_CLIENTEDGE, WC_LISTVIEW, 0, Mask, x, y, Width, Height, Globals->CurrentWindow, (HMENU)0, PB_Instance, 0))
  {

    // done after window creation to get the default colors...
    if (!Initialized)
    {
      PB_Gadget_GetCommonControlsVersion(); // make sure its called as the custom grid drawing needs to know the skin mode

      OriginalFrontColor = ListView_GetTextColor(Result);
      OriginalBackColor  = ListView_GetBkColor(Result);

      ZeroMemory(&ListIconVT, sizeof(PB_GadgetVT));

      ListIconVT.GadgetType = PB_GadgetType_ListIcon;
      ListIconVT.SizeOf     = sizeof(PB_GadgetVT);

      ListIconVT.GadgetCallback      = ListIcon_Callback;
      ListIconVT.FreeGadget          = ListIcon_FreeGadget;
      ListIconVT.AddGadgetColumn     = ListIcon_AddGadgetColumn;
      ListIconVT.AddGadgetItem2      = ListIcon_AddGadgetItem2;
      ListIconVT.GetGadgetState      = ListIcon_GetGadgetState;
      ListIconVT.SetGadgetState      = ListIcon_SetGadgetState;
      ListIconVT.GetGadgetText       = ListIcon_GetGadgetText;
      ListIconVT.SetGadgetText       = ListIcon_SetGadgetText;
      ListIconVT.CountGadgetItems    = ListIcon_CountGadgetItems;
      ListIconVT.ClearGadgetItems    = ListIcon_ClearGadgetItems;
      ListIconVT.RemoveGadgetItem    = ListIcon_RemoveGadgetItem;
      ListIconVT.GetGadgetItemState  = ListIcon_GetGadgetItemState;
      ListIconVT.SetGadgetItemState  = ListIcon_SetGadgetItemState;
      ListIconVT.GetGadgetItemText   = ListIcon_GetGadgetItemText;
      ListIconVT.SetGadgetItemText   = ListIcon_SetGadgetItemText;
      ListIconVT.RemoveGadgetColumn  = ListIcon_RemoveGadgetColumn;
      ListIconVT.SetGadgetColor      = ListIcon_SetGadgetColor;
      ListIconVT.GetGadgetColor      = ListIcon_GetGadgetColor;
      ListIconVT.SetGadgetItemColor2 = ListIcon_SetGadgetItemColor2;
      ListIconVT.GetGadgetItemColor2 = ListIcon_GetGadgetItemColor2;
      ListIconVT.SetGadgetItemData   = ListIcon_SetGadgetItemData;
      ListIconVT.GetGadgetItemData   = ListIcon_GetGadgetItemData;
      ListIconVT.SetGadgetAttribute  = ListIcon_SetGadgetAttribute;
      ListIconVT.GetGadgetAttribute  = ListIcon_GetGadgetAttribute;
      ListIconVT.SetGadgetItemAttribute2 = ListIcon_SetGadgetItemAttribute2;
      ListIconVT.GetGadgetItemAttribute2 = ListIcon_GetGadgetItemAttribute2;

      Initialized = 1;
    }
   
    SendMessage(Result, LVM_SETEXTENDEDLISTVIEWSTYLE, ExMask, ExMask);
   
    StandardListIconCallback = (WNDPROC)SetWindowLongPtr(Result, GWLP_WNDPROC, (LONG_PTR)CustomCallback);

    Gadget = PB_Gadget_GetOrAllocateID(GadgetID);
    Gadget->Data[DATA_GridColor] = -1;
   
    if (Flags & WS_TABSTOP)
      Gadget->Data[DATA_InternalFlags] |= FLAG_DisplayGrid; // Uses the colormask as storage, to avoid allocating a 'prop' only for that flag

    // 3state mode is only on when both flags are set
    //
    if ((Flags & LVS_REPORT) && (Flags & LVS_SHAREIMAGELISTS))
    {
      // The blocked flag disallows the user from selecting the inbetween state himself
      // (to match the behavior of the CheckBoxGadget)
      //
      Gadget->Data[DATA_InternalFlags] |= FLAG_ThreeStateMode|FLAG_ThreeStateBlocked;
     
      if (ImageList = ListView_GetImageList(Result, LVSIL_STATE))
        PB_Gadget_AddInbetweenImage(Result, ImageList);
    }

    Result = PB_Gadget_RegisterGadget(GadgetID, Gadget, Result, &ListIconVT);

    ListIcon_AddGadgetColumn(Gadget, 0, Title, ColumnWidth);
  }

  return Result;
}


M_PBFUNCTION(HWND) PB_ListIconSampleGadget(integer GadgetID, int x, int y, int Width, int Height, const TCHAR *Title, int ColumnWidth)
{
  return PB_ListIconSampleGadget2(GadgetID, x, y, Width, Height, Title, ColumnWidth, 0);
}
Here's the header:
/*
*  ListIconGadget() command for PureBasic
*/

#include <Gadget/Gadget.h>

// Define the unicode functions
#define PB_ListIconSampleGadget M_UnicodeFunction(PB_ListIconSampleGadget)
#define PB_ListIconSampleGadget2 M_UnicodeFunction(PB_ListIconSampleGadget2)

Here's the desc:
; Langage used to code th library: ASM or C
;
C

; Number of windows DLL than the library need
;
0

; Library type (Can be OBJ or LIB)
;
LIB

; Number of PureBasic library needed by the library
;
1
Gadget

; Help directory name
;
MyGadget

;
; Library functions (FunctionName, Arg1, Arg2, ...)
;
ListIconSampleGadget, Long, Word, Word, Word, Word, String, Long, [Long], (#Gadget, x, y, Width, Height, Title$, TitleWidth [, Flags]) - Create a ListIcon gadget in the current GadgetList.
Long | Unicode
Finally, the PB file:

Enumeration
  #GADGET_ListIconSample
EndEnumeration

If OpenWindow(0, 0, 0, 640, 480, #PB_Window_ScreenCentered | #PB_Window_SystemMenu, "Hello")
  CreateGadgetList(WindowID(0))
    ListIconSampleGadget(#GADGET_ListIconSample, 0, 0, 200, 250, "Hello", 100, 0)

  AddGadgetItem(#GADGET_ListIconSample, -1, "Hello")
  GetGadgetColor(#GADGET_ListIconSample, 0)

  Repeat
    Event = WaitWindowEvent()
 
  Until Event = #PB_Event_CloseWindow
 
EndIf
Here's a combo box gadget in assembly:
;
;  ComboBox assembly example for gadget interface
;
;   (c) 2002 Fantaisie Software
;


%macro APIDeclareA 2
  EXTERN _%1A@%2
  %define %1 _%1A@%2
%endmacro

%macro APIDeclare 2
  EXTERN _%1@%2
  %define %1 _%1@%2
%endmacro

%macro PBFunction 1
  GLOBAL PB_%1
PB_%1:
%endmacro


  EXTERN  PB_MemoryBase
    EXTERN _PB_Instance
    EXTERN     PB_StringBase
       
    EXTERN _PB_Gadget_ObjectsArea
    EXTERN _PB_Gadget_CreateGadget
    EXTERN _PB_Gadget_CurrentObject
    EXTERN _PB_Gadget_DefaultFont
    EXTERN  PB_Gadget_CheckReAllocate
   
  APIDeclareA SendMessage,16
  APIDeclareA CreateWindowEx,48

STRUC VT
  .FreeGadget RESD 1
  .GetGadgetState RESD 1
  .SetGadgetState RESD 1
  .GetGadgetText RESD 1
  .SetGadgetText RESD 1
  .AddGadgetItem RESD 1
  .AddGadgetItem2 RESD 1
  .RemoveGadgetItem RESD 1
  .ClearGadgetItemList RESD 1
  .ResizeGadget RESD 1
  .CountGadgetItems RESD 1
  .GetGadgetItemState RESD 1
  .SetGadgetItemState RESD 1
  .GetGadgetItemText RESD 1
  .SetGadgetItemText RESD 1
ENDSTRUC

CB_ADDSTRING equ 143h
CB_GETCURSEL equ 147h
CB_RESETCONTENT equ 14Bh
CB_INSERTSTRING equ 14Ah
CB_DELETESTRING equ 144h
CB_SETCURSEL equ 14Eh
CB_GETCOUNT equ 146h
CB_GETLBTEXT equ 148h
CB_SELECTSTRING equ 14Dh

CBS_SIMPLE equ 1h
CBS_DROPDOWN equ 2h
CBS_DROPDOWNLIST equ 3h
CBS_HASSTRINGS equ 200h

WS_CHILD equ 40000000h
WS_VISIBLE equ 10000000h
WS_TABSTOP equ 10000h
WS_BORDER equ 800000h
WS_VSCROLL equ 200000h
WS_HSCROLL equ 100000h
WS_CLIPSIBLINGS equ 4000000h
WS_GROUP equ 20000h

WS_EX_CLIENTEDGE equ 00000200h
WS_EX_WINDOWEDGE equ 00000100h
WS_EX_STATICEDGE equ 00020000h
WS_EX_TRANSPARENT equ 20h

WM_SETFONT equ 30h

SEGMENT .text USE32 CLASS=CODE


PBFunction ComboBoxGadgetTest
    POP         ecx
    POP        dword [arg1]
    POP        dword [arg2]
    POP        dword [arg3]
    POP        dword [arg4]
    MOV   dword [arg5],0 ; Name
    PUSH     ecx
    MOV        ecx,WS_CHILD | WS_VISIBLE | WS_BORDER | CBS_HASSTRINGS | WS_GROUP | WS_VSCROLL | WS_TABSTOP | CBS_DROPDOWNLIST
    MOV        edx,WS_EX_CLIENTEDGE
PB_ComboBoxGadgetReal:
    MOV   dword [ComboBoxVT+VT.GetGadgetState], ComboBox_GetGadgetState
    MOV   dword [ComboBoxVT+VT.SetGadgetState], ComboBox_SetGadgetState
    MOV   dword [ComboBoxVT+VT.AddGadgetItem] , ComboBox_AddGadgetItem
  MOV   dword [ComboBoxVT+VT.GetGadgetText] , ComboBox_GetGadgetText
    MOV   dword [ComboBoxVT+VT.SetGadgetText] , ComboBox_SetGadgetText
    MOV   dword [ComboBoxVT+VT.ClearGadgetItemList], ComboBox_ClearGadgetItemList
    MOV   dword [ComboBoxVT+VT.CountGadgetItems], ComboBox_CountGadgetItems
    MOV   dword [ComboBoxVT+VT.RemoveGadgetItem], ComboBox_RemoveGadgetItem
    CALL  PB_Gadget_CheckReAllocate
    MOV         [ActualNumber],eax
    PUSH     dword 0
    PUSH     dword [_PB_Instance]
    PUSH     eax                          ; Our ID (was Menu...)
    PUSH     dword [_PB_Gadget_CurrentObject]  ; ParentWindow
    PUSH     dword [arg4]                ; Height
    PUSH     dword [arg3]                 ; Width
    PUSH     dword [arg2]                 ; y
    PUSH     dword [arg1]                 ; x
    PUSH     ecx
    PUSH     dword [arg5]            ; Name
    PUSH     dword ComboBoxClass ; Template class..
    PUSH     edx
    CALL     CreateWindowEx
    MOV        ecx,eax
    PUSH  eax                 ; Save eax for future use
    MOV        eax,[ActualNumber]
    MOV     edx,[_PB_Gadget_ObjectsArea]   ; Point on the right entry in the memory bank to store our new gadget infos
    SHL     eax,4               ; eax*16
    ADD   edx,eax             ;
    MOV        [edx],ecx
    MOV        dword [edx+4], ComboBoxVT    ; Store the gadget associated class for fast GetGadgetState()
    PUSH    dword 1                              ; Set the default Windows font for the gadgets...
    PUSH    dword [_PB_Gadget_DefaultFont]
    PUSH    dword WM_SETFONT                ;
    PUSH    ecx                                  ;
    CALL    SendMessage                      ;
    POP   eax                       ; Return the Gadget address in 'eax'
    RET
   

PBFunction ComboBoxGadgetTest2
    POP         ecx
    POP        dword [arg1]
    POP        dword [arg2]
    POP        dword [arg3]
    POP        dword [arg4]
    MOV   dword [arg5],0 ; Name
    POP   dword [Flags]
    PUSH     ecx
    MOV   ecx, [Flags]
    AND   ecx, CBS_DROPDOWN
    JZ    CBG_NotEditable
    MOV   ecx, [Flags]
  JMP   CBG_Next
CBG_NotEditable:
  MOV   ecx, [Flags]
  OR    ecx, CBS_DROPDOWNLIST
CBG_Next: 
    OR         ecx, WS_CHILD | WS_VISIBLE | WS_BORDER| CBS_HASSTRINGS | WS_GROUP | WS_VSCROLL | WS_TABSTOP
    MOV        edx, WS_EX_CLIENTEDGE
  JMP   PB_ComboBoxGadgetReal
   

; (#Gadget, Position, String$)
;
ComboBox_AddGadgetItem:
  PUSH    dword [esp+12]        ; String to add (Position on the stack)
    PUSH    dword [esp+12]        ; Position
    PUSH    dword CB_INSERTSTRING       
    PUSH    dword [esp+16]    ; Gadget
    CALL    SendMessage
  RET   12


; (#Gadget)
;
ComboBox_ClearGadgetItemList:
  PUSH    dword 0           
    PUSH    dword 0
    PUSH    dword CB_RESETCONTENT
    PUSH    dword [esp+16]
    CALL    SendMessage
  RET   4


; (#Gadget)
;
ComboBox_CountGadgetItems:
  PUSH    dword 0
    PUSH    dword 0       
    PUSH    dword CB_GETCOUNT
    PUSH    dword [esp+16]    ; Gadget
    CALL    SendMessage
    RET   4


; (#Gadget)
;
ComboBox_GetGadgetState:
    PUSH    dword 0                                         ;
    PUSH    dword 0                                         ;
    PUSH    dword CB_GETCURSEL                ;
    PUSH    dword [esp+16]                         ; The gadget address...
    CALL    SendMessage                                ; Result in eax is the gadget result state
    RET   4
   

; (#Gadget)
;
ComboBox_GetGadgetText:
    PUSH    dword 0
    PUSH    dword 0
    PUSH    dword CB_GETCURSEL
    PUSH    dword [esp+16]
    CALL    SendMessage                ; Get the current select indes in 'eax'
    CMP        eax,-1
    JE        ComboBox_GGT_End
    PUSH    dword [PB_StringBase]
    PUSH    eax
    PUSH    dword CB_GETLBTEXT    ; CB_GETTEXT or LB_GETTEXT, depending of the gadget type
    PUSH    dword [esp+16]
    CALL    SendMessage
    CMP        eax,-1
    JE        ComboBox_GGT_End
    ADD        dword [PB_StringBase], eax
ComboBox_GGT_End:
  MOV   eax, [PB_StringBase]
  MOV   byte [eax], 0
    RET   4
   

; (#Gadget, Position)
;
ComboBox_RemoveGadgetItem:
  PUSH    dword 0
    PUSH    dword [esp+12]                      ;
    PUSH    dword CB_DELETESTRING     ;
    PUSH    dword [esp+16]                        ; The gadget address...
    CALL    SendMessage                                ;
    RET   8


; (#Gadget, State)
;
ComboBox_SetGadgetState:
  PUSH    dword 0
    PUSH    dword [esp+12]                      ;
    PUSH    dword CB_SETCURSEL        ;
    PUSH    dword [esp+16]                        ; The gadget address...
    CALL    SendMessage                                ; Result in eax is 1 if the checkbox is pressed !
    RET   8


; (#Gadget, String$)

ComboBox_SetGadgetText:
  PUSH    dword [esp+8]                        ;
  PUSH    dword 0
    PUSH    dword CB_SELECTSTRING     ;
    PUSH    dword [esp+16]                        ; The gadget address...
    CALL    SendMessage                                ;
    RET   8
   
   
SEGMENT .data CLASS=DATA

ComboBoxClass: db "COMBOBOX",0

SEGMENT .bss CLASS=DATA

Flags:            RESD 1
arg1:                      RESD 1
arg2:                      RESD 1
arg3:                      RESD 1
arg4:                      RESD 1
arg5:                      RESD 1
arg6:                      RESD 1
ActualNumber      RESD 1

; VirtualTable for Combobox
;
ComboBoxVT:     RESD 15
So, you are partially right - some libs are written in C. But you are still not - never - coding in C when using PureBASIC. Remember that just because a library is written in c, you are not actually coding in C. You're coding in that language - and that language only - unless your able to make a hybrid source code set - more than one language makes up the project.

"On two occasions I have been asked [by members of Parliament!]: 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out ?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question."    — Charles Babbage.
My Github

2015-03-12 20:16:11

Yes. I'm trying to get people to not use it.  I'm trying to get people to stop making the mistake that good games have anything to do with how good or bad a language is and wake up and see that they're not only using what is basically C, they're paying for the privilege.
I am not saying it calls your C compiler or anything to that effect.  Purebasic is the same in that I can one-for-one almost all the language structures back and forth.  Writing your standard libraries in assembly is in no way a good thing.  Not having a garbage collector is in no way a good thing.  Even VB6 hides memory management from you behind automatic reference counting and gives you things that would be considered at least somewhat modern.  If you're going to jump onto the Purebasic bandwagon, just jump onto the C bandwagon and then, when you need to call C code, you won't have to translate headers.
Yes, you can get up and running with it quickly.  But that's it.  The end.  Once your project gets even to a medium size, Purebasic is now fighting you.  I'd even say that VB6 is better, at least for the next couple years until it stops running.  I'm not advocating Python.  I'm advocating anything but Purebasic.  Using Purebasic is doing an outright disservice to you as a programmer.  I give Danny a 90% chance of realizing this within the next year.  The rest of you may need longer, depending.
I went through Purebasic, I know what I am saying.  I'm even able to tell you how the story goes in most if not all cases.  You're using niche variant of basic here.  You go to do an intermediate project, say an online game, but it doesn't really matter.  It either fails or proves to be really, really hard, so you start looking at how other people do it.  And they're saying "just install these 5 packages and use these 4 language features, solving these 30 problems".  So you decide to stop being convinced that niche variant of basic is the best and give it a chance and actually learn it.  And then you never look back.  Now wouldn't it be wonderful if you just cut out the wasted months on niche variant of basic here?  it's not just Purebasic that has this problem, it's almost all of them.  I have watched this happen here.  I have had it happen to me.
By all means learn two languages.  But Purebasic and something else is less than useless.
And before someone no doubt tells me about how Purebasic makes opening windows easy, no one uses the Windows API for that, not unless you've got a special reason.  See Sdl, see GLFW.  Sdl gives you basic sound, too, and it's not too hard to get going in your project.  I'm not recommending C either, but if you must go to a language that has the feature set of Purebasic, you might as well pick the free choice.

My Blog
Twitter: @ajhicks1992

2015-03-12 20:24:49

Oh my god, Camlorn. Will you ever read posts? Since your trying to demote PB, I'll spell it out for you. PureBASIC. Is. Not. C. Or. C. Plus. Plus. I'd like you to prove to us how PB is C. I'd like you to prove to us how C is better than PB. Because its not. I can garentee that you can't prove it. If your such a damn god, why not you go and write DMNB or DMPA in C. We'll see how good you are then.

"On two occasions I have been asked [by members of Parliament!]: 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out ?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question."    — Charles Babbage.
My Github

2015-03-12 20:35:23

@Camlor: Also, your doing something called Frogging. Do you know what that is? Its saying things you have no idea about. I want complete proof that you've done these things and you can back them up with articles, references, etc.

"On two occasions I have been asked [by members of Parliament!]: 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out ?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question."    — Charles Babbage.
My Github

2015-03-12 20:36:20 (edited by The Dwarfer 2015-03-12 20:38:26)

Camlorn, reading the first part of your post raises some questions for me. As I am not intending to take this to a personal level, I'll not get angry over this, but I'm a bit frustrated, yes.

camlorn wrote:

Yes. I'm trying to get people to not use it.  I'm trying to get people to stop making the mistake that good games have anything to do with how good or bad a language is and wake up and see that they're not only using what is basically C, they're paying for the privilege.

If this is the case, then why are we having this discussion? If we can still make good games with pb, despite its shortcomings, then why are you, trying to get people not to use it?

camlorn wrote:

Writing your standard libraries in assembly is in no way a good thing.  Not having a garbage collector is in no way a good thing.

Will you provide us with the luxury of an explanation? You can't just outright state something like that, especially to someone like guitarman who is just learning. For that matter, I've survived without both things, and perhaps that's just because I've been performing relatively low level programming. But the thing is, if one learns pure basic, they can always grow out of it in a year or two and migrate to something bigger should they start on higher level projects. But if guitarman chooses to learn PB as a first, starting out type of things, then there's really no reason he shouldn't.

If you have issues with Scramble, please contact support at the link below. I check here at least once a day, so this is the best avenue for submitting your issues and bug reports.
https://stevend.net/scramble/support

2015-03-12 20:39:20 (edited by Ethin 2015-03-12 20:39:50)

I completely agree with severestormsteve1. Also, I'd like to point out that most of your information is incorrect. As a very experienced professional PB programmer, I pretty much know its ins-and-outs. To that end, I must say that you are putting up quite a good fight, but a losing one.

"On two occasions I have been asked [by members of Parliament!]: 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out ?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question."    — Charles Babbage.
My Github

2015-03-12 22:13:22

No, actually, I'm not.  I actually use it extensively when I was your age. I've read the manual again today because I figured you'd try to pull this one on me.
Purebasic has for loops, while loops, if statements, case statements, procedures, typed variables, structs, commands, macros, arrays, strings, pointers, and inline assembly support.  Have I missed a major language feature?  Because C has all of them, just with slightly different syntaxes and less syntax special cases (i.e. needing the peak and poke functions).  Yes, you have to install libraries, but you're getting much better community and tools.
A garbage collector means that you essentially never need to free a pointer again.  Languages with garbage collectors move the burden of knowing what is and is not currently allocated from the programmer to the compiler and runtime.  Furthermore, these languages can usually detect attempts to accidentally access memory that is no longer yours and some can defragment the heap.  Many of these languages provide higher level stuff that's also helpful; garbage collection and being immune to buffer overflow problems and/or clobbering the stack by default often go hand in hand.  There is actually a garbage collector available for C; it is called the Boehm collector and does some magical statistical stuff to work.  Given the choice, it is almost never good to choose to manage a problem that a tool or language can deal with for you.
A good programmer can probably program even very complex projects in less powerful languages.  Using a more powerful language will raise the threshold at which a project becomes too hard to manage, reduce the number of bugs, and provide better security.  Python is mostly immune to buffer overflow attacks, for example; I'd say completely, but the nature of attacks is that we don't know all of them.  If I wanted, I could probably take out DMNB repeatedly with buffer overflows or other similar attacks, and most of these come back to having had to write those parts of the code yourself and using a language that allows such exploits.  If someone who actually does know hacking ever decides to target DMNB, it's defenseless. 
And I have done prototypes that are more advanced than DMNB.  I have a fully functional but super boring online game with completed combat and death, including a swamp-style first person perspective, support for level maps and teleporting between environments.  I never released it because it cannot securely and stably support more than a  few players without lag, and the game requires a high-end internet connection from everyone using it.  These problems are the same facing DMNB, and they are not fixable if they show up at the prototype level.  They are not caused by bugs, they are caused by core architecture problems that must be fixed on day one.  I tried to tell Danny about interpolation and client-side simulation and was ignored.  You cannot do an online game that provides walking with the arrow keys successfully without such.  The internet is simply too slow.  Other problems that higher level languages provide include various data structures with uniform interfaces, giving one improved performance.  If I did care enough to bother doing a DMNB clone, then I could probably not only make the code simpler in Python or Node.js, I can probably make it faster too.
And do tell, Ethin, what source would satisfy you?  Do you think, given my background and experience,  I would be this emphatic if there was truth to your statements about me?  Do you think, given the size and complexity of Libaudioverse, that I am in any way clueless?  And why are you assuming that I have made all of my code available publicly?  Why not look at my blog, where I talked about my attempts?  I may have even written postmortems, I'm not 100% sure at the moment.  There are only two people in this community that have had long-term success with this problem: Aprone and Gorthalon.

My Blog
Twitter: @ajhicks1992

2015-03-12 22:35:42 (edited by Ethin 2015-03-12 22:38:56)

And Gorthalon wrote RTR, and there was hardly ever any lag, even though he wrote it in PB, and even if their are 8 to 9 players on it doesn't lag. Explain that, Camlorn. Explain how a game can't lag when there are 8 to 9 players on it, yet you don't want us using PB. I'm seriously starting to doubt your statements and your sanity, Camlorn. Some of your posts on this topic are rather... insane-looking, if you know what I mean. Your literally trying to force us to do something.
About the buffer attacks, we're trying to resolve it. PB is rather helping us in that respect. It gives us rather understandable messages, whereas C compilers do not: They give you rather cryptic statements as error and warnning messages.

"On two occasions I have been asked [by members of Parliament!]: 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out ?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question."    — Charles Babbage.
My Github

2015-03-12 23:05:01

As for the hacking aspect, that is always an issue; Aprone coded swamp in a language other than pb, and even to the semi-experienced hacker that was easy to get into, hints why he had to make accessing the server paid and place banning restrictions on those who injected commands, changed files, hacked and/or spammed the server... etc.
  But Camlorn, I totally understand you now, and now that I think of it I'm not even so frustrated as I were earlier. Thing is, you have, as you said, so much experience, and thus utilize advanced coding techniques. But for some one like me who's game doesn't use those, pure basic does my purpose; I'm able to get my code working the way it should, albeit I have to tweak it in most cases. But to that end, I don't need anything to do with memory allocation and such. But in the upcoming years, when my programming experience increases, I'll undoubtedly learn more languages to suit my needs. But for now, and I feel pretty confident that for my racing game as well, pb will do just fine.
  When I do learn other languages, I will still keep pure basic in my reserves; it's great if you want to sit down and jot down a game or two without too much in the way of complications, and pieces of software as well.

If you have issues with Scramble, please contact support at the link below. I check here at least once a day, so this is the best avenue for submitting your issues and bug reports.
https://stevend.net/scramble/support

2015-03-12 23:08:23 (edited by Ethin 2015-03-12 23:11:41)

Camlorn, your being very stubborn here. Why can't you just except the fact that we all use the programming languages we think best? Why are you trying to force us to use what you think is best? If your trying to force us to use your programming languages that you select and those programming languages that you select only, your doing a terrible job at it. Grow up, and stop acting like a little baby who wants everything to revolve around him. This is not your community. You do not own it. You are not a god, although you seem to think your one.
I'm going to state this for the umpteenth time: PureBASIC, while it has the same features as C, is not C! That's final! Argument closed!
OK, enough of my rants and ravings.
Guitarman, it mainly depends on the game you want. I'd suggest learning one language before going into another; PureBASIC, for instance. Don't try learning C/C++ first. It will cause your brain to go all fuzzy on the inside because you can't understand stuff. (Camlorn, please don't post a contradiction here, please? I don't like arguing with someone who will stay firm on their points and will not change for the better.) Well, gotta go. See y'll later.

"On two occasions I have been asked [by members of Parliament!]: 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out ?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question."    — Charles Babbage.
My Github