Menu

Show posts

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

Show posts Menu

Topics - bigsofty

#41
Off Topic / CPC 464 Wifi
2016-Oct-18
I'm continuously amazed at what comes out of the CPC scene. Wifi on a CPC, internet access, rom emulation and floppy drive emulation all by one guy.  :O

http://www.spinpoint.org
#42
I document the old fashioned way, that is, via text files.

This little program extracts the bits I document for a directory of GBAS files and writes them to a new subdir within that directory when its done.

It extracts from each GBAS file...

Constants
Globals
Global Functions
Types
Type Properties
Type Methods

Sorts them and writes them to a .TXT file.

See end for an example.

Code (glbasic) Select
// --------------------------------- //
// Project: GLBDocumenter
// Start: Wednesday, August 24, 2016
// IDE Version: 14.371


GLOBAL dir$ = "C:/Coding Folder/Projects/GLBasic/plasma/" // Scan dir
GLOBAL docsDir$ = "GLBDocs" // Where to store generated text files
GLOBAL sorting% = TRUE // Use alphabetic sorting

GLOBAL files[] AS TFile // Holds all the file data

TYPE TFile
filename$
dir$
globals$[]
constants$[]
functions$[]
types[] AS TType
text$[]
ENDTYPE

TYPE TType
name$
properties$[]
methods$[]
ENDTYPE

// Do it

ReadInFiles( files[], dir$ )
ProcessFiles( files[] )
WriteFileData( files[] )

END


INLINE
/*-------------------------------------------------------------------------------------*\
| |
|                                     READ A Dir                                        |
| |
\*-------------------------------------------------------------------------------------*/
ENDINLINE
// Scan a dir reading in all the samples
FUNCTION ReadDir: dir$ = "", ext$ = "GBAS"
LOCAL aFile AS TFile, gbasFileList$[]
aFile.dir$ = dir$
IF dir$="" THEN dir$ = GETCURRENTDIR$()
LOCAL saveCurrentDir$ = GETCURRENTDIR$()
SETCURRENTDIR( dir$ )
GETFILELIST( "*.*", gbasFileList$[] )
FOREACH filename$ IN gbasFileList$[]
IF UCASE$ ( RIGHT$( filename$, 4) ) = UCASE$( ext$ )
aFile.filename$ = filename$
DIMPUSH files[], aFile
DEBUG "File: " + aFile.filename$ + "\n"
ENDIF
NEXT
SETCURRENTDIR( saveCurrentDir$ )
ENDFUNCTION



