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.

Topics - Kitty Hello

Pages: [1] 2 3 ... 38

I had to add a 3D eggplant to one of my games and noticed, that my AC3D license was too old and the uppgrade fee was raised a lot and whatnot. So I installed the new Blender 2.9 and after a few videos, I got the hang of it. It improved a LOT! If you want to do 3D, try this out.
So, the Blender export filter was broken due to API changes. I had a few nights to get that running again. The old script was about 10+ years old. :)
(reminder to myself: always comment code. Code you wrote 5 years ago is code someone else might have written...)

So, I fixed the export and found, the dda files were quite big. I inserted a scale factor for normals and vertex coordinates and now... the dda (ASCII!) file format is more compact than the ddd binary file format I used to be so proud of.

The trick is, that the vertex positions*1000 often result in numbers like "5" or "15", which is 2-3 bytes including a separating space caracter. The binary always takes 4 bytes per float. Same for the normal directions*100.
The next update will bring both, the export filter and the dda 2.0 support to you.

Code Snippets / Load data from memory
« on: 2021-Oct-14 »
I tell you a secret. GLBasic can load data from a memory buffer, as if it was a file. With the attached code, you can use the contents of a string to "read" it as a file. This should work for about everything. Sprites, sounds, binary files, ...

Code: (glbasic) [Select]

LOCAL mem$ = "Hello World"
LOCAL memlen = LEN(mem$)

LOCAL file$ = MemMakeFile$(mem$)

LOCAL text$
OPENFILE(1, file$, TRUE)
READSTR 1, text$, 64
STDOUT text$ + "\n"


extern "C" {int sprintf(char *str, const char *format, ...); }

FUNCTION MemMakeFile$: BYREF data$, nofBytes = -1
IF nofBytes < 0 THEN nofBytes = LEN(data$)
LOCAL url$
LOCAL hx$ = RIGHT$("0000000000000000" + HEX$(nofBytes), 8)
void* address = &data_Str[0];
char buffer[64];
sprintf(buffer, "%x", address);

url_Str = CGStr("mem://") + hx_Str + CGStr(".") + CGStr(buffer);


Announcements / New BETA
« on: 2021-Jun-15 »
Including long requested MEM2FONT and FONT2MEM commands.

Userlibs [ *.gbal] / Dictionary, SortedList
« on: 2021-Feb-05 »
Here's an improved version of the Dictionary and a Sorted List for strings. I'll include that into the GLBasic Samples folder, because it's very handy, okay?
Code: (glbasic) [Select]
// --------------------------------- //
// Project: T_Dictionary
// Start: Friday, August 16, 2019
// IDE Version: 16.252

TYPE T_DictionaryPair

TYPE TDictionary
pairs[] AS T_DictionaryPair

// ------------------------------------------ //
//! Get string at given key
// ------------------------------------------ //
FUNCTION get$: key$
LOCAL i% = _index(key$, FALSE)
IF i>=0 THEN RETURN self.pairs[i].val$

// ------------------------------------------ //
//! Set string at given key
// ------------------------------------------ //
FUNCTION set%: key$, val$
LOCAL i% = _index(key$, TRUE)
self.pairs[i].val$ = val$

// ------------------------------------------ //
//! Get index in pairs[] for given string
// ------------------------------------------ //
FUNCTION _index%: BYREF name$, create%=TRUE
LOCAL up%, dn%, mid%
up=0; dn=LEN(self.pairs[])-1
WHILE up < dn
mid = (up+dn) / 2
IF self.pairs[mid].key$ > name$
dn=MAX(mid-1, up)
IF self.pairs[mid].key$ < name$
up=MIN(dn, mid+1)
RETURN mid // not bigger, not smaller, guess what!?

IF LEN(self.pairs[]) AND self.pairs[up].key$ = name$ THEN RETURN up

