Hi Krisse!… yes sorry about that, I’ve been very busy at work with the release of our latest projects, and my personal projects have kept me far from the VB scene too, but the good news is that I’m halfway with the new version of the engine.
About the variadic functions, are functions with the form
SomeType functionName(SomeType firstParameter, …);
the “…” is called ellipsis and is used to allow the function to being called with a variable number of arguments, for example:
functionName(argument1, argument2, argument3, argument4);
functionName(argument1, argument2);
both calls are legal, and it’s a very handy programming technique to achieve things like propagate different kind of events in a parenting system, which is what I’m trying to accomplish.
But I suspect that the way the compiler handles the save stack frame and return from that kind of function is buggy.
jorgeche
After some research I found that it may be the save_r6_r9 code which is wrong, and I found it in the following files:
lib1funcs.asm:
/* Save registers 6 .. 9 on the stack for variable argument functions */
/* Called via: jalr __save_r6_r9,r10 */
__save_r6_r9:
mov ep,r1
mov sp,ep
sst.w r6,0[ep]
sst.w r7,4[ep]
sst.w r8,8[ep]
sst.w r9,12[ep]
mov r1,ep
jmp [r10]
but it isn’t the same code generated by the compiler, which looks like this:
0700beb0 <__save_r6_r9>:
700beb0: 3f 00 mov lp, r1
700beb2: ea 03 mov r10, lp
700beb4: c3 dc 00 00 st.w r6, 0[sp]
700beb8: e3 dc 04 00 st.w r7, 4[sp]
700bebc: 03 dd 08 00 st.w r8, 8[sp]
700bec0: 23 dd 0c 00 st.w r9, 12[sp]
700bec4: 01 18 jmp [r1]
and in v850.md
;; Save r6-r9 for a variable argument function
(define_insn “save_r6_r9”
[(set (mem:SI (reg:SI 3)) (reg:SI 6))
(set (mem:SI (plus:SI (reg:SI 3) (const_int 4))) (reg:SI 7))
(set (mem:SI (plus:SI (reg:SI 3) (const_int 8))) (reg:SI 8))
(set (mem:SI (plus:SI (reg:SI 3) (const_int 12))) (reg:SI 9))
(clobber (reg:SI 10))]
“TARGET_PROLOG_FUNCTION && ! TARGET_LONG_CALLS”
“jarl __save_r6_r9,r10”
[(set_attr “length” “4”)
(set_attr “cc” “clobber”)])
but this is a “GCC Machine Description” which I’m completely clueless about.
jorgeche
Hey Krisse, I’ve doing some testing on this matter, and moving the screen one pixel at a time never producer a jump as big as in your captures ( from 3 pixels to 6 in a single screen move). The difference between the japanese arc an the background platform always rises/decreases by one.
I recorded the change in distance for both object’s positions on screen (projected to 2d space) and the change in distance was always of 1 pixel. It did go back and forth because of rounding to an integer. Now the difference when moving the screen to the right and the objects are closer to the left of the screen will always increase because the object closer to the screen moves faster.
Maybe the jump from 3 to 6 pixels you got was because in a single update mario moved more distance, remember that I’m using independent framerate move, so it’s possible for mario to displace more distance in a given frame because of the drop of frame rate.
I will try to find a way to solve the rounding problems, but I don’t think it’s that easy to do. So there is another work around to solve it:
The engine uses the Sprite_setPosition method to calculate the x and y coordinates to render a bgmap based on the object’s 3d position in space. It is possible to inherit a new class from Sprite and make it to calculate the same position based on other factors i.e: each layer having a different velocity when the screen scrolls. But such solutions are a specialization of an specific requirement for a sidescroll game, and as such it does not make sense to include into the core engine since the whole engine is designed from the premise that every game world is a 3d space with objects defined by their 3d coordinates.
jorge
Ok I’ve isolated the problem and can now see Krisse’s point. I’m looking into it. Will post soon an update on the matter.
jorge
Yes the problem should be just 1 pixel, that’s why it’s not that much noticeable. I cannot notice the 3, 4, 4 and 6 pixel from the pictures.
Krisse, can you specify between which 2 objects are you measuring the number of pixels so I can take a look at their coordinates progression? Is it between the japanese arc and the middle bridge part?.
jorge
Sure, the objects in my engine are positioned in 3D Space, so when you create a game world you place things with x,y and z coordinates.
Here is the calculation:
position2D->x = FIX23_9_ROUNDTOI(position3D->x +
(
FIX23_9_MULT(
_optical->horizontalViewPointCenter – position3D->x,
position3D->z
)
>> __MAXVIEWDISTANCE_POW
)
);
I will use numbers out of my head to illustrate the problem:
We have two objects at the same x coordinate 100, but at different z positions: 64 and 83 for example. At the moment of project the x position from 3d to 2d space let’s say that
– 64 becomes 50.48 rounded to 50
– 83 becomes 74.16 rounded to 74
When the screen moves there will be moment in which the projected position from 64 will be rounded to 51, but 83 will be rounded still to 74.
From my understanding because some positions get rounded first than others to the next pixel is what causes the problem.
jorgeche
Hi Krisse, If I recall correctly, there are some affine functions which are not complete or don’t work as I expected, but I got bored and didn’t take the time to polish them, so that could be the problem :-).
jorgeche
Hi guys, it would be great to have feasible C++ support for the VB, I myself find it very hard to design/program anything without thinking of objects after I learned OOP, but as stated by many of you the memory allocation on a heap would kill the performance and constraint the work RAM of the machine.
It never hurts though if you’re going up for a job to bring a demonstration of your previous work in case the prospective employer wishes to see it.
Nice comment and good tip, I myself got my current job position by showing the vbjaengine 🙂
The concept of virtual methods really makes a lot of things possible beyond simple tasks. With that, a Mario that inherits from sprite could manage how it’s going to move, die and so forth. A spiny or turtle could determine their actions as well. The Object Oriented Paradigm simplifies the debugging and testing aspects quite a bit. In SMB, some turtles (green shells) can not go beyond the ledge they are on. Others (red) could go past the edge to fall to a lower platform or into a pit. Of course if implemented in VB both would have to be red.
After I understood Polymorphism there was not way back for me, and that’s why I had to find a way to have that feature for my VB programming, it was a joy for me to understand the underlaying of how it works behind the scenes in languages like C++ to do it’s magic and trying by myself to replicate it to some extent, which was indeed more fun than any other thing I did for the engine.
jorgeche
Those tools look interesting… but would need some test to see if they are of any use for my engine since it is not based on tiles. I decided to make something with a more general purpose usage than solely being useful to create platformers, so, an editor for my engine will have to be a little more specific and tied to my design. Obviously a tile engine will make a lot easier to develop platform games and even make room for more complex games of such kind, but I doubt there will ever be that much effort to develop a homebrew game for the VB with commercial quality standards, so I decided to make something which allows other people develop quick games of whatever kind they want, I think my engine can handle most of the released games except for those polygon based games like Red Alarm, and that was the reason to develop Mario VB as a showcase of my engine’s capabilities.
About vibe… I assume you’re talking about VIDE and the map editor plug-in recently released; it is a great tool, I’ve been using it for all my work in Mario VB… but I think that there is a lot of room to make something which can make faster the process of creating content for the engine, that’s why a custom tool would be great… or maybe to exted VIDE’s capabilities to support my engine with a plugin or something, but as I said, it would be necessary the effort of other people since I’m not a Windows programmer and I’m not interested in doing so.
jorgeche
cualquiercosa327, I’m not really interested in continue developing the game itself, mainly because it’s more about creating the assets (graphics, sounds, levels, etc) which is not what I like; instead I plan to continue adding some features that the engine is missing right now like particle effects (this is at the top of my list), then I want to add more affine effects (and fix the rotation), I’m thinking about tile based collision detections and polygons too, and maybe even implement communication if some day I decide to buy a second VB.
The level editor would be great, but I will need help from other people to get that working because I’m not a Windows developer (and I’m not interested in learning it either). But it will never be a replacement for programming skills, the real objective of the editor will be to create graphical objects and place them into a stage, once that’s done, you have to go to code how each object must behave.
jorgeche
XJaPaN wrote:
Has anyone ensured that the ROMs are working?
They all work in Rboy.
I beat almost all of them in a reasonable time… but the 20th is really difficult… I think I spent more than 5 hours solving it :-P.
jorgeche
Thanks RunnerPack, about the tip, it didn’t work for me the Windows environment variable when I tried it so that’s why I suggested the CygWin but it could be because I’ve always worked on Linux and don’t really know much about Windows.
I would like to retake the level editor we once talked about if you have interest on developing it, since it would really make a difference for the engine appeal.
jorgeche
Why not just make an image with all your frames (like zub_frames_vb.gif), convert to a BG map and chars, and control which frame is displayed by simply changing the offset into the BG?
Right now I have 30 frames of animation for Mario in my demo, and I have maybe 20 or so more frames to import. Each animation frame uses 20 chars, thats 600 chars, let assume that it is half that number if I use the char optimizations that Vide does, they are still 300 chars, which will consume more than half a char segment, so it is not that good.
If you take a close look to tile base sprite engines, they use various techniques to allocate different characters bases on how many animation frames they have.
The way you propose is applied in my engine but for simple characters like koopa or the piranha plant (take a look at the bgmap memory).
If you look the char memory in Wario, you will notice that the chars for Wario are rewritten each time that a new animation frame is shown, so I took the idea from it.
jorgeche
Thanks for the explanation, I thought that the cache was for data, not instructions.
I’ve been activating it in some heavy functions and I can appreciate some performance gains now. The problem is that I have no way to say for sure where it will work and where not because most of my intensive loops use late binding to call the propper methods based on the object being processed, and since the methods are on different translation units the only way to be sure is to test it on the VB.
jorgeche
Jmm I’m not sure why, but if I set the clock resolution to 10, I got a more stable frame rate, it never goes over 50 (I’m setting the target fps to 60 thought)… but this way it never goes below 45!… and it runs really smooth.
I’m capping frame rate using this method:
__TARGET_FPS = 60
while(true){
················currentTime = Clock_getTime(_clock);
················if(currentTime – lastTime > 1000 / __TARGET_FPS){
························// save current time
························lastTime = currentTime;
························// process user’s input
························Game_handleInput(this);
························ASSERT(this->stateMachine, Game: no state machine);
························// update the game’s logic
························StateMachine_update(this->stateMachine);
························// simulate collisions
························CollisionManager_update(this->collisionManager);
························// render the stage and its entities
························Stage_render(this->stage);
························// increase the frame rate
························FrameRate_increaseFPS(this->frameRate);
···············}
·······}
jorgeche
Yup, I enable cache, but didn’t notice major improves with that at least not visible in the FPS since I didn’t do any proper measurement, but before setting the ROM wait to 1, I saw drops as low as 20 FPS in the most loaded part of my game (between the bridge and the first piranha plant) when the engine was loading that part, now it has never gone down the 35s.
I did profiling on the heavy method which determines which objects must be loaded, and takes care off all the process of creating the game entities and loading their graphics:
Stage_loadObjects(Stage);
Using a clock resolution of 1, I got the following peaks on time duration of such method:
Default ROM wait: higher duration = 35 time units, lowest FPS = 28
ROM wait set to 1: higher duration = 25 time units, lowest FPS = 38
BTW I use cache enabling mainly while writing the param table which is the most time consuming procedure I can think of, I’m not sure about cache working, but I suppose it does not make any difference to active it around a loop which has calls to other function (frame functions for that matter)..
jorgeche
Hey man it works great!… I’ve doing a lot of optimizations to my code and algorithms, and although I’m sure all them help, this tip makes a great difference, now my game is running really smooth on hardware.
The main bottleneck was loading graphics on the fly and this makes the process a lot faster.
BTW, it works with FlashBoy.
Thanks for sharing!
jorgeche
That would help me a lot since I don’t preload anything, and read chars and bgmaps on the fly… how do you change the ROM wait state?
jorgeche
Thanks for the follow up, it makes things clear. I’ve changed all my math to fixed point, it indeed runs faster than with floats.
BTW, congratulations for your first place in the competition.
jorgeche