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

Messages - CW

#46
-In a previous thread Lee and I began discussing plans for a spread-sheet style program which can manage up to eight rosters of units (eight players, or teams if you will) for use in live games such as D&D or Warhammer. Any game in which the players must keep track of a large number of units, their attributes and their health.

Lee wrote:
=======

Btw one little tip I can give you is read up on the basics of databases, things like different tables etc as believe me it will help with regards to data management as I'm sure your aware RPG's can be very heavy on data storage with various weapons/armor etc. Not only that but a well organised data structure makes retrieving what you need easier & more efficient on storage as well as access. A flat database like a spreadsheet becomes a nightmare to maintain when you start getting more data.

I used to use MySQL to handle my data but am looking into the sqlite wrapper that is posted elsewhere on this forum. Setting up a database with multiple tables requires a bit more setting up & planning but it rewards you afterwards with easy access & maintenance.

Obviously I don't know your experience with regards to databases but if you need an example of what I mean please let me know  =D

Lee
#47
Thx kanonet! That is awesome.  =D

-CW

PS Fuzzy; I am going to move our discussion over to a new thread. We are So.. off topic here. It is time to move.  :)
Hmm.. but which section to move to? We don't really have a 'Collaboration' category. 'Announcements' maybe?
Yeah, look for it there.
#48
Hi sf!

I don't have a smart phone, so I've never had the opportunity to play with GLbasic on one. Nope, I just program for my laptop system.
I look forward to being able to write my own apps for a smartphone. When I do, knowing what GRABSPITE can and can't do will be handy; so I'll keep that problem with GRABSPITE in mind.

Thanks!
-CW
#49
Thanks Lee! Will do.
Maybe I can call upon you for some play-testing and some brutally honest critiquing? Anyway, that day is well in the future. lol
-CW
#50
simi  :offtopic:

Yeah Fuzzy! That's exactly what I have in mind.  :good:

Sadly, I can only code in my spare time and I keep getting derailed by side projects, so it's a long-term goal.
I may have something worth showing off in a month or so. So far all I have are a set of working tabs and a bunch of dreams.
I would love to see any sample code you have cooked up, if it is still around. You might inspire me with some good ideas.

-CW
#51
Ok, fair enough. Thanks Toad and Fuzzy. Thanks all.
-CW  8)
#52
Hi Moru.

I'm afraid I'm struggling to get my vision across. That is my fault. I'm sorry. Let me try again. It isn't a matter of inputting faster than the screens can be refreshed. It's a matter of checking the keyboard far faster than the user can type the keys and NOT refreshing the screen if no keys are pressed. With Inkey$() you MUST refresh every time you check, weather anything has changed on the screen or not. Either way there is a lot of idle time on the keyboard between presses which could be put to good use. Why waste that time refreshing the screen? Isn't basic slow enough already?  :bed:

Consider a chess program which must do in depth tree searches while the screen is otherwise idle, yet must be ready to break off its search the instant the user enters a new command. Any game which must do in depth parsing or heavy crunching could make very good use of the idle time. If the processing cycles are limited to however fast the screen can be refreshed, that is a serious limitation to computational speed. (Which can do more computing, 30 program cycles a second, or 60,000?) Or consider a typing game which instantly responds to a mistyped letter, perhaps with a sound or graphic explosions. The key issue here is that it is expensive to CPU cycles to refresh the screen more often than is actually needed to display the graphics, and InKey$ requires A LOT of refreshing. If the screen hasn't changed, why refresh it? That time can be better used rendering, searching, calculating, updating and so on.

We could set a timer and check the keyboard every quarter second, or half-second to reduce the drag on the system. (You would still have a lot of unnecessary screen refreshes, just not as many.) But even here you run into the problem of the keyboard being unresponsive if a user presses a key during the dead times.  The goal is to check the keyboard on the fly, but the requirement to refresh the screen weather it needs it or not is a serious drag on a program.

I'm not currently writing a chess program, but I am working on a custom user interface with an animated cursor. (I am writing a game utility which can handle a lot of the bookwork associated with live games (D&D, StarFire, WarHammer, ect.) Any game which has a lot of units. I'll post on it when I get the basic framework hammered out. It's a type of spreadsheet program with interactive health and stat bars, and a library of units which can be loaded to any of eight rosters. Anyway, back to the current topic.)

The problem is, the Showscreen overhead associated with Inkey$() drags the program to a crawl, while trying to use K=Key() requires heavy parsing of the key codes, in Basic, which would be specific to my particular keyboard; which is almost as bad. So if it is possible, perhaps even easy to gain a significant boost to processing speed when using Inkey$(), why wouldn't I ask if it can be done? When GLbasic improves, we all win.