// not found. But must be at [up].
IF create%
dn = LEN(self.pairs[]) // one below last
REDIM self.pairs[dn+1]
FOR mid = dn TO up+1 STEP -1
self.pairs[mid] = self.pairs[mid-1]
IF dn>0 AND self.pairs[up].key$ < name$ THEN up=up+1

ALIAS where AS self.pairs[up]
where.key$ = name$
where.val$ = ""

TYPE TSortedSet

// ------------------------------------------ //
//! Get string at given key
// ------------------------------------------ //
FUNCTION isSet%: key$
LOCAL i% = _index(key$, FALSE)

// ------------------------------------------ //
//! Set string at given key
// ------------------------------------------ //
FUNCTION insert%: key$
_index(key$, TRUE)

// ------------------------------------------ //
//! Get index in pairs[] for given string
// ------------------------------------------ //
FUNCTION _index%: BYREF name$, create%=TRUE
LOCAL up%, dn%, mid%
up=0; dn=LEN(self.keys$)-1
WHILE up < dn
mid = (up+dn) / 2
IF self.keys$[mid] > name$
dn=MAX(mid-1, up)
IF self.keys$[mid] < name$
up=MIN(dn, mid+1)
RETURN mid // not bigger, not smaller, guess what!?

IF LEN(self.keys$[]) AND self.keys$[up] = name$ THEN RETURN up

// not found. But must be at [up].
IF create%
dn = LEN(self.keys$[]) // one below last
REDIM self.keys$[dn+1]
FOR mid = dn TO up+1 STEP -1
self.keys$[mid] = self.keys$[mid-1]
IF dn>0 AND self.keys$[up] < name$ THEN up=up+1

self.keys$[up] = name$

Test program
Code: (glbasic) [Select]
LOCAL sose AS TSortedSet

STDOUT "isset dog " + sose.isSet("dog") + "\n"
STDOUT "isset rat " + sose.isSet("rat") + "\n"
FOREACH k$ IN sose.keys$[]
STDOUT "-" + k$ + "\n"

STDOUT "------------------\n"

LOCAL dict AS TDictionary

dict.set("cats", 5)
dict.set("mice", 7)
dict.set("dogs", "many")
dict.set("birds", "any")
STDOUT "dogs: " + dict.get$("dogs") + "\n"
STDOUT "rats: " + dict.get$("rats") + "\n"
FOREACH p IN dict.pairs[]
STDOUT "-" + p.key$ + " = " + p.val$ + "\n"

Here's the output
Code: (glbasic) [Select]
isset dog 1
isset rat 0
dogs: many
-birds = any
-cats = 5
-dogs = many
-mice = 7

Off Topic / Romantic Lockdown?
« on: 2021-Jan-29 »
For those of us, who are married, the current lockdown situation might be a great challenge, because women do need care, adventure and variation. Before the lockdown, this was made easy for us, because there was restaurants, day trips and gathering with friends. We could even stay out after 9pm. Remember, on our wedding day, we (hopefully) all promised to "love and care" for the bride.
For me, love, that is not "I like what you have/are", it's more a "It's not because of the one you love - it's my free will. I want to put great effort to bring her joy. Take some of her burden. ". That kind of love.
How will this work with the latest limitations put on us? I am sort of desperately clueless.
So, maybe you have better ideas that you want to share, to make our wedding promise shine brightly true in a dark world full of lies.

-Post your idea
-Don't talk about the lockdown
-Don't post your opinion on the lockdown
-Don't ask on our opinion on the lockdown
-Don't try to think logically about the lockdown
-Do not complain about the lockdown or the gouverment or anyone responsible for the lockdown.

So, what I have is:

Make a fire
If you have a garden, get some metal bowl, the bigger the better, put some dry wood on (you can get that in a supermarket, here. But also a farmer close by migtht sell you a sack). Put some liqud fire starter above and burn it. Beware, when it's cold outside, it took me a full hour to get it burning properly. Add some garden chairs, maybe two branches and some marshmellows.
It worked fine, but for sure you will have the kids attending ;). So I'd give a romance rating of 7/10.

