Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

Godlord

Members
  • Posts

    5689
  • Joined

  • Last visited

    Never

Posts posted by Godlord

  1. > look at a premade code and figure it out from it?

    Good luck with that. You'll have to understand numerous concepts related to both advanced computer graphics and linear algebra if you want to take that route.

    > Does anyone know of a good article that explains the logic behind Shaders, it doesn't necessarily have to be oriented to SFML, as I'm pretty sure the logic is universal. I really don't want a link to some pre-made code, as I want to figure this out myself; I've tried looking around and I just can't find anything that would explain it to me.
    >
    > Regards,
    >
    > GP

    SFML is just a cross-platform library that simply offers an abstract interface to deal with graphics, sound, etc. However, it doesn't really do anything with shaders. If you want to learn about writing shaders for OpenGL, then you can find more information at the following websites:

    * http://www.arcsynthesis.org/gltut/index.html
    * https://en.wikibooks.org/wiki/OpenGL_Programming

    Yours faithfully

    S.J.R. van Schaik.
  2. SDL doesn't really offer any functions to tint images. However, there are a few ways to do it. The most obvious and fastest way to do it is to simply use OpenGL. Alternatively, you can also write your own function that applies the following formula to your images: dst_colour = src_colour * blend_colour / 255; However, since that operation has to be done in software, it is going to be painfully slow. Finally, the way used for old games is to have multiple palettes, where you'd dim the background by simply switching to another palette for that image or those images (of course, you'll need images where the palette indices are specified within the pixels, rather than the colours directly).

    Yours faithfully,

    S.J.R. van Schaik.
  3. > Did a bit of research and wow, thanks for bringing it up. Never heard of it before.

    Or QueryPerformanceCounter(), if you can deal with all of its pitfalls (or if you don't care about them).

    Yours faithfully,

    S.J.R. van Schaik.
  4. > Nothing closed-source, please! Everything should be open-source. (:

    This seems to be yet another case of **[security through obscurity](http://en.wikipedia.org/wiki/Security_through_obscurity)**.

    > Tile Engine:
    >
    > Maps themselves will be tile based. Using 32x32 pixel tiles. We will keep the standard Eclipse layers, Ground, Mask and Fringe Layer(s). We will essentially use a similar style to the existing Eclipse method for saving/loading maps. I'm not a fan of all the small maps and having to warp around when you reach map edges, so I'd like the possibility for very large maps, like 200x200 or larger maps. That being said, editing maps on the live server here would be hectic and sending updates to all clients would be a pain in the ass. I propose we use stray away from the current Eclipse method and use Offline tools for game development. So there would be a map editor, an item editor, etc that are all standalone applications. The method for getting maps client side would be fairly simply, it'll check to see if the .map exists client side, if not, it'll download the map from the server, essentially meaning that the first time the player ever joins a large map, a 'Downloading Map %' message would appear. We would also give people the option to download these maps during random events within the client, so as a player is walking around on a different map, it's syncing any maps that the player does not already have downloaded.

    For large maps, I would personally implement a seamless map system, where a map consists of multiple zones with a size of 50x50, for instance. The client will then have a cache that contains the eight surrounding zones, next to the current map. That way you can reduce the amount of loading screens to a minimum. However, keep in mind that you will still have to support the possibility of having multiple maps, where those maps are to be constructed from multiple zones, which will act like tiles for those maps.

    I don't think online editors are a bad idea per se, unless you take the amount of executable bloat into account, of course. If I am not mistaken, Eclipse tends to send every edit from the client to the server, whenever these editors are used. This is generally a bad idea as that will cause a lot of network traffic to be going on. Instead, it would be a better idea to simply cache the local changes, until the edit is being saved, whereupon the changes are being send to the server. In order to reduce the network traffic, it is likely that you want to use delta compression, though. However, that doesn't mean that I am against offline editors, it's just that a good implementation of online editors will share the exact same properties, except for the modularity.

    > Player Movement:
    >
    > I'd like to see player movement pixel based however this is just personal preference, I think it adds a lot to the game. To save on network traffic, the method I've come up with for movement is based on large MMO style games. The movement commands are sent at 3 different stages. 1\. When a player starts walking. 2\. When a player changes direction 3\. When a player stops movement. It will also send the movement speed. What this does is make movement client side, rather than the players x,y position being sent from the client > server > to map a few times every second, this method only sends data at the starting, stopping or changing direction.

    Yes, that's a better idea than the current movement system that is present within Eclipse.

    Alternatively, you can also decide to implement a point 'n' click system, based on the [networking model for Age of Empires](http://www.gamasutra.com/view/feature/3094/1500_archers_on_a_288_network_.php). Basically, you stack up all the movement commands with the final position in a command frame, which is then send to the server. From time to time, the server will then distribute these command frames to all the players to whom these commands are relevant. That way, they can all execute the movement as a simulation just as is done in real-time strategy games. Furthermore, to reduce the amount of network traffic, you can decide to update the position of a unit that has already been ordered to move somewhere, when that unit has been ordered to move somewhere else. On top of that, you can also implement waypaths as is present in some real-time strategy games as well.

    > I've only thought of one problem with the possible movement system.
    >
    > Lets setup a scenario with two players, Player 1 and Player 2.
    >
    > If I understand your planned system correctly, this is how it could play out.
    >
    > Player 1 and 2 are on the same map, player 1 moves up and the client sends the packet, and tells player 2's client that that person is moving. Moving them every x seconds until the stop command is received.
    >
    > Well lets say player 1 takes a few seconds after that player has already stopped to send that stop packet, wouldn't that cause player 2 to see the player jump back/forward when they finally do get that command?

    That's only a problem if you use TCP with the Naggle algorithm enabled (or if you are Australian), in which case your latency will be about 400ms, if you provide insufficient data to be sent across the wire. Otherwise, it wouldn't be difficult to get latencies of about 50ms to 100ms, in which case those jumps are less noticeable.

    > One major problem that I foresee with the revisions of maps idea, is that if we store a variable in the map cache files, it could easily be modified in order to gain advantage in or even damage the game as a whole.
    >
    > I think some sort of encryption will be a must for the map cache.

    In what way can revisions be exploited? Sure, you can change the local map, which will only change the visual representation, as the server will match all your actions against its own maps.

    > You do that. Just don't use SHA encryption methods, they are intentionally made to be slow to prevent brute forcing for passwords. Stick to your standard MD5, or even write your own quick algorithm. ![:P](http://www.touchofdeathforums.com/community/public/style_emoticons/<#EMO_DIR#>/tongue.png)

    SHA1 is as standard as MD5 is for files. However, the most standard algorithm to validate files is probably going to be CRC32.

    Yours faithfully,

    S.J.R. van Schaik.
  5. > Wouldn't I still need to copy the data from the buffer? It's not guarenteed that realloc will use the same area of memory, right?

    realloc will copy over the memory, if it can't extend the current chunk of memory.

    > Also, you're "next_power_of_two" will not work on numbers that are already powers of two.

    It will, actually, as it doesn't decrement the input before filling in the right-hand side with ones. However, that is the behaviour of next_strict_power_of_two in my repository (I intended to actually show you the one that does have the same behaviour as you described):

    ```
    size_t cdl_next_power_of_two(size_t input) {

    size_t index;

    --input;

    for (index = 1; index < sizeof(size_t); index <<= 1) {

    input |= input >> index;

    }

    return ++input;

    }
    ```

    Yours faithfully,

    S.J.R. van Schaik.
  6. Normally, Microsoft Windows will look in the same path as where the executable is located for those system libraries. Therefore you normally won't have to register them. However, you might want to try registering them, as it won't do any harm.

    Yours faithfully,

    S.J.R. van Schaik.
  7. It's kind of hard to pin-point the exact cause, as the process consists of multiple steps:

    * Read the local INI file for the local version.
    * Download and read the remote INI file for the current version (possible problem: downloading may not work due to insufficient rights; msinet.ocx may be missing).
    * If the local version does match, exit the process.
    * Download the RAR-package (possible problem: downloading may not work due to insufficient rights; msinet.ocx may be missing).
    * Extract the RAR-package (possible problem: unrar.dll may be missing).
    * Update the local INI-file (possible problem: writing may not work due to insufficient rights).

    Yours faithfully,

    S.J.R. van Schaik.
  8. > I know, it does ask it then, but it still doesn't correctly update the files then.
    >
    > I though doing it this way would make it do it correctly, but is that true?

    You might want to check what kind of errors you are getting when updating the files. As I can't be entirely sure whether the source of the problem is the lack of administrator rights or not. Although, in this specific case, it doesn't seem to be.

    Yours faithfully,

    S.J.R. van Schaik.
  9. > Oh I'm sorry I didn't saw the difference. xD
    >
    > EDIT: So it did worked now but is this thesame as running a programm as admin, because when I run it as admin it also does it wrong.

    Basically, it should ask the user whether he or she wants to run the programme as an administrator or not, because that's how UAC works.

    Yours faithfully,

    S.J.R. van Schaik.
  10. Re-allocating and copying memory are slow operations. Therefore, you'll want to rewrite your resize-method in such a fashion that it can accept the amount of bytes that have to be stored. That way, you won't have to use a loop where you keep re-allocating the buffer until you have found a size that satisfies your demand. Additionally, you want to compute the next power of two, as sizes that are a power of two are favoured when using the heap. Furthermore, being able to compute the next power of two allows you to implement greedy allocation in a straight-forward fashion. In order to compute the next power of two you can use the following function from my library:

    ```
    size_t next_power_of_two(size_t input) {

    size_t index;

    for (index = 1; index < sizeof(size_t); index <<= 1) [

    input |= input >> index;

    }

    return ++input;

    }
    ```

    On top of that you are currently using the C++ allocation operators. These are only useful when you want to allocate objects, as they will invoke the constructors and destructors automagically for you. Otherwise, you will simply want to use malloc, calloc, realloc and free instead:

    * realloc allows you to resize buffers more easily (if possible, it will simply extend the current chunk of memory, rather than allocating a new one).
    * There is no distinction between single entities and arrays, as is the case with the C++ allocation operators.
    * The C++ allocation operators are likely to call malloc and free anyway.

    So in the end, your resize method will look like this:

    ```
    bool ByteStream::resize(size_t size) {

    char *data = NULL;

    size = next_power_of_two(size);

    if (this.size == size) {

    return true;

    }

    data = (char *)realloc(size);

    if (data == NULL) {

    return false;

    }

    this.data = data;

    this.size = size;

    return true;

    }
    ```

    Additionally, your naming convention is confusing, as you tend to use the same style (capitalised camelcase) for both classes and methods. I'd encourage you to use capitalised camelcase (e.g. FooBar) for classes, and plain camelcase (e.g. fooBar) for methods.

    If your goal is to read data from files, or write data to files (or across the wire), then you will have to use stdint.h, as this header will define the following types for you:

    * int8_t: signed 8-bit integer.
    * int16_t: signed 16-bit integer.
    * int32_t: signed 32-bit integer.
    * int64_t: signed 64-bit integer.
    * uint8_t: unsigned 8-bit integer.
    * uint16_t: unsigned 16-bit integer.
    * uint32_t: unsigned 32-bit integer.
    * uint64_t: unsigned 64-bit integer.

    Furthermore, you will have to deal with endianness, as some architectures use big endian (e.g. some POWER-processors) rather than little endian (e.g. all x86-processors).

    Additionally, you want to avoid storing floats and doubles, directly. As these are encoded differently per architecture as well. My suggestion here is to encode and decode them as IEEE-754 32-bit and 64-bit floating-point numbers respectively. You will also want to avoid using structures directly, as the compiler may introduce padding to ensure that the processor can efficiently access the members within the structure. Therefore, I encourage you to use the members of the structure instead.

    Finally, you don't want to use integers to represent memory sizes, as integers may not be sufficiently large enough to represent every possible memory address. Instead, you'll want to use size_t to represent memory sizes.

    Yours faithfully,

    S.J.R. van Schaik.
  11. In order to elevate your process during run-time, you have to import "ShellExecuteEx" from shell32.dll and declare a structure that looks exactly like [this](http://msdn.microsoft.com/en-us/library/windows/desktop/bb759784%28v=vs.85%29.aspx). You will then have to set up that structure before calling the function, these are required to set up an elevated process:

    * Set lpVerb to "runas".
    * Set lpFile to the path of the executable (which can be found by using GetModuleFileName, which can be imported from kernel32.dll).

    You can then use this code to create new processes (http://stackoverflow.com/a/4762460):

    ```
    Public Enum ShowConstants

    SW_HIDE = 0

    SW_NORMAL = 1

    SW_SHOWMINIMIZED = 2

    SW_SHOWMAXIMIZED = 3

    SW_SHOWNOACTIVATE = 4

    SW_SHOW = 5

    SW_MINIMIZE = 6

    SW_SHOWMINNOACTIVE = 7

    SW_SHOWNA = 8

    SW_RESTORE = 9

    SW_SHOWDEFAULT = 10

    End Enum

    Private Type SHELLEXECUTEINFO

    cbSize As Long

    fMask As Long

    hwnd As Long

    lpVerb As String

    lpFile As String

    lpParameters As String

    lpDirectory As String

    nShow As Long

    hInstApp As Long

    lpIDList As Long

    lpClass As String

    hkeyClass As Long

    dwHotKey As Long

    hIcon As Long

    hProcess As Long

    End Type

    Private Declare Function ShellExecuteEx Lib "shell32.dll" Alias "ShellExecuteExA" (pExecInfo As

    SHELLEXECUTEINFO) As Long

    Public Function ExecuteProcess(ByVal FilePath As String, ByVal hwnd As Long,

    ByVal nShow As ShowConstants, Optional lpParameters As String = "",

    Optional LaunchElevated As Boolean = False)

    Dim ExecInfo As SHELLEXECUTEINFO

    On Error Goto Hell

    With ExecInfo

    ' Set up the structure.

    .cbSize = Len(ExecInfo)

    .fMask =

    .lpFile = FilePath

    .nShow = nShow

    .lpDirectory = ExtractDirectoryFromPath(FilePath)

    .lpParameters = lpParameters

    .hwnd = hwnd

    ' On Microsoft Windows Vista and later, one can use runas instead of Open, in order to execute the

    ' process as an elevated process. In that case, the user will be asked whether he or she wants to

    ' run the process as an administrator.

    If LaunchElevated = True Then

    .lpVerb = "runas"

    Else

    .lpVerb = "Open"

    End If

    End ExecInfo

    ExecuteProcess = ShellExecuteEx(ExecInfo)

    Exit Function

    Hell:

    ExecuteProcess = False

    End Function

    Private Function ExtractDirectoryFromPath(Path As String) As String

    On Error Resume Next

    Dim Position As Long

    ' Find the right-most slash.

    Position = InStrRev(Path, "\")

    ' Extract everything on the left.

    ExtractDirectoryFromPath = Left$(Path, Position - 1)

    End Function
    ```

    Additionally, you will have to check if the running process does have administrator rights, as you won't

    have to elevate the process if it does. For this you will have to use AllocateAndInitializeSid, FreeSid and CheckTokenMembership which can all be imported from advapi32.dll (http://stackoverflow.com/a/4762460):

    ```
    Private Const SECURITY_BUILTIN_DOMAIN_RID As Long = &H20

    Private Const DOMAIN_ALIAS_RID_ADMINS As Long = &H220

    Private Declare Function AllocateAndInitializeSid Lib "advapi32.dll" (pIdentifierAuthority As Any,

    ByVal nSubAuthorityCount As Byte, ByVal nSubAuthority0 As Long, ByVal nSubAuthority1 As Long,

    ByVal nSubAuthority2 As Long, ByVal nSubAuthority3 As Long, ByVal nSubAuthority4 As Long,

    ByVal nSubAuthority5 As Long, ByVal nSubAuthority6 As Long, ByVal nSubAuthority7 As Long,

    lpPSid As Long) As Long

    Private Declare Sub FreeSid Lib "advapi32.dll" (ByVal pSid As Long)

    Private Declare Function CheckTokenMembership Lib "advapi32.dll" (ByVal hToken As Long,

    ByVal pSidToCheck As Long, pbIsMember As Long) As Long

    Private Type SID_IDENTIFIER_AUTHORITY

    Value(0 To 5) As Byte

    End Type

    Private Function IsAdministrator() As Boolean

    Dim NtAuthority As SID_IDENTIFIER_AUTHORITY

    Dim pAdministratorGroup As Long

    Dim lResult As Long

    NtAuthority.Value(5) = 5

    If AllocateAndInitializeSid(NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_AlIAS_RID_ADMINS, 0, 0,

    0, 0, 0, 0, pAdministratorGroup) <> 0 Then

    If CheckTokenMembership(0, pAdministratorGroup, lResult) <> 0 Then

    IsAdministrator = (lResult <> 0)

    Exit Function

    End If

    Call FreeSid(pAdministratorGroup)

    End If

    IsAdministrator = False

    End Function
    ```

    You can then use this code to elevate your own process:

    ```
    Public Const MAX_PATH = 206

    Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (

    ByVal lpModuleName As String) As Long

    Private Declare Function GetModuleFileName Lib "kernel32" Alias "GetModuleFileNameA" (

    ByVal hModule As Long, ByVal lpFileName As String, ByVal nSize As Long) As Long

    Public Function SelfElevate() As Boolean

    Dim FilePath As String

    Dim hModule As Long

    Dim lResult As Long

    FilePath = Space$(MAX_PATH)

    hModule = GetModuleHandle(App.EXEName)

    lResult = GetModuleFileName(hModule, FilePath, MAX_PATH)

    If lResult = 0 Then

    SelfElevate = False

    Exit Function

    End If

    If IsAdministrator() Then

    SelfElevate = True

    Exit Function

    End If

    SelfElevate = ExecuteProcess(FilePath, 0, SW_NORMAL, "", True)

    End Function
    ```

    Yours faithfully,

    S.J.R. van Schaik.
×
×
  • Create New...