I don't mean this as a criticism, just an observation, and I'm reluctant to even mention it for fear of offending anyone, but it seems to me the response to my question has largely been "That's the way GLbasic is, and maybe you can live with it", rather than "Yeah, that is a good idea and maybe we can get to it eventually" or "It is a necessary evil and here is why it can't be done." But anyway, that is why I brought it up, and now it's time to let it go.
-CW
#53
SF, I can offer some lessons I've learned when trying to create custom fonts. GLbasic has a few quirks when it comes to fonts which we all quickly learn to deal with. After a time or two, using custom fonts will be as easy as can be.

1. In the Font Creator tool, always click on the [C:\ ...] button to set your path, THEN click on the [OK, Create] button.  If you think you have created a font, only to have it go missing, suspect that you forgot to set the path or click on the OK button.

2. When setting the path, be sure to locate and select the Media folder. (You may have to open a couple of folders from within the wizard to get there.)

3. Start each program with the following code. (Change "smalfont.png" to whatever you named your font. The name is cap sensitive.)

Code (glbasic) Select
SETSCREEN 1366,768,TRUE
GLOBAL sw%,sh%;GETSCREENSIZE sw,sh
SETCURRENTDIR(GETCURRENTDIR$()+"Media")
GLOBAL fontkey% = GENFONT()
LOADFONT "smalfont.png",fontkey
SETFONT fontkey
GLOBAL fw%,fh%;GETFONTSIZE fw,fh


4. If you use the default name, realize that there is only ONE "l" in "smalfont.png".

5. Always include the ".png" extension when you load your font. If you don't include the extension, the program may not load it. I'm not sure why, just that this has been an issue for me in the past.

6. Don't add ".png" when naming your font, or you may windup with something like "name.png.png".

7. Post if you have any trouble and someone will be very happy to help. We have a good crew here.

8. Have fun!

Cheers!
-CW
#54
Hi all!

I've been away for a bit. (US holiday and a nephew's graduation.)
Here is a bit of code I created to benchmark the Inkey$() vs. Key() commands. We know Key() is faster, but how much faster is it? This program will give you some idea. (You may want to create a 'smalfont.png' file with somewhat larger text for ease of reading. Save it to the Media folder. The program should scale fine.)

Code (glbasic) Select

SETSCREEN 1366,768,FALSE
SETCURRENTDIR(GETCURRENTDIR$()+"Media")
GLOBAL fontkey% = GENFONT()
LOADFONT "smalfont.png",fontkey
SETFONT fontkey
LOCAL fw%,fh%;GETFONTSIZE fw,fh

LOCAL Cycle_Count% = 0,Test2_Cycle_Count%=0,EndTime# = GETTIMERALL()+30000
LOCAL MaxChars = 30

PRINT "Test 1: ShowScreen called every cycle.",1,0*fh
PRINT "        Processing speed limited by FPS.",1,1*fh
PRINT "-------------------------------------",1,2*fh

PRINT "-------------------------------------",1,10*fh

DRAWRECT 65+4,3*fh-1,5+(MaxChars+1)*fw+7,fh+2,RGB(255,255,255)
DRAWRECT 65+5,3*fh,5+(MaxChars+1)*fw+5,fh,RGB(0,0,255)

USEASBMP

LOCAL K$,String$,hold%

REPEAT

K$ = INKEY$()
IF K$ <> ""
IF LEN(String$)<=MaxChars THEN String$ = String$+K$
PRINT String$,75,3*fh
USEASBMP
ENDIF

PRINT ShowFPS()+" FPS = Program Cycles Per Second." ,10,12*fh
PRINT "Type Up to "+MaxChars+" Characters of Text.",65,4*fh+5
PRINT "Test will run for 30 seconds.",50,6*fh
PRINT Cycle_Count + " cycles completed so far.",50,7*fh
        SHOWSCREEN; Cycle_Count = Cycle_Count+1
UNTIL KEY(211) OR GETTIMERALL()>EndTime// Exit if [DELETE] key is pressed.

CLEARSCREEN
PRINT "Cycles in 30 seconds = "+Cycle_Count,10,200
PRINT "Press Key to begin Test 2.",10,230
SHOWSCREEN;KEYWAIT

String$ = ""
LOCAL K%,Count%
EndTime = GETTIMERALL()+30000

CLEARSCREEN
PRINT "Test 2: Showscreen called only when screen update needed.",1,0*fh
PRINT "        Processing speed not limited by FPS.",1,1*fh
PRINT "-------------------------------------",1,2*fh

PRINT "-------------------------------------",1,10*fh

