Author Archives: freak

A little bit of history about the debugger

In the last entry i mentioned that the debugger is compatible between 32bit and 64bit (you can debug a 64bit program with the 32bit debugger and vice versa). Why is that and why do we have 3 different debuggers anyway?

Its interesting actually: a lot of these things were not planned to be like that. In fact the whole debugger was not planned at all. It was one of these things that start as a simple idea and just grow into something huge. To understand more about that we have to go all the way back to when the current debugger was written. It was the year 2004, the current PB version was 3.91. The Windows debugger consisted of a small window which only showed the global variables and allowed stepping through the program. PureBasic for Linux was much worse. There was no IDE at all and the debugger did notning more than print the output of Debug statements to the command line.

At that time i decided to write the new IDE. Thats another project that vastly outgrew the original plans even on its initial release. The plan was to write a simple crossplatform IDE with the same set of features as the IDE for Windows at the time. Most of the IDE was working and we planned to include it in the 3.93 release. All it did for debugging on Linux was to make sure the program runs in a terminal window so you can see the debug output. To improve that, Fred gave me the source to the Linux debugger lib (just a collection of printf statements) so i could improve it.

The Windows debugger was just a library that got compiled into the executable which launched a new window in a thread. The idea was to do the same for Linux and just duplicate the feature set of the Windows debugger. Man am i glad that this didn’t work out! If that worked, we would probably be stuck with two very platform specific debuggers with probably a similary limited feature set as we had back then, and maybe no OSX debugger at all. Well, it turns out that Gtk doesn’t play so well with threads, especially when the main program doesn’t even know about the debugger thread.

New plan then: the debugger had to be an external program. Usually debuggers get access to their target programs by reading their memory directly, even patching the target program’s code as needed. Since this approach is quite platform specific we decided against that. After all, if we write a new debugger it should be available for Windows as well. So we still have the design of a special debugger library which gets compiled into the executable even today. This library allows the debugger to connect via pipes to exchange the needed data. This design requires a minimum of platform specific code and it works quite well.

Now we come to the reason for the three debuggers. The console debugger exists because I started this work on Linux with the given minimalistic library that just printed the output. This just grew to be the console debugger. To ease the testing i first implemented a new feature such as array display in console mode to make sure i got all the interaction with the compiler generated tables and stuff like that right and only as a last step i also added a GUI version of that. I still do it the same way today. So the main purpose of the console debugger is the development of the debugger itself. I also use it a lot to debug the IDE because I do not want to load that beast into the gui debugger every time.

I almost didn’t write the standalone gui debugger. After all, why add an extra window when you can access all the features from the IDE. The only reason i did it was to not kill the jaPBe project. Without any way to debug a program other than the IDE, people would have abandoned it fairly quickly. I was tempted though. After all, it would have been an easy way to get rid of the “competition”. 🙂 Looking back, the standalone debugger has proven useful in many more situations than that. For example this way programs can be debugged with elevated privileges on Vista or 7 without the need for the whole IDE to run at that level. Also it has again proven helpful in the development of the IDE and debugger itself. The codebase of the gui debugger is much smaller than that of the IDE so it is much easier to find a bug in there. Since most of the code is shared with the IDE we get that fixed as well.

The three debuggers also help in porting to a new platform like with the x64 port. As soon as the compiler works at least at a minimum, the first order of businesses is to get the console debugger up and running. This is then used to further debug the compiler output. When that works reliably enough the next step is to get the gui debugger and IDE running. Getting the IDE to run is quite the milestone for every port, as it is quite huge and makes use of a lot of different libraries.

Back to the communication between executable and debugger. As i said, it works through pipes. Its a simple package based binary protocol that sends a header structure and then data with a variable length. It hasn’t changed much since the first version although the code for handling the pipes has changed quite a lot. With the 64bit port we faced the question what to do with this communication protocol. Changing all values to 64bit would have been rather simple and the obvious choice. The reason why i choose not to do it was again for development purposes. The 64bit version was still quite unstable and having a stable 32bit debugger there to analyse it was a big help. At one point i was running the 32bit gui debugger to debug the 64bit gui debugger while debugging a 32bit executable. 🙂

