Putting the 'role' back in role-playing games since 2002.
Donate to Codex
Good Old Games
  • Welcome to rpgcodex.net, a site dedicated to discussing computer based role-playing games in a free and open fashion. We're less strict than other forums, but please refer to the rules.

    "This message is awaiting moderator approval": All new users must pass through our moderation queue before they will be able to post normally. Until your account has "passed" your posts will only be visible to yourself (and moderators) until they are approved. Give us a week to get around to approving / deleting / ignoring your mundane opinion on crap before hassling us about it. Once you have passed the moderation period (think of it as a test), you will be able to post normally, just like all the other retards.

Brick Atelier

Krice

Arcane
Developer
Joined
May 29, 2010
Messages
1,648
Or you could just release your code under the GPL like the developers of the free tools you use have done. Pretty fair deal really.
I don't use GCC that much to be honest. I'm mainly using Visual Studio for developing, because it's just way better than Code::Blocks or any of the free tools. For graphics I'm using Paint.net which is a closed source freeware program (with optional donations) and Affinity Designer which is a commercial software. In fact I hardly use any open source programs, because they usually suck so much.

What sometimes happens to open source projects that they are taken over by some random dudes who just take the project and then start to generate money with it. Like what happened to Blender 3D. That's why it's quite wise not to open source everything.
 

Krice

Arcane
Developer
Joined
May 29, 2010
Messages
1,648
I found a bug from the release version, whee. I began to work on the project just for the fun of it and found out that the temporary brush with "use as brush" is deleted during exit even it doesn't exist. It's kind of easy bug to make, since the "current" brush pointer is used for the temp brush and the brushes that are stored in the pad. The only difference is that the temp brush has a mask value of zero. The release version doesn't actually tell anything about the crash, because it happens during the exit procedure, it just maybe slows down the procedure for some reason. I think I already fixed the bug, at least the debug version no longer crashes. When you move the brush to pad I'm actually not sure if it stays as "temp" brush as well as a brush stored in the pad, in which case it could be deleted twice, although debug version doesn't give any kind of crash or error message.
 

Krice

Arcane
Developer
Joined
May 29, 2010
Messages
1,648
I made an actual 'temp' brush pointer so it's easier to handle everything. 'current' pointer is now only pointing to either to an existing brush (list) or temp brush. There is still some pointer stuff going on which looks ugly, but I think it now works as supposed and there is no memory leak etc. You can also delete the temp brush if you want to. I'm still trying to figure out how to implement drag and move for brushes in the pad.
 

Krice

Arcane
Developer
Joined
May 29, 2010
Messages
1,648
Trying to think how to implement paste resize and rotate. Dislike the idea of a widget, there has to be other way to do it. Maybe some kind of tools to rotate and resize, but they would also require some kind of widgets I guess, or maybe not. Resize and rotate for pixel art is hard enough, but overlaying a widget at least feels like even harder task. Maybe it's not that difficult.
 

Krice

Arcane
Developer
Joined
May 29, 2010
Messages
1,648
I made a pattern mode for the stamp brush. It almost works, I think I know what is the problem. In pattern mode the brush doesn't slide with the mouse location, it draws the brush as a pattern so you can for example create a brick brush and draw an area with that brick pattern. It's not the most exciting feature, but it was surprisingly easy to implement so why not.
 

Krice

Arcane
Developer
Joined
May 29, 2010
Messages
1,648
Big surprise even to myself, but I can't figure out how to implement that pattern feature. It should always start from 0,0 where you begin to draw, but how to update that offset when mouse is moving. I have the source location of the movement, it's already there.
 

Krice

Arcane
Developer
Joined
May 29, 2010
Messages
1,648
This fails for some reason, I can't see what is the problem. The offset values seem to be ok, but the pattern breaks and it looks random, especially with both x and y axis movement. Am I missing something?

Code:
void Brush::Pattern_To(Painter &pnt, int x, int y, const Point &offset)
{
    const int br_w=Get_Width();
    const int br_h=Get_Height();

    int sx=offset.x % br_w;
    int sy=offset.y % br_h;

    //use individual pixels (color data) of the brush, but offset it to
    //create a pattern of that brush
    for (int dy=y; dy<y+br_h; dy++)
    {
        for (int dx=x; dx<x+br_w; dx++)
        {
            if (brush_data->mask->Is_Mask_Pixel(sx, sy))
            {
                Pixel px=Get_Drawing_Pixel
                    (dx, dy, brush_data->pixels->Get_Pixel(sx, sy),
                        pnt.pixels->Get_Pixel(dx, dy), Solid);
                pnt.Set_Pixel(dx, dy, px);
            }
            sx++;

            //wrap brush data around to draw as pattern
            if (sx>=br_w)
                sx=0;
        }
        
        sy++;
        if (sy>=br_h)
            sy=0;
    }
}
 