Watch the dusk
Open google maps, find a nearby place with a hill or a small mountain, that has a road on the west side. Then find a restaurant, that offers take-away food nearby. Order food, driver to that place, pull the handbrake and keep the engine running (Yeah, sue me Greta!) and watch the sun go down. Make sure to have a pack of wet tissues in the car for the fingers. Also, this might need good timing. Alternatively, just drive to a parking lot at a lake nearby and leact the lights on, if you're too late for dawn.
We did this (again with the whole family). It's no substitute for a real restaurant, but hey, better than netflix. 6/10?

2D-snippets / PlyTxt - Polygon Text TXT files
« on: 2020-Oct-17 »
Sometimes, I need vector graphics - polygons.
And designing them is always complicated. Most times, I just need 10 points.
So, I decided to make a vector format, that is editable with any text editor.

The file format is described in "Media/fileformat.plxtxt" and goes like:

#plytx - 5 byte header information. File encoding without BOM!

# --= PolyText ==-
# Polytext is a vector format, that is easy to edit
# with a text editor.

# *** SYNTAX ***
# Everything right of a '#' is considered a comment.
# lines starting with ':' are commands. Commands must be lowercase.
# whitespace between command arguments is ignored.
# arguments can be separated by whitespace. Comma ',' is treated as whitespace
# for better readability.

# *** NODES ***
# The point information is given in the 'map' command.
# Points are named:
#         0..9 A..Z a..z
# This results in max. 62 points per file.
# The above point names also are the default order of the point names.
# Point names can have gaps, so you can easily define a polygon
# by the points A C E and refer to the names range A-E.
# ^Y     The name '0' is a special point and refers to the origin
# |      of the local coordinate system.
# 0-->X  X positive is to the right, Y positive is towards the top.

# You can embrace nodes by (), [], {} or <>
# These points get a special tag when importing them.
# It does not matter if you only write one brace, like (X or X),
# or both (X) braces.
# Also, you can set multiple braces for one point:
# {(X]> # this would set all 4 brace flags for the point 'X'.
# ASCII-art characters can be used to indicate connected lines.
# The following characters are valid:
# - + . _ / \ ^ : , ´ ` '
# The following characters are reserved for the future:
# " * ! ? & % $ §

################## COMMANDS #########################################
# *** FONT ***
# :font w h
# specify the font width and height ratio, because most text editors
# do not use quare fonts. For 'Consolas' this is like 7 18

# *** ORIGIN ***
# :origin orgx orgy
# A corrdinate that represents the position of node name '0'.
# Defaults to 0 0

# *** SCALE ***
# :scale factorx [factory]
# A factor that is applied to the X and Y coordinate of each point.
# factory equals factorx if ommited. The default scaling is 1.0.

# *** POLY ***
# :poly point_names...
# defines a polygon that is defined by the given points.
# If no points are given, the range 0-z is assumed.
# Points can either be listed individually, like:
# :poly abc efg x
# or with the range operator '-':
# :poly a-c, e-f, x
# The range operator adds all points in the ASCII-value order.
# Non existing points are simply skipped.
# You can specify a negative range for reverse direction:
# :poly c-a

# *** MAP ***
# :map
# Here, the point coordinates are given. Everything below the :map
# command is considered as part of the point list.

######################## EXAMPLE ################################
:font 7 18 # consolas
:origin 1 2
:scale 7
:poly A-Z
:poly a-d
    z               __P--(Q)-----R # Example map for a C64 Thrust-Style game
A-------B       O---               # 'z' is only used as the player start position
        |       |
        |       |                  # 'A' to 'Z' is the cave polyon.
        |   0   |                  # 0 indicates the origin of coord system
        |       |
        |       |
     ___C       N
    /       b    {M_____       # The { } are cannons
   D       : :          ---L
   |     a.   :...c       K    # 'a' to 'd' form a second polygon -> an island
   |       d...            J
   E}                     I/
    F---------[G]--------H/    # Base of cave