So this is why the debuggers are compatible. The communication protocol keeps its 32bit header structure and the debuggers can adapt to the executable’s bit size when working with the contained data. Now with the 4.50 this design pays off once again because you can now actually load the 64bit compiler into the 32bit IDE for compiling and debugging. The final step was to make the PowerPC and x86/x64 communication compatible. This is something i just did recently because its a bit more of a change because the different byte-order has to be taken into account and so far there was just no need for this. Anyway, i did not do all this work just so you don’t have to use Rosetta on the IDE on OSX. Now that the debugger communication is compatible between all platforms, the way is finally open for one of my longer term goals: network debugging across all platforms.

Now with the next version we will have that as well: Network debugging across all platforms and processor types. I recently ran the debugger in a 32bit Linux VM, debugging a PPC executable on the Mac, while itself being debugged by another debugger instance on 64bit Vista. That just rocks! 🙂

To all those not really interested in this kind of stuff: you benefit from this as well. All these steps to new platforms and crossplatform compatibility have made the debugger more stable as a whole too, because many bugs become more apparent when you switch platforms frequently. So everybody wins.

PureBasic 4.41 final is out

Hello folks,

The final version of PureBasic 4.41 is out. It’s a stabilisation release, so we focused only on bug fixes and we have killed quite some :). You can grab it on your online account while it’s hot !

Have fun,

The Fantaisie Software Team.

PureBasic 4.41 RC1 Released!

Hello everybody,

The next release is here. We spent quite some time fixing bugs, so here is the 4.41 bugfix release. As you can see it is called “Release Candidate”. I will explain what the different types of releases mean for PB now:

  • Alpha Release:  These are development snapshots and are not given out to the public. Features are usually not fully finished. This is just to get some early feedback from a few people during development.
  • Beta Release:  Beta means that all new features are implemented and nothing new will be added except bugfixes (except if a feature is found to be too incomplete to be usable).
  • Release Candidate:  This is what used to be the “final beta release” before. In the release candidates we plan to fix only very critical bugs. Minor bugfixes will be postponed to the next version. We release them when we think the version is ready. At this point even people that do not try the betas should test the new version as its the last chance to discover a critical bug.  This release starts directly as a release candidate as there are no new features to test and we only need the validation that we did not break anything with our bugfixes before going to the final release. Releases that introduce new features will have a beta phase as usual.

We also plan to do these bugfix releases (like 4.31 and 4.41) in between new feature releases on a regular basis from now on, so if you are not interested that much in new features and want the most stability then you can just skip the new feature releases and use the bugfix releases only. This way the new features have been tested for a while and bugs in them have been fixed. We also plan to try to shorten the release cycle as the 4.30 and 4.40 release cycles have been way too long.

Please test the new version and tell us whether the bugs marked as fixed are indeed gone and also let us know if any new problems show up. As usual this release can be downloaded on your account on http://www.purebasic.com/

The PureBasic Team

Merry Christmas

I want to wish everybody in the PureBasic community a Merry Christmas and a happy New Year! Thank you for taking part in the making of PureBasic by giving feedback and helping find bugs. It was a fun year. Although there was only one major release this year its still quite the accomplishment in my opinion as it is one of the largest updates we did so far.

It has become somewhat of a custom for us to do a release around Christmas or New Year as a present. There won’t be anything like that this year.  The 4.40 isn’t that far behind, but calling it a Christmas-release is kind of wrong because it has been out there (in beta) for quite a while now. Well, i guess you can’t get it right every time. We’ll try to hit the spot again next time 🙂

