Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 28 Jun 2000
Offline Last Active Yesterday, 09:21 PM

#5292378 how can i use the CreateTimerQueueTimer()?

Posted by Wyrframe on 18 May 2016 - 05:28 PM

        ULONG flags;
        DWORD dwPeridic;
            flags = WT_EXECUTEDEFAULT;


Why not use the macro that actually exists, the way the documentation describes? The error you were getting is because the first parameter to the macro must be an assignable expression (an lvalue). Why do you need up to 500 threads to service your timer callbacks in the first place?


I have no idea what your (1) is asking.


As for your (2)... SetTimer() and KillTimer() deliver timer events as WM_EVENT events, and require a window handle. CreateTimerQueueTimer lets you specify arbitrary callback functions and callback parameters instead. AFAIK this design decision has nothing to do with the periodicity or precision of the timers associated with them.

#5292371 Introducing Stanza: A New Optionally-Typed General Purpose Programming Langua...

Posted by Wyrframe on 18 May 2016 - 05:11 PM

Trying to take prisoners in one of programming's holy wars is not user-friendly.


Maybe the language is useful. I can see some of the nicer features I got used to in Objective Caml hiding under the surface. Maybe the library is even robust and the compiler optimization fantastic.


But I don't have faith that any of these are true, after reading...



Indentation is important in Stanza programs. Be careful when trying out the examples.

And don't use tabs. Stanza won't let you. We don't like tabs.


Well, good for you. But this aggressive, inflammatory approach to user-friendliness just lost you an entire market of potential users who aren't even going to give the time of day to that attitude. It comes across as petty, and that's not something you want a reputation for. If you have a technical reason for blacklisting \t, put that in the documentation instead.




Also, a bug report: on 64-bit Ubuntu with 2 GB of RAM, after following the instructions to install Stanza and successfully running `stanza version`, I try to compile the "Hello World" example, and this causes `cc` to crash with an out-of-memory error while trying to consume a 7.6 MiB "tmp1.s" assembly.

[dispos@vbox: ~/mystanza]$ time ./stanza examples/helloworld.stanza -o helloworld
cc -std=c99 'tmp1.s' '/home/dispos/mystanza/runtime/driver.c' -o 'helloworld' -lm
Cannot allocate memory

real    0m38.292s
user    0m5.576s
sys     0m1.796s

[dispos@vbox: ~/mystanza]$ cc -v 2>&1 | tail -n 1
gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04)

[dispos@vbox: ~/mystanza]$ date -R --reference=../lstanza.zip
Wed, 18 May 2016 15:40:50 -0700

#5292358 how can i use the CreateTimerQueueTimer()?

Posted by Wyrframe on 18 May 2016 - 04:18 PM

Exactly as it says in the documentation: Due Time is how long until the timer first fires. Period is how long AFTER THAT it will fire again, and then again, and then again... unless it is zero. If you are getting a crash when you use a nonzero period, it sounds like something about your handler is crashing on the second or some subsequent timer firing.


If you expect the timer to fire once, and then never again, give a Period of zero. If you need it to fire multiple times over time, give it a period and debug your callback for what's really going on.



Also, on a resource waste note... you are creating a TimerQueue (a somewhat heavyweight object) for each of your timers, and then creating only one TimerQueueTimer (a lightweight object) in each of them.

#5285676 Optimizing Chunks [Distance]

Posted by Wyrframe on 07 April 2016 - 06:22 PM

Spotted it. You're gonna kick yourself.

for (int y = minY; x <= maxY; y++)
    float dY = y * 16 - playery;
    for (int z = minZ; x <= maxZ; z++)

Hint: what variable are you testing against in your Y/Z bounds checks?


And this is why we use an IDE that highlights all occurrences of a variable when you put the caret or mouse over it, folks. :)

#5285674 Typing skills

Posted by Wyrframe on 07 April 2016 - 06:18 PM

"Sufficient and competent, respectively."





Your ability to proof-read and debug your code is more important, because once you learn to type, generally you'll write what you intended to first time... its the things which you didn't have in your mental model of the code at the time you were writing it that are going to bite you most often. More bugs are caused by getting the logic of a test or a looping structure wrong, than are caused by having one too few semicolons or one too many minus signs.

#5285428 Gamepads in Assembly

Posted by Wyrframe on 06 April 2016 - 08:52 AM