Krice

Arcane
Developer
Joined
May 29, 2010
Messages
1,648
Thiis is one of those bugs... I tried to isolate the drawing routine, it does seem to work perfectly, but somehow mouse coordinates don't work with it. It's a mystery, since if mouse coordinates would give "wrong" location for the offset, it should be everywhere. I've noticed it does seem to break when there is both x and y mouse movement at the same time, but I can't see how it's different than just x or y movement, they both change the offset.
 

Krice

Arcane
Developer
Joined
May 29, 2010
Messages
1,648
I'm trying to write undo/redo for copy/paste -operations, because they are not part of the undo system. It can be either a command or image undo, but copy/pastes are a separate class. Even trying to figure out how to write undo/redo for that is a head scratcher. It needs a new undo node type, so I have to make the current one an abstract class, because it can't hold the undo/paste data. Then I have to figure out if it's a command or image undo, because it's more like a command undo. In fact creating two different types of undos with their separate calling routines was a mistake in the first place. Maybe I need to fuse it to one generic undo system it should have been from the beginning, so regardless of what you undo/redo it just works.
 

Krice

Arcane
Developer
Joined
May 29, 2010
Messages
1,648
Refactoring C++ is sometimes nice, because a reason many people whine about: inheritance. In this case when you have a class (Undo_Node), you can inherit from it if you need to create different types of objects, but they work with the same base class implementation through public interface, so there is no need to change routines that are using the class, because they don't notice anything, other than the creation of the object which now needs to be a derived class.

Code:
//Undo node stores command data and tile position.
class Undo_Node
{
    int redo_command;
    int undo_command;

protected:
    int tile_position;

public:
    Undo_Node(int c, int p);
    virtual ~Undo_Node() = 0;
  
    virtual void Action() = 0;
    void Post_Action();
    void Pre_Action();

    void Display(int x, int y);
    virtual void Display_Tile(int x, int y) = 0;
};

//This node is all other types than paste.
class ImageUndoNode : public Undo_Node
{
private:
    Masked_Tile *tile;

public:
    ImageUndoNode(int c, int p, Tile *ct, Tile *cm);
    ~ImageUndoNode();

    void Action();
    void Display_Tile(int x, int y);
};

//This node is for paste operations.
class PasteUndoNode : public Undo_Node
{
private:
    StaticPaste *paste;

public:
    PasteUndoNode(int c, int p, StaticPaste *s);
    ~PasteUndoNode();

    void Action();
    void Display_Tile(int x, int y);
};
 

Krice

Arcane
Developer
Joined
May 29, 2010
Messages
1,648
I began to rewrite this for wxWidgets. I started from scratch basically, because it's impossible to cut and paste the code in many cases. Some data can be imported to the new project, like command data etc. The good thing is that wx obviously has gui code ready, so I don't have to worry about that. I don't yet know if it has some kind of useful canvas feature for drawing.
 

Krice

Arcane
Developer
Joined
May 29, 2010
Messages
1,648
And back to SDL2 version. wxWidgets was too weird because callback stuff, would have required a complete rewrite from scratch. Working with the SDL2 you just have to draw everything in the beginning of an event loop, which does make stuff a bit weird, but it's not that hard. In case of dialog windows you have to draw the entire editor data or whatever is in the background at that time, then draw on top of that. It DOES make it slower, no matter what people say about GPU rendering. However I can make it a bit faster by baking some things to static textures, like pane headers, and other text routines that display text.
 

Krice

Arcane
Developer
Joined
May 29, 2010
Messages
1,648
Pane headers are now baked versions which makes them a lot faster. It wasn't an easy things to do, but it feels better now that they are not drawn "manually" with each letter etc. I can now move on to improving actual stuff, although there are still problems with menu update when leaving them etc. I know this project is quite wacky, and I probably don't even have a reason to work on this, but what else I have?
 

Krice

Arcane
Developer
Joined
May 29, 2010
Messages
1,648
Went back to wxWidgets version, I think it could be nice to create a new project, like a regular painting program rather than tile based editor. How hard could it be? I will still keep working on this project as well, I don't mind having more projects.
 

Krice

Arcane
Developer
Joined
May 29, 2010
Messages
1,648
..and back to SDL2-version. I don't like wxWidgets. The current goal is to write a native file dialog so I don't have to use windows.h and then the project can be compiled in linux and osx. std::filesystem of C++17 is making things a bit easier, but I still have to manually code the dialog with possibly creating a scroll bar for it which I don't yet have as a generic gui item. By now I have a window with the list of files displayed, but I can't yet select anything or scroll the list. I think it's not that hard, but it sure is tedious.
 