Our plan is to go for a shorter release cycle with smaller releases in the future to reduce the waiting time for new features and bug fixes and also to keep the whole think more manageable. The next thing in line is a 4.41 bug fix release somewhen in January and then there is the 4.50 coming next. We are working on that already. I want to talk a bit about what i am currently working on so you can see what is ahead:

Data Breakpoints

Data breakpoints are like normal breakpoints, only they are not defined by a line number but by a condition. As soon as this condition becomes true the program will halt. This is a great feature for debugging a problem like a variable having an unexpected value but you have no idea where the change is made. So in this case you would just define ChristmasText$ <> “Merry Christmas” as the condition and the program will halt as soon as the value changes.

The conditions are evaluated by the debuggers expression parser which provides access to variables, arrays, lists etc but also some functions from the Memory library so you can even check for things inside memory buffers. Everything you can put behind an “If” should be possible as a data breakpoint.

Of course this feature comes at a price and that is speed. The conditions have to be re-evaluated for every executed line to notice all changes correctly. This is quite the slowdown. However, if you develop on a fairly recent machine it should not be a big deal at all. Also keep in mind that you won’t run your programs with data breakpoints all the time. They are only for tracking down specific problems and there speed is not really critical.

Multiple compiler support

Ever since we introduced the 64bit version in 4.30 people have requested that we merge the 32bit and 64bit version somehow so they can easily compile projects for both platforms. While a merge of the versions won’t happen any time soon (the versions are just very different internally and it would be a bit of a mess), there will now be a feature to provide a similar functionality. Basically there will be a list of “additional compilers” in the preferences where you can add the paths to other compilers installed on your system. These compilers are then available for selection in the compiler options. This will work with compilers all the way back to version 4.10.

So by adding the 64bit compiler to this list, you can easily build both 32bit and 64bit targets from the same IDE and from a single project. Even better, the debuggers of the x86 and x64 versions are compatible so as long as the compiler’s version number matches you can even debug poth from within the same IDE (if the version does not match, all debugging will be in the standalone debugger). The same is true now for the PowerPC and x86 versions on OSX. You can load the PowerPC compiler into the x86 IDE and compile/debug from there. This way you won’t have to run the entire IDE in Rosetta which is quite the slowdown.

Well, this is it for this little peak at the current development. Have a Merry Christmas every one!

Forum update planned for September 9, 2009

The 3 PureBasic forums hosted on our server will be updated to phpBB3 on September 9, 2009. The work will start somewhen during the day. The forums will be locked/unreachable for hopefully only a short time.

As we know from past experiences with forum moves/updates, it doesn’t always work flawlessly. If there is a longer unexpected downtime we will post any information here.

Update:

Everything is working as planned, but it does take longer than expected. The database conversions are quite slow, and we have to rebuild the search index for all forums too which takes even longer. Because these tasks are putting a heavy load on the server we are keeping all forums locked until this is complete. Everything should be back up and running by tomorrow. Thank you for your patience.

2DDrawing in v4.40 under the hood

A lot changed in the 2DDrawing library with the v4.40 version. In fact, it basically underwent a complete rewrite. Only very few code parts remain from the previous version. Since it has come up in various questions and bug reports on the forum i am going to explain the new design a little bit and what consequences it has on stuff like mixing API and PB commands for drawing.

Lets start off with what the 4.31 library looked like:

The Windows version of the library was based entirely on GDI (the Windows drawing API). GDI allows output on a window, image, printer, sprites and the screen with the same commands so for the most part only the code that set up the drawing needed to be specific and the rest was shared (hence the separation of the output functions like ImageOutput() from StartDrawing()). One detail that a lot of users relied on was the fact that the GDI handle to the drawing context (HDC) was returned for StartDrawing() which allowed to easily mix API and PB commands in the drawing operation even without much knowledge of GDI. The internal data structure of the library was published a long time ago in the PB Library SDK and since the library didn’t change much over time there is still some code that relies on them.