(be sure to support USB hubs as well, not every USB port will have its own dedicated connection to the controller)
Just FYI, hubs are a mandatory part of the protocol. Even the ports on your PC are actually downstream-facing ports of an internal hub. If you only have one port on your entire computer, that's internally a hub with one downstream-facing port. The only difference between it and an external port multiplexer is that the built-in hubs' upstream interface is a PCI client controller or suchlike, instead of being an upstream USB port.

#5284066 Optimizing Chunks [Distance]

Posted by Wyrframe on 29 March 2016 - 09:13 AM

This loads (for an 8 x 8 x 8 planet) from 1, 1, 1 to 1, 1, 8 before throwing out of bounds exceptions (On !ischunkloaded[x, y, z]). When I try to catch the exception and figure out what values are breaking it, unity crashes.
Try just printing to console each x,y,z and distance, or comment out that entire if construct and debugging it. Possibly, Unity is trying to evaluate ischunkloaded[x,y,z] and show you the value, but not trapping the same exception that's being thrown at runtime.


Alternatively, if it is a bounds issue, print out all of minX/Y/Z and maxX/Y/Z before entering the loop. Find out what axis we're off on.


Also, I noticed a problem in the bounds logic I gave you. This may be part of it.

int minX = (int)Mathf.Max(0, (playerx - loadRange) / 16) + 1;
int maxX = (int)Mathf.Min(planetSize, playerx + loadRange + 15) / 16 + 1;
if (minX > planetSize / 16 || maxX < 1) continue;

Note two things. First, division doesn't flatten at 1, it flattens at 0, so we have to add one after the division to get the right indexes. Second, I've moved the division by 16 out of the upper bound calculation, since both terms were being divided, and there was a possible rounding error going on there as it was.


Is is because you access the ischunkloaded ranging from 1..8 and not 0..7?
OP has said that his array is 1-indexed, though not why. I don't know if that's a Unity thing, or part of how he designed his ischunkloaded array.

#5283903 Optimizing Chunks [Distance]

Posted by Wyrframe on 28 March 2016 - 01:44 PM

So, when you say "planets over 1,000 chunks"... do you means planets made up of a 10x10x10 cube of chunks? Or do you mean planets of a diameter or radius of 1,000 chunks (1000 x 1000 x 1000)? Because there's six orders of magnitude difference between how many chunks that totals up to.


Totally aside from that, there's two whole categories of things you're doing suboptimally here.


* You're testing every chunk of every planet for being in or out of range of every player... when in fact, you should at worst be iterating over the chunks currently loaded for that player to find which ones to unload, and then searching for chunks that need to become loaded.

* You're iterating over all players, and presumably, all planets (assuming this FixedUpdate() function is a member of your planet object) outside this loop.

* You're re-sorting the list every time you add an item to it, instead of only sorting it once after all adds.


You can exclude a lot of tests by adding layers of guards here:

* You can exclude an entire player/planet test based on the player being too far from that planet to even consider testing chunks of that planet.

* You can also only iterate over only the chunks which are inside the bounding cube of that player's range, instead of testing every cube of the entire planet.

* You can test against range-squared, instead of range, to save you a square root calculation per chunk/player pair. Here's some pseudocode fragments which may help...

float loadRange = 200;                      // Extract this magic constant from the inner loop to somewhere more maintainable.
float loadRangeSq = loadRange * loadRange;  // Calculate its square.
int currentLoad = toLoad.Size();            // Memorize the current length of the load queue.

int playerx = (int)(player.transform.position.x - this.transform.position.x);  // Express player's position relative to planet.
[... and for the other two axes ...]
int minX = max(1, (playerx - loadRange) / 16);               // Calculate extends of bounding rectangle of view, in chunk units.
int maxX = min(planetSize, (playerx + loadRange + 15) / 16); // Ditto. Note the +15 to cause rounding up.
if( minX > planetSize || maxX < 1 ) continue;                // Stop looking at this player if the planet is entirely out of range.
for(int x = minx; x <= maxx; x++)    // Use the calculated bounds, not the whole planet.
float dX = x * 16 - playerx;  // Only need to calculate this once per X term. Could even make this cheaper; I leave it as exercise for the reader.
[... Y and Z loops too ...]
// And now; the entire inner loop body.
float distanceSq = dX*dX + dY*dY + dZ*dZ;  // This, too, can be made cheaper. How is an exercise to the reader.

