• What do you need help with? Version 5
    5,752 replies, posted
I'm working in C++, and I am wondering about something. I'm creating a menu-system with buttons and boxes. Everything in the menu is controlled by the MenuSystem class. Every item in the menu inherits from the class "MenuItem". My plan is to have an array of MenuItems in the MenuSystem, and then have the MenuSystem call Update and Draw on every item. My question is; how do I handle adding buttons and boxes into the array of MenuItems? Is it a simple matter of casting, or is it complicated? Edit: It wasn't too complicated. I got some help. I'm using the vector template class (c++ standard library). I have a vector-list of pointers to the base class, and I just add all the items that are inherited from that base class using vector's "push_back". Then I loop through each item in the vector to call each item's update and draw.
When developing with Java for Android, how would I check if a certain key is down? If I have to use events, how would I get data from that event to a View?
Quick question about C#: How do I make dynamic paths? As in, if I want to distribute my program to multiple computers where the location of the program will be different, how am I still able to use the content I need to write the location for? I tried wildcards (*/(rest of the location) and it didn't work.
[QUOTE=NotAName;36016213]Quick question about C#: How do I make dynamic paths? As in, if I want to distribute my program to multiple computers where the location of the program will be different, how am I still able to use the content I need to write the location for? I tried wildcards (*/(rest of the location) and it didn't work.[/QUOTE] If you just do something like: [code] System.IO.StreamReader sw = new System.IO.StreamReader("content/level1.txt"); [/code] it'll look in the current working directory (the app (.exe) path by default) and find files/folders there.
[QUOTE=NovembrDobby;36016334]If you just do something like: [code] System.IO.StreamReader sw = new System.IO.StreamReader("content/level1.txt"); [/code] it'll look in the current working directory (the app (.exe) path by default) and find files/folders there.[/QUOTE] [code] System.Media.SoundPlayer WrongAnswerPlayer = new System.Media.SoundPlayer("Content\wrongAnswer.wav");[/code] Gives me an "Unrecognized escape sequence" error
[QUOTE=NotAName;36016391][code] System.Media.SoundPlayer WrongAnswerPlayer = new System.Media.SoundPlayer("Content\wrongAnswer.wav");[/code] Gives me an "Unrecognized escape sequence" error[/QUOTE] Use forward slashes(/) for directories not backslashes(\). Backslashes are used to escape characters to turn them into special characters like null "\0" and newline "\n".
[QUOTE=Naelstrom;36016847]Use forward slashes(/) for directories not backslashes(\). Backslashes are used to escape characters to turn them into special characters like null "\0" and newline "\n".[/QUOTE] Thanks, it works now. Although, kinda weird that when you copy an address as text it gave me backslashes.
[QUOTE=NotAName;36017807]Thanks, it works now. Although, kinda weird that when you copy an address as text it gave me backslashes.[/QUOTE] forward slashes is windows way, if you want it to be more multiplatform use double back slashes
This is less of a question and more of an advice thing. Working with java, I just discovered Netbeans' GUI builder. Saves heck a lot of time to design the interface and see the result directly instead of dealing with tedious layout code. However, I feel that layouts is one of those basics you should learn to handle manually aswell. I've done some work with jframes and get the basic gist of layout managers though. Should I proceed with the GUI builder or stick with manual layout coding?
[QUOTE=Richy19;36018210]forward slashes is windows way, if you want it to be more multiplatform use double back slashes[/QUOTE] Don't you mean [b]back[/b] slashes is windows way, and if you want to be multiplatform use [b]single forward[/b] slashes? [url=http://bit.ly/KkUIWq]Double back slashes don't work on linux.[/url] While single forward slashes work on both windows and Linux.
I'm trying to make a simple "Hello World" in ASM, but I don't know what library to link it with. Any help? [code]global _start extern _MessageBoxA@16 extern _ExitProcess@4 section code _start: push dword 0 push dword title push dword banner push dword 0 call _MessageBoxA@16 push dword 0 call _ExitProcess@4 section data banner: db 'Hello, World!', 0 title: db 'Hello!', 0[/code]
[QUOTE=The Kakistocrat;36020091]I'm trying to make a simple "Hello World" in ASM, but I don't know what library to link it with. Any help? [code]global _start extern _MessageBoxA@16 extern _ExitProcess@4 section code _start: push dword 0 push dword title push dword banner push dword 0 call _MessageBoxA@16 push dword 0 call _ExitProcess@4 section data banner: db 'Hello, World!', 0 title: db 'Hello!', 0[/code][/QUOTE] MessageBoxA is in user32.lib, and ExitProcess is in Kernel32.lib (you don't [i]really[/i] need to call it; you can just push 0 and return)
[QUOTE=ShaunOfTheLive;36020322]MessageBoxA is in user32.lib, and ExitProcess is in Kernel32.lib (you don't [i]really[/i] need to call it; you can just push 0 and return)[/QUOTE] Thanks, it links perfectly.
I'm still having some trouble compiling Qt stuff. For instance, I'm attempting to compile the C++ code below: [code] /* * * Simple Text Editor Test * 20 May 2012 * */ #include <QApplication> #include <QTextEdit> /* * */ int main(int argc, char **args) { QApplication app(argc, args); QTextEdit textEdit; textEdit.show(); return app.exec(); } [/code] Using [I]cmd[/I], I navigate to the directory where this .cpp file is and execute [I]qmake[/I], which works fine and generates the part1 files as expected. However, when I try to call either [I]make[/I] or [I]nmake[/I], neither work. [I]nmake [/I] isn't recognized as a proper batch file and [I]make [/I]says there's no target specified. I am working with Qt 4.8.1 and minGW tools. Any help please?
You can't use cmd, you need to use the Visual Studio Command Prompt (there's a shortcut to it in your start menu).
I need to expose functions and variables in C++ to an editor/map loader/etc. For each entity, I want to be able to mark member variables (m_iHealth, m_flSpeed, etc.) as well as functions (::TurnOn()...). However, I don't want to just mark these variables/functions as "public" and then have some sort of hackish method to cast entities down to their lowest derived class. [cpp] class CBaseEntity { public: CBaseEntity(); public: void SetVisible(bool visible); //Expose This Property private: int m_iHealth; //Expose this property } class CDerivedEntity : public CBaseEntity { public: CDerivedEntity(); public: void MyFunction(); //Expose this property private: bool m_bIsEnabled; //Expose this property } [/cpp] And then be able to create an entity via something like this: [cpp] CBaseEntity *pEntity = new CDerivedEntity; [/cpp] And then be able to set the member properties/call member functions of the DERIVED entity with access only to the CBaseEntity. I apologize for this being confusing. Think about how Source and Hammer works.
[QUOTE=Lord Ned;36037378]I need to expose functions and variables in C++ to an editor/map loader/etc. For each entity, I want to be able to mark member variables (m_iHealth, m_flSpeed, etc.) as well as functions (::TurnOn()...). However, I don't want to just mark these variables/functions as "public" and then have some sort of hackish method to cast entities down to their lowest derived class. [cpp] class CBaseEntity { public: CBaseEntity(); public: void SetVisible(bool visible); //Expose This Property private: int m_iHealth; //Expose this property } class CDerivedEntity : public CBaseEntity { public: CDerivedEntity(); public: void MyFunction(); //Expose this property private: bool m_bIsEnabled; //Expose this property } [/cpp] And then be able to create an entity via something like this: [cpp] CBaseEntity *pEntity = new CDerivedEntity; [/cpp] And then be able to set the member properties/call member functions of the DERIVED entity with access only to the CBaseEntity. I apologize for this being confusing. Think about how Source and Hammer works.[/QUOTE] You can just cast the pointer to the derived class like so: [code]CBaseEntity* pEntity = new CDerivedEntity(); (CDerivedEntity*)pEntity->MyFunction();[/code] If you don't know what kind of derived class it is, you can create a virtual function in the base class that returns a unique ID. Then in all functions that derive it to return a different ID like so: [code]class CBaseEntity { public: CBaseEntity(); public: void SetVisible(bool visible); //Expose This Property public: virtual std::string GetType(); private: int m_iHealth; //Expose this property } class CDerivedEntity : public CBaseEntity { public: CDerivedEntity(); public: void MyFunction(); //Expose this property public: std::string GetType(); private: bool m_bIsEnabled; //Expose this property } std::string CBaseEntity::GetType() { return "NULL"; } std::string CDerivedEntity::GetType() { return "CDerivedEntity"; }[/code] [code]CBaseEntity* pEntity = new CDerivedEntity(); if (pEntity->GetType() == "CDerivedEntity") { (CDerivedEntity*)pEntity->MyFunction(); }[/code] Hopefully that'll give you more ideas on what you can do.
[QUOTE=dajoh;36036080]You can't use cmd, you need to use the Visual Studio Command Prompt (there's a shortcut to it in your start menu).[/QUOTE] I'm still getting a bunch of errors after trying this with a fresh install of QtSDK. From within Visual Studio 2008 Command Prompt: [code] ... >qmake -project ... >qmake Warning: failed to resolve epocroot. Either 1. Set EPOCROOT environment variable to a valid value. or 2. Ensure that the HKEY_LOCAL_MACHINE\Software\Symbian\EPOC SDKs\CommonPath registry key is set, and then a. Set EPOCDEVICE environment variable to a valid device or b. Specify a default device in the devices.xml file. repeat above message ad nauseum [/code] After doing that, it [I]appears[/I] to generate all the correct files. However, when I call [I]nmake[/I]: [code] ... >nmake Microsoft (R) Program Maintenance Utility Version 9.00.21022.08 Copyright (C) Microsoft Corporation. All rights reserved. makefile (83) : fatal error U1000: syntax error : ')' missing in macro invocation Stop. ... > [/code] This is on a completely new install, by the way, of both QtSDK and MSVS 2008.
[QUOTE=Naelstrom;36039908]You can just cast the pointer to the derived class like so: [code]CBaseEntity* pEntity = new CDerivedEntity(); (CDerivedEntity*)pEntity->MyFunction();[/code] If you don't know what kind of derived class it is, you can create a virtual function in the base class that returns a unique ID. Then in all functions that derive it to return a different ID like so: [code]class CBaseEntity { public: CBaseEntity(); public: void SetVisible(bool visible); //Expose This Property public: virtual std::string GetType(); private: int m_iHealth; //Expose this property } class CDerivedEntity : public CBaseEntity { public: CDerivedEntity(); public: void MyFunction(); //Expose this property public: std::string GetType(); private: bool m_bIsEnabled; //Expose this property } std::string CBaseEntity::GetType() { return "NULL"; } std::string CDerivedEntity::GetType() { return "CDerivedEntity"; }[/code] [code]CBaseEntity* pEntity = new CDerivedEntity(); if (pEntity->GetType() == "CDerivedEntity") { (CDerivedEntity*)pEntity->MyFunction(); }[/code] Hopefully that'll give you more ideas on what you can do.[/QUOTE] The problem with that is it becomes a massive switch-statement that has to be updated every time I add an entity to the game.
Any experience with merchant processing or payment gateways? If so, then I would really appreciate some direction regarding transaction information that is sent to the banks. Processing stage referenced from Authorize.net: [img]http://developer.authorize.net/resources/images/howitworks/step3.png[/img]
[QUOTE=Lord Ned;36042948]The problem with that is it becomes a massive switch-statement that has to be updated every time I add an entity to the game.[/QUOTE] can i see what you're trying to accomplish? if you look i defined a virtual function that can be redefined by the inheriting classes. so say if you wanted to have a unique draw function for each entity: you'd just make a virtual draw member in the base class and redefine it in the base class'es derivitives. this would keep you from making a massive switch to draw all your base object's derivitives. [editline]asdf[/editline] If you need some code references, I've been doing it in my engine. I have a base class called [url=http://farmpolice.com/astrostruct/classNNode.html]NNode[/url] that a bunch of classes derive from. You can see me drawing and updating all the objects in [url=https://github.com/naelstrof/Astrostruct/blob/master/src/NScene.cpp]NScene[/url] without any massive switch statements or nastiness.
[QUOTE=Naelstrom;36044525]can i see what you're trying to accomplish? if you look i defined a virtual function that can be redefined by the inheriting classes. so say if you wanted to have a unique draw function for each entity: you'd just make a virtual draw member in the base class and redefine it in the base class'es derivitives. this would keep you from making a massive switch to draw all your base object's derivitives. [editline]asdf[/editline] If you need some code references, I've been doing it in my engine. I have a base class called [url=http://farmpolice.com/astrostruct/classNNode.html]NNode[/url] that a bunch of classes derive from. You can see me drawing and updating all the objects in [url=https://github.com/naelstrof/Astrostruct/blob/master/src/NScene.cpp]NScene[/url] without any massive switch statements or nastiness.[/QUOTE] I'm trying to define Entity properties, that my editor can modify. The editor only deals with CBaseEntity's - This obviously only exposes any members from CBaseEntity. I want to have it so there's a way to access the members of derived classes when you only have access to the base class. I'm currently looking into a "Datamap", and trying to have CBaseEntity carry a datamap that has ways of accessing the derived members.
Ah, that's out of my league; sorry I couldn't have helped more. :u
[QUOTE=Naelstrom;36044862]Ah, that's out of my league; sorry I couldn't have helped more. :u[/QUOTE] Not a problem, thanks for the input anyways. :)
I've got something that's got me stumped. I have the following problem: A simple std::list of objects, each has certain values like the time it was measured, it's type and the value. This list is read and parsed to file. So far so good. Once the file is written and the handle is closed, I give a terminal command from the program to compress it with gzip. Code is Unix C++, to be placed later on an ARM platform. The entire program works fine, but I'd like to compress my measurements since they can otherwise eat up a bit of space in the long term and the target platform has limited space/bandwidth. [cpp] if(measurements.size()>0){ std::ofstream filestream; filestream.open(TBX.StringToChar(dir+filename+extension), std::ios::app); // Iterate through our config stored in memory. for(std::list<MeasuringObject>::iterator it = measurements.begin();it !=measurements.end(); it++){ //Get a pointer to the current measurement. MeasuringObject measurement = *it; std::cout << "Saving: "<< measurement.fetchtime << "," << measurement.name << "," << measurement.value << "\n"; filestream << measurement.fetchtime << "," << measurement.name << "," << measurement.value << "\n"; } filestream.close(); std::string zipcommand = "tar -czf "+dir+filename+".gzip "+dir+filename+extension; system(TBX.StringToChar(zipcommand)); //TBX.removeFile(dir+filename+extension); } [/cpp] For some reason, the tar gzip operation completes and returns 0 (which is operation successful), yet when I try to extract the file, it fails with an unknown error. If I try zipping up the file with the same command from a terminal outside the program, I can extract it without problem. The source file exists and is readable and the gzipped file is created, but for some reason it becomes unreadable/corrupted. Anyone got clue what I'm doing wrong?
why not use zlib?
[QUOTE=Kamshak;36052595]why not use zlib?[/QUOTE] That's my alternative option if I can't fix this. This is much easier though, so I'd rather make this work.
For the love of god please never use system ever except in dire situations where it is literally the only choice
[QUOTE=Lord Ned;36037378]I need to expose functions and variables in C++ to an editor/map loader/etc. For each entity, I want to be able to mark member variables (m_iHealth, m_flSpeed, etc.) as well as functions (::TurnOn()...). However, I don't want to just mark these variables/functions as "public" and then have some sort of hackish method to cast entities down to their lowest derived class. [cpp] class CBaseEntity { public: CBaseEntity(); public: void SetVisible(bool visible); //Expose This Property private: int m_iHealth; //Expose this property } class CDerivedEntity : public CBaseEntity { public: CDerivedEntity(); public: void MyFunction(); //Expose this property private: bool m_bIsEnabled; //Expose this property } [/cpp] And then be able to create an entity via something like this: [cpp] CBaseEntity *pEntity = new CDerivedEntity; [/cpp] And then be able to set the member properties/call member functions of the DERIVED entity with access only to the CBaseEntity. I apologize for this being confusing. Think about how Source and Hammer works.[/QUOTE] Okay, so in case anyone comes across this in the future, here's how I did it. It is a bit of a combination of black magic as well as Naelstroms virtual-function derivation. Each class declares a "datamap_t" structure, which holds a pointer to a typedescription_t array, a number of fields counter, and a pointer to a base "datamap_t" struct. If this class is a baseclass and is not derived from anything, then it will end up setting the datamap_t::base member to null. Each class then implements a virtual function "GetDataMapDesc()", which returns a pointer to the class's datamap_t::base, or null if it is the base class. Because these virtual, overridden functions are chained down the inheritance line, calling "GetDataMapDesc()" with a pointer to your baseclass will give you the bottom-most-inherited class's datamap_t - Which contains pointers to all previous classes. This allows you to access all derived datamembers with only a pointer to the base class. Then, with some trickery, you can use these to get/set values, because the typedescription_t holds the offset into the class. Here's some code: [cpp] //------------------------------------------------------------------------- // Purpose: Describes one exposed property. datmap_t::dataDesc holds an // array of these. //------------------------------------------------------------------------- struct typedescription_t { //Identifier for your field - INTEGER, BOOLEAN, FLOAT, VECTOR, etc. fieldtype_t fieldType; //Plaintext name of the member-variable const char *fieldName; int fieldOffset; //Offset from baseclass int flags; //Useful for saying if a member should be saved, if it should be exposed to an editor, et.c unsigned short fieldSize; //Recorded but unused //Name of the variable, or name of action const char *externalName; //'External' name - Useful to change say "m_iHealth" to "#PROPERTY_HEALTH" and then change that in your editor, etc. }; //------------------------------------------------------------------------- // Purpose: Each class holds a datamap_t structure. Each datamap_t structure // points to its parent's datamap_t, until it reaches the base class. //------------------------------------------------------------------------- struct datamap_t { //Describes the visible fields (see above) typedescription_t *dataDesc; //pointer array //Count of fields int dataNumFields; //This reflects the associated class-name char const *dataClassName; //Something like "CBaseClass" //This points to a base class's data map. NULL if none. datamap_t *baseMap; //Used to get the parents datamap, allowing you to reach the CBaseClass }; [/cpp] That is the data structure kept with each class. You then have to fill these, and they are filled at compile time. [cpp] //Each class needs to specify that it has a datamap. This can easily be wrapped up in a macro to save ourselves the trouble. This would go in the PUBLIC: section of each class's HEADER! #define DECLARE_DATADESC() \ static datamap_t m_dataMap; \ static datamap_t *GetBaseMap(); \ template<typename T> friend void DataMapAccess(T *, datamap_t **p); \ template<typename T> friend datamap_t *DataMapInit(T *); \ virtual datamap_t *GetDataDescMap(); //This is black magic used by the DataMap functions. It is black magic. template <typename T> inline void DataMapAccess(T *ignored, datamap_t **p) { *p = &T::m_dataMap; } //Then, in the IMPLEMENTATON (CPP) of each file, we need to define what variables are tracked, etc. datamap_t CBaseEntity::m_dataMap = {0, 0, "CBaseEntity", NULL }; datamap_t *CBaseEntity::GetDataDescMap(){ return &m_dataMap; } //datamap_t *CBaseEntity::GetBaseMap(){ return NULL; } <-- USE THIS FOR A BASECLASS datamap_t *className::GetBaseMap(){ datamap_t *pResult; DataMapAccess((BaseClass *)NULL, &pResult); return pResult; } //<-- OTHERWISE USE THIS. //This part gets quite confusing, but has to do with specific implementatiosn of datamap_t *DataMapInit.() template <typename T> datamap_t *DataMapInit(T *); template<> datamap_t *DataMapInit<CBaseEntity>( CBaseEntity * ); namespace CBaseEntity_DataDescInit { datamap_t *g_DataMapHolder = DataMapInit((CBaseEntity *)NULL); /*I don't know.*/ } template<> datamap_t *DataMapInit<CBaseEntity>( CBaseEntity * ) { typedef CBaseEntity classNameTypedef; \ CBaseEntity::m_dataMap.baseMap = CBaseEntity::GetBaseMap(); static typedescription_t dataDesc[] = { {FIELD_VOID, NULL, 0, 0}, //An empty entry in the array to allow empty datamaps. //Now, you can define each field you want to expose. { fieldType, #name, offsetof(classNameTypedef, name), FTYPE_NONE, sizeof( ((classNameTypedef *)0)->name ), NULL}, //Fill out one of these for each member to expose //Now finish off the datamap }; if ( sizeof( dataDesc ) > sizeof( dataDesc[0] ) ) { classNameTypedef::m_dataMap.dataNumFields = _ARRAYSIZE( dataDesc ) - 1; classNameTypedef::m_dataMap.dataDesc = &dataDesc[1]; } else { classNameTypedef::m_dataMap.dataNumFields = 1; classNameTypedef::m_dataMap.dataDesc = dataDesc; } return &classNameTypedef::m_dataMap; } [/cpp] And finally, to wrap up our uncalled for and impromptu lesson how to access and edit the members: [cpp] void CBaseEntity::SetKeyValue( const char *szKey, const char *szValue ) { //Loop through data description and put the key in anywhere we have a entry for. for(datamap_t *dMap = GetDataDescMap(); dMap != NULL; dMap = dMap->baseMap ) { for(int i = 0; i < dMap->dataNumFields; i++) { typedescription_t *pField = &dMap->dataDesc[i]; int fieldOffset = pField->fieldOffset; //If the field matches, lets set it. if(_strcmpi(pField->externalName, szKey) == 0) { switch(pField->fieldType) { case FIELD_INTEGER: (*(int *)((byte *)this + fieldOffset)) = atoi(szValue); break; case FIELD_FLOAT: (*(float *)((byte *)this + fieldOffset)) = atof(szValue); break; case FIELD_BOOLEAN: (*(bool *)((byte *)this + fieldOffset)) = (bool)(atoi(szValue) != 0); break; } } } } } void CBaseEntity::GetKeyValue( const char *szKey, char *szValue, int iMaxLength ) { if(szKey == NULL || szValue == NULL) return; //Loop through data description and put the key in anywhere we have a entry for. for(datamap_t *dMap = GetDataDescMap(); dMap != NULL; dMap = dMap->baseMap ) { for(int i = 0; i < dMap->dataNumFields; i++) { typedescription_t *pField = &dMap->dataDesc[i]; if(pField->fieldType != FIELD_VOID) { int fieldOffset = pField->fieldOffset; //If the field matches, lets set it. if(_strcmpi(pField->fieldName, szKey) == 0) { switch(pField->fieldType) { case FIELD_INTEGER: sprintf_s(szValue, iMaxLength, "%d", (*(int *)((byte *)this + fieldOffset)) ); break; case FIELD_FLOAT: sprintf_s(szValue, iMaxLength, "%f", (*(float *)((byte *)this + fieldOffset)) ); break; case FIELD_BOOLEAN: sprintf_s(szValue, iMaxLength, "%d", (*(bool *)((byte *)this + fieldOffset)) != 0); break; } } } } } } [/cpp] And that's pretty much the gist of it. This all comes from the HL2 Mod Code, so no credit for coming up with it here. I just sat down for 3 or 4 hours and unraveled Valve strings to figure out what was going on. [b]This is not a complete implementation, it is 20% psuedocode/typed from memory and contains errors.[/b] Also, the GET/SET keyvalue doesn't do any safechecking, so make sure you do that, etc. This can be improved a great deal with a set of macros, however I felt they complicated the issue so you're on your own to create (or borrow Valve's, which I did) them. This can also be expanded to create function callbacks (useful for I/O), etc.
I keep giving up on projects, mainly because I get frustrated or bored with the concept. I want to start a new one, write up a document and make all the major decisions first before I start writing code so I don't have to rewrite basic code over and over, as I have had to do. The problem is I want to make this game 3d. A survival zombie game (yes I know it's cliche and overdone but I think it'll be fun to make) where you have to live in a city that is I am legend esque, finding supplies and steering clear of dark buildings, and hiding in your house at night. The problem with 3d is I have never done it. I am frightened by the art required, and by the whole animation and texture idea. I am afraid that I won't get anything done apart from making blobs that move around. My questions is this: how easy is it to create animations and models for 3d games, and are there any tutorials on this matter?
Sorry, you need to Log In to post a reply to this thread.