I'm trying to do a C64 Thrust remake. Maybe.

Announcements / Comming up features
« on: 2020-Oct-17 »
Next version will allow you to omit the 'self.' and the [] array indicators.
Here's a test example, that already compiles:

Code: (glbasic) [Select]


ia[] AS T1
    FUNCTION foo:
    ALIAS p AS self.ia[0]

FUNCTION foo: bar[]

FOREACH a IN t.ia[]; a.i1=0; NEXT
FOREACH a IN t.ia  ; a.i1=0; NEXT

LOCAL a$[]
FOREACH b$ IN a$[]; b$="X"; NEXT
FOREACH b$ IN a$  ; b$="X"; NEXT

//  []     [] omited
t.ia[] = t.ia[]
t.ia = t.ia

foo(t.ka  )


Inline / 3rd party / QR-Code library (QRcode)
« on: 2020-Jul-02 »
Attached, you'll find a wrapper for that creates a sprite with a QR code for a given UTF-8 text.
See also the UTF-8 library, if you really need utf-8 characters (not tested).

The new update 16.507 is available on STEAM now.
Among some bug fixes, this offers more possibilities on the Android platform. The mousewheel works better and DDgui got some bugfixes. (Yikes - I forgot to upload that - will soon do!)

You've seen the great efforts of spacefractal the last months. So, the Chomebook support is in and the game controlers are, too.
I fixed some bugs in the IDE and made strings even faster by implementing move semantics.
The bluetooth library is finally done and can be used for Windows and Android. Might also work on other platforms, but not tested.
For Android, I added a camera support and you can request permissions using the Android dialog popups.
Code: (glbasic) [Select]
IF "1" == android_JAVACALL("requestPermission:android.permission.CAMERA")

To see it all in action, here's a project that uses all of them.

Code Snippets / UTF-8 (UTF8) utilities
« on: 2019-Dec-10 »
Here's how to deal with UTF-8 strings in GLBasic. It can convert to and from ISO 8895-1 (Latin-1), so you can "PRINT" UTF-8 strings, and write UTF-8 file from latin encodings.
Code: (glbasic) [Select]
// --------------------------------- //
// Project: UTF8- Routines
// --------------------------------- //

//! Copyvert an ansi text with codepage latin-1 (ISO 8895-1) to a UTF-8 string.
//! Prefix the UTF8_BOM$() at the start of a file when you write it to disk.
FUNCTION UTF8_fromLatin1$: latin2$
LOCAL out$
FOR i% = 0 TO LEN(latin2$)-1
LOCAL cha = ASC(latin2$, i)
IF cha < 0x80
INC out$, CHR$(cha)
// all 11 bit codepoints (0x0 -- 0x7ff)
// fit within a 2byte utf8 char
// firstbyte = 110 +xxxxx := 0xc0 + (char>>6) MSB
// second    = 10 +xxxxxx := 0x80 + (char& 63) LSB
INC out$,  CHR$(bOR(0xc0, bAND(ASR(cha,6), 0x1f))) // 2+1+5 bits
INC out$,  CHR$(bOR(0x80, bAND(cha, 0x3f))) // 1+1+6 bits


