Jump to content
  • Advertisement

polaris2013

Member
  • Content Count

    53
  • Joined

  • Last visited

Community Reputation

142 Neutral

About polaris2013

  • Rank
    Member
  1. Wow thanks! That explains it! The reason I was using double is because I thought it would make a difference with the <cmath> function sin(), since in my compiler the floating point version is just a macro for the double precision version of sin(). But it sounds like if the precision is changed in an internal state then it should also have changed for the sin() function as well? And that's where my problem is. Anyway, I guess the next thing I'm going to do is look up a reference implementation of sin(). Thank you SiCrane!!! edit: sorry, sin() should be atan2().
  2. This is a very strange bug and I'm wondering if anyone else is able to reproduce it. Basically I'm getting a rounding error in variables of type double, but it only occurs after the Direct3D Device is created. Here is a code sample: [source=cpp] HRESULT CEngine::InitializeD3D(HWND hWnd, UINT nWidth, UINT nHeight, bool windowed) { //front matter... Test1(); //Create a Direct3D device. if(FAILED(m_pD3D->CreateDevice(adapter, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &m_pD3DDevice))) { if(FAILED(m_pD3D->CreateDevice(adapter, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &m_pD3DDevice))) { RaiseErrorFlag("\tUnable to create Direct3D device.", 0, RET_IRRECOVERABLE); return E_FAIL; } m_pLog->WriteToLog("\tUnable to use HW Vertex Processing- Defaulting to SW Vertex Processing"); } Test1(); //back matter... return S_OK; } void CEngine::Test1() { //3.1415927 = float //3.141592654 = D3DX_PI //3.1415927410125732 = double (wrong) //3.1415926535897931 = double (right) //3.14159265358979323846 = pi (more digits) double t = 180.0; double f = 3.1415926535897932 / 180.0; double t1 = 180.0 * 3.1415926535897932 / 180.0; double t2 = t * 3.1415926535897932 / 180.0; double t3 = (double)(t) * 3.1415926535897932 / 180.0; double t4 = static_cast<double>(t) * 3.1415926535897932 / 180.0; double f1 = 180.0 * f; double f2 = t * f; double f3 = (double)(t) * f; double f4 = static_cast<double>(t) * f; if(t1 != t2) { //this statement should never execute t1 = t2; } } The first time Test1() is executed, t1-t4 and f1-f4 are all equal and they equal what I have commented above as "double (right)". The second time its executed, t1 is the only one that's correct, all the others are the value indicated as "double (wrong)", and thus the if statement evaluates to true. Compiler is VS 2005 Express. The Direct3D version is October 2006, which I know is pretty old, but I don't want to go through all the work of changing it and then have that not fix it. My suspicion is that the variable t is somehow being rounded to a float, because when I evaluated everything with floats instead of doubles I got the same answer as "double (wrong)" except with fewer digits. I don't have a 2nd computer to test with, so I was hoping somebody could help me out. Thanks!
  3. polaris2013

    Line Endings Problem in Script File

    Thanks SiCrane, but since I just got it working I'll stick with what I've got. However, now that I look at it, it makes no sense that my change fixed it. The length variable evaluates to 36 whether the file is opened as text or as binary. What changes is how the parser counts it's position (ends up at 36 when I open as binary, ends up at 33 when I open as text). That makes no sense to me at all!! Angelscript shouldn't have any understanding of how I calculated the length, or how I opened the file. But somehow it does! This is very fishy. Something else is probably at work, but I'm tired of thinking about CR LFs for now so I'm going to leave it at that. edit: Hoping Witchlord reads this: One thing about the Angelscript documentation is that it's got a great "magnifying glass" explaining how each function in used, but it lacks a good "overview" explaining how everything fits together, and the starting documentation is a bit spartan. If I may be so bold, I would be willing to write down my "newbie" FAQ and even go so far as to try to answer all of my questions (make a starter guide) to the best of my ability if it could be used to improve the documentation of Angelscript. Lord knows I've had enough problems getting started, I just hope everyone else doesn't have as much trouble as I've had! :-) [Edited by - polaris2013 on January 3, 2009 12:02:53 PM]
  4. polaris2013

    Line Endings Problem in Script File

    Ok, I feel dumb. I noticed that I tell it the script length when I was reviewing it. However, in my defense, I copied that code from the Angelscript documentation to calculate the script length, and that code doesn't work. So it's not Angelscript at fault, it's the Angelscript documentation. Either way, it resulted in a few hours of needless debugging to figure out that the problem was with the line endings in the first place. char* script; FILE *f = fopen(szFile, "r"); // Determine the size of the file fseek(f, 0, SEEK_END); int len = ftell(f); fseek(f, 0, SEEK_SET); // Load the entire file in one call script = new char[len]; fread(&script[0], len, 1, f); fclose(f); That adds 2 characters for each line ending, and the parser only reads back 1 character per line ending. Still would be simpler to have a setting in the parser, because I can't think of a better way to fix this than to read through the whole file and count the number of newlines. Or I guess I could just google something. edit: Ok simpler than I thought. Just had to change it to read binary instead of text, now both read 2 chars per line ending. This is the change: FILE *f = fopen(szFile, "rb"); Well, I just wasted a whole day changing one character in my game. What will tomorrow bring? =P [Edited by - polaris2013 on January 3, 2009 11:32:38 AM]
  5. polaris2013

    Line Endings Problem in Script File

    OK, I'm still starting out so maybe there's a setting in the Angelscript configuration I haven't found, but Windows-style line breaks don't seem to be compatible with the Angelscript parser. I can't possibly be the only one to have encountered this problem can I? And yes, I AM using the latest version 2.15! This script file builds without complaint: void main(){float a = 1.0f;}; This one fails (I put the ";" at the end so I could have a break point when the parser got to an empty statement) void main() { float a = 1.0f; }; In the first one, the function asCParser::GetToken sourcePos == sourceLength == 29 on the next call after the empty semicolon is cleared. In the second one, sourcePos == 33 sourceLength == 36 on the next call so it keeps reading and gets unrecognized tokens which cause the build to fail. --- I don't see any functions in Angelscript to change how it handles line endings, and I do know there are utilities to change between Unix-style and Windows-style line endings, but that's not the point. I want to allow users to write their own scripts and this extra step is unacceptable for that purpose. edit: accidental edit (but see next post, the issue is resolved) [Edited by - polaris2013 on January 3, 2009 12:19:37 PM]
  6. polaris2013

    Need help getting started

    Oh, well I solved it but since somebody else was wondering about the answer I'll go ahead and say what fixed it. There was a setting under Project -> Properties -> Configuration Properties -> C/C++ -> Code Generation that I had to change. Turns out multi-threaded debug was the way to go instead of single-threaded debug. Anyway, that was obviously not an obvious place to hide that setting so I hope this helps someone.
  7. polaris2013

    Need help getting started

    Compiler = Visual Studio 2005 Express (VS8) Angelsciprt Version = 2.15 I opened up the angelscript project for VS8, compiled it, copied the output library "angelscriptd.lib" to my project's directory, and added the library to my linker's dependency list. Now when I include "angelscript.h" I get the following link errors: 1>Linking... 1>MSVCRTD.lib(MSVCR80D.dll) : error LNK2005: _free already defined in LIBCMTD.lib(dbgheap.obj) 1>MSVCRTD.lib(MSVCR80D.dll) : error LNK2005: _malloc already defined in LIBCMTD.lib(dbgheap.obj) 1>MSVCRTD.lib(MSVCR80D.dll) : error LNK2005: _fclose already defined in LIBCMTD.lib(fclose.obj) 1>MSVCRTD.lib(MSVCR80D.dll) : error LNK2005: _fprintf already defined in LIBCMTD.lib(fprintf.obj) 1>MSVCRTD.lib(MSVCR80D.dll) : error LNK2005: _fopen already defined in LIBCMTD.lib(fopen.obj) 1>MSVCRTD.lib(MSVCR80D.dll) : error LNK2005: _strtol already defined in LIBCMTD.lib(strtol.obj) 1>MSVCRTD.lib(MSVCR80D.dll) : error LNK2005: _strtoul already defined in LIBCMTD.lib(strtol.obj) 1>MSVCRTD.lib(ti_inst.obj) : error LNK2005: "private: __thiscall type_info::type_info(class type_info const &)" (??0type_info@@AAE@ABV0@@Z) already defined in LIBCMTD.lib(typinfo.obj) 1>MSVCRTD.lib(ti_inst.obj) : error LNK2005: "private: class type_info & __thiscall type_info::operator=(class type_info const &)" (??4type_info@@AAEAAV0@ABV0@@Z) already defined in LIBCMTD.lib(typinfo.obj) 1> Creating library .\Debug/QuadsEngine.lib and object .\Debug/QuadsEngine.exp1>LINK : warning LNK4098: defaultlib 'MSVCRTD' conflicts with use of other libs; use /NODEFAULTLIB:library 1>.\Debug/QuadsEngine.exe : fatal error LNK1169: one or more multiply defined symbols found Angelscript documentation provides the following nugget of wisdom: Quote:When compiling the static library you have to make sure that the correct compiler settings are used so that you don't get conflicts in linkage with the CRT functions. This happens if you for example compile the library with dynamically linked multi-threaded CRT and your application with statically linked single-threaded CRT. Well, I see I'm getting CRT errors, but how do I figure out if my compiler settings are the same? I assume this is with respect to single-threaded/multi-threaded/multi-threaded DLL and Release/Debug. I think that they're both set to single-threaded debug, but I'm not sure how to check. And if something else is the problem, I really don't know what else to do.
  8. polaris2013

    C++ "this" pointer off by 4 bytes

    Maybe it will help if I post some code (forgive the hungarian, this is for windows and I wanted to be consistent) [source=cpp] E_VAL CObjectBase::QueueRequest(MESSAGE msg) { if(g_pObjectMessageQueue == NULL) return RET_ERROR; CMessage* vmsg = new CMessage; vmsg->m_pRequestingObject = this; vmsg->m_pRequestingObject = &*this; vmsg->m_pRequestingObject = static_cast<CObjectBase*>(this); vmsg->m_pRequestingObject = static_cast<CObjectBase*>(&*this); vmsg->m_pRequestingObject = dynamic_cast<CObjectBase*>(this); vmsg->m_pRequestingObject = dynamic_cast<CObjectBase*>(&*this); vmsg->m_wRequestingObjectType = Get_Type(); vmsg->m_wRequestingObjectMessage = msg; g_pObjectMessageQueue->QueueRequest(vmsg); return RET_OK; } Yes, I went bonkers with typecasting to see if one of them would work. They don't. As was suggested by this article: http://carcino.gen.nz/tech/cpp/multiple_inheritance_this.php edit: some more code (also slightly modified the code that was above before the edit)- here's the message handler (yea, I know this is unsafe casting, but I don't see any other way to do it) [source=cpp] void CGame::UpdateState(DWORD msec) { //iterate through requests until NULL is returned while(m_pMessageQueue->PeekRequest()) { CMessage* msg = m_pMessageQueue->PopRequest(); CRegion* r; switch(msg->m_wRequestingObjectMessage) { case MSG_MAPCHANGE: r = (CRegion*)msg->m_pRequestingObject; ChangeMap(r->Get_PointerIndex()); break; } } } Here's an example call: [source=cpp] CRegion* region; //allocate it somehow region->QueueRequest(MSG_MAPCHANGE); Also SC4Freak, I'm not doing any manual byte aligning so I think it is unlikely to be the same as your problem. edit #2: The problem is that the wrong address is stored in CObjectBase::QueueRequest(), because the this pointer is not the same as the pointer in the example call edit #3: now that I wrote it all down like that I see an obvious workaround that avoids using the "this" pointer, but I would still like to know why this happened for future reference. [Edited by - polaris2013 on July 12, 2008 9:03:01 PM]
  9. I'm trying to make an object that can create a message, and one of the elements of the message is a pointer to the object that created the message. OK? The problem is that when I set the message's pointer to "this" that pointer is off by 4 bytes! To the external world, the object is at the address 0x000dbda40 , but to the internal world "this" points to at 0x000dbda44 I am using inhereitance (lots of objects can create messages and they all derive from a base object), so that might be related to the problem. But the only workaround I can think of is to subtract those 4 bytes off, and I'm not really sure that's safe...
  10. I'm taking a total shot in the dark here, but you might consider modifying this line of code in your program: Direct3DCreate8(D3D_SDK_VERSION); to whatever the version of your old SDK was (probably somewhwere in the 10s). Also anywhere else that constant appears. I've noticed MS does change some things unexpectadly in new versions that makes legacy code harder to work with.
  11. I think the general procedure for a circular dependence is to write a forward declaration (if Wikipedia is to be trusted). This seems to work unless the class requiring the forward declaration has other classes which are inherited from it. Up until this point I haven't had any forays into circular dependence, so when I tried it out I was getting a lot of errors "base class undefined". I found that I could get it to compile again by either (1) removing the circular dependence, or (2) moving the circular dependence to the leaf classes. Unfortunately, if I have to move the dependence to the leaf class, then what is the point of having this parent class when the shared code can't be shared? So I created a test project just to test if the circular dependence in a parent class was the problem or if it was some forward declaration that I had missed. The result is that either I did the same thing wrong twice or this just can't be done. I had the same problem in my test project as in my original project. So am I correct? Or did I do the same thing wrong twice? Well, I guess if I did the same thing wrong twice, I better post my test project so someone can identify the problem (just the headers): Parent Class: #ifndef HEADER_PUREABSTRACT //#if !defined HEADER_PUREABSTRACT #define HEADER_PUREABSTRACT #include "Derived1.h" class CDerived1; class CPureAbstract { public: virtual int ImaVirtualFunction(void); //=0; protected: CPureAbstract(void); ~CPureAbstract(void); }; #endif Derived1.h #ifndef HEADER_DERIVED1 //#if !defined HEADER_DERIVED1 #define HEADER_DERIVED1 #include "PureAbstract.h" class CDerived1 : public CPureAbstract { public: int ImaVirtualFunction(void); CDerived1(void); ~CDerived1(void); }; #endif Derived2.h #ifndef HEADER_DERIVED2 //#if !defined HEADER_DERIVED2 #define HEADER_DERIVED2 #include "PureAbstract.h" class CDerived2 : public CPureAbstract { public: int ImaVirtualFunction(void); CDerived2(void); ~CDerived2(void); }; #endif In my original project, the circular dependence is more of a pointer to a container class. The CActor class has a pointer to the CActorContainer class (well, I would like for it to).
  12. polaris2013

    virtual static (C++)

    C&P of my above edits: (I realized you probably wouldn't realize I had made those edits unless I added a reply to the topic) ---------------------------------------- WAIT A SECOND, I misspoke above. I just noticed that I had commented out the part where I called CMonster::MaxInventorySize() and when I uncommented it, the call still gives me a compiler error that the function is not static and that it is an illegal call. So I still do not have a solution. The first solution does not work because the class CActor cannot access the maximum inventory size. Although it is an abstract class, there is still shared code between CMonster and CPlayer that rely on the max inventory size, for example whether or not another item can be picked up. Therefore the problem is this: 1) CPlayer has a static maximum inventory size 2) CMonster has a static maximum inventory size 3) CActor, which is the parent to both of these classes, must be able to access the correct maximum inventory size 4) The maximum inventory size of the monster must be accessible without having an object instantiated.
  13. polaris2013

    virtual static (C++)

    Ha, thank you RDragon I knew this was something that someone else could solve instantly! The second solution was just what I needed! I must admit, I don't fully understand what the const keyword does. I see a lot of other people's code where they put const in places I never thought of and it works. The general rule (I think) is the const modifies the thing to the left of it so this is somehow making the function constant, like static would, except with a different keyword? Am I correct in my understanding of your solution. I mean, I guess I don't have to understand the solution as long as it works, but it would be appreciated. THANK YOU! :) ------------------ EDIT #1: WAIT A SECOND, I misspoke above. I just noticed that I had commented out the part where I called CMonster::MaxInventorySize() and when I uncommented it, the call still gives me a compiler error that the function is not static and that it is an illegal call. So I still do not have a solution. EDIT #2: (reply to below comment from RDragon) The first solution does not work because the class CActor cannot access the maximum inventory size. Although it is an abstract class, there is still shared code between CMonster and CPlayer that rely on the max inventory size, for example whether or not another item can be picked up. Therefore the problem is this: 1) CPlayer has a static maximum inventory size 2) CMonster has a static maximum inventory size 3) CActor, which is the parent to both of these classes, must be able to access the correct maximum inventory size 4) The maximum inventory size of the monster must be accessible without having an object instantiated.
  14. This is a rather unusual question so let me set it up first: I have a class CActor from which CMonster and CPlayer are both derived. One of the members of the Actor class is the inventory. Monsters and Players have different maximum inventory sizes, however each monster has the same maximum inventory size and trivially each player has the same maximum inventory size (only 1 player). Some of the shared Actor functions need to access the maximum inventory size, so the best way I could think of to handle that was to make a pure virtual function that was defined in both CMonster and CPlayer to return their respective maximum inventory sizes like so: //CActor:: virtual inline unsigned int MaxInventorySize() = 0; //CPlayer:: inline unsigned int MaxInventorySize(){ return 60; } //CMonster:: inline unsigned int MaxInventorySize(){ return 4; } However I have no run into a situation where it would be useful call this function without an object, specifially: CMonster::MaxInventorySize(); Unfortunately virtual and static do not play together, so I cannot do this. I'm wondering what would be the best solution to this. I ran into this problem last night and have thought about it some since then but haven't recognized any simple solution yet so I figured this is the type of question someone else can probably answer in 3 seconds so I should quit thinking about it and just ask someone instead.
  15. http://img125.imageshack.us/my.php?image=resedhilitejr1.png I am trying to make a dialog that uses a box as highlighted in the picture above. What kind of resource is this?! I tried ListBox, but it's not editable. I thought of Edit Boxes, but you can't scroll groups of those relative to the dialog box. I can't figure out how to make this type of resource! If you are not familiar with ResEd, this is how that control works: you click on one of the rows and you can edit the data directly in the box. Some of the rows have edit boxes, some have comboboxes, and still others have a button that links to another dialog. The scrollbar on the side shows more elements since not all of them are visible at once. Warcraft 3 also has a resource like this for it's object editor, if you're familiar with that. How do you make this? At least, what is it called?
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!