DRAWRECT 65+4,3*fh-1,5+(MaxChars+1)*fw+7,fh+2,RGB(255,255,255)
DRAWRECT 65+5,3*fh,5+(MaxChars+1)*fw+5,fh,RGB(0,0,255)
PRINT "Type Up to "+MaxChars+" Characters of Text.",65,4*fh+5
PRINT "Test will run for 30 seconds.",50,6*fh
USEASBMP

REPEAT
FOR K = 1 TO 255
IF KEY(K)=TRUE THEN BREAK
NEXT

IF K<255
K$ = INKEY$()
IF K$ <> ""
IF LEN(String$)<31 THEN String$ = String$+K$
PRINT String$,75,3*fh
USEASBMP
ENDIF

PRINT ShowFPS()+" FPS, yet the program is cycling at max speed." ,10,12*fh
PRINT Test2_Cycle_Count + " cycles completed so far.",50,7*fh
SHOWSCREEN
ENDIF
Test2_Cycle_Count = Test2_Cycle_Count+1
UNTIL KEY(211) OR GETTIMERALL()>EndTime// Exit if [DELETE] key is pressed.

CLEARSCREEN
PRINT "RESULTS",100,2*fh
PRINT "InKey$() allowed "+Cycle_Count+" cycles in 30 seconds.",10,5*fh
PRINT "    Key() allowed "+Test2_Cycle_Count+" cycles in 30 seconds.",10,6*fh
PRINT "Key() was "+(Test2_Cycle_Count / Cycle_Count)+" times faster than InKey$().",10,8*fh
PRINT "Click Mouse to Exit.",10,10*fh
SHOWSCREEN
MOUSEWAIT
END

// ------------------------------------------------------------- //
// ---  SHOWFPS  ---
// ------------------------------------------------------------- //
FUNCTION ShowFPS:
// FPS counter
LOCAL dtime#,fps#
STATIC delay#,FPS#

dtime = GETTIMER()
fps = ((1000/dtime)+fps)/2
delay=delay+dtime
IF delay>500 // 1/2 sec
  delay=0
  FPS=fps
ENDIF
RETURN FPS

ENDFUNCTION // SHOWFPS


If we could only unhitch Inkey$() from the necessity to call Showscreen each time, maybe by adding a Inkey$(-1) parameter, it could mean a real boost to program speeds when processing is done in the background while watching for input at the keyboard. With the tremendous overhead imposed by Showscreen, it may actually be quicker to duplicate all of the core features of Inkey$() with Key() using basic. (UGG!) 

Thank you all for your suggestions. Ocean, Kanonet, I don't know how to launch separate threads in GLbasic. Could you or someone do a tutorial on that topic? I would love to learn that ability. Mr. Toad, I tried CLEARSCREEN, but it doesn't seem to trigger a INKEY$() reset. Kanonet, I didn't know GLbasic used a keyboard buffer. If this is the hitch necessitating SHOWSCREEN with Inkey$(), then perhaps it begins to make some sense now. I don't know much about the inner workings of GLbasic, but I know my ignorance is a handicap. Still, if the command could be freed in some way to operate like Key(), it would be a powerful upgrade to the command and to the language version we both love.

I will try coding my input routines both ways to see which gives the bigger payoff. Given the overhead, maybe reinventing the wheel using K=key() really would yield a significant gain. If so, I will post the results to my other thread relating to this topic, rather than here under Bugs and Feature Suggestions. There is nothing more I can add to this thread, so I will leave off on it now.

Cheers!
-CW
#55
I see. But Moru, this seems like such a serious and puzzling bottleneck to execution speed.

With INKEY$() wedded (or welded) to SHOWSCREEN, the ability to execute code is limited to the maximum FPS because a program can only cycle code as fast as it can perpetually refresh the screen. Is there a good technical reason why this should be so? Could Inkey$() be revised to run independently of the screen, in the way Key() does?  Consider the following example which uses Key(). Notice how the screen is only updated when there is something to be updated, unlike INKEY$() which must update the screen every time the keyboard is checked.

Code (glbasic) Select
SETCURRENTDIR(GETCURRENTDIR$()+"Media")
GLOBAL fontkey% = GENFONT()
LOADFONT "smalfont.png",fontkey

////////////////////////////////////////////////
//       Setup Static Background Screen                     
PRINT "GetKey$() Test",20,50
PRINT "Press [Backspace] key to quit.",20,75
USEASBMP;SHOWSCREEN
/////////////////////////////////////////////////
/////////////////////////////////////////////////

REPEAT
LOCAL K%
FOR K = 0 TO 255
IF KEY(K) = TRUE THEN BREAK
NEXT
        IF K < 255
                PRINT "Key Press Code "+K+" Detected."50,120
                SHOWSCREEN
        ENDIF

UNTIL KEY(14) // Exit when [BackSpace] key is pressed.
/////////////////////////////////////////////////