Linux was a different story. Here every output requires its own API (Gtk for window an image, libgnomeprint for printer and some pixel based routines for SDL output). So the Linux library had a plugin like system just like some other PB libraries have to select the right command depending on the output. The Mac OSX version basically had only one output for images. The printer library created a temporary image and sent it to the printer when drawing was done. There was no drawing for windows, sprites or the screen on OSX. The drawing functions shared the pixel based drawing code we used for SDL on Linux.

Why the library was rewritten:

The reason was the alphachannel. As explained in a previous entry, i worked on improving the capabilities of PB when it comes to displaying alphachannel images. After that was finished i felt that at least some support for 2DDrawing was needed in addition to the DrawAlphaImage() command as well. The problem here is that GDI does not support the alphachannel even though it can handle 32bit images. Since Windows 98 you can load images with alphachannel and display them with the AlphaBlend() API but that is pretty much it. Any manipulation of the image with GDI will cause the alpha information to be lost. The same problem exists with Gdk on Linux. The ony drawing functions that exist work on GdkDrawable objects and these do not support the alphachannel. GDI+ is the Windows replacement for GDI which can deal with the alphachannel, but we needed a crossplatform solution to this problem. So we made the decision to create our own drawing functions similar to the pixel based ones for SDL and OSX which could handle the alphachannel in all drawing commands. As you can see from the result i went a step further and added the gradient drawing support (which also would not be possible with the API functions).

The new design:

Since our pixel based routines can only draw on images we now need separate “subsystems” for drawing even on Windows. So now we have this plugin-architecture on all OS. The real drawing functions are called through pointers which are set when the drawing is started so the speed impact is minimal. For those concerned about executable sizes: A drawing subsystem is only linked when the corresponding output function is used in the code. So if you do not use ImageOutput() none of the image drawing code will be linked.

So there is now a GDI subsystem on Windows and the new “PixelBuffer” one. The PixelBuffer subsystem does all its drawing directly on the memory of the output image with no API involvement. The only exception is the drawing of text. We did not want to add the overhead and license troubles by including an external font rendering engine like freetype so DrawText() uses GDI to render the text to a special device context from which the text is then drawn to to the real output with the alphachannel and gradients taken into account. It works in a similar way on the other OS where the native API is used to render the text and then it is copied to the real output. There is of course a speed penalty from this, but it cannot be avoided and it is questionable how much faster a separate rendering engine would be with this task.

Things to watch out for for on Windows:

I tried my best to keep the library backward compatible. If you use PB drawing commands only then there should be no difference at all. If you mix them with API then there are some things to watch out for:

  • As the “HDC result from StartDrawing()” is very commonly used i kept that behavior the same. So even though the PB commands do not use it for the drawing, there is still a device context created and returned from StartDrawing() which you can use to draw on the image with API.
  • You can still mix API drawing functions with PB functions on the same output without problems. The only thing that changed here is that GDI functions that change the global state of the device context no longer affect the PB drawing functions like they used to because the PB functions do not actually used that device context. So a function like SetWorldTransform() will not cause DrawImage() to draw a rotated image anymore. However it should still work if you use the BitBlt() API.
  • You have to be aware that GDI functions will erase the alphachannel. So if you draw on a 32bit PB image and use a GDI function, the modified area will look transparent after that. The best way to avoid this problem is to use 24bit images as output when API commands are involved. (We changed the default image depth to 24bit in 4.40 beta2 to make the transition easier)
  • PB Images are now always DIBs (device independent bitmap) to allow for the pixel based drawing. The #PB_Image_DisplayFormat flag used to create a DDB (device dependent bitmap), but this is no longer supported. #PB_Image_DisplayFormat now has the value 32 to create a 32bit image instead. Some GDI functions (like GetDIBits()) expect a DDB, so you may get trouble there.
  • DrawImage() can still draw API created images (including DDBs and icons). Again you have to be aware that a 32bit API created bitmap will probably have all alpha values as 0 which PB will interpret as fully transparent. Using 24bit is the solution here as well. Also DrawImage() expects DIBs to be bottom-up (the default on Windows). If you use top-down DIBs then they will be drawn upside down. There is no way to avoid that as Windows does not provide a way to find out the pixel orientation of a DIB.
  • If you relied on the library’s internal data structures then you are out of luck. Nothing is as it was before on the library’s internals.