INLINE
/*-------------------------------------------------------------------------------------*\
| |
|                                     Read In Text                                      |
| |
\*-------------------------------------------------------------------------------------*/
ENDINLINE
// Scan a dir reading in all the samples
FUNCTION ReadInFiles: files[] AS TFile, dir$
LOCAL f = GENFILE(), a$, t$[], n%, rv#
ReadDir( dir$ )
IF dir$="" THEN dir$=GETCURRENTDIR$()
LOCAL saveCurrentDir$=GETCURRENTDIR$()
SETCURRENTDIR(dir$)
IF NOT ( DOESDIREXIST( docsDir$ ) ) THEN SHELLCMD("cmd.exe /c mkdir " + docsDir$, FALSE, FALSE, rv#)
FOREACH file IN files[]
OPENFILE(f, file.dir$ + file.filename$, TRUE)
WHILE NOT ( ENDOFFILE( f ) )
READLINE f, a$
// Cheack and split ";"
IF SPLITSTR( a$, t$[], ";" ) > 0
FOREACH a$ IN t$[]
DIMPUSH file.text$[], a$
NEXT
ELSE
DIMPUSH file.text$[], a$
ENDIF
WEND
CLOSEFILE f
NEXT
SETCURRENTDIR( saveCurrentDir$ )
ENDFUNCTION



INLINE
/*-------------------------------------------------------------------------------------*\
| |
|                                     Process Files                                     |
| |
\*-------------------------------------------------------------------------------------*/
ENDINLINE
// Scan a dir reading in all the samples
FUNCTION ProcessFiles: files[] AS TFile
LOCAL n%, t$[], inType%, inFunc%,typeStart%, inInline%, typ AS TType
FOREACH f IN files[]
//DEBUG "\n\nFILE: \"" + f.filename$ + "\"\n"
inType% = FALSE; inFunc% = FALSE
FOREACH a$ IN f.text$[]
n% = SPLITSTR( a$, t$[], ", \t" )
IF LEN( t$[] ) = 0 THEN CONTINUE
IF LEFT$( t$[0], 2 ) = "//" THEN CONTINUE
SELECT t$[0]

CASE "TYPE"
inType% = TRUE
typeStart% = TRUE
DIMPUSH f.types[], typ
f.types[ -1 ].name$ = t$[1]
//DEBUG "\n TYPE: "+f.types[ -1 ].name$ + "\n"

CASE "ENDTYPE"
inType% = FALSE
typeStart% = FALSE

CASE "FUNCTION"
inFunc% = TRUE
typeStart% = FALSE
IF inType%
DIMPUSH f.types[ -1 ].methods$[], Func$( a$ )
//DEBUG " m:"+f.types[ -1 ].methods$[-1]+"\n"
ELSE
DIMPUSH f.functions$[], Func$( a$ )
//DEBUG " f:"+f.functions$[-1]+"\n"
ENDIF

CASE "ENDFUNCTION"
inFunc% = FALSE

CASE "GLOBAL"
DIMPUSH f.globals$[], LTRIM$( MID$( a$, INSTR( a$, "GLOBAL" ) + 6, -1 ) , " \t" )
//DEBUG " G:"+f.globals$[-1]+"\n"

CASE "CONSTANT"
DIMPUSH f.constants$[], LTRIM$( MID$( a$, INSTR( a$, "CONSTANT" ) + 8, -1 ) , " \t" )
//DEBUG " C:"+f.constants$[-1]+"\n"

CASE "//"

CASE "INLINE"
inInline% = TRUE

CASE "ENDINLINE"
inInline% = FALSE

DEFAULT
IF inType% AND typeStart% AND NOT ( inInline% )
DIMPUSH f.types[ -1 ].properties$[], LTRIM$( a$ , " \t" )
//DEBUG " P:" + f.types[ -1 ].properties$[ -1 ] + "\n"
ENDIF
ENDSELECT
NEXT
//
NEXT
ENDFUNCTION



INLINE
/*-------------------------------------------------------------------------------------*\
| |
|                                Process a Function Call                                |
| |
\*-------------------------------------------------------------------------------------*/
ENDINLINE
// Scan a dir reading in all the samples
FUNCTION Func$: a$
LOCAL b$ = LTRIM$( MID$( a$, INSTR( a$, "FUNCTION" ) + 8, -1 ) , " \t" )
b$ = REPLACE$ (b$, ":"," ( " )
IF INSTR( b$, "//" ) = -1
b$ = b$ + " )"
ELSE
b$ = REPLACE$ (b$, "//"," )  //" )
ENDIF
b$ = REPLACE$( b$, " (  )", "()" )
b$ = REPLACE$( b$, "(  ", "( " )
b$ = REPLACE$( b$, "  )", " )" )
RETURN b$
ENDFUNCTION


INLINE
/*-------------------------------------------------------------------------------------*\
| |
|                                Process File Data                                      |
| |
\*-------------------------------------------------------------------------------------*/
ENDINLINE

// Scan a dir reading in all the samples
FUNCTION WriteFileData: files[] AS TFile
LOCAL n%, f%, r
FOREACH file IN files[]
// Open file
OPENFILE( f%, file.dir$ + docsDir$ + "/" + file.filename$ + ".txt", FALSE)
WRITELINE f%, "FILENAME: " + file.dir$ + file.filename$
// Constants
WRITELINE f%,""; WRITELINE f%, "CONSTANTS:"
IF sorting% THEN SORTARRAY file.constants$[], ADDRESSOF(compare)
FOREACH c$ IN file.constants$[]
WRITELINE f%, "\t" + c$
NEXT
// Globals
WRITELINE f%,""; WRITELINE f%, "GLOBALS:"
IF sorting% THEN SORTARRAY file.globals$[], ADDRESSOF(compare)
FOREACH g$ IN file.globals$[]
WRITELINE f%, "\t" + g$
NEXT
// Global Functions
WRITELINE f%,""; WRITELINE f%, "GLOBAL FUNCTIONS:"
IF sorting% THEN SORTARRAY file.functions$[], ADDRESSOF(compare)
FOREACH f$ IN file.functions$[]
WRITELINE f%, "\t" + f$
NEXT
// Types
WRITELINE f%,""; WRITELINE f%, "TYPES:"
FOREACH t IN file.types[]
WRITELINE f%, "\t" + t.name$ + ":"
// Properties
WRITELINE f%, "\t\tPROPERTIES:"
IF sorting% THEN SORTARRAY t.properties$[], ADDRESSOF(compare)
FOREACH p$ IN t.properties$[]
WRITELINE f%, "\t\t\t." + p$
NEXT
// Methods
WRITELINE f%, "\t\tMETHODS:"
IF sorting% THEN SORTARRAY t.methods$[], ADDRESSOF(compare)
FOREACH m$ IN t.methods$[]
WRITELINE f%, "\t\t\t." + m$
NEXT
NEXT
WRITELINE f%,""
CLOSEFILE f%
NEXT
ENDFUNCTION


INLINE
/*-------------------------------------------------------------------------------------*\
| |
|                                     Sort Function                                     |
| |
\*-------------------------------------------------------------------------------------*/
ENDINLINE

FUNCTION compare: BYREF a$, BYREF b$
   IF ASC( LCASE$( a$ ) ) < ASC( LCASE$( b$ ) ) THEN RETURN -1
   IF ASC( LCASE$( a$ ) ) > ASC( LCASE$( b$ ) ) THEN RETURN 1
   RETURN 0
ENDFUNCTION



An example of the output.

Code (glbasic) Select
FILENAME: C:/Coding Folder/Projects/GLBasic/plasma/2Dmesh.gbas

CONSTANTS:
ANITYPE_2D_ROTATE = 0
RENDERFX_2D_QUICK = 2
RENDERFX_2D_NORMAL = 0
RENDERFX_2D_COLOURED = 1

GLOBALS:
meshes2D AS T2DMeshes

GLOBAL FUNCTIONS:

TYPES:
T2DMeshes:
PROPERTIES:
.batch AS TVBeam
.models AS T2DModels
.m[] AS T2DMesh
.total2DMeshes%
METHODS:
.Add ( m AS T2DMesh )
.Destroy()
.Del ( mNum% )
.New()
.Render ( batch AS TVBeam, useModels AS TModels )
.SetUp()
.Update()
T2DMesh:
PROPERTIES:
.aniRotSpd#
.aniType%
.baseRadius# // Radius of unscaled Mesh
.drawFlag% = TRUE
.isInterpolatedFlag% = TRUE
.isRotatededFlag% = TRUE
.isScaledFlag% = TRUE
.lineAlpha% = 255
.lineColour% = 0xffffff
.lineWidth# = 8
.lineCombined% = 0xffffff00
.matrix#[]
.mdlNum%
.oldScl AS TVec2
.oldPos AS TVec2
.oldRot AS TVec2
.pos AS TVec2
.rot AS TVec2
.radius# // Radius of scaled 2DMesh(based on baseRadius)
.realTimeScalingFlag% = FALSE
.renderFX%
.scl AS TVec2
.vAniRotDir AS TVec2
METHODS:
.Animate()
.AniRotate()
.CacheTransform()
.CalcRadius ( )  // TODO ( Wrong!
.Destroy()
.Hide()
.RenderColoured ( batch AS TVBeam, use2DModels AS T2DModels = models2D )
.RenderColouredOLD ( batch AS TVBeam, use2DModels AS T2DModels = models2D )
.RenderNormal ( batch AS TVBeam, use2DModels AS T2DModels = models2D )
.Render ( batch AS TVBeam, use2DModels AS T2DModels = models2D )
.RenderColoured2 ( batch AS TVBeam, use2DModels AS T2DModels = models2D )
.RenderQuick ( batch AS TVBeam, use2DModels AS T2DModels = models2D )
.sRotateX ( x# )
.sRotateY ( y# )
.sMove ( x#, y# )
.SetUp ( use2DModels AS T2DModels = models2D )
.sRotate ( x#, y# )
.sScale ( x#, y# )
.SetRadius ( baseRadius# )
.Show()
.Set()
.sMoveTo ( x#, y# )
.sTurn ( x#, y# )
.sScaleRel ( x#, y# )
.Update()
.vMoveTo ( pos AS TVec2 )
.vRotate ( rot AS TVec2 )
.vTurn ( rot AS TVec2 )
.vMove ( pos AS TVec2 )
.vScaleRel ( scl AS TVec2 )
.vScale ( scl AS TVec2 )
#43
I just picked up this from the App Store as it was recommended to me. I already have had various VNC clients but they were always laggy through the WIFI network.

This little app is different though, it basically uses the lightning connector as the method to transfer the picture from your PC to the iPad screen. On the PC your iPad is detected as a 2nd monitor. And it works, without lag and very little compression artefacts. Once set up, you really can use your iPad as a 2nd little monitor on your PC, allowing you to drag windows onto to it and use your mouse cursor as usual. Great stuff!

For GLBasic, you can drag the debug window onto it or even keep the help constantly open. CPU use is almost zero too, pretty impressive.

See... http://www.duetdisplay.com/
#44
Off Topic / 8bit Simpsons
2016-Jun-27
Love the pixel art in this. This guy should do a full cartoon!

#45
Lots of good stuff to be had but here is my personal pick, it's old but for RTS style games it simply did not get any better...

Total Annihilation (Only 99p!)- http://store.steampowered.com/app/298030/?snr=1_7_7_ut2_150_7

I thoroughly recommend it to anyone who hasn't tried it before.
#46
https://www.indiegogo.com/projects/the-sinclair-zx-spectrum-vega-plus-console#/

Last chance to buy a limited (coloured) edition tonight. Grabbed a white one for myself.  :-*
#48
Off Topic / Pi 3 - Model B
2016-Mar-01
New Pi just wen't on sale, Quad core, 64bit, wifi... pretty powerful.

Here's the full specs.

QuoteDESCRIPTION
The Raspberry Pi just got juicer! Now with a Quad-Core 64bit CPU, WiFi & Bluetooth!

The Raspberry Pi 3 Model B is the third generation Raspberry Pi. This powerful credit-card sized single board computer can be used for many applications and supersedes the original Raspberry Pi Model B+ and Raspberry Pi 2 Model B.

Whilst maintaining the popular board format the Raspberry Pi 3 Model B brings you a more powerful processor, 10x faster than the first generation Raspberry Pi.

Additionally it adds wireless LAN & Bluetooth connectivity making it the ideal solution for powerful connected designs.

Raspberry Pi 3 - Model B Technical Specification

  • Broadcom BCM2387 chipset
  • 1.2GHz Quad-Core ARM Cortex-A53
  • 802.11 bgn Wireless LAN and Bluetooth 4.1 (Bluetooth Classic and LE)
  • 1GB RAM
  • 64 Bit CPU
  • 4 x USB ports
  • 4 pole Stereo output and Composite video port
  • Full size HDMI
  • 10/100 BaseT Ethernet socketbr
  • CSI camera port for connecting the Raspberry Pi camera
  • DSI display port for connecting the Raspberry Pi touch screen display
  • Micro SD port for loading your operating system and storing data
  • Micro USB power source
Raspberry Pi 3 - Model B Features

Now 10x Faster - Broadcom BCM2387 ARM Cortex-A53 Quad Core Processor powered Single Board Computer running at 1.2GHz!
1GB RAM so you can now run bigger and more powerful applications
Fully HAT compatible
40pin extended GPIO to enhance your "real world" projects.
Connect a Raspberry Pi camera and touch screen display (each sold separately)
Stream and watch Hi-definition video output at 1080
Micro SD slot for storing information and loading your operating systems.
10/100 BaseT Ethernet socket to quickly connect the Raspberry Pi to the Internet
#49
GLBasic - en / INTEGER64
2016-Feb-29
INTEGER64(num#)

Seems to be undocumented(also not in the logs)?  :blink:

Converts a number to a 64bit integer.

#50
Seems to be a problem with GETNUMJOYSTICKS() if you turn the gamepad on (I'm using a wireless 360 gamepad) after your app has started, it's always zero. I could tell people that it will require a restart if their gamepad is not recognised but this feels a bit clumsy.

Any tips on how to avoid this?
#51
Off Topic / Sculptgl
2015-Dec-16
Anyone who remembers Sculptris will be right at home with this. Its a 3d modeler/topology editor.

http://stephaneginier.com/sculptgl/



Lets hope Pixologic lets this developer carry on without a buy-out!  :S
#52
Anyone tried GLBasic on one these little beauties? I'm thinking of picking one of these up.

It's actually feasible to ship a computer + game for just the cost of the game on it! Who would have though that day would ever come, lol!  :D

#53
Off Topic / Free books
2015-Dec-05
Free Packt book each day...

https://www.packtpub.com/packt/offers/free-learning

It's a bit of  lucky dip but there's always something that pops up every now and then.

#54
This tiny routine sets a new origin, rotates and scales any thing between the two new commands...

Code (glbasic) Select

Transform2DON( rotateAngle#, translateX#, translateY#, scaleX#, scaleY# ) // Angle, new origin X and new origin Y coords

... Normal 2D code goes here

Transform2DOFF()


file 1, quick demo...

Code (glbasic) Select
// --------------------------------- //
// Project: Transform2D
// Start: Monday, November 16, 2015
// IDE Version: 12.312


// SETCURRENTDIR("Media") // go to media files

GLOBAL angle#
WHILE 1
X_MAKE2D
angle# = FMOD( angle# + 0.5, 360 )

Transform2DON( MOD( -angle#, 360 ) , 320, 240 )
FOR x = 0 TO 9
FOR y = 0 TO 9
DRAWRECT -400 + x*80, -400 + y*80, 80, 80, RGB(y*25.6, x*25.6, SIN(angle/2)*255 )
NEXT
NEXT
Transform2DOFF()

Transform2DON( angle# * 2 , 320 + COS(angle*2)*200, 240 + SIN(angle)*200, SIN(angle)*4, SIN(angle)*4 )
DRAWRECT -120, -50, 240, 100, RGB(SIN(angle/2)*255, 55, 0)
PRINT "ROTATE + TRANSLATE + SCALE", -100 ,0
Transform2DOFF()

SHOWSCREEN
WEND


file 2, the actual lib to rotate, translate and scale the 2D stuff...

Code (glbasic) Select
// --------------------------------- //
// Project: Transform2D
// Start: Monday, November 16, 2015
// IDE Version: 12.312

INLINE

    };
    extern "C" void __stdcall glPushMatrix();
    extern "C" void __stdcall glPopMatrix();
    extern "C" void __stdcall glTranslatef( float, float, float );
    extern "C" void __stdcall glScalef( float, float, float );
    extern "C" void __stdcall glRotatef( float, float, float, float );
    namespace __GLBASIC__ {

ENDINLINE

FUNCTION Transform2DON: rotateAngle#, translateX#, translateY#, scaleX# = 1.0, scaleY# = 1.0
INLINE
   glPushMatrix();
   glTranslatef(translateX, translateY, 0.0);
   glScalef(scaleX, scaleY, 1);
   glRotatef( rotateAngle, 0, 0, 1.0);
ENDINLINE
ENDFUNCTION

FUNCTION Transform2DOFF:
INLINE
   glPopMatrix();
ENDINLINE
ENDFUNCTION

// Same stuff, just a little more flexible

FUNCTION Push2DMatrix: // Transformation On (Preserve current transformation matrix)
INLINE
   glPushMatrix();
ENDINLINE
ENDFUNCTION

FUNCTION Pop2DMatrix: // Transformation Off (restore the previous transformation matrix)
INLINE
   glPopMatrix();
ENDINLINE
ENDFUNCTION

FUNCTION Translate2D: translateX#, translateY# // Translate 2D
INLINE
   glTranslatef(translateX, translateY, 0.0);
ENDINLINE
ENDFUNCTION

FUNCTION Rotate2D: rotateAngle# // Rotate 2D
INLINE
   glRotatef( rotateAngle, 0, 0, 1.0);
ENDINLINE
ENDFUNCTION

FUNCTION Scale2D: scaleX#, scaleY# // Scale 2D
INLINE
   glScalef(scaleX, scaleY, 1);
ENDINLINE
ENDFUNCTION



It should be very fast are all the work is being done on the GPU.

Edit: Small bug in translate fixed, using these 2D function as a matrix stack should work now.
#55
I have a small problem with function prototypes. Every time I start to use them it completely breaks my way of coding, I normally do everything in Types, that is, as close as you can get to OO coding in GLB. So if I create a sprite type, I would have a type, with fields, various methods for updating, rendering, creating ect. It usually works great but function prototypes forces you to use static functions, that is create everything outside a type.

So this for example...

Code (glbasic) Select
PROTOTYPE EaseFuncProto#: t#

GLOBAL Ease AS TEase

TYPE TEase

EaseType[] AS EaseFuncProto

FUNCTION Linear#: t#; RETURN t; ENDFUNCTION

FUNCTION SetUp:
DIM self.EaseType[1]
self.EaseType[0] = self.Linear
ENDFUNCTION

ENDTYPE


Produces this compile error...

Code (glbasic) Select
C:\Users\Ian\AppData\Local\Temp\glbasic\gpc_tempg.cpp: In member function `DGInt __GLBASIC__::TEase::SetUp()':
C:\Users\Ian\AppData\Local\Temp\glbasic\gpc_tempg.cpp:2285: error: no match for 'operator=' in '(((__GLBASIC__::DGArray<__GLBASIC__::EaseFuncProto>*)((__GLBASIC__::TEase*)this)) + 4u)->__GLBASIC__::DGArray<T>::operator() [with T = __GLBASIC__::EaseFuncProto](0) = ((__GLBASIC__::TEase*)this)->__GLBASIC__::TEase::Linear'
C:/Program Files (x86)/GLBasic_v12/Compiler/platform/Include/glb.h:1530: note: candidates are: prototype __GLBASIC__::GLB_PROTO<prototype>::operator=(prototype) [with prototype = DGInt (*)(DGInt)]
C:/Program Files (x86)/GLBasic_v12/Compiler/platform/Include/glb.h:1527: note:                 __GLBASIC__::GLB_PROTO<DGInt (*)(DGInt)>& __GLBASIC__::GLB_PROTO<DGInt (*)(DGInt)>::operator=(const __GLBASIC__::GLB_PROTO<DGInt (*)(DGInt)>&)
*** FATAL ERROR - Please post this output in the forum


I can fix this by basically moving everything out of the type but boy is this messy. I don't see why it needs to be done at compile time as the function pointers can be assigned after a class has been created.

Any suggestion on how to keep PROTOTYPE functionality within the type?
#56
Off Topic / Sidtracker-64
2015-Jun-30
This one is not free but its just so damn good I though I would write up some info.

This is an iOS app that emulates the C64 SID Chip and wraps it in a lovely tracker util. It cost UK £9.99 and its great for creating Chiptunes. The interface is just as good too, very intuitive, easy to pick up and for a tracker that's almost unheard of!

Some specs...
Code (glbasic) Select
SID synthesizer engine specs:
· Fully emulated SID 8580 R5 chip.
· 3 separate voices
· 8 waveforms - tri, saw, pulse with pwm, noise, trisaw, tripulse, sawpulse, nowave
· Wavetable editing
· 3 volume envelopes
· Dedicated vibrato controls
· 1 multimode filter LP/BP/HP (12/6/12db) with sweep envelope
· Filter table editing. Change filter cutoff and modes up to 1/240
· Hard sync and Ringmod per voice
· PWM sweep envelop
· PWM table editing
· Hard restart
· Variable emulation speed from 25-240hz (standard 50)
· 32 instruments per song (copy/paste/rename)

Tracker (sequencer):
· 3 voice patterns
· Mute voices on/off
· Change instrument per step
· FX pattern - change volume/filter/speed per step
· Loop pattern
· Song building
· Live or step recording
· Metronome / count in
· Follow mode
· Note effects (Glide/sustain/vibrato/filter & pulse reset/tie)
· Song mode with transpose

Midi:
· Keyboard input 1-3 voices (mono, duo and polyphonic)
· CC-assignable synth parameteras
· Modulation wheel vibrato
· Pitch bend
· Midi Clock in
· Selectable input channel

Export:
· .s64 - native SidTracker 64 file
· .m4a - audio
· .sid - for use in sidplayer
· .prg - exports play data for a real Commodore 64



http://createdigitalmusic.com/2015/06/sidtracker-64-puts-retro-chip-music-creation-ipad/
#57
Media Section / Chiptone
2015-Jun-24
Nice little FX generator and if the author continues, it should a great all round sound FX / Music creation tool!

http://sfbgames.com/chiptone/

BTW, needs flash.
#58
Anyone used this command, there does not seem to a reference in the manual to it?
#59
Came across this the other day, its a 3D model search engine, decent filter and with quite a nice 3D preview viewer too.

https://www.yobi3d.com/#!/

Hopefully useful to someone else too. ;)
#60
Very nice little pixel editor, with some powerful features, procedurally rendered tiles for example.

http://www.vitruality.com/tools/spartan/