Jump to content

Custom Ragnarok Online Client


Shinryo

Recommended Posts


  • Group:  Members
  • Topic Count:  3
  • Topics Per Day:  0.00
  • Content Count:  28
  • Reputation:   1
  • Joined:  05/09/12
  • Last Seen:  

Bump mapping has quite an impact on the frame rate. I'm actually thinking about a toon shader. Any opinions?

I'm actually curious about the toon shader part. Could you do a compile and/or render a toon shader version of some of the maps? It would be best if you provide a side-by-side comparison, or even better a "split-screen" comparison like they do in TV sets when they're set on "demo mode". You should also include a few character sprites for comparison of how each shader affects the looks of them.

If it look anything remotely close to what I expect, I might even consider opening photoshop to rework all textures to fit in a toon-shaded RO. I still don't know why Gravity didn't make the whole world render with a toon shader. I wonder if I could also get away with possibly turning sprites into larger resolutions...

Edited by Kiso
Link to comment
Share on other sites

  • 2 weeks later...

  • Group:  Members
  • Topic Count:  6
  • Topics Per Day:  0.00
  • Content Count:  61
  • Reputation:   153
  • Joined:  11/10/11
  • Last Seen:  

The toon shader will have to wait until my current scheduling is finished (this will be somewhere around august). The sprites won't receive the shader, since it wouldn't make sense. You could, however, implement a custom fragment shader to filter sprites according to HQ2X or some other (with a drop in performance, of course) as soon as the source gets released somewhere around september.

@Project:

I have decided to use CEGUI as the base for the user interface. Almost every element is configurable through XML. Sadly, the way how the old client handles the gui textures is pretty slow, therefore the old skin system of the client has been dropped. CEGUI uses sprite sheets to reduce the batch count. The images are split in parts. It still has the advantage of unified buttons, frames, etc., without the need to edit hundrets of textures just for a single skin. I have written a tool that will combine all images into a sprite sheet to simplify the creation of new skins.

Besides that, it also simplifies the usage of language files, since the text of buttons and windows can be loaded from UTF8 encoded text files and can be changed at runtime (e.g. LanguageManager::getSingleton().setLanguage("fr") will load msgstringtable_fr.txt, etc).

I am currently working on the network management. There were questions how the packets will be structured. Here is an example:

namespace RoPackets
{
#pragma pack(push, 1)
typedef struct _0x0064
{
 short packet_id;
 unsigned long Version;
 unsigned char ID[24];
 unsigned char Passwd[24];
 unsigned char clienttype;
} PACKET_CA_LOGIN;
....

sizeof(...) will be used to get the correct size, based on the PACKET_VER and preprocessor directives. Any opinions?

Link to comment
Share on other sites


  • Group:  Developer
  • Topic Count:  28
  • Topics Per Day:  0.01
  • Content Count:  547
  • Reputation:   270
  • Joined:  11/08/11
  • Last Seen:  

At last another update on your topic. :D

I think that the preprocessor directives fit in well, but there is one problem. How do you intend to deal with packets that have variable packet length?

Since you use a modular system, why dont you write an interface for each packetversion and let it handle the work. Why a interface for each packetversion? Since there are different functionalities for nearly all packetversions I think that is needed. That would also provide you and the users with the posibilty to change packets for different packet versions on their own and not only this but you would not have to think about any packet structures, since it would all be handled by the module itself.

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  6
  • Topics Per Day:  0.00
  • Content Count:  61
  • Reputation:   153
  • Joined:  11/10/11
  • Last Seen:  

I am currently working on a test program for the network management using boost::asio. The size of a packet structure has still to be set by the developer itself. My goal is to provide a very simple approach which is easy to modify. For example, here is a snapshot how it currently looks like:

 RoPackets::PACKET_CA_LOGIN login_packet = {0};