To sum it up: Stick to 24bit images and in most cases mixing PB drawing with API drawing should work just as it did before.

Things to watch out for on Linux:

I am not aware of code that mixed 2DDrawing with API on Linux. StartDrawing() used to return the GdkDrawable handle for Image+WindowOutput() before. It now returns that only for the WindowOutput() as there is no more drawable when drawing on an image. Backward compatibility wasn’t possible here.

One thing to note in general is that PB images are now GdkPixbuf objects and no longer GdkPixmap. This is a big improvement as many Gtk functions expect GdkPixbuf nowadays, so it is actually easier to use PB images with Gtk functions.

Things to watch out for on OSX:

Nothing to say here. Since the 2DDrawing support was so poor before, it only got better with this release. There is now a separate QuickDraw based subsystem for WindowOutput(). Yes i know that QuickDraw is deprecated, but it was much easier to implement this way than to go for a full Quartz based one. I have plans to do a Quartz subsystem one day to have better PrinterOutput() (for the moment, it still works with images as an intermediate).

One thing to note is the new output for sprites and the screen with OpenGL (this applies to all OS): There is no way to modify the data in video memory, so if you call StartDrawing() the whole sprite data or the entire screen content is transferred to main memory for the drawing. This is very slow. So doing 2DDrawing everytime you refresh the screen is too costly. The better way is to draw on sprites just once and then display them over and over. Still, this is better than having no 2DDrawing for sprite/screen at all.

Future plans:

There is still room for optimisation in the new 2DDrawing code. For now the focus was on getting a stable implementation. Also the plan is to eventually have the alpha drawing routines also for SpriteOutput() and ScreenOutput() but this will need some more work to support all possible pixel formats for the screen. Stay tuned…

Is your 64bit program really solid ?

If you ask Windows for memory it will generally start with low addresses first. There is nothing wrong with that. For a 64bit program however, this means that under normal circumstances unless you actually use up 4Gb of memory, your pointers will still fit into a 32bit value. So if you store a pointer into a too small variable (say a long) you will not notice, because the upper half of the 64bit pointer value isn’t even used. So your program may look quite solid and usable right now but if you feed it something like a 4Gb file to load it will start crashing. This may sound like an unlikely case but it will become much more common even for programs that are not meant to deal with large amounts of data, simply because as disk space, memory and computer speeds grow, so do the amounts of data that users deal with.

Anyway, I recently found this link: http://msdn.microsoft.com/en-us/library/bb613473.aspx

Notice at the very bottom the mention of the AllocationPreference registry setting. If you develop 64bit applications (especially if you are porting code from 32bit to 64bit) then this key will help you a great deal. What it does is it instructs Windows to give you high addresses first. The result are pointers that don’t fit into 32bit right from the start. So these errors that usually go unnoticed will blow up right in your face and you can fix them.

The link doesn’t explicitly state the OS this works on but i tested both on XP 64bit and Vista 64bit and it works fine on both. You have to restart the computer after setting the registry value for the change to take effect. You can then verify with a simple program if the high addresses are returned (make sure you compile it with the 64bit compiler 😉 ):

