We're using cookies to ensure you get the best experience on our website. More info
Understood
@syncophonoRegistered September 17, 2016Active 6 years, 10 months ago
25 Replies made

RunnerPack wrote:
This is all assuming that the images you want are composed of BGMaps stored in the ROM. It’s entirely possible for the game to generate the contents of certain BGMaps “on-the-fly”, especially for characters with a lot of “moving parts” like Wario himself. This kind of thing will be caught by the breakpoints, but since it’s not copying anything, the code will look a bit different.

And then there are images composed of a collection of Objects. I don’t know if this technique is used in Wario, or any other commercial VB game, but it’s a possibility.

It’s possible that Wario is a collection of objects. Which means his “special purpose” animation data that describes the movement of his objects would need to be found as well. Luckily most enemies in the game do not look like they are made from objects.

Also if the game has any dynamic loading of chars, that too could be an issue for deciding which BGMap lines up with which load.

This really requires a good understanding of how the game works. So we’ve got some assembly to read!

Thanks for the advice! Which emulator can set breakpoints?

I don’t want to derail the thread, whose initial idea is very good, into a discussion about programming paradigms and concepts. If you think that there is no real advantage in the usage of OOP features or libraries that abstracts part of the problem of providing a single interface to work with multiple game mechanics, you’re more than welcome to pursue your project as you see fit.

I’m out.

I don’t really see how the thread is derailed. The discussion of the common interface is important for the development of this project, because it needs to be established before anyone makes games. I think the discussion went pretty far, we shared many of our ideas on programming. Sorry if you viewed the discussion as a debate on paradigms, that was not my intent. I would encourage you stick around if you are interested. But its up to you. I’ll try not to get wrapped up in my opinions on programming.

My goal is to start a project that everyone can enjoy working on at the minigame level, regardless of programming style.

Ultimately, the implementation of the main interface doesn’t matter as much as the implementation of the minigames themselves, which could be in any paradigm spanning any number of files and including any libraries they need to use.

Our suggestion is to use GameStates because the state machine pattern is a nice way to swap functionality by using a common interface, and because states generalize common phases liking initialization, execution and exiting.

What functionality needs to be swapped? We don’t want people to override an important initialization function or something, because if it’s overridden, the base behavior won’t be performed( unless the macros have a super keyword?) If each minigame is unique, what are we swapping?

If we are trying to reuse memory space for game structs, why not use a union? It’s a language feature instead of a macro.

We could also just have each minigame run a function which creates its data on the stack. That way we don’t even need to make an allocator, or an init function. ie,:

condition game(){
int create, my, data, here;
game_loop{
return WIN;
}
}

The purpose of inheritance is to reuse code

The purpose of inheritance is to reuse DATA. While polymorphism is a feature of many OOP languages that use inheritance, it’s not exclusive to inheritance or OOP. Function pointers could be used for polymorphism and many other tasks that aren’t tied to objects.

The real code reuse comes from functions, where I can run the same code in multiple places. If the function is pure, I can also be certain I’m not modifying any global state when I call it.

Yeah, you can achieve something analogous to encapsulation by the use of “static” in C

It’s not “analogous” to encapsulation, it IS encapsulation. It’s restricting the scope of your data, which makes the program easier to understand by breaking it down. Even a block {} is a form of encapsulation.

the purpose of classes is to model software in the same way that we conceive our phenomenical experience which consists of objects that have properties that determine their behavior.

But minigames aren’t real world objects. They have a lot of data that has nothing to do with the real world, and everything to do with the hardware. So it doesn’t make anything easier to understand, all the same code needs to be there in some way or another. You end up with classes that are nothing like the real world.

The purpose of inheritance is to reuse code and, by polymorphism, to allow for scalability by means of generic programming (among many other things). The fact that there only needs to be one instance of a single class doesn’t nullify those advantages.

Inheritance doesn’t automatically make scaleable software, abstraction does. But abstraction is not exclusive to OOP or inheritance. A function is a form of abstraction.

Globals allow unrestricted modification of the program’s state, while classes’ attributes restricts those modifications to parts of the program

Global state can be a problem, but at the same time, all games need it. It’s crazy to work in languages that forbid global state. But if we really wanted to avoid accessing it directly, we could pass parameters. Maybe we just pass it to a function then as a const parameter?
That way, the programmer gets a list of all the vars they need,
and they cannot modify it, therefore not tampering with any global state:

void step( const unsigned time );

In that way, it’s not global and its scoped in the function.

Since there is only one minigame active at any time, there needs to exists only the singleton instance of that minigame class in work RAM, therefore only one time variable. When it ends, the instance is deleted and the instance of the new minigame class is created..

If we are trying to reuse memory space for game structs, why not use a union? It’s a language feature instead of a macro.

  • This reply was modified 7 years, 1 month ago by syncophono.
  • This reply was modified 7 years, 1 month ago by syncophono.

As someone who would only be playing this and not contributing to it (I don’t have the skills, but am so thankful to those of you who do!)

Even if you don’t have skill with programming, it might still be possible for you to contribute. Are you any good with graphics?

if the game consists of say 50 minigames, increasing the speed in the way you suggest will be a nightmare to balance since the speed progressing from the first to the last will be too big.

The game won’t be running all 50 at a time, it just runs 1 at a time. You could have as many minigames as the memory allows, and performance will only matter at the level of the individual minigame code itself.

To avoid those problems, and maybe others, but at the same time to achieve the desired effect, modern game engines pass to the update methods a deltaTime argument that can be scaled by the programmer. That way the simulation is not dependent on the game’s performance, the scaling can be non linear and async processes are not affected. The VUEngine’s GameState’s execute method passes such a value to the game objects, but it is only used to affect animations (that is, the engine’s classes only use the time delta to affect the animations’ speed, but derived classes specific to each minigame could use the time delta for other purposes), while things like physics simulations are updated by another facility.

