LoginLogin
Nintendo shutting down 3DS + Wii U online services, see our post

Random's Big Dumb Library + Map Editor

Root / Submissions / [.]

haloopdyCreated:
Download:N383Z4MD
Version:0.7.0Size:680KB
This is the library I'll use in my programs (if I ever make any). Oh, and there's also a map editor. It's a collection of functions that provide:
  • Noise generation (useful for terrain)
  • Prime number generation/detection
  • Kinda fast dictionaries (associative arrays/arrays indexed by strings)
  • Bit and byte vectors with automatic resizing
  • LZS compression for GRPs (both slower and worse at compression than rei's, so it's useless)
  • Various math functions
  • Debug logger for outputting messages on top/bottom screen
  • Functions for basic character movement around a map
  • Textboxes
  • Menus (built from textboxes)
  • Sound effects
  • Screen Effects (render to sprite)
  • A Turing machine?
OK but seriously, it's not good. Run RNDLIBTEST to check out some of the stuff it can do. For instance, try the Noise Gen function. It has an implementation of the Plasma effect. RNDMAP is a simple map editor. Maybe it'll be useful? But it only saves maps in a format that you have to extract with RNDLIBFULL; if anybody wants to use it, I can create another tutorial for it. https://www.youtube.com/watch?v=JDlII65rCZM https://www.youtube.com/watch?v=ZTeuFlkbtYM https://www.youtube.com/watch?v=4lY3t_yYRVQ I don't want any credit if you use this library.

Instructions:

How to use the Game Engine

Also, included in the project are EXAMPLE1, EXAMPLE2, and EXAMPLE3 which are the completed programs from the above tutorial.

How to use the map editor

Run RNDMAP. You must have RNDLIBFULL in the same folder as RNDMAP. It saves in a custom format, so use the BGMAPLOAD function in RNDLIBFULL to unpack it:
DIM MAP$,META$[0]
LOAD "TXT:MYFILE",MAP$,FALSE
META$=BGMAPLOAD(MAP$)
BUT! If you're using the map with my dumb GAME engine, you do this:
GAMEPREPAREMAP "MYFILE",3,1.0

How to use everything else:

EXEC "PRG3:RNDLIBFULL"
Run the above to make all functions available. You can make the slot whatever you like; it doesn't have to be 3.

Functions Available:

Prime Numbers:

ISPRIME(NUM) : determine if a number is prime (up to 16,383*) NEXTPRIME(NUM) : get the closest prime larger than NUM (up to 16,383*) PREVPRIME(NUM) : get the closest prime smaller than NUM (up to 16,383*) CACHEPRIMES NUM : generate the prime data for numbers up to NUM * = with default settings. Running CACHEPRIMES will change the upper range; for instance, CACHEPRIMES(100000) will change the upper bound to 100000 for ISPRIME, NEXTPRIME, and PREVPRIME Examples:
?ISPRIME(5) 'TRUE
?ISPRIME(200) 'FALSE
?NEXTPRIME(20) '23
?NEXTPRIME(11) '13
?PREVPRIME(10) '7
CACHEPRIMES 100000 'Takes a little bit
?ISPRIME(99999) ' FALSE

Bit/Byte Vectors

GETBIT(BIT,VECTOR%) : Get the bit (0 or 1) for the position BIT within the given bit vector* SETBIT BIT,VALUE%,VECTOR% : Set the bit for the position BIT to the value VALUE (0 or 1) within the given bit vector* GETBYTE(BYTE,VECTOR%) : Get the byte (0-255) for the position BYTE within the given byte vector* SETBYTE BYTE,VALUE%,VECTOR%) : Set the byte for the position BIT to the value VALUE (0-255) within the given byte vector* * = A bit/byte vector is just an integer array. You can use existing arrays; the data is treated as though it is packed. Examples:
DIM V%[0] 'A bit/byte vector is just an integer array
?GETBIT(0,V%) '0
SETBIT 5,1,V%
?GETBIT(5,V%) '1
?GETBYTE(65,V%) '0
SETBYTE 12,128,V%
?GETBYTE(12,V%) '128
?GETBIT(103,V%) '1 (we set that bit with the previous SETBYTE)

Dictionary