For i = 1 To 10
  a$ + RSet(Hex(AllocateMemory(1000), #PB_Integer), 16, "0") + Chr(13)
Next i
MessageRequester("Pointer values", a$)

In this mode you can easily distinguish a valid pointer from a truncated one by looking at it as hex like above. Since the virtual address space is limited to 8TB on current x64 Windows versions, a pointer allocated in this mode will look something like 000007FFFXXXXXXX because the addresses cannot go any higher. If a pointer got cut somewhere it will either look like 00000000XXXXXXXX or FFFFFFFFXXXXXXXX depending on wether the cut 32bit value was positive or negative (the sign-extension of the negative numbers will create all the F’s).

The PureBasic package itself is a good example of how easily such bugs go unnoticed. We payed a lot of attention to this when porting the libraries and also the programs like IDE, debugger and compiler to 64bit with PB 4.30. There was a lot of testing by the users after that too and PB 4.31 x64 is quite stable. However, if you turn on this mode the 4.31 IDE and debugger will not even start. Even the compiler won’t compile anything. So if you want to try this with your own programs you obviously cannot use PB 4.31 for it. The new 4.40 version was tested with this mode and these bugs are now fixed. Since it is still in beta, you may run into the odd crash though. If this happens please let us know.

Keep in mind that this setting is systemwide. So other x64 programs could well crash on you too if they have such unnoticed bugs.

Have fun fixing a ton of bug you never knew existed 😛

PureBasic 4.40 Beta1 released!

The wait is finally over. The first beta of our brand new v4.40 release hits the public. It brings exciting new features in all areas:

  • On the compiler side there is the new ‘Threaded’ scope keyword to create thread-local variables and the new ‘.a’ and ‘.u’ native types for unsigned byte/word.
  • On the Library side there is the new ‘Map’ library to have easy hash-maps, and a completly rewritten 2DDrawing library with Sprite/ScreenOutput() even for OpenGl (slow though) and cool alpha-channel and gradient support for ImageOutput().
  • And finally, the IDE gets a much improved AutoComplete and Project management!
  • Not to forget, there is also a brand new x64 Version for Linux available!

You can find the new version on your download account on http://www.purebasic.com/

To better explain the new features, we put together some examples which can be found here: http://www.purebasic.com/beta/v440_examples.zip

Now it is up to you to help us make this new version as solid as possible. Please report any problems you have with this new version in our bug forums. Expecially the Linux x64 version needs much testing as it is brand new, and the IDE because of the massive changes that were needed for the Project management.

Here is the full changelog:

- Added: Linux x64
- Added: Map Library for hash tables
- Added: 'Threaded' Keyword for thread-local variables
- Added: Structure assignment copies the structure (a.point = b.point)
- Added: ClearStructure(*Pointer, Structure)
- Added: AES to cipher library: AESEncoder(), AESDecoder(), StartAESCipher(), AddCipherBuffer(), FinishCipher()
- Added: Dylib for OS X
- Added: Trim/LTrim/RTrim() got an optional character to trim
- Added: Added #PB_Function, #PB_OSFunction, #PB_Map to Defined()
- Added: ReverseString(String$), InsertString(String$, StringToInsert$, Position), RemoveString(String$, RemoveString$ [, Mode [, StartPosition [, NbOccurences]]])
- Added: Add blob support to databases
- Added: Added peephole optimizer to 64 bit versions to produce better code
- Added: '.a' (ascii) and '.u' (unicode) native type to provide native unsigned byte and word.
- Added: FileBuffersSize(#PB_Default, ...): #PB_Default support change the buffersize to the next opened files
- Added: #PB_URL_Protocol to Get/SetURLPart()
- Added: #PB_Shadow_TextureAdditive
- Added: FTPDirectoryEntryRaw(), FillMemory(Memory, Value, Size [, Type])
- Added: Global, Protected, Threaded, Shared and Static now accept a type to affect all default variable declaration.

- Added: AddWindowTimer(), RemoveWindowTimer(), #PB_Event_Timer, EventTimer()
- Added: #PB_Window_Tool - create tool windows
- Added: StatusBarProgress()
- Added: StatusBarImage() - now supports normal images (not just icons)
- Added: #PB_Checkbox_ThreeState flag to create a 3 state checkbox (state values: #PB_CheckBox_Checked, #PB_CheckBox_Unchecked, #PB_CheckBox_Inbetween)
- Added: ShortcutGadget()

- Added: CreateImageMenu(), CreatePopupImageMenu() for OSX
- Added: Full alphachannel support for all GUI elements that display images 
- Added: Full alphachannel support for Image lib 

- Added: New drawing modes for 2DDrawing in ImageOutput()
   - #PB_2DDrawing_AlphaBlend
   - #PB_2DDrawing_AlphaClip
   - #PB_2DDrawing_AlphaChannel
   - #PB_2DDrawing_Gradient

- Added: LinearGradient(), BoxedGradient(), CircularGradient(), EllipsicalGradient(), ConicalGradient(), 

CurtomGradient()
- Added: GradientColor(), ResetGradientColors()
- Added: DrawAlphaImage() for all outputs on all OS
- Added: DrawAlphaImage() has a new transparency parameter and can be used to draw non-alpha images part transparent

- Added: QuickDraw subsystem for WindowOutput() on OSX
- Added: Sprite/ScreenOutput for OpenGL (all OS)
- Added: DrawingFont() works for SDL output!
- Added: OutputWidth(), OutputHeight(), OutputDepth() for 2DDrawing
- Added: GrabDrawingImage(), DrawRotatedText()
- Added: RGBA(), Alpha()

- Added #PB_PixelFormat_ReversedY - for pixel buffers that are stored upside-down (Windows ImageOutput or OpenGl)
- Removed: #PB_Image_DisplayFormat is now deprecated (value set to 32 to have 32bit as default)

- Added: #PB_OS_Windows_7 for OSVersion()

- Updated: OGRE to 1.6.2, sqlite 3.6.14.2, PCRE to 7.9

- Changed: Call(C)Function(Fast) parameters have been changed from 'Any' to 'Integer'.
- Fixed: Image Decoders are now threadsafe

PureBasic IDE:
- Added: Highlight matching keyword for keyword under cursor (tied to BraceMatching color setting) 
- Added: Edit->Goto matching keyword
- Added: PB_TOOL_Preferences Environment variable for IDE tools
- Added: Theme management to customize menu icons
- Added: New 'Silk' theme based on the Iconsset by Mark James

- Added: Autocomplete scans implicit variable declaration and respects scope
- Added: Structure item autocomplete

- Added: Project Management:
      - Autocomplete for all files within a project (even if not opened)
      - Multiple compiler settings for different compile targets
      - Compile all compile targets at once
      - Per-Project list of last opened files
      - Project ToolsPanel tool for fast access to the project files

- Changed: moved encoding/newline setting from compiler options to file menu


Debugger:
- Improved: greatly improved VariableViewer update speeds
- Added: progressbar display if VariableViewer update takes long
- Added: column sort capability to VariableViewer (Windows Only)

If you are wondering where the parallel optimized sort functions are that i talked about in the blog, unfortunately these did not make it into this version. There were some problems and unfinished things in them and there just was not enough time to finish it for this version. Don’t worry though, it will be in the next one for sure 🙂

Have fun with this version!

PureBasic 4.31 beta1 released

A new PureBasic release has entered the beta stage. This is a bugfix-only release, there are no new features. The purpose of this release is to give those that only switch to newer releases once the beta-period is over a stable base to work with while the v4.40 release is going through the alpha and beta stages. We tried to focus on the major bugs in the 4.30 release and skip minor issues. Note that some even bigger bugs could not be resolved without major changes to the code and so we postponed these to the next release as well.

You can download it as usual on your user account.

Note: Since there are no new features and we want to get our focus back on the v4.40 release soon, this beta-period will be very short (maybe only one beta release). So if you reported bugs that are now marked as fixed, please test soon to verify that things work as they should now.

The v4.40 release is still a bit away, but we are working very hard on it. The list of new things is quite long again and we still need to work a few things out. Stay tuned.