Jump to content

Shinryo

Members
  • Posts

    61
  • Joined

  • Last visited

  • Days Won

    8

Everything posted by Shinryo

  1. Nope. Still ongoing. Made some heavy cleanups and will release some binary prototypes soon.
  2. What kind of a bug is it? Maybe it got fixed in recent webkit versions. Qt 5 also allows to embedd a webview based on webkit, which basically would give the same benefits as Awesomium or Berkelium.
  3. Still ongoing. Abandoning this project in its current state would be a crime to myself. I was just very busy in the last few months with my new job and playing Tera Online, lol. However, I have stopped playing MMORPGs in general and like to spend my free time with the development of the client to improve my virtual reality knowledge. I have reviewed some scripting engines like LUA, AngleScript, Python, etc. As far as I remember, V8 is the rendering engine behind Chromium? Might take a look at it. I've spent the last few days to also review some GUIs which would not be a performance bottleneck. CEGUI is indeed easy to use through it's XML structure, but it also introduces some limitations for transitions or animations. Awesomium (used in Fimbulwinter Client) and Berkelium allow to render Chromium inside an offscreen buffer and therefore allow to create animations and transitions based on CSS3 and HTML5. But the performance of blitting the rendered offscreen back to a texture might slow down the client too much, especially in high resolutions (like 1920x1080). Another approach would be to use QML with Qt5 for GUI rendering which includes animations and transitions. It renders directly to a framebuffer object and is therefore pretty fast. But this works only with OpenGL. I don't plan to insert such limits. Quite the opposite, I plan to add further 3D file formats to not only support Granny3D objects. Yep. I have yet to decide from what version upward. Nope. ------------------- Some notes: As already mentioned, I have not yet decided which scripting engine to use. I also struggle whetever I shall drop DirectX support and continue GUI development with Qt 5 and QML, based on OpenGL and Ogre3D. It seems like Qt 5 has also support for V8. On the other side, I cannot depend on V8 from Qt, since the current codebase is split into core, rendering, networking, scripting, etc. So the scripting part will be gone if someone decides to replace the Ogre3D and Qt 5 rendering with a custom rendering engine. Mhm... My best bet would probably be: - Rendering: Ogre3D, OpenGL only, Qt 5 and QML - Scripting: AngleScript - Networking: Boost.Asio Oh, and as a side note: I have forked the core module into an editor module yesterday, which uses the same rendering and scripting modules. The main purpose is to allow easier debugging of visual artifacts. It might become a full fledged map editor though.
  4. No, the project is far away from being dead. I've got a new job more than a month ago and this caused the project to slow down quite a bit. I've spent a lot (and I mean a lot) time with investigating a good way to allow scriptable effects (since I'm too lazy to implement all of them myself) that can be created easily even by non-developers. I think this is one of the most crucial steps to make this project a success. Everything else (besides rendering itself) is just some easy stuff. Also, there was a major cleanup which allows everyone to customize almost everything they want easily. I've splitted the code base into two seperate projects, which consist of the rendering part (world, gui, ...) and the content creation (networking, data storage, ...). These can be used like frameworks or be completely replaced without breaking the other part. For example, someone could inherit the content creation and add advanced control that allows to interact with a modified rendering part which displays 3D characters that move around like inside a first person shooter. Both parts are combined inside a core library, which represents the controller. So yes, the project now uses the MVC pattern and everyone of you should know yourself what benefits this has. Here are two small screenies. But don't expect too many visual improvements, since I have worked more on the code instead of the rendering. And don't worry, I will still make sure to release the source code as soon as I have either no interest anymore or when the project is in a usable (for others to develop with) state. Thanks for everyone who is supporting this project! PS: I don't have a cool project name, any ideas? I thought of WeeRagnarokClient or WeeClient, but dunno. Or maybe rMinerva Client, because of Athene and Minerva, lol.
  5. I am very happy to see that this project is going to be continued. I will try to create a list of changes that happened after r25.
  6. The screenshot that was posted before showed the part where the function "GrannyVersionsMatch" was called by the client. The conditional check was replaced with NOP instructions in order let the client always accept the version, regardless of the result returned by "GrannyVersionsMatch". I think you might know yourself that this is not a good solution, unless new Granny3D versions really support those files from version 2.1.0.5 (I don't know much about Granny3D). Basically, you have to find out to which virtual address the function "GrannyVersionsMatch" is gonna be relocated upon client startup. E.g. 0084D860 (for RagexeRE 2012-05-08). Somewhere within the client, there must be a call to this address. So you have to search with a hex editor for "FF 15 60 D8 84 00". The first two bytes are the call, the last 4 the address (reversed order). If you have found the correct position, skip 8 bytes and replace the next coming byte with EB. This should be sufficient. You can also replace the whole call (FF 15 60 D8 84 00) with B0 01 90 90 90 90. GrannyVerionsMatch fills the lower part of the AX register with 1, when the version is correct. The previous edit will force it to be always 1. It's pretty hard to get the correct virtual offset of the "GrannyVersionsMatch" function on your own, if you are not experienced with import tables and dll files. Therefore, you should first read some notes on google (import tables rva dll, etc.). E.g. http://www.sunshine2...s/tut_rvait.htm. You could also get your hands on IDA (The Interactibe Disassembler) and let it calculated all needed offsets for you (search for the function afterwards and jump to the position where it is being called). Edit: Here are also some screens that might help you: This is how it looks like in IDA: This is how it looks like if you replace the conditional jump: And this is how it looks like when you replace the call itself:
  7. You want to be able to use custom 3D models. You also showed a video where custom 3D models are used. You even have a screenshot with a hexedit to bypass the version check of the dll. So.. what's exactly the problem now?
  8. Hair sprites don't need a table. Everything else looks like this: PcIdTable = { ... JT_KNIGHT_H = 4008, ... } PcNameTable = { ... [PcIdTable.JT_KNIGHT_H] = "Lord Knight", ... } PcSpriteNameTable = { ... [PcIdTable.JT_KNIGHT_H] = "·Îµå³ªÀÌÆ®_", ... }
  9. It's up to you if you want this behaviour.
  10. I have implemented a lua state class which acts as the interface you have mentioned. The custom client will read all lua related stuff (*.lua > *.lub) from a folder called "scripts" which resides at the root folder of the client. This folder is split into "tables" and "functions" which again contain lua files that are related to either pc, map, accessory, etc. Here's an example of a function I am currently using to get the hair sprite path: GetPcHairSpritePath = function(hair_id, male) local prefix = "" local postfix = "" if hair_id < 1 then hair_id = 1 elseif hair_id > 27 then hair_id = 27 end if male == false then prefix = "Àΰ£Á·/¸Ó¸®Åë/¿©/" postfix = "¿©.spr" else prefix = "Àΰ£Á·/¸Ó¸®Åë/³²/" postfix = "³².spr" end return prefix..hair_id.."_"..postfix end Right now, it is even possible to create custom classes with ease. XML and LUA help a lot in creating customization which is something that I try to achieve. I also plan to export whole classes so that those can be accessed through lua (e.g. network handler, window manager, etc). Therefore an SQL like database would be only good for storing configuration stuff or paths.
  11. @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?
  12. @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:
  13. 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.
  14. 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).
  15. 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.
  16. 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!
  17. 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.
  18. 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.
  19. 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?
  20. Yes, it's actually supposed to error. actOR seems to not check for the amount of actions inside an act file and expects to have 104 of them, which are split in 13 "character animation" parts (8 directions for each part). However, these sprites have more than 104 actions and therefore actOR might throw this error. Besides that, I don't think that actOR is meant to be used for all sprite types. Only for character sprites. Might be a good idea to write a new act editor.
  21. Thanks for your interest in this project! @Maki: I will definitely add cel shading, but it has to wait until around september. I have a schedule for this project which I have to complete first. @Mysterious: I don't plan to support all available packet versions until now. The best solution is to support the most recent packets, based on the state of this client and let macro directives handle the current active version, most likely how it actually is with rAthena. However, the architectur will be different. Meyraw had a pretty nice idea. Each packet was defined as a struct, containing all relevant packet information. Something like this: struct packet_0x111 { unsigned short cmd; int index; #if PACKET_VER 20120101 char blah; #endif .... } The packet above is made-up and and doesn*t exists, btw. @Project: It actually becomes interesting, because I have started to implement further stuff besides the rendering. I've started with sprites and their animations and I can't believe that it took a whole day to find an acceptable solution for rendering the sprite billboards. As you may already know, billboards always face the camera. But what happens if the latitude of the camera changes and you're near a wall/object? Right, the billboard will be clipped by the wall. Something like this will be the outcome: http://www.abload.de...012_22j0yyy.png When you look at the original client, it looks like this: http://www.abload.de...ero0053jy5v.jpg My billboard obviously is clipped. The original client has some kind of evil magic to let the sprite be always on top of these objects (well, not so magically, but ugly). However, the best workaround I have come up so far is to modify the z value of the billboard vertices based on the camera angle and the distance from the camera to the sprite. It's not exactly the same way how Gravity does it, but it's still pretty satisfying. Here's the outcome: http://www.abload.de...012_21jfluw.png Here's some code how it could be implemented in a shader, if needed: out.position = mul(worldViewProjMatrix, in.position); out.position.z -= latitude * 2.5f / distance(out.position, cameraWorldPosition); Latitude is between 0° and 90°. The constant 2.5f has no magic behind it. The output looks better with it. Don't forget that the operation above should only be made for the upper vertices, since you might get in trouble if there is only a plane behind the character. You might end up the same way as the original client: http://www.abload.de...ero00728ja5.jpg With my client: http://www.abload.de...012_23d8e5k.png If someone needs further information, don't hesitate to ask via PM. Concluson: My solution seems to be faster and looks better then the originals. There is also no distortion with high angle views. I'm pretty satisfied.
  22. @Maki: Yes, I mean Cel Shading. It might become tricky though, since the textures have not been designed for this case. @Syouji: No, I haven't added this feature yet. However, I won't hard-code this into the client as Gravity did. @Project: I've been improving the lightmapping of my client today and did some research with the original client. As far as I can see, Gravity had problems with getting the lighting correctly themselves. That's why it is indeed a bad idea to re-implement the same buggy behavior. Furthermore, I found out that the level of my posterization filter was off by one. So the correct level is 17.0f - 1.0f (or 16, whatever). The confirmation was done with a reduced diffuse color in comodo which displays only the colormap (which is not affected by global lighting). Furthermore, I have removed all dynamical lights from comodo and saw how some object still had light affecting them. Like in this example: http://www.abload.de...ero002qvl1b.jpg I haven't found out where the blue color on the trees comes from. Diffuse colors were set to 0.1f with a black ambient color. Here's also a screen with weird shading: http://www.abload.de...ero0038molg.jpg Take note that dynamical lights (those in the RSW structure) were removed. And just for your interest: As far as I have tested, the lights in the RSW structure only affect objects, not the ground. I have also added an option to disable posterization if needed. I think the client looks better without it: http://www.abload.de...012_00ovorc.png
  23. Thank you! You can send me a map and I can load it up to make some screenshots, if you wish. Or you can wait until september, where I plan to release a binary build and the source code.
  24. Thanks! Here are some further screenshots, I'm not yet satisfied though: Izlude: http://www.abload.de/img/screenshot04252012_001ha6c.png Rachel: http://www.abload.de/img/screenshot04252012_000totr.png Comodo: http://www.abload.de/img/screenshot04252012_00b3o0e.png Dicastes: http://www.abload.de/img/screenshot04242012_21x0rx6.png Bump mapping has quite an impact on the frame rate. I'm actually thinking about a toon shader. Any opinions?
×
×
  • Create New...