Cheers!
-CW
#56
The following is more of a feature request to improve Inkey$(), than a code-killing bug. There is a way to program around the issue, but it seems like such an ugly kludge. Could Inkey$() function as smoothly as Key()?
-CW
====================

Code (glbasic) Select

// Inkey$(): Feature or Bug?
//--------------------------
// First run using Test 1 code section
// Then turn it to commented lines,
// activate Test 2 code section and run again.
// Feature or Bug?
//---------------------------

SETCURRENTDIR(GETCURRENTDIR$()+"Media")
GLOBAL fontkey% = GENFONT()
LOADFONT "smalfont.png",fontkey


////////////////////////////////////////////////
//       Setup Static Background Screen                     
PRINT "GetKey$() Test",20,50
PRINT "Press [Backspace] key to quit.",20,75
USEASBMP;SHOWSCREEN
/////////////////////////////////////////////////
/////////////////////////////////////////////////

LOCAL K$ = ""
REPEAT

///////////////////////////
// Test 1: Refresh the screen only when a character is pressed, otherwise, continue to show the current screen, which displays the last key pressed.
//
// This test will fail for INKEY$() is never reset and so never checks the keyboard again.
// ------------------------
//

K$ = INKEY$()
IF K$ <> ""
PRINT "Key Press = "+K$,150,120
SHOWSCREEN
ENDIF


//
///////////////////////////////
// Test 2: Refresh the screen every loop. This seems to impose a huge overhead on using INKEY$() when the screen must be redrawn each and every
// time we check for a keypress. Shouldn't there be a way to reset INKEY$() directly, without calling SHOWSCREEN? Maybe something like K$=INKEY$(-1) ?
//
// This test will succeed, as INKEY$() is reset when SHOWSCREEN is called, and so is set to check the keyboard again the next time it comes around.
// ----------------------------
//

// K$ = INKEY$();SHOWSCREEN
// IF K$ <> ""
// PRINT "Key Press = "+K$,150,120
// ENDIF


//
////////////////////////////////

UNTIL KEY(14) // Exit when Del key is pressed.
#57
Yeah, but any console which requires always-on will be a big turn off for me. Not that I'm not always on anyway, but it's the principle of the thing. Sort of like the e-readers that don't allow you to load free books from the public-domain, or stores that charge you extra if you don't use their 'loyalty' card and let them compile a profile on you to sell to marketers. Just the other day I had a Google ad for an automobile pop up on my screen which showed a map to the nearest dealership and had a fat tan star over where I live. How the heck did Google get my home address??! I strongly resent the intrusive liberties marketers advance on my privacy. That is one dealership I will never buy from.

Ah hell. It's happening, isn't it? I'm turning into a cranky old cat-loving, sweater-wearing curmudgeon.   
-CW
#58
Addendum:

Having studied the problem for a day I have concluded that the best approach for speed and for the handling of both upper and lower case char sets for my project is to use both the INKEY$() and ASC() commands. Trying to avoid the use of one or the other through key() would be counter productive because I would wind up having to reinvent the wheel through BASIC code, only to see a major reduction in processing speed for my troubles, rather than finding a gain. (Not to mention all of the ugly and pointless bloat.) Key() has its uses, but trying to leverage it in an attempt to avoid string handling is a pointless and futile effort. Maybe a gain could be found using inline C++, but trying to do it in Basic is a non-starter. When you come right down to it, GLbasic does what it does VERY well. Now I have a direction for my code.

-CW
#59
I've been looking over your keymap program Kanonet, and I am very impressed. Yours is a wonderful basis for implementing alternate keymaps, alternate languages, and alternate character sets  to GLbasic. Very nice! It more compliments than solves my intended goal, so I'll have to press on. I will keep your utility in mind for future projects where an alternate keymap is handy.

Thanks,
-CW
#60
I think I see the method. Thanks Kanonet and Moru.  :)

Caps are important to me as I'm trying to code a swift yet flexible user-input for text & characters with a custom cursor and a hard limit to the number of input characters in the field. My current project doesn't really *need* all this, but I have a vision in mind and must try to see it through. If successful, the result will be a boring, blinking cursor, as bland as tofu. But this will open the door to future possibilities, such as a cursor which creeps, inch-worm like, across the page as you type, has attitude, does somersaults, changes colors, and gets eaten by a bird which then flies away. This sort of input routine can open the door to things such as typing games with sound, where graphics explode in the background in instant response to mistyped characters. Or the computer can be freed to parse previous inputs or attend to other tasks while waiting for the user to type the next command. I mean, How fun could that be?

That's the trouble with visions of games not yet written. Trying to code functions general enough for multiple applications creates a lot of headaches which could be avoided. But then, if you never stretch as a programer, you never grow. Bland Tofu can be good for you!

-CW