Krice

Arcane
Developer
Joined
May 29, 2010
Messages
1,648
I had to figure out how to code double clicking manually and it's kind of funny. The only thing you need to do is start a timer when mouse button is released and then read the time when mouse button is pressed again, if it's less than let's say half a second then it's a double click. First I thought you need some kind of variable to check if mouse button is pressed twice, but you don't need that, because when you release the button it is the first click.
 

Krice

Arcane
Developer
Joined
May 29, 2010
Messages
1,648
std::filesystem doesn't know or care what a hidden file is so it's listing everything, including hidden and system files. It has been surprisingly difficult to find out how to retrieve file attributes in Windows. When I google it everything is about GetFileAttributes which is windows.h stuff, but I want only C++ implementation. I guess you have to check out file attributes for each file and folder to hide them. Well, an option for files is to list only .wst files which is the Brick file format, because why would you want to load anything else (then again it's possible to change the extension). But it wouldn't take care of folders.
 

Krice

Arcane
Developer
Joined
May 29, 2010
Messages
1,648
It seems like C++ doesn't know about hidden and system files, they are Windows specific. Then again maybe checking for access permissions could help, maybe listing only files that can be read and written by the user. I am really wasting my time on this.
 

Krice

Arcane
Developer
Joined
May 29, 2010
Messages
1,648
The syntax of ::perms is so weird that I can't use it. It's an enum class of flags, but sure don't know how to use it. I can't find any examples of just that, everyone seems to work on Windows level if their program has anything to do with file permissions. I have always wondered why something like actual I/O is so difficult to implement even in library level, let alone in language level. I know, hardware changes etc. but can't the language change as well? I going to leave this for now and get back to roguelike development.
 

Krice

Arcane
Developer
Joined
May 29, 2010
Messages
1,648
Think I'm going to try something funny. You know when you have to use friend to expose private part of class to some other class? I was wondering if it's possible to never use friend, remove all friends and code the proper OOP way. I'd like to try, because I can't get anywhere else in this project. The rotation routine is too complex to implement, the file dialog is tedious etc.
 

Krice

Arcane
Developer
Joined
May 29, 2010
Messages
1,648
Yesterday I already fixed some friends. Today I listed them to see how many there are still, 33 friend classes and 3 friend structs. You can quickly fix a friend by creating a public getter for some data, but it's the "bad" way to handle it. A better way is to create a function in the class that handles some internal data, depending on parameters of the function. This is more like passing a message which true OOP languages do, because it doesn't directly expose the internal data of the class.
 

Krice

Arcane
Developer
Joined
May 29, 2010
Messages
1,648
With Scene class it just got ugly with getters, but it's maybe some kind of bad design.

Code:
public:
    Scene(const char *name, int tile_width, int tile_height);
    ~Scene();

    Pixel Get_Color(Mouse &md);
    Filename &Get_Filename() { return tile_file; }
    int Get_Header_Width();
    std::string Get_Name();
    int Get_Tile_Index();
    Plane Get_Tile_Size();
    Tileset *Get_Tileset_Handle() { return tiles; }
    bool Is_Changed() const { return is_changed; }
    bool Is_Header_Hit(int x, int y);
    bool Is_Named() const { return is_named; }
 

Krice

Arcane
Developer
Joined
May 29, 2010
Messages
1,648
Friend classes fixed, some of them became a bit ugly. Two friend structs left. One of them is strange, for some reason I've made a StaticPaste class which has Masked_Tile and location, then there is Paste class which has same data (plus movement location for the paste), but there is no inheritance. I wonder what was the idea there, why didn't I inherit from the StaticPaste?
 

Krice

Arcane
Developer
Joined
May 29, 2010
Messages
1,648
StaticPaste's idea was that it made a copy of the tile, but it was a good idea for the actual paste as well, rather than pointing at the list of copied tiles. All friends removed and it took 4,8 hours. I think in the next phase I'm going to take a look at some of the member functions which handle only global data rather than internal, in fact there could be a class called Globals or something that has everything not related to each instance of a Scene (a tileset).
 

Krice

Arcane
Developer
Joined
May 29, 2010
Messages
1,648
I'm testing SDL3 with a small project. It seems to have a file dialog, maybe calling the native dialog I guess? SDL3 has changed some things, like return values are now bool in functions that returned integer previously. Some other changes as well, you no longer need to link to sdl_main library, it's gone. I think it's not that difficult to migrate when compared from SDL1 to SDL2, that was a hard one.
 

As an Amazon Associate, rpgcodex.net earns from qualifying purchases.
Back
Top Bottom