Speed scaling can be implemented in a GameNameGameState class from which all minigames inherit. In this way, the “primary game” doesn’t need to exist, since it would just be logic shared by all minigames, achieving your goal of avoiding the need to reimplement on each one the same functionality.

I agree, delta time sounds like it would allow for a much more gradual speedup. Should we use fixed-point as the delta? I would imagine floats would be too slow.

By using inheritance, there is no need to use global variables. The time remaining would be a protected attribute of the GameNameGameState class accessible to all the minigames.

There isn’t really a difference between:
globals.time
and self.time.

Plus, self.time indicates multiple time variables (one per minigame), when in reality we only need one time variable that is applied to all minigames. A global variable makes more sense here because the one parameter would affect everything.

In this way, the “primary game” doesn’t need to exist, since it would just be logic shared by all minigames, achieving your goal of avoiding the need to reimplement on each one the same functionality.

If we were to use inheritance from the base game, each minigame would get unnecessary copies of the main game state. Only one minigame will ever run at a time, so the copies of main game state don’t need to be a part of the minigame at all. They can exist in one place independent of the minigames that don’t need to access it.

The purpose of a classes and inheritance is to create a template that you can create instances of. However, only one instance of a game will ever exist, so why make it a class?
If we are trying to encapsulate, we can encapsulate at the file level. If you make a variable STATIC inside a .c file, its the same as making a variable PRIVATE inside of a class: it can’t be accessed anywhere else, not even with EXTERN.

  • This reply was modified 7 years, 1 month ago by syncophono.

“Task Panic” is a pretty good name because it describes what you’ll be doing in the game. Though we shouldn’t add “3D” after it because some games might be 2D.
I’m leaning towards the “dual D-pad” controls. Its a unique feature of the Virtual Boy and we should take advantage of that.
We shouldn’t mirror the controls because I want START to be able to pause the game.

  • This reply was modified 7 years, 1 month ago by syncophono.

Something else to decide on: The key input interface.
Every Ware game has always complied to a specific set of keys and not deviated from it. The game boy advance game, for instance, used only the D-pad and the A button as inputs.
For the VB, which buttons should be used as this interface? Using every button on the controller would make picking up and playing the game in 5 seconds a little difficult. So we should limit ourselves a to a subset of the buttons on the controller.
I’m thinking the two d-pads as the only inputs allowed.
What do you think?

@Twila
The passes parameters should be less specific to the individual minigames themselves, but maybe based on how the player is doing.
For instance, we could pass if the player lost the last game, what the speed is, and the level of difficulty, ect.
The games can use these params to create these adjustments.

@KR155E
I think there is value in having a primary game running in a main loop. The primary game keeps track of your score, lives, and the game speed.
Game speed is especially a reason there should be something calling a step function for each game. Because if we want to run at double-time, the main game can call the update function twice.
If each microgame had its own main loop and was running independently, every game would need to individually implement speed-up behavior on its own.
If the programmer needs access to the time remaining, we can expose it in “common.h”.

On game speed, what do you think about implementing speeding up? Is calling the update function multiple times adequate, or maybe some VUEengine parameters can be tweaked?

@Twila The state is global, so all you would need to do to retain the previous player position is simply not update it in your INIT function. However I recommend initializing all your data before the game starts. These games only give you a few seconds, and as such, its better for the player to have some familiar aspects to rely on.

Making it original is a great idea! Though, not sure what to call it. VBWare?
A repository like github would certainly aid in the open development process, I like it.
The VUEngine would be a useful tool in microgame development, especially with the new release.
What is the purpose of using inheritance? My intent for the microgame struct is to give the primary game access to each subgame’s functions. The data for each microgame can just be global and static inside its own file:

—-Example Microgame file:

#include “common.h”

static int exampleData, moreExampleData;

void init(void){
exampleData=0;
/*Called once at start of game*/
}
void update(void){
exampleData++;
/*Game logic*/
}
void draw(void){

}
/*Fill out function pointers here, the only part of the file that is given to the primary game.*/
const struct MICROGAME_INFO example{ init, update, draw };
—-

If we do it this way, a microgame creator can just write their game all in one file, without needing to inherit from anything. They can then include anything they want, such as the libgccvb or the vuengine. Of course some basic functionality can be given in common.h so that devs aren’t doing the same initialization in every file.

  • This reply was modified 7 years, 1 month ago by syncophono.

What’s the platform support on the new compiler? Is it only for Windows?

ElmerPCFX wrote:

My GCC 4.7.4 patches should compile quite happily on linux, after all that’s what they’re supposed to be built on.

I still need to clean them up for an “official” release, but they seem to be quite stable now.

If you want a Mac toolchain, then you’d follow something like these instructions …

https://solarianprogrammer.com/2016/05/10/compiling-gcc-6-mac-os-x/

The older GCC 2.95 compiler that’s in GCCVB is something that I’ve not personally been able to compile with any reasonably-modern set of linux tools. Too much has changed over the years, and the GCC build process was failing for me.

As it was, it still took some hunting down of “compatibility” patches in order to get both binutils 2.24 and GCC 4.7 compiling with the latest GCC toolset.

Thanks, I’ll try it out! Where can I download your 4.7.4 patches so I can apply them to gcc?

I did a some research and OpenCV had a lot of documentation for video editing. So I wrote a test program that does many of the things needed for this compression:
-View the video frame by frame
-Resize the image
-Convert to grayscale
-Take out crop sections of the image(for comparison)

To convert the pixel to 2 bit,
Take the 1 byte grayscale value:
10111011
and shift it right by 6
00000010
Result: 10 (2)

I have included the source code.