DICCREATE$(INITIALSIZE) : Create a dictionary with the given initial capacity (can be 0) DICGET$(KEY$,DIC$) : Retrieve the value* from dictionary DIC$ at the given key (returns "" if key doesn't exist) DICSET KEY$,VALUE$,DIC$) : Set the value* for the given key in dictionary DIC$ (adds key if key doesn't exist yet. Increases capacity automatically if dictionary is getting full) DICHASKEY(KEY$,DIC$) : Return whether or not dictionary DIC$ has the given key. DICRESIZE DIC$,NEWSIZE : NOT NECESSARY TO CALL. Increase capacity to at LEAST given size. Will only increase dictionary size. Actual size set may be different. * = float and integer versions are available: DICGETI%, DICGETF#, DICSETI, DICSETF Examples:
DIM D$[0] 'A dictionary is just a string array.
D$=DICCREATE$(10) 'Set initial capacity to a large value for faster insertion. Resizes automatically regardless
?DICGET$("MYKEY",D$) 'Prints nothing
DICSET "MYKEY","HIHI", D$ 
?DICGET$("MYKEY",D$) 'Prints HIHI
DICSETI "MONKEYS",53,D$
?DICGETI%("MONKEYS",D$) 'Prints 53

Math Crap

DISTANCE(X1#,Y1#,X2#,Y2#) : Get the distance between two points CLOSESTMULTIPLE(NUM,MULT) : Get the closest number to NUM that is a multiple of MULT. LERP(A#,B#,T#) : Get the value for linear interpolation between A and B at point T. BLENDCOLORS(COL1,COL2,SHIFT#) : Blend two colors together. SHIFT# tells how much of the second color to add (0 is all the first color, 1 is all the second color, 0.5 is a perfect blend) BRIGHTENCOLOR(COL,AMT) : Brighten color by given amount. This is a linear shift: all channels are increased by the given amount. If the amount goes over 255, it is capped. BRIGHTENCOLORM(COL,M#) : Bright color by given multiple. This is much more like the "brightening" you would expect: each channel is scaled by the given amount, which keeps the overall color roughly the same. Use this version if you expect real brightening. SIGN(X) : Gives the sign of X. Returns 1 if X>0, -1 if X<0, and 0 if X==0. Examples:
?DISTANCE(1,2,2,2) '1
?DISTANCE(1,1,2,3) '2.236...
?CLOSESTMULTIPLE(10,3) '9
?CLOSESTMULTIPLE(12,5) '10
?LERP(5,10,0.5) '7.5
?BLENDCOLORS(&HFF00FF00,&HFFFF0000,0.5) ' &HFF777700
?SIGN(-5) '-1
?SIGN(5) '1

String Stuff

STRINGJOIN$(ARRAY$,JOINCHR$) : Join an array of strings together and place JOINCHR$ between them. STRINGSPLIT$(STRING$,DELIM$) : Split a string into an array using the given character as a delimiter. SARRAYTOSTRING$(ARRAY$) : Convert a string array into a single string. This can be used to turn dictionaries into single strings. STRINGTOARRAY$(STRING$) : Convert a string converted with SARRAYTOSTRING back into a string array. This can be used to unpack dictionaries (if you pack them into a single string with the above function). Examples:
DIM A$[0]
A$=STRINGSPLIT$("DATA1/DATA2/SOMETHING/WHATEVER","/") 'An array with 4 elements: DATA1, DATA2, SOMETHING, WHATEVER
?STRINGJOIN$(A$,"%") ' DATA1%DATA2%SOMETHING%WHATEVER

Noise Generators

There are currently two noise generator functions: DIAMONDSQUARE2D# and HILLGENERATOR#. Both return a 2D array filled with values ranging from 0-1 (floating point). DIAMONDSQUARE2D#(N,WIDTH,HEIGHT,SEED,DECAY#,CURVE#) HILLGENERATOR#(WIDTH,HEIGHT,SEED,HILLCOUNT,MINRADIUS#,MAXRADIUS#,CURVE#,CIRCULAR) In DIAMONDSQUARE2D#, N is the "chunk" size and width/height are the chunks across/down. Chunk size is 2N. So, the final map size will be 2N*WIDTH by 2N*HEIGHT. This is just how Diamond-Square works. The chunk size will determine the "feature" size, so a larger N will make the landscape "bigger" while a smaller one will give more details. N=2 is the smallest you should go, and remember that it's 2N so making it like 15 might cause an out of memory error. DECAY# basically determines the noisiness (smaller = less noise) and CURVE# flattens out the areas (higher = flatter). HILLGENERATOR# raises HILLCOUNT circles in a WIDTHxHEIGHT area. The minimum and maximum circle radius can be set. CIRCULAR does nothing right now, but in the future it will generate something akin to an island. CURVE# does the same thing as before: flattens out areas wither higher CURVE# values. Examples:
DIM D#[0,0]
D#=DIAMONDSQUARE2D#(3,16,16,MILLISEC,0.8,1) 'D will be 128x128
'Do something with the float values in D#

Textboxes

Textboxes are simple boxes which display formatted text with automatic line breaking and scrolling. They are drawn on the GRP layer of your choosing. They are nowhere near finished, but maybe they're a little usable... not really. Textboxes are HIGHLY customizable, so there's a lot of settings and it might get confusing. I'll add a wrapper around customization in the future so it's easier, but for now, I would stick with the default settings. Textboxes are OBJECTS, so you will need to create the textbox object, then pass that object around to all the functions. Keep this in mind when you're looking at the following examples: Examples:
DIM TB$[0]
TB$=TBCREATE$()
'DICSETF "CHRSCL",2.0,TB$ 'Uncomment this to see text scaling in action

DIM TEXT$="Look at all this text that we're outputting to the screen! Too bad it's not enough to make it scroll."
TBSHOW TB$ 'Draw textbox
TBTEXT TBFIX$(TEXT$,TB$),TB$ 'Show text with automatically-inserted elements (such as the pause at the end)
TBHIDE TB$
You can also load TESTTB to see a test program for textboxes.

Menus

Every game needs a menu somewhere. Most of the time, unless it's the MAIN menu, you're just selecting from a small set of choices. Why program this every time you need it when you can have an automatic menu that matches your textboxes? Menus work a lot like textboxes, except that they require more setup. Since they require more setup, I've created a "quick" function which does all the setup for you. Maybe one day I'll go over the ridiculous amount of customization, but for now, this'll have to do. Menus can be placed anywhere on the screen, HOWEVER, unlike textboxes, they can be "anchored" to a corner other than the top left. For instance, if you set the menu's X and Y to 0 and you specify the anchor as the bottom left, the 0,0 will now mean the bottom left. Menus can be anchored to any of the four corners; the default is the lower right (for use with textboxes). Furthermore, even though menus are built from textboxes, they will ignore their width, height, and text location settings since menus are automatically sized to fit the text they are displaying. Examples:
DIM MN$[0]
MN$=MENUCREATE$()

DIM OPT$[0]
PUSH OPT$,"Kittens"
PUSH OPT$,"Puppies"
PUSH OPT$,"Echidnas"
PUSH OPT$,"Bunnies"

DIM SELECTED=MENUQUICK(OPT$,MN$)

IF SELECTED>=0 THEN PRINT "You've selected: "+OPT$[SELECTED] ELSE PRINT "You cancelled!"
You can also load TESTMENU to see it in action. I use STRINGSPLIT to create the list of options in that program.

Turing Machine

Why use this? IDK. Run RNDLIBTEST, then select "Toys" at the main menu, then "Turing". This is a Turing "editor" and "debugger" all in one. -Left panel of 0's = test tape (circular). Use CPAD to move head up/down, left/right to alter symbol manually. -Main area is state list. Each state can perform 3 actions based on input (only 3 inputs for the debugger: 0,1,S). -W = write symbol, M = move head, S = next state. -DPAD to move around state/action list. A=change action, B=clear -X = menu. Can load/save turing machines or clear current -Y = run next Turing step using current head position and current state. Holding Y will run machine at 30fps. machine will beep if runs into halt state -Empty = no write, no move, or halt state. I'll add the others later or something.

Notes:

Changes:

0.7.0

  • Added a Turing machine
  • Added some string functions (RPAD, LPAD, STRREPLACE)

0.6.1

  • Fixed file select menu crash for rndmap
  • Fixed REMOVECHUNK incorrect removal

0.6

  • Added a BG map editor called RNDMAP
  • Added more functions for saving/loading backgrounds
  • Updated the game library functions to work... better? Old programs won't work with the new library.

0.5

  • Simple Game Engine superseded by just Game Engine which is faster and better
  • Fixed some textbox bugs; can disable animations now
  • Added easy textbox coloring; sets a pile of colors all automatically
  • Textbox text selection color (menus, input) can be set separate from regular text color
  • Added test library to test all the crap
  • More sound effects
  • The beginning of a framework for stacked special effects using render to sprite.
  • Stuff for automatic path smoothing (if you follow my BG tile order (which I haven't posted yet))
  • Diamond-square noise generator
  • Hill-raising noise generator
  • A simple frame timer
  • Path snaker (useful for rivers/paths/whatever)
  • Scaled GCOPY (slow but useful maybe)
  • Convert between reals (0-1) to grayscale, tricolor, and hue wheel
  • Convert button directions to angles
  • Rotate points around an origin

0.4

  • Dictionaries are now much faster and should keep their constant access time for much larger dictionaries. Dictionaries up to 1000 elements now have roughly the same access time as dictionaries with 100.
  • Added menu system. Menus can be anchored to corners of the screen and use many of the same options as textboxes.
  • Added string functions for splitting/joining/etc.

0.3

  • Made dictionary work for single character keys (it would crash before)
  • Made dictionary lookup twice as fast for keys which resort to linear scan.
  • Added the textbox library

0.2

  • Fixed dictionary functions so it actually hashes correctly now
  • Added the beginnings of Simple Game Engine stuff.
In the future, I want to add:
  • Textbox wrapper functions so it's easier to use
  • An RPG Library

How do I "unpack" the maps I make on the editor?

Replying to:rando
How do I "unpack" the maps I make on the editor?
Ah let me update the program real quick; there was a way before but now there's an easier way. Edit: updated the project When the update is out, you just run something like this:
DIM MAP$,META$[0]
LOAD "TXT:MYFILE",MAP$,FALSE
META$=BGMAPLOAD(MAP$)
Now the map should be in the BG. You don't have to do anything with META, it's just there if you need it. BUT! If you're using the map with my dumb GAME engine, you do this:
GAMEPREPAREMAP "MYFILE",3,1.0
Where "MYFILE" is the name of the FILE, 3 is the collision layer, and 1.0 is the scale you want to display the bg at.

Replying to:DFrost
What about 3D?
3D... library? I don't have any, sorry.

Replying to:rando
How do I "unpack" the maps I make on the editor?
How do I save the loaded map (I used gamepreparemap) to a file or files that can be loaded?

Replying to:rando
How do I "unpack" the maps I make on the editor?
Save the... loaded map? Isn't it already saved? Isn't that how you were able to load it in the first place? I'm confused.

Replying to:rando
How do I "unpack" the maps I make on the editor?
Oh, I should be more specific. How can I save the loaded map that I loaded with gamepreparemap to a dat file or dat files?

Replying to:rando
How do I "unpack" the maps I make on the editor?
Oh you don't need gamepreparemap for that. There's a few ways to do it depending on whether you want the BG to load before saving. It's all SB commands. If you don't care about the BG being loaded just to save it, you can do:
GAMEPREPAREMAP "MYFILE",3,1.0
DIM DAT[10000] 'However big it needs to be to hold your bg
FOR I=0 TO 3
 BGSAVE I,DAT 'Store BG to array
 SAVE FORMAT$("DAT:BGLAYER_%D",I),DAT 'Save array
NEXT
You don't have to use format if you don't know how it works. Just do "DAT:BGLAYER_"+STR$(I). If you don't want to load the bg just to save it, you can extract the data from the package:
VAR S$,SV$[0],D$,DAT[10000] 'Again, as big as you need
LOAD "TXT:MYFILE",FALSE OUT S$
SV$=STRINGTOARRAY(S$)
D$=DICGET$("DAT",SV$)
FOR I=0 TO 3
 VAR LB$="L"+STR$(I)
 DAT=STRINGTOIARRAY(DICGET$(LB$+"D",D$))
 SAVE FORMAT$("DAT:BGLAYER_%D",I),DAT
NEXT
NOTE: this data that you're extracting using BGSAVE is just a flat array. You load it with BGLOAD, but BGLOAD needs the width and height, so make sure you know what it is. The map package stores all this information; I can show you how to extract it if necessary.

Replying to:DFrost
What about 3D?
I'm saying you could make a 3D engine

Maybe you can add a huffman coding algorithm? I think it would be very useful and do better than LZSS in a lot of cases.

Replying to:h267
Maybe you can add a huffman coding algorithm? I think it would be very useful and do better than LZSS in a lot of cases.
Maybe. But compression is useless because the guy who made petitmodem already has a stupidly good and really fast compression algorithm.

Replying to:h267
Maybe you can add a huffman coding algorithm? I think it would be very useful and do better than LZSS in a lot of cases.
I wouldn't mind waiting around a little more if it means it could achieve better compression ratios. Besides, it would be a nice achievement and addition to your library.

Replying to:h267
Maybe you can add a huffman coding algorithm? I think it would be very useful and do better than LZSS in a lot of cases.
huffman coding is worse than LZSS

Replying to:h267
Maybe you can add a huffman coding algorithm? I think it would be very useful and do better than LZSS in a lot of cases.
How? I thought the variable-length dictionary entires ended up saving more space than LZSS.

I'm so sorry. Someone requested that I fix the crash on the map editor and I never uploaded the fix. I'm sure you've moved on by now, whoever you were, but the fix is up now in case anybody still cares

Replying to:haloopdy
I'm so sorry. Someone requested that I fix the crash on the map editor and I never uploaded the fix. I'm sure you've moved on by now, whoever you were, but the fix is up now in case anybody still cares
That was me. It's fine, I actually made it so it only displays text files in loading maps, I had to change the library for that but it was a minor change. You're good.