void Latin8FromUtf8(char* str, int slen) {
    int i = 0;

    char* dest = str;

    const char* pStrC = str;
    const char* pEnd = str + slen;
    // *pStrC != '\0' &&
    while(pStrC < pEnd) {
        const wchar_t c = wchar_t(static_cast<unsigned char>(*pStrC++));

        // U-0 to U-7F
        if((c & 0x80) == 0x00) {
        // U-80 to U-7FF
        if((c & 0xE0) == 0xC0) {
            if(i<slen) {
                wchar_t d = static_cast<wchar_t>(*pStrC++);
                *dest++=(char((c&0x1f)<<6 | (d&0x3f)));

        // U-800 to U-FFFF
        if((c & 0xF0) == 0xE0) {
            if(i+1<slen) {
                const wchar_t d = static_cast<wchar_t>(*pStrC++);
                const wchar_t e = static_cast<wchar_t>(*pStrC++);
                *dest++=(char((c&0x0f)<<12 | (d&0x3f)<<6 | (e&0x3f)));
        // three continuation (U-10000 to U-10ffff)
        if((c & 0xF8) == 0xF0) {
            if(i+2<slen) {
                const wchar_t d = static_cast<wchar_t>(*pStrC++);
                const wchar_t e = static_cast<wchar_t>(*pStrC++);
                const wchar_t f = static_cast<wchar_t>(*pStrC++);
                *dest++=(char((((c&0x0f)<<18 | (d&0x3f)<<12 | (e&0x3f)<<6 | (f&0x3f)) + 655536)  & 0x000000ff));
    *dest = '\0';

//! Convert the utf8$ string to a Latin-1 (ISO 8895-1) string. Use this to 'PRINT' an UTF-8 string.
FUNCTION UTF8_toLatin1$: utf8$
LOCAL copy$ = utf8$
char* str = copy_Str.getbuffer(1);
Latin8FromUtf8(str, LEN(copy_Str));
RETURN copy$


//! Return the 3 byte UTF-8 BOM (byte order mask).
//! That is the first 3 bytes of an UTF-8 text file.
RETURN CHR$(0xef) + CHR$(0xbb) + CHR$(0xbf)

Announcements / Server change
« on: 2019-Sep-20 »
Our webhoster quits. I have time to the end of 2019 to move to another hoster.
I amy very anxious about the email/https certificate after the move.
On the other hand, I can move to a hoster that cares about the linux backbone, so I don't have to care about this anymore. It caused my so much headache, since I'm a total noob when it comes to this.

Just wanted to let you know.
If anyone if good at that stuff, please let me know.
I would have to:
-move the php sites (easy)
-backup all email (4 accounts. I use thunderbird. I plan to pull them all local and then copy back. Would that be OK?)
-move 3 data bases (yes, this forum too!). I have no idea, but I hope something like mysql-php offers that option...
-point the domains (3) to the new server (I hope that one is a quick one. My new hoster offers a GUI for that).
-What about the certificate for the https/email accounts?
-Anything I missed?

The version sounds like nothing special, but indeed, this update brings:
I took some time, yesterday and finally fixed what was due for years. I am so sorry for the delay. You will love it. It makes work so much easier, if you use TYPEs.

Also, DDgui was a bit polished and the new toast messages look quite good. (See my 2nd G.A.C.K. trailer on STEAM - sprite editor, where I copy/paste an image).


Wohoo! Finally made it to where it should go. I hope people will like it.
I added support for moving platforms. Did anyone program that before? Dude, that is really hard. I'm programming for about 0x20 years now, but that was a brain twister even for me. It's not 100.00% perfect after all...

I remember yeeeers ago, someone had a bit of code, that created a random city. Houses and stuff.
Can anyone remember this?
It would be cool to make a "deliver a pizza" game in 3D, with a city like: C64's Miami Vice, but in 3D:

The following is a C++ wrapper for a library, that does high-quality image scaling.
To use it, just add the gbas file to your project. The C++ lib is linked by REQUIRE.

Here's how to use it as a STRETCHSPRITE substitute:
Code: (glbasic) [Select]
FUNCTION HQStretchSprite: id%, x%, y%, w%, h%
ReSampler(id, s2, w,h)
GRABSPRITE s2, 0,0,0,0
Warning - the above does not work (yet), if you're currently on an offscreen (USESCREEN x).

Pages: [1] 2 3 ... 38