if( distanceSq < loadRangeSq && !isChunkLoaded[x,y,z] && LoadDone ) {
    toLoad.Add( [...] );
    // Presumably, after the chunk is loaded it is added to that player's chunks-displayed list.
// And then, outside of the X loop again...
if( toLoad.Size() > currentLoad ) {
    // Only re-sort if we did add anything.
    toLoad.Sort( [...] );

That's the load-queue populator. You should iterate over the player's current chunk list and un-load any that are now out of range, because the player's current view list is probably *always* going to be smaller than the number of chunks that *might* be in the player's view.


Also, if this load/unload is the server-side view of chunks, remember to load chunks when ANY player enters range, but don't unload a chunk until ALL players are out of range.

#5283483 SpriteFont render Umlaute

Posted by Wyrframe on 25 March 2016 - 05:44 PM

Are you certain that the font you're loading has glyphs for the characters you're trying to render? Check the return value of TTF_GlyphMetrics.

#5279569 Need help with a schoolproject

Posted by Wyrframe on 04 March 2016 - 05:18 PM

So my main question is how long would it take for a programmer (preferably with 3 years or less of experience) to do these tasks.

If you have specific experience with all of these features (because these aren't "tasks") in small scale, you should be able to slap-dash something with all of this together in a few months.


If you have never done most of these, expect it to take 1-10 years of part-time work.



Remember; a task is something you can actually do. "Design the Store API", "Replace Existing PRNG UI with Dice+Physics", "Rebalance turret building cost". A feature is something you expect to be able to see when looking at the product. "Friends list", "In-game Store", "Server".


As a word of advice with regards to designing a Gantt chart of the tasks needed to develop something... if you can't nail a task down to a single-digit number of hours, either the task is too big and nebulous still and you need to break it up into smaller parts, or you don't really know how long it is going to take because you don't know what work is required to complete that task.

#5273052 AI trouble sdl 1.2

Posted by Wyrframe on 28 January 2016 - 02:59 PM

What you need is a simple, generic pathfinder which you can feed each ghost. The pathfinder gets fed a ghost's current position, current direction of travel, and the position of its "target". That target is very clearly defined in each ghost's Scatter and Chase states; specific map coordinates, or locations relative to PacMan (including +0,+0 relative to PacMan).


The pathfinder has to respect the ghost's movement rules; they never reverse their direction, they only turn left, turn right, or carry on straight.


You only need to query the pathfinder for a given ghost when they reach a decision point. Once they're on a lane headed towards the next intersection, they can't change their mind anyways, so just let them carry on straight until they can choose to turn again.


Post some of your current ghost AI code, and we may be able to give you specific, pointed examples of how to improve what you're doing already.

#5272998 AI trouble sdl 1.2

Posted by Wyrframe on 28 January 2016 - 09:49 AM


#5272023 Risks Of Using Computer As Webhost?

Posted by Wyrframe on 20 January 2016 - 09:57 AM

While we're making suggestions of configure-it-yourself server hosting (as opposed to HTTP-only hosting services), OVH (based in France and in Canada, near Montréal, just inches north of the US border) offer services such as this. A large variety of O/S available. They give you a 100 Mbit internet connection and no transfer limits. Does not come with DNS hosting (for that, I suggest No-Ip), but is pretty hard to beat. Especially if you're in the States, considering the CAD$ current exchange rate.


Bear in mind their VPS SSD line does not guarantee uptime or SLA, as they reserve the right to "pause" the VM without notice, in order to move it between physical hosts whenever they need to reorganize their datacenter. You have to go up to their VPS Cloud line of products to get a four-nines SLA (<= 52 hours of downtime per year).

#5271564 Box2D in LibGDX - Throwing body based on swipe angle.

Posted by Wyrframe on 17 January 2016 - 11:17 AM

Well, you're applying a constant vertical force of 30, and a lateral force of (mouse.x - [ball center]), in an attempt to fling the ball towards the mouse. A few questions:

* Does `mouse`, wherever it is, get updated before the fling() method is called? If not, this method will not have the expected results.


* Is `mouse` in world-space coordinates, or screen-space? If the latter, this method will not have the expected results.


* Why aren't you normalizing and then scaling the vector (velocityX,velocityY), since those are exactly the data you're trying to calculate based on `mouse`? See GestureListener.fling(float,float,int).

#5271302 Play my software through a browser

Posted by Wyrframe on 15 January 2016 - 11:21 AM

You're going to need to find a local expert. Perhaps someone in the company you just bought. There is no turnkey solution, and even if someone's willing to help you with something this complex for free, you're going to get what you pay for.