-
Posts
2,600 -
Joined
-
Last visited
Content Type
Blogs
Forums
Store
Gallery
Videos
Downloads
Everything posted by reepblue
-
Global Illumination with Voxel Cone Step Tracing
reepblue commented on Josh's blog entry in Development Blog
How many bounces do you plan to calculate in total and is each bounce harder than the last? -
-
My intention was to do that but the UI listens to mouse events and I couldn't figure out how to alter some widgets with actions alone. Again, the widgets are Lua assisted so there can also be a lot of back and forth. I decided it wasn't worth it for the 1% that's going to actually play with a controller. The mouse input works pretty well with the steam controller and it should be the same on the deck.
-
The time finally came to revamp the main menu for Cyclone. Doing menu work for me is really hard to get into but once I'm knee deep into it, it's all I want to do. I decided now is the time to work on a semi-final menu system due to the following. I just finished Steam Input and the menu wasn't compatible. The white text on a bright background was hard to make out. I only had a "New Game" option. There was no way to jump to a map you wanted to play without the console enabled. The first step was to figure out how to integrate the GUI with Steam input. The Leadwerks GUI system is from my experience is an unfinished predecessor of the same GUI calls of the Ultra App Kit. The input was really for a mouse and keyboard but I didn't want to bother learning imgui or another API. One thing that made it really complex is that Leadwerks uses Lua scripts for the GUI draw and event queue commands, In the end, I just did a Steam Input binding to control the mouse with the touchpad or a joystick and told the OS to simulate the left mouse being pressed when the action is called. I don't know if this will get me any approval badges, but now you can control the menu with just the controller. The extra parameters don't seem to do anything but I kept them in. Regardless, it works. We don't have to call any "Legacy Keys" for the bindings! //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CycloneMenu::OnUpdate() { if (!Hidden()) { if (Input::ActionHit(ACTION_MENUSELECT)) { EventQueue::Emit(Event::MouseDown, Window::GetCurrent(), Key::LButton, Window::GetCurrent()->GetMousePosition().x, Window::GetCurrent()->GetMousePosition().y); } } } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CycloneMenu::ProcessEvent(const Leadwerks::Event iEvent) { ... else if (iEvent.id == Event::MouseDown) { // A hacky way of doing this. #ifdef _WIN32 INPUT Inputs[3] = { 0 }; Inputs[0].type = INPUT_MOUSE; Inputs[0].mi.dx = Window::GetCurrent()->GetMousePosition().x; // desired X coordinate Inputs[0].mi.dy = Window::GetCurrent()->GetMousePosition().y; // desired Y coordinate //Inputs[0].mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE; Inputs[1].type = INPUT_MOUSE; Inputs[1].mi.dwFlags = MOUSEEVENTF_LEFTDOWN; Inputs[2].type = INPUT_MOUSE; Inputs[2].mi.dwFlags = MOUSEEVENTF_LEFTUP; SendInput(3, Inputs, sizeof(INPUT)); #endif ... } } Now, controlling the mouse with a joystick isn't the best approach. I also had to make my buttons much bigger so it was harder to miss the bounds of the button when using the controller. I also kept all my UI elements in the center of the screen. Next was the options menu. I used choice boxes on everything to make it less Mouse centric, Finally came the new "Play" menu which I wanted to revamp from just a simple button that would load the "start" map. Right now, I'm forecasting only to ship with 10 maps but what about any new maps later on? Would I just add it onto the 10? What if I want to make a set of maps that focus on a theme or a new element? Would that break the progression? What about when custom maps are loaded? People would be going to the "Custom Maps" box more than the "New Game" button by then. It's not like it's a story or anything to justify those maps being held at a different standard than other maps. I decided to take a similar approach to the campaigns in Left 4 Dead. The chapters shipped with the game are loaded into the menu first. Then the application looks for anything under the addon's folder and loads those in. Each chapter can have a collection of maps that are easily selected by the user. { "name": "Cyclone 101", "author": "Reep Softworks", "maps": { "Level 0": { "filepath": "Maps/lvl0.map", "imagepath": "Materials/GUI/background_lvl0_artpass1.tex" }, "Level 1": { "filepath": "Maps/lvl1.map" }, "Level 2": { "filepath": "Maps/lvl2.map" } } } Custom maps work the same way no special treatment. This all works with a json script and the application can locate the script in the zip package. Also, if no image is defined for a map, a "NO IMAGE" texture substitutes in. Just click start, and off you go! { "name": "MyCoolAddon", "author": "reepblue", "maps": { "The Cool Addon Map": { "filepath": "Maps/addontest.map", "imagepath": "Materials/GUI/loadingscreen.tex" } } } One thing I'm not sure about is splitting my 10 maps in 3 chapters. I did this after feedback of the list being so empty with just one entry. Hopefully I'll have time to make new maps. Being that now I'm free to work on small collections instead of one long track should be motivating. A goal of arranging the maps like this is so I can justify the game based on the amount of content over "how long" it is. It should be really easy to integrate Steam Workshop with this but I'm not going worry about it now, Tonight I'm happy I can play Cyclone with my Steam Controller without reaching for the mouse and keyboard!
-
Steam: https://store.steampowered.com/app/18... itch.io Page: https://reepblue.itch.io/cyclone Discord: https://discord.gg/Hh7Ss9fWaW Cyclone is a puzzling first-person action-platformer from the creator of the hit Portal modification, Blue Portals. Solve a series of perplexing puzzles by placing gravity-bending vortexes in the world. Launch objects, redirect projectiles, and fling yourself across the room to reach the exit! Due for Early Access Q2 2022!
© 2022 Reep Softworks
-
Steam: https://store.steampowered.com/app/18... itch.io Page: https://reepblue.itch.io/cyclone Discord: https://discord.gg/Hh7Ss9fWaW Cyclone is a puzzling first-person action-platformer from the creator of the hit Portal modification, Blue Portals. Solve a series of perplexing puzzles by placing gravity-bending vortexes in the world. Launch objects, redirect projectiles, and fling yourself across the room to reach the exit! Due for Early Access Q2 2022!
© 2022 Reep Softworks
-
I can use Ultra App Kit! ? I thought there was an in-engine solution for this being the texture converter tool does this. But it makes sense. What I got works for right now and I felt like I spent too much time worrying about what could happen 3 years from now. I don't think loading in UAK would be a good idea if I just need one class from it.
-
I ended up doing a batch copy of the images I want from Steam and converted the images using the editor tools. This is only a lazy fix as new devices get supported or the image path can change whenever Valve feels like it. I rewrote the function to make it clearer what I want to do. I have little-to-no experience of reading raw binary data from a file, so I'm just shooting in the dark with samples I'm finding elsewhere. In Ultra, I would just load the png to the GUI with the pixmap class and call it a day. ? Leadwerks::Texture* LoadGlyphTexture(const Action actionname) { // This is the home location for all glyph. const std::string game_glyph_path = "Materials\\GUI\\Glyphs\\"; // Texture Leadwerks::Texture* return_texture = NULL; // The final texture path to load. std::string final_texture_path = ""; // For KBM, this should be staight forward. if (g_iCurrentDevice == INPUTDEVICE_KBM) { if (actionname.key > Key::XButton2) { // Basic key final_texture_path = game_glyph_path + GLYPH_KB_KEY_TEXTURE; } else { if (actionname.key == Key::LButton) { final_texture_path = game_glyph_path + "shared_mouse_l_click_lg.tex"; } else if (actionname.key == Key::RButton) { final_texture_path = game_glyph_path + "shared_mouse_r_click_lg.tex"; } else if (actionname.key == Key::XButton1) { final_texture_path = game_glyph_path + "shared_mouse_4_lg.tex"; } else if (actionname.key == Key::XButton2) { final_texture_path = game_glyph_path + "shared_mouse_5_lg.tex"; } else { // This should also be used for scrolling. final_texture_path = game_glyph_path + "shared_mouse_mid_click_lg.tex"; } } return_texture = LoadTexture(final_texture_path); } #ifdef USE_STEAMWORKS else if (g_iCurrentDevice == INPUTDEVICE_STEAMINPUT) { // Find what Steam wants to load as the Glyph. std::string steaminput_iconpath = ""; if (actionname.steamanalog != eControllerAnalogAction_NULL) { EInputActionOrigin origins[STEAM_CONTROLLER_MAX_ORIGINS]; int nNumOrigins = SteamInput()->GetAnalogActionOrigins(m_ActiveControllerHandle, m_CurrentActionSet, m_ControllerDigitalActionHandles[actionname.steamanalog], origins); if (nNumOrigins) { steaminput_iconpath = std::string(SteamInput()->GetGlyphPNGForActionOrigin(origins[0], k_ESteamInputGlyphSize_Large, 0)); } } else if (actionname.steamaction != eControllerDigitalAction_NULL) { EInputActionOrigin origins[STEAM_CONTROLLER_MAX_ORIGINS]; int nNumOrigins = SteamInput()->GetDigitalActionOrigins(m_ActiveControllerHandle, m_CurrentActionSet, m_ControllerDigitalActionHandles[actionname.steamaction], origins); if (nNumOrigins) { steaminput_iconpath = std::string(SteamInput()->GetGlyphPNGForActionOrigin(origins[0], k_ESteamInputGlyphSize_Large, 0)); } } if (!steaminput_iconpath.empty()) { // Strip the name of the image. auto name = FileSystem::StripAll(steaminput_iconpath); // Build the path with the name of the image of Steam wanted to load. final_texture_path = game_glyph_path + name + ".tex"; // Load the texture off the disk. return_texture = LoadTexture(final_texture_path); // Ok, if the texture doesn't exist (i.e A new controller is supported), build an image from the png. // TODO: This isn't working as of yet.... if (return_texture == NULL) { auto stream = Leadwerks::FileSystem::ReadFile(steaminput_iconpath); if (stream == NULL) { Msg("Warning: Failed to load glyph image \"" + Leadwerks::FileSystem::RealPath(steaminput_iconpath) + "\""); return NULL; } stream->Seek(0); std::vector<uint8_t> data; auto sz = stream->GetSize(); data.resize(sz); uint8 pixels[128 * 128 * 4]; memcpy(&pixels, data.data(), sz); return_texture = Texture::Create(128, 128); return_texture->SetPixels((const char*)pixels); //<- This just makes garbage. } } } #endif return return_texture; } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- Leadwerks::Image* Input::GetActionGlyphTexture(const Action actionname) { Leadwerks::Image* imageref = new Leadwerks::Image(); if (imageref == NULL) { Msg("Error: Failed to create image for glyph!!"); return NULL; } imageref->texture = LoadGlyphTexture(actionname); return imageref; } Other than where I dump garbage data into a texture, the results came out really well. I perfer not to ship my game with all the glyphs for every input device though.
-
Made progress, but now I'm getting garbage instead of nothing. //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- Leadwerks::Image* Input::GetActionGlyphTexture(const Action actionname, Leadwerks::GUI* pGUI) { Leadwerks::Image* imageref = NULL; if (g_iCurrentDevice == INPUTDEVICE_KBM) { auto image_path = Input::GetButtonGlyph(actionname); imageref = pGUI->LoadImageA(image_path); } else if (g_iCurrentDevice == INPUTDEVICE_STEAMINPUT) { if (actionname.steamanalog != eControllerAnalogAction_NULL) { // TODO } else if (actionname.steamaction != eControllerDigitalAction_NULL) { auto image_path = Input::GetButtonGlyph(actionname); auto stream = Leadwerks::FileSystem::ReadFile(image_path); if (stream == NULL) { Msg("Warning: Failed to load glyph image \"" + Leadwerks::FileSystem::RealPath(image_path) + "\""); return NULL; } stream->Seek(0); std::vector<uint8_t> data; auto sz = stream->GetSize(); data.resize(sz); uint8 pixels[128 * 128 * 4]; memcpy(&pixels, data.data(), sz); imageref = new Leadwerks::Image(); if (imageref == NULL) Msg("Error: Failed to create image for glyph!!"); imageref->texture = Texture::Create(128, 128); imageref->texture->SetPixels((const char*)pixels); if (imageref->texture == NULL) Msg("Error: Failed to create texture for glyph!!"); } } return imageref; }
-
I don't think I'm storing the buffer right? The SteamUtils call returns false. auto stream = Leadwerks::FileSystem::ReadFile(Input::GetButtonGlyph(actionname)); if (stream == NULL) return NULL; std::vector<uint8_t> data; auto sz = stream->GetSize(); data.resize(sz); int i = stream->Read(data.data(), sz); if (i == 0) return NULL; uint8 pixels[128 * 128 * 32]; if (!SteamUtils()->GetImageRGBA(i, pixels, 128 * 128 * 32)) return NULL; imageref->texture = Texture::Create(128, 128); imageref->texture->SetPixels((const char*)pixels);
-
I need to load a PNG image from the Steam directory into the GUI. Just using the LoadImage function of the GUI gives me this. Error: Texture file header not found. Error: Failed to load texture "C:/Program Files (x86)/Steam/controller_base/images/api/knockout/sc_rt_md.png" Is there a way of going about this? Do I have to convert this into a Texture first?
-
The beta was compiled with the later version of the Steamworks SDK and Josh forgot to include it. Unless you want to do the work replacing it yourself, I recommend you opt out of the beta.
-
I tried these a while ago but I couldn't get them to work. You're better off using raw XInput or better yet - Steam Input.
-
It's been roughly over a year since active development started on this project. Today, I'm excited to announce that Cyclone now has a "Coming Soon" page on the Steam Store! This marks a huge milestone for the project and I'm looking forward to getting this out as soon as possible. Cyclone is planned on being released as an Early Access title. Releasing into Early Access will grant a layer of feedback, bug reports, and ideas that can help build the remainder features, as well as additional content. So much was done, yet there's much more to do before the planned Early Access release scheduled for Q2 2022! If you are looking forward to Cyclone, please consider adding it to your wishlist and/or giving it a follow to be informed about future updates.
-
When you release the entity, you release the script. Never have an actor self remove itself.
-
Will Ultraengine have material sound?
reepblue replied to Vida Marcell's topic in General Discussion
Thank you! -
Will Ultraengine have material sound?
reepblue replied to Vida Marcell's topic in General Discussion
Can we have something to allow us to open the material file without reloading it? Can the material asset store the json class? This way, we can put any additional values we want and have our code do the rest. -
Building Ultra App in Code::Blocks in Linux, Needed Libraries
reepblue replied to Azure_Zero's topic in Programming
TBH, I don't understand how C++ projects work in VSCode. Lib files are often associated with Windows libraries. You should be linking with .a files with some -l flags to link to system libraries. Haven't really looked into UAK since I started my game but I think you just need the AppKit.a file and the -l flags. Try looking for them in the make file. Not at my PC atm. -
Building Ultra App in Code::Blocks in Linux, Needed Libraries
reepblue replied to Azure_Zero's topic in Programming
Those are Windows library files. I thought you are building under Linux. I would study the make file as previously suggested. -
Building Ultra App in Code::Blocks in Linux, Needed Libraries
reepblue replied to Azure_Zero's topic in Programming
I really liked CodeLite. Code::Blocks used to freeze and lock up on me. -
Building Ultra App in Code::Blocks in Linux, Needed Libraries
reepblue replied to Azure_Zero's topic in Programming
I'm surprised you're still using Code::Blocks. Last time I used it, it was a complete nightmare. -
I think this is why most other engines support baking lightmaps which I know you want to avoid. I guess if you can't figure it out, I would say allow the end user to adjust the resolution of the shadow maps manually. Personally, I didn't see much of a difference above 1024, and I only bumped it if I had to.
-
Interesting. Since you're going back to shadow maps, is there any ideas of reducing shadow banding? I made the shadow maps resolution for the spotlights in Cyclone at 1024 for a cleaner result but there is still some banding if you were to look hard enough. Also, you could only adjust the resolution if you had api access.
-
-
Steam: *Coming Soon* itch.io Page: https://reepblue.itch.io/cyclone Discord: https://discord.gg/Hh7Ss9fWaW Find out more at http://reepsoftworks.com/cyclone/ Cyclone is a passioned driven indie title from a former mod developer. This small slice of gameplay features exciting movement gameplay in which players can place cyclone vortexes launching objects or themselves up or across distances. An important layer of this small title is the future plan of user generated content support. Cyclone aims to make players into creators by providing a way to load in custom maps and additional scripts using Lua sandboxing.
© 2021 Reep Softworks