 login_packet.packet_id = 0x0064;
 login_packet.Version = 20;
 login_packet.clienttype = 1;
 memcpy(login_packet.ID....
 memcpy(login_packet.Passwd....

 NetworkManager::getSingleton().send(&login_packet, sizeof(RoPackets::PACKET_CA_LOGIN));

As you can see, the developer has to decide what size the packet has. The sizeof() operator just helps in simple packets. The network manager kind of takes the burden of having different interfaces. He takes the incoming packets and redirects them to the proper functions. It's up to the user to decide what function shall be called.

Edited by Shinryo
Link to comment
Share on other sites


  • Group:  Developer
  • Topic Count:  28
  • Topics Per Day:  0.01
  • Content Count:  547
  • Reputation:   270
  • Joined:  11/08/11
  • Last Seen:  

Seems pretty ok. You seem to have a nice way of coding all in all, for example using design patterns. ;)

It is my mistake that you got me wrong. I do not think that the sending packets are a problem. But for receiving it could get troublesome with those structures.

How do you plan on reading incoming packets? Read the packet ID and a switch/ifelse for working with the incoming packet?

But all in all, I personally like the idea better, that the network manager consists of a method called for example "login" which gets some parameters like username as string and all others that are needed and the packet is created within this method not somewhere in the GUI code. Do you get what I mean?

Because of my post above, I just thought over it again and came up with the idea of using a single interface for packet version and use the newest functionality for all elder packet versions too and simply drop calls to methods that arent supported by the packet version. You could therefore even provide a debug option to log such calls. All in all it will end in a call of a Singleton send call after all for sending a packet, but the code itself would be a lot cleaner, dont you think?

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  6
  • Topics Per Day:  0.00
  • Content Count:  61
  • Reputation:   153
  • Joined:  11/10/11
  • Last Seen:  

Thanks! :)

I see the point of having a central place where all the network stuff gets together. The interface part could result in redundant code, though. For example: let's say I have a packet xyz that has changed. For this to work, the new packet has to override the old one (plain inheritance, etc) and may have only one or two lines changed. Bringing this further, there could also be a packet builder, that notifies another class to send as soon as the packet has been build based on the packet version. This would, however, add further complexity which might become an overkill.

The past has shown, that some new packets share some common parts with older packets, but not with those packets that might have been used between these two versions. Furthermore, it might get hard to revert simple changes without creating a whole clone of a specific version in case of simple customization.

Another approach might be to allow packet redirection for custom code implementation, while the network manager still takes the positon as the central point. It needs only a map with packet id and the proper function pointer to work. A function like NetworkManager::getSingleton().registerPacket(packet_id, function) would be used in the initialization part. Based on the PACKET_VER macro, it could also redirect to the proper function which would have your suggested behaviour and still the simplicity to modify custom stuff.

Link to comment
Share on other sites


  • Group:  Developer
  • Topic Count:  28
  • Topics Per Day:  0.01
  • Content Count:  547
  • Reputation:   270
  • Joined:  11/08/11
  • Last Seen:  

I dont know why, but somehow I cant read your post in here. Seems like the boards has some issues since the update, so I read it on your profile page.

I like that idea of the register function. It would come in handy for customizations, but all in all that shouldnt be the first target of your project. I know that my version will result in redundant code, but I am a friend of clean code and I hate using preprocessors multiple times within a single function, like in network part of the eA/rA source. It becomes quite messy for me.

After all I would suggest you to keep it as modular as possible and to only implement the latest packet version to start with, because right now we need an up to date client and the support of the latest packet version. This would also give the rA developers an incentive to support the latest packet version and implement it. Since I know your good with reverse engineering too I think that would not be that much of a problem for you I guess.

Because of your idea with the register function I would change my idea to only create an interface with a function like:

public void register( Networkmanager manager );

So that each packet version class itself registers only the packets and function it needs itself. But after all my idea is something you can like or not, its just my opinion of clean code but I know that the opinions on these kind coding style differ.

Anyway I like your work so far and hope you keep it up and get it through, so there can finally be a custom ragnarok client. :)

Edit: Trololol. The board is trolling me, right after I wrote this post I got to see the 5th page and with it your post. :D

Edited by Lemongrass
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  6
  • Topics Per Day:  0.00
  • Content Count:  112
  • Reputation:   89
  • Joined:  11/12/11
  • Last Seen:  

I am currently working on the network management. There were questions how the packets will be structured. Here is an example:

namespace RoPackets
{
#pragma pack(push, 1)
typedef struct _0x0064
{
 short packet_id;
 unsigned long Version;
 unsigned char ID[24];
 unsigned char Passwd[24];
 unsigned char clienttype;
} PACKET_CA_LOGIN;
....

sizeof(...) will be used to get the correct size, based on the PACKET_VER and preprocessor directives. Any opinions?

I've been waiting for the networking part.

Also, wouldn't you be better off making your own packetver?

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  6
  • Topics Per Day:  0.00
  • Content Count:  61
  • Reputation:   153
  • Joined:  11/10/11
  • Last Seen:  

Indeed, but the client shall be able to connect to an official server too. Maybe a custom packet version (which has to be recognized by rAthena server in the end) with support for official servers would be the way to go.

@Network:

I have finished the send/recv operations in the network manager with boost::asio and implemented a network handler (the central part) which acts as a packet database (registers all known packets at initialization with pre-set sizes, so that you can either set the size of a packet manually as soon as you're sending it or take the size from the database) and handles the incoming and outgoing packets. This database also contains function pointers. The register function will replace the information in the database and return the db entry with the old function pointer, etc. With this, you can easily hook into a packet, call the old function and operate with your custom implementation. It is up to you whetever you want to redirect the packet to a static or a member function (using boost::bind). Besides that, there's also the possibility to exchange the function pointers of packet ids based on preprocessor directives to counter Gravity's never ending random packet shifting.

Here is an example:

registerPacket(0x0069, -1, boost::bind(&NetworkHandler::recv_0x0069_PACKET_AC_ACCEPT_LOGIN, this, _1));

Also, the login process is almost complete. Some screenshots will follow soon! :)

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  8
  • Topics Per Day:  0.00
  • Content Count:  29
  • Reputation:   1
  • Joined:  12/31/11
  • Last Seen:  

heh. Just by reading and looking at the images, I just can't wait for the release.hehe.

Keep up the good work and good luck!

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  3
  • Topics Per Day:  0.00
  • Content Count:  28
  • Reputation:   1
  • Joined:  05/09/12
  • Last Seen:  

I got curious about having custom mods in this client. Could it be easy to implement a way to add higher resolutions for images and then have them resized to scale with ROs standard resolutions images? I mean could this be done fto make "HD" sprites of the normal sprites?

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  6
  • Topics Per Day:  0.00
  • Content Count:  61
  • Reputation:   153
  • Joined:  11/10/11
  • Last Seen:  

Actually, not. The dimensions of a sprite follow a defined pixel ratio (0.1428571492433548f to be exactly), which is multiplicated with the dimensions of the sprite. Since everything else is based on unified sizes it's pretty easy to support high resolution sprites (just one line to change). However, you would still have to save the information about additional pixel ratio somewhere. The best solution would be to implement a lookup table where custom pixel ratios are saved for specific sprites. For example: Let's say you have a sprite with the dimension 100x100 pixel. If you recreate this one to 200x300, you would set the pixel ratio to 2.0f for width and 3.0f for height.

So yes, it's actually pretty easy to modify a lot with just a few changes.

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  3
  • Topics Per Day:  0.00
  • Content Count:  28
  • Reputation:   1
  • Joined:  05/09/12
  • Last Seen:  

I see, so if this were to be implemented I'd have to either code a module with a custom table that tells the client to process specific images in a specific manner. Would it be more dofficult to add metadata on the .spr files themselves and have the custom client look for this information before loading/showing the image?

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  6
  • Topics Per Day:  0.00
  • Content Count:  61
  • Reputation:   153
  • Joined:  11/10/11
  • Last Seen:  

You could indeed create a new sprite version and append some further information at the end of sprite files. I recommend to use 0xFFFF to prevent version collision if gravity shall decide to add new versions ever. This would result in even less code changes, but would prevent the original client from using those sprites (if even desired).

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  3
  • Topics Per Day:  0.00
  • Content Count:  28
  • Reputation:   1
  • Joined:  05/09/12
  • Last Seen:  

I'm not worried much about sprites being non-compatible with other clients... even officials. It's not like they couldn't simply be kept in "raw" (PSD, PNG, BMP, etc) for porting to other clients should it be necessary. Then again, it'd be pretty odd for someone to add "HD" sprites in a normal client that would probably wouldn't understand how to process the image anyways... might wind up showing a giant player character or a strangely disproportionate gear on a character.

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  9
  • Topics Per Day:  0.00
  • Content Count:  379
  • Reputation:   304
  • Joined:  11/10/11
  • Last Seen:  

You can already add HD sprite in the official client :

- The sprite file support RGBA image type, so not need to be limited to a palette of 256 colors.

- You can create a large sprite, and scale it after using the act file property.

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  7
  • Topics Per Day:  0.00
  • Content Count:  133
  • Reputation:   189
  • Joined:  05/20/12
  • Last Seen:  

A possible solution for higher quality sprites is to upscale the sprites with the scale2x algorithm. I've done some testing that gave pretty good results. You can see a quick demo I made with canvas here (very heavy load and Chrome only, the other browsers smooths the image, ruining the desired result). If you're looking into cell shading this could probably help to give a nice cartoonish effect. :)

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  6
  • Topics Per Day:  0.00
  • Content Count:  112
  • Reputation:   89
  • Joined:  11/12/11
  • Last Seen:  

This client has to allow for the creation of custom windows. It has to. It might just be me, but I feel like a lot of ideas that I want to implement on the server side are limited by the fact that the client doesn't have a proper interface to handle it.

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  6
  • Topics Per Day:  0.00
  • Content Count:  61
  • Reputation:   153
  • Joined:  11/10/11
  • Last Seen:  

It's pretty easy to create custom windows in my current implementation. For example: If you want to send a packet from server to client and the client shall pop up a window (not important what kind of window), you just have to create a static or a member function wherever you like, register the new packet through the network handler and bind the packet to your function. In this function you can load the window either from an xml layout or create the window in code. :)

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  6
  • Topics Per Day:  0.00
  • Content Count:  61
  • Reputation:   153
  • Joined:  11/10/11
  • Last Seen:  

@KeyWorld:

The original client does not seem to support the operations (scaling and rotation) inside the act format when the sprite is being projected onto a window. So if he scales the sprite images up and reduces the size inside the act format, all sprite images in the login interface (which might not be important) and others (equip window, skill window, etc.) will have huge sizes.

@curiosity:

I had implemented a shader quite some time ago that allowed me to change the colors of sprites based on a 1D texture lookup. This forced me to also implement a bilinear texture filtering shader which worked fine. It had some glitches when moving around, though. I just recently understood the half texel problem which might have been the cause, but it's basically possible to implement such scaling filters without big issues.

@Project:

I have improved the networking part and added some little features like mouse freedom. The login interface is almost complete. I have created an interface to create cegui windows with animated sprites and investigated the correct usage of actors. The probably most important part: I have cleaned up the project configuration for visual studio. There is now a dependencies folder containing all necessary 3rd party libraries (boost, ogre, cegui, lua, luabind, etc) that you can download seperately (16.6 MB as compressed zip file). As soon as the source gets released, you can just checkout the repository and it will compile just fine without the need for downloading any libraries. However, I provide only precompiled windows libraries for now, since I don't have enough time to focus on creating linux and mac libraries. This will follow when I have more free time.

Here's also a screenie showing some progress. I will make a video soon:

screenshot05252012_21jpx40.png

Edited by Shinryo
  • Upvote 1
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  26
  • Topics Per Day:  0.01
  • Content Count:  2244
  • Reputation:   182
  • Joined:  11/19/11
  • Last Seen:  

awesome!

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  146
  • Topics Per Day:  0.03
  • Content Count:  1195
  • Reputation:   467
  • Joined:  11/15/11
  • Last Seen:  

Is it my eyes or is the text there using anti-aliasing?

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  14
  • Topics Per Day:  0.00
  • Content Count:  139
  • Reputation:   10
  • Joined:  11/10/11
  • Last Seen:  

That is one hell of a client! Keep up the good work! /oops

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  28
  • Topics Per Day:  0.01
  • Content Count:  562
  • Reputation:   152
  • Joined:  02/21/12
  • Last Seen:  

*fap fap fap fap fap*

sweetjesusa81c9b86jpg.jpg

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  6
  • Topics Per Day:  0.00
  • Content Count:  61
  • Reputation:   153
  • Joined:  11/10/11
  • Last Seen:  

@Maki:

Yes. The text can also be changed within XML files and thus allows easier translation without the need to modify hundrets of textures, since they are split apart. This means you can have different language files using the same skin.

@Rest:

Thx! :)

@Project:

I'm currently adding LUA support. The idea of using lua files was a great step by Gravity, the only pitfall is that those files are messed up and it's pretty hard to keep compatibility with old and new client versions. For example: Take a look into "lua files/admin" and "lua files/datainfo". I haven't tracked down if the original client dropped "lua files/admin" and uses "lua files/datainfo" instead (especially for the function ReqJobName). Those in the admin folder have wrong display names and have probably been used when the data was placed in msgstringtable, while the jobnames in the datainfo folder are split into man and woman tables, using translations for spain?

The probably best solution would be to recreate custom lua files that are clean and structured. This would, indeed, create the need of merging information from official lua files into the custom files. But this doesn't really matter since the official files have to be reversed anyway. Any thoughts?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...