Hakaku Posted December 22, 2009 Report Posted December 22, 2009 SDL_image and SDL_net are separate from SDL itself. You can download those from here. To set up SDL just follow steps 1 to 4 from this guide (for SDL_Image and SDL_net it's the same thing; basically just copy over the necessary header files and library/dll files). You'll also need the zlib library if you don't have that already; the process for setting it up is essentially the same thing (i.e. put the library files in the /lib/, and the header files in the /include/ folder). Quote
Bak Posted December 22, 2009 Report Posted December 22, 2009 you're right that it keeps them packed. However, if you create a folder inside the zone folder with the name of an arena, and put graphics inside, it will override the lvz graphics/images for that arena. I think the order continuum checks is: 1. arena folder (zoneName/arenaname/graphic.png)2. (?)zone folder (zoneName/graphic.png)3. lvz file graphic4. default graphic (graphics/graphic.png) Maybe it would be good to keep them internal for discretion too, although that would require substantial rework so maybe just unzipping will suffice for now. Some projects have this:#include "SDL.h"#include "SDL_thread.h" While others have the SDL/ folder in front... shouldn't they all have the SDL/ ? Well, you can either unzip them into both directories, which I agree is bad, or change them all to have the SDL folder. SDL_net and SDL_image are cross platform libraries in the spirit of SDL. Check out http://www.libsdl.org/libraries.php for a complete list of libraries and their development packs. Quote
Bak Posted December 22, 2009 Report Posted December 22, 2009 cause the block is read as one byte block of a definite size, uncompressed, and only then I know it's a bunch of object definitions. So I just scroll through the byte buffer. Can you paste the code? Quote
Samapico Posted December 23, 2009 Author Report Posted December 23, 2009 cause the block is read as one byte block of a definite size, uncompressed, and only then I know it's a bunch of object definitions. So I just scroll through the byte buffer. Can you paste the code? Relevant part: if (sectionheader.compressedSize > 0 && sectionheader.decompressedSize > 0) { u8 decompressedData[sectionheader.decompressedSize]; u8 compressedData[sectionheader.compressedSize]; //Read compressed data if (fread(compressedData, sectionheader.compressedSize, sizeof(u8), fileh)) { int decompressedSize = sectionheader.decompressedSize; //Decompress the data util->zlibDecompress( compressedData, sectionheader.compressedSize, decompressedData, &decompressedSize); if (sectionheader.decompressedSize != (unsigned)decompressedSize) { //expected size doesn't match... ? } if (sectionheader.fileTime == 0 && slen == 0) { //This section contains object definitions LvzObjectSectionHeader objHeader; LvzObjectSectionType objSectionType = LVZ_UnsupportedFormat; //Data pointer to scroll through the definitions section u8* dataPtr = decompressedData; memcpy(&objHeader, dataPtr, sizeof(objHeader)); dataPtr += sizeof(objHeader); printf("Object definition section: %u objects, %u images\n", objHeader.objectCount, objHeader.imageCount); //Determine which format is used if (!strcmp_nonnull(objHeader.uncompressedSectionType, 4, "CLV1")) objSectionType = LVZ_CLV1; else if (!strcmp_nonnull(objHeader.uncompressedSectionType, 4, "CLV2")) objSectionType = LVZ_CLV2; printf("sizeof(lvzobj)=%i sizeof(imgdef)=%i", sizeof(LvzObjectDefinition), sizeof(LvzImageDefinition)); //Read each object, one at a time for (ii = 0; ii < objHeader.objectCount; ii++) { addObjectDefinition(currentLvzFile, (LvzObjectDefinition*)dataPtr, objSectionType); dataPtr += sizeof(LvzObjectDefinition); } //Read each image definition, one at a time for (ii = 0; ii < objHeader.imageCount; ii++) { //Grab the image filename, located after the fixed-size header strcpy(currentImageFileName, (char*)dataPtr+sizeof(LvzImageDefinition)); //Add the definition, with the fixed size header located at the pointer addImageDefinition(currentLvzFile, (LvzImageDefinition*)dataPtr, currentImageFileName, objSectionType); //Advance the data pointer dataPtr += sizeof(LvzImageDefinition); dataPtr += strlen(currentImageFileName)+1; } } else { printf("File section '%s'\n", currentLvzFileName); //This section contains a file addFile(currentLvzFile, currentLvzFileName, decompressedData, decompressedSize); } } else printf("Could not read compressed data\n"); } else printf("Section size = 0\n"); Entire loadLvzFromFile function: BOOL loadLvzFromFile(const char * filename) { unsigned int i, ii; LvzFileHeader lvzheader; LvzSectionHeader sectionheader; LvzFile* currentLvzFile; char currentLvzFileName[_MAX_FNAME]; char currentImageFileName[_MAX_FNAME]; BOOL success = FALSE; FILE * fileh = NULL; printf("Opening LVZ file '%s'\n", filename); if (util->isLegalFilename(filename)) { fileh = fopen(filename, "rb"); if (fileh) { //File opened if (fread(&lvzheader, sizeof(lvzheader), 1, fileh) == 1) { //Lvz header read //Header must contain 'CONT' if (!strcmp_nonnull(lvzheader.fileType, 4, "CONT")) { //We have a valid LVZ file currentLvzFile = addLvzFile(filename); printf("%i sections in LVZ\n", lvzheader.sectionsCount); for (i = 0; i < lvzheader.sectionsCount; i++) { if (fread(§ionheader, sizeof(sectionheader), 1, fileh) == 1) { if (!strcmp_nonnull(sectionheader.sectionType, 4, "CONT")) { //Section header read //Read the filename (null-terminated string) int slen = freadstr(fileh, currentLvzFileName, _MAX_FNAME); printf("Section %i: '%s', %i -> %i\n", i, currentLvzFileName, sectionheader.compressedSize, sectionheader.decompressedSize); if (sectionheader.compressedSize > 0 && sectionheader.decompressedSize > 0) { u8 decompressedData[sectionheader.decompressedSize]; u8 compressedData[sectionheader.compressedSize]; //Read compressed data if (fread(compressedData, sectionheader.compressedSize, sizeof(u8), fileh)) { int decompressedSize = sectionheader.decompressedSize; //Decompress the data util->zlibDecompress( compressedData, sectionheader.compressedSize, decompressedData, &decompressedSize); if (sectionheader.decompressedSize != (unsigned)decompressedSize) { //expected size doesn't match... ? } if (sectionheader.fileTime == 0 && slen == 0) { //This section contains object definitions LvzObjectSectionHeader objHeader; LvzObjectSectionType objSectionType = LVZ_UnsupportedFormat; //Data pointer to scroll through the definitions section u8* dataPtr = decompressedData; memcpy(&objHeader, dataPtr, sizeof(objHeader)); dataPtr += sizeof(objHeader); printf("Object definition section: %u objects, %u images\n", objHeader.objectCount, objHeader.imageCount); //Determine which format is used if (!strcmp_nonnull(objHeader.uncompressedSectionType, 4, "CLV1")) objSectionType = LVZ_CLV1; else if (!strcmp_nonnull(objHeader.uncompressedSectionType, 4, "CLV2")) objSectionType = LVZ_CLV2; printf("sizeof(lvzobj)=%i sizeof(imgdef)=%i", sizeof(LvzObjectDefinition), sizeof(LvzImageDefinition)); //Read each object, one at a time for (ii = 0; ii < objHeader.objectCount; ii++) { addObjectDefinition(currentLvzFile, (LvzObjectDefinition*)dataPtr, objSectionType); dataPtr += sizeof(LvzObjectDefinition); } //Read each image definition, one at a time for (ii = 0; ii < objHeader.imageCount; ii++) { //Grab the image filename, located after the fixed-size header strcpy(currentImageFileName, (char*)dataPtr+sizeof(LvzImageDefinition)); //Add the definition, with the fixed size header located at the pointer addImageDefinition(currentLvzFile, (LvzImageDefinition*)dataPtr, currentImageFileName, objSectionType); //Advance the data pointer dataPtr += sizeof(LvzImageDefinition); dataPtr += strlen(currentImageFileName)+1; } } else { printf("File section '%s'\n", currentLvzFileName); //This section contains a file addFile(currentLvzFile, currentLvzFileName, decompressedData, decompressedSize); } } else printf("Could not read compressed data\n"); } else printf("Section size = 0\n"); } else printf("Invalid section %i data\n", i); } else printf("Could not read section %i\n", i); } //end for each section success = TRUE; } else printf("Invalid LVZ file '%s'\n", filename); } else printf("fread failed\n"); } else printf("fopen failed\n"); } else printf("'%s' not a legal filename\n", filename); printf("Opened LVZ file '%s', success=%i\n", filename, success); return success; } Quote
Bak Posted December 23, 2009 Report Posted December 23, 2009 For errors that shouldn't occur use the LOG_ERROR(const char*) macro, or LOG_ERROR2(const char*, arg1), or LOG_ERROR3(const char*, arg1, arg2) <- printf like format LvzObjectSectionHeader objHeader; ... memcpy(&objHeader, dataPtr, sizeof(objHeader));Here, the correctness depends on the endianness of the architecture (the way in which the structure is laid out in memory). If objHeader is interpreted as laid out differently (for example on a powerpc mac), this won't work as expected. Quote
Samapico Posted December 23, 2009 Author Report Posted December 23, 2009 LvzObjectSectionHeader objHeader; ... memcpy(&objHeader, dataPtr, sizeof(objHeader));Here, the correctness depends on the endianness of the architecture (the way in which the structure is laid out in memory). If objHeader is interpreted as laid out differently (for example on a powerpc mac), this won't work as expected. hmmmtypedef struct { char uncompressedSectionType[4]; //'CLV1' or 'CLV2' u32 objectCount; //Mapobjects+Screenobjects count u32 imageCount; //Image definitions count } LvzObjectSectionHeader;The format in the file itself is fixed... So... I'm not sure how else I would do this. If I read it block by block, I'll have the same problem; I'll end up having to memcpy a u32 from the file data to the header. ?I can see how to do this for my LvzObjectDefinition struct, which has bitfields, but for this one, I have no idea. Quote
»doc flabby Posted December 23, 2009 Report Posted December 23, 2009 Btw samp, consider using "goto" to avoid that "if indent hell " its one of the situations its actually designed for (error handling) Quote
Samapico Posted December 23, 2009 Author Report Posted December 23, 2009 I think this'll work: Settings Used: /*[images];;;;One of these per Image DefinitionLVZ__imagePath=LVZ__imageFrames=(,) [Animations] ;;;;One of these per mapobject/screenobjectLVZ__obj Unique Image = LVZ__imageLVZ__obj Animation Milliseconds = */ Example: [images]LVZ_center_image0Path=center_imageLVZ_center_image0Frames=(1,1) LVZ_center_image1Path=center_animLVZ_center_image1Frames=(10,3) [Animations]LVZ_center_obj0 Unique Image = LVZ_center_image0LVZ_center_obj0 Animation Milliseconds = 1000 LVZ_center_obj1 Unique Image = LVZ_center_image1LVZ_center_obj1 Animation Milliseconds = 1500 This should work fine for image definitions that define an image from another lvz file, so should be good. Edit: well, that indentation isn't a problem on my widescreen monitor but that's an idea Quote
Samapico Posted December 23, 2009 Author Report Posted December 23, 2009 Callbacks... basically they're events that a module can trigger, and another module could "listen" for a specific callback and do something about it, right? For example, I could have a callback that says a specific LVZ file is done loading (or all lvz's requested are loaded, or they didn't load right), and whatever module loads the map/graphics when entering an arena will have to wait for this before loading stuff, cause the lvz might override graphics. (Or not, since it would just be a function call, no delay involved) I'll also need to somehow listen for the objon/off/set/move packets, and mess with the animations. I think I seen some code that told the Net module to pass on every packet about "something", or something like that... Anyway, I'll start by unpacking some lvz's Yes callbacks are events you listen to, which are sort of like interrupts. Rather than periodically polling if a player has died, it's much cleaner to simply say "call this function when a player dies". This is the idea with callbacks. For the packets, however, you'll want to do the following: register and wait for the CB_REGPACKETS callback to occur, then call Net::regPacketFunc for any packets they wish to handle. regPacketFunc takes in a string for the type of packet you want to listen for and a callback-like function. The packet types and relevant fields are defined in conf/modules/net.conf in the [Packet Templates] section. grep for regPacketFunc to see some examples. How do you define packets with variable size in the packet templates (objset packets are 2xN bytes)? Quote
Bak Posted December 23, 2009 Report Posted December 23, 2009 use type "raw", see the "incoming file transfer" type in net.conf (grep for it to see how it's handled in code) The format in the file itself is fixed... So... I'm not sure how else I would do this. you can do like: u32 value = (data[3] << 24) | (data[2] << 16) | (data[1] << | data[0];and it will work everywhere. There are functions to do this in Modules/Shared/LittleEndian.h/.cpp // extract a little endian u32 u32 getU32(u8* loc) { u32 rv = 0; for (int x = 3; x >= 0; --x) { rv *= 256; rv += loc[x]; } return rv; } Quote
Samapico Posted December 23, 2009 Author Report Posted December 23, 2009 amidoinitrite? /* * Reads data from rawData and formats the information the lvzImage structure * Returns the number of bytes read (should be 6+strlen(filename)+1 with CLV1 or CLV2) */ int rawToLvzImage(const u8* rawData, LvzImage* lvzImage, LvzObjectSectionType sectionType) { switch (sectionType) { case LVZ_CLV1: case LVZ_CLV2: lvzImage->framesX = rawData[1] << 8 | rawData[0]; lvzImage->framesY = rawData[3] << 8 | rawData[2]; lvzImage->animationTime = rawData[5] << 8 | rawData[4]; //Grab the image filename, located after the fixed-size header lvzImage->imageName.assign((char*)rawData+6); //include the '\0' character in the count return 7 + lvzImage->imageName.size(); case LVZ_UnsupportedFormat: return 0; } } edit: wee, that seems to work Quote
Samapico Posted December 24, 2009 Author Report Posted December 24, 2009 I did some modifications in SettingsHandler to be able to use the ScreenLocation stuff directly, without having to actually write a setting for it... void getScreenLocation(Point* loc, char letterX, int offsetX, char letterY, int offsetY) { map <char, Point>::iterator i; i = letterLocationMap.find(letterX); if (i != letterLocationMap.end()) loc->x = offsetX; else loc->x = offsetX + i->second.x; // and y i = letterLocationMap.find(letterY); if (i != letterLocationMap.end()) // fine, just a regular coordinate loc->y = offsetY; else loc->y = offsetY + i->second.y; AssignedPoint ap; ap.ptr = loc; ap.letterX = letterX; ap.letterY = letterY; ap.xOffset = offsetX; ap.yOffset = offsetY; letterAssignments.push_back(ap); } void getSettingAsScreenLocation(Point* loc, const char* category, const char* setting) { string defaultLoc = "(0, 0)"; string set = *sh.getSettingAsString2(category,setting,&defaultLoc); if (set.length() < 3 || set[0] != '(' || set[set.length() - 1] != ')') LOG_ERROR2("malformed screen location (no parenthesis): '%s'",set.c_str()); else { set = set.substr(1,set.size() - 2); // strip parenthesis size_t comma_loc = set.find(','); if (comma_loc == string::npos) LOG_ERROR2("malformed screen location (no comma): '%s'",set.c_str()); else { string first = set.substr(0,comma_loc); string second = set.substr(comma_loc + 1); trimWhitespace(&first); trimWhitespace(&second); if (first.size() > 0 && second.size() > 0) { int offsetX; char letterX = tolower(first[0]); map <char, Point>::iterator i = letterLocationMap.find(letterX); if (isdigit(letterX) || letterX == '-' ) // fine, just a regular coordinate { letterX = 0; offsetX = strtol(first.c_str(),0,0); } else { offsetX = strtol(first.c_str() + 1,0,0); } // and y int offsetY; char letterY = tolower(second[0]); i = letterLocationMap.find(letterY); if (isdigit(letterY)) // fine, just a regular coordinate { letterY = 0; offsetY = strtol(second.c_str(),0,0); } else { offsetY = strtol(second.c_str() + 1,0,0); } getScreenLocation(loc, letterX, offsetX, letterY, offsetY); } else LOG_ERROR2("Screen Location Setting doesn't contain two sets of values: '%s'",set.c_str()); } } } Not tested yet, so it may contain minor bugs, but the point is... I'd find it weird to have an interface function in settingsHandler that doesn't actually play with settings... So how would you have done it? I guess I could write a setting, then getSettingAsScreenLocation, but that seems like even more trouble for me, as I'd have to convert the already binary data to text, then back to binary through the interface. And where would that setting go anyway? Speaking of settings... all these settings are written only for the current arena, right? Say I write a bunch of settings in images and animations while loading arena 1, then go to arena 2, these settings will be gone? Quote
Samapico Posted December 24, 2009 Author Report Posted December 24, 2009 hmmmm... so my LvzObject struct has a Point * that gives it its x/y... for screenobject I just use the functions above and it will handle the object (creating and deleting it in memory); but if I have a mapobject... I could cheat and use the same functions with a 0 reference, and I know I'll use these coordinates as map reference when calling the animations... otherwise I have to keep a list of points of my own only for the mapobjects? Quote
Bak Posted December 24, 2009 Report Posted December 24, 2009 your functions look fine; even though the extra one does not deal directly with the settings, it does so indirectly (if the screen location anchors change it will update the points accordingly). It seems okay to keep it in the SettingsHandler for that reason. Your second question is an interesting one, although I think there's some misunderstanding. For the above functions, you pass in a pointer to a Point which you have allocated (either on the stack or on the heap); SettingsHandler does no memory management in this respect. For mapobjects, there are no relative values, so just get the x/y values of the mapobject and call Animation* (*playLoopingAnimation)(const char* name, int xPixel, int yPixel, bool centered, int layer); for screenobjects, the animation location may be change. Luckily, the Animations interface doesn't handle screenobjects yet so you can write it any way you want. Since all screen objects are likely to be within the bounds of the screen, it's fairly pointless to do sorting and such things for bounds checking on the screen (as is done for mapobjects for efficiency since the majority of active mapobjects are likely to be off screen). I believe it is sufficient to, internally within Animations, just have a single list of screenobjects with their Point and their display time and such. Then, the interface for creating a screenobject would be something like Animation* (*playLoopingScreenAnimation)(const char* name, char letterX, int offsetX, char letterY, int offsetY, bool centered, int layer); (in addition to the timed variant). The memory for the Point then would be managed internally within the Animations interface. If you want me to make the modifications to Animations let me know and I'll do it. Also let me know if I didn't answer what you were asking. Quote
Samapico Posted December 24, 2009 Author Report Posted December 24, 2009 Oh, that clears things up, thanks; So... I could just have a Point in my struct, and pass the pointer to the settingshandler. And then it will change the coordinates directly in my structure when the reference changes, right? (atleast that's what I understand from this bit of comment: "Note that the point pointer you pass into this function may be modified long after the call, as is the case in continuum. For example, if the player list gets resized some of the points may be moved, so DON'T USE A STACK VARIABLE.") But isn't there some kind of risk that it still tries to change my data after my structure has ceased to "exist"? You're right that the Animation interface itself could handle the Point, but will the Point data be updated as the reference changes (i.e. player hits F2), and what will happen if the reference changes after the animation is done playing and the pointer is invalid? Quote
Samapico Posted December 24, 2009 Author Report Posted December 24, 2009 Alright, this should be pretty platform-independant, and it works! LVZ ini Outfile=disc_test.lvz File=system.bmpFile=boom.bmp [objectimages]IMAGE1=system.bmp,10,6,500IMAGE2=boom.bmp,10,4,400 [mapobjects]-28000,28000,IMAGE1,BelowAll,ServerControlled,500,1-24000,24000,IMAGE1,BelowAll,ServerControlled,500,5000-1000,1000,IMAGE1,BelowAll,ServerControlled,500,100001,1,IMAGE1,BelowAll,ServerControlled,500,169000,0,IMAGE1,BelowAll,ServerControlled,500,32500 [screenobjects]0,-6,IMAGE1,TopMost,ServerControlled,500C0,B-6,IMAGE1,TopMost,Kill,500R-0,R-9,IMAGE2,AfterChat,ShowAlways,400S2047,R-1,IMAGE2,AfterChat,Death,400S-1150,R110,IMAGE2,AfterChat,Death,400R-0,R110,IMAGE2,AfterChat,Death,400 Console output Opening LVZ file 'disc_test.lvz'Lvz file 'disc_test.lvz' added3 sections in LVZSection 0: 'system.bmp', 12608 -> 287566File section 'system.bmp'File 'system.bmp' addedSection 1: 'boom.bmp', 32515 -> 485078File section 'boom.bmp'File 'boom.bmp' addedSection 2: '', 131 -> 154Object definition section: 11 objects, 2 imagesisMap:1 ID:1 Loc:( -28000, 28000)dispTime:5000 Layer:50 Image:0 Mode:5isMap:1 ID:5000 Loc:( -24000, 24000)dispTime:5000 Layer:50 Image:0 Mode:5isMap:1 ID:10000 Loc:( -1000, 1000)dispTime:5000 Layer:50 Image:0 Mode:5isMap:1 ID:16900 Loc:( 1, 1)dispTime:5000 Layer:50 Image:0 Mode:5isMap:1 ID:32500 Loc:( 0, 0)dispTime:5000 Layer:50 Image:0 Mode:5isMap:0 ID:0 Loc:(r0,r-9)dispTime:4000 Layer:650 Image:1 Mode:0isMap:0 ID:0 Loc:(s-1986,r0)dispTime:4000 Layer:650 Image:1 Mode:4isMap:0 ID:0 Loc:(s-1150,r110)dispTime:4000 Layer:650 Image:1 Mode:4isMap:0 ID:0 Loc:(r0,r110)dispTime:4000 Layer:650 Image:1 Mode:4isMap:0 ID:0 Loc:( 0, -6)dispTime:5000 Layer:50 Image:0 Mode:5isMap:0 ID:0 Loc:(c0,b-6)dispTime:5000 Layer:50 Image:0 Mode:3Image definition 'system.bmp' added (10,6,500)Image definition 'boom.bmp' added (10,4,400)Opened LVZ file 'disc_test.lvz', success=1 Da code /* * Reads data from rawData, and formats the information in the lvzObject structure * Returns the number of bytes read (should be 10 with CLV1 or CLV2) * * Some fields of lvzObject are NOT filled by this functions: * -imageHandle (this requires the UniqueImage data to be created, which requires the image definitions to be read) * -parentLvz (this is filled in addObjectDefinition, which is called after this function) * -objectName (this requires the name of the parent LVZ) * -animationTime (this is determined by the image definition, which are after the object definitions) */ /* Data layout in file Mapobject 0: [low 7 bits id] [1 bit mapobject] 1: [high 8 bits id] 2: [low 8 bits x] 3: [high 8 bits x] 4: [low 8 bits y] 5: [high 8 bits y] 6: [8 bits image num] 7: [8 bits layer] 8: [low 8 bits display time] 9: [4 bits mode] [high 4 bits display time] ScreenObject: 0: [low 7 bits id] [1 bit mapobject] 1: [high 8 bits id] 2: [low 4 bits x_coord] [4 bits x_type] 3: [high 8 bits x_coord] 4: [low 4 bits x_coord] [ 4 bits x_type] 5: [high 8 bits y_coord] 6: [8 bits image num] 7: [8 bits layer] 8: [low 8 bits display time] 9: [4 bits mode] [high 4 bits display time] */ int rawToLvzObject(const u8* rawData, LvzObject* lvzObject, LvzObjectSectionType sectionType) { switch (sectionType) { case LVZ_CLV1: case LVZ_CLV2: //MapObject: lvzObject->isMapObject = rawData[0] & 0x01; lvzObject->objectID = (rawData[0] & 0xFE) >> 1 | rawData[1] << 7; if (sectionType == LVZ_CLV2 && !lvzObject->isMapObject) { lvzObject->objectRef = Point(LVZ_SCREEN_REFERENCES[rawData[2]&0x0F], LVZ_SCREEN_REFERENCES[rawData[4]&0x0F]); lvzObject->objectLoc = Point(unsignedToSigned( (rawData[2]&0xF0) >> 4 | rawData[3] << 4, 12), unsignedToSigned( (rawData[4]&0xF0) >> 4 | rawData[5] << 4, 12) ); } else { lvzObject->objectRef = Point(0, 0); lvzObject->objectLoc = Point(unsignedToSigned( rawData[2] | rawData[3] << 8, 16) , unsignedToSigned( rawData[4] | rawData[5] << 8, 16) ); } lvzObject->imageID = rawData[6]; lvzObject->objectLayer = LVZ_LAYERS[ rawData[7]%LVZ_TopMost ]; //Display time for mapobjects and screenobjects are in 1/10th of second in the file lvzObject->displayTime = ( rawData[8] | (rawData[9] & 0x0F) << 8 ) * 100; lvzObject->displayMode = (rawData[9] & 0xF0) >> 4; printf("isMap:%i ID:%i Loc:(%c%i,%c%i)\n", lvzObject->isMapObject, lvzObject->objectID, (lvzObject->objectRef.x ? lvzObject->objectRef.x:' '), lvzObject->objectLoc.x, (lvzObject->objectRef.y ? lvzObject->objectRef.y:' '), lvzObject->objectLoc.y); printf("dispTime:%i Layer:%i Image:%i Mode:%i\n", lvzObject->displayTime, lvzObject->objectLayer, lvzObject->imageID, lvzObject->displayMode); return 10; case LVZ_UnsupportedFormat: default: return 0; } } I have some interesting functions that might be useful in other modules, dunno if they'd qualify for utilities or shared or something like that Headers /* strcmp_nonnull * Compares a non-null terminated string with another string * Useful to validate headers */ int strcmp_nonnull(const char * nonNullStr, int nonNullStrLen, const char * str2); /* freadstr * Source: http://www.daniweb.com/forums/thread171897.html# * * reads a null-terminated string from a file, from its current position * * Returns the length of the string read * Returns -1 if an error occurs */ int freadstr(FILE* fid, char* str, size_t max_size); /* * Interprets an unsigned value of n-bits as a signed value * @param unsignedValue unsigned int value to convert * @param numberOfBits number of bits on which the unsigned value is represented * @return signed value; output may be unpredictable if unsignedValue > 2^numberOfBits - 1 */ int unsignedToSigned(unsigned int unsignedValue, int numberOfBits); Body int unsignedToSigned(unsigned int unsignedValue, int numberOfBits) { if (unsignedValue >= (unsigned)(1 << (numberOfBits - 1))) //Value is negative return -((1 << numberOfBits) - unsignedValue); else //Value is positive return unsignedValue; } int freadstr(FILE* fid, char* str, size_t max_size) { int c; size_t count = 0; do { c = fgetc(fid); if (c == EOF) { /* EOF means either an error or end of <strong class="highlight">file</strong> but * we do not care which. Clear <strong class="highlight">file</strong> error flag * and return -1 */ clearerr(fid); return -1; } else { /* Cast c to char */ *str = (char) c; if (*str != '\0') count++; } } while ((*str++ != '\0') && (count < max_size)); return count; } int strcmp_nonnull(const char * nonNullStr, int nonNullStrLen, const char * str2) { int i; for (i = 0; i < nonNullStrLen; i++) if (nonNullStr[i] != str2[i]) return nonNullStr[i] - str2[i]; return 0; } Now... gotta list these object and image definitions, and link the objects to the images Quote
Bak Posted December 24, 2009 Report Posted December 24, 2009 you're right, passing a stack pointer is a bad idea. Right now, the pointers are kept forever. It's probably necessary to add a function to SettingsHandler to stop tracking Point*'s when you dispose of animations. Then, it's probably a good idea to change in SettingsHandler list letterAssignments; to map letterAssignments; for quick freeing. Quote
Samapico Posted December 24, 2009 Author Report Posted December 24, 2009 I hate these types lol... just figured I needed to do &*mylist.end() to get the pointer I needed... that's dumb Quote
Samapico Posted December 26, 2009 Author Report Posted December 26, 2009 Trying to get some images to show up... and I must say it's not going well Is there some callback I need to wait for before using the playAnimations stuff? Or maybe some place where the level is loaded that I could call my functions, instead of loading it all with the init() of my module? I think the Animations module didn't even get to its postload step, and I'm trying to make it display animations... that could explain the segfaults Also, how do I fopen/fwrite to the path of the current zone? It currently writes in the bin/bin folder... not a problem to test for now though, I just moved the files manually to the Single Player folder, and it should work there. Quote
Bak Posted December 27, 2009 Report Posted December 27, 2009 You probably should wait until the downloads complete before reading the lvz and drawing animations, the callback from FileTransfer.h is CB_PREENTER_DOWNLOADS_DONE . Doing it too early will cause segfaults, as you described. For things with precedence relationships there will usually be a callback, although for lvz waiting for the file transfers to complete will suffice (make sure it is called in single player mode though, it's possible it's not; let me know if it's not and I'll add it). For the zone path, use a function from the Net interface: /** * Get the path to the directory where the zone's file are kept, do after you set zone name, obviously. * this has the '/' at the end so you can just append a filename * @return path to the directory where the zone's file are kept */ const char* (*getZoneDataPath)();Again, use it in CB_PREENTER_DOWNLOADS_DONE and it should be valid. Also, while you're making the module (after it works), think of some cool and easy extensions to put in (for example, animations relative to specific ship types was one thing people suggested, so they could have animations on top of each type of ship). Maybe a mode like "InRegionXYZ" where XYZ is an asss region name (then again, I need a region module too), where an lvz would only display when you're in a certain region. Maybe we could incorporate sounds into lvz too (I also need a sounds module), for like entering regions, or sounds coming from certain locations on the map (I think the SDL_mixer library supports such things easily). Are there any other cool ones you can think of? Quote
Samapico Posted December 29, 2009 Author Report Posted December 29, 2009 For some reason, it crashes instantly with a 'send report' dialog when I start the .bat... I think it doesn't like my SettingsHandler module; had to recompile it with the new getScreenLocation function :/I tried by changing the version of the interface "I-SettingsHandler-23" to "I-SettingsHandler-24", and it gave me a warning about module/code versions... Also, I still can't compile 'some' projects (FileTransfer, Graphics, Net) because of:'cannot find -|SDL_net' or -|SDL_imageEven though the includes for SDL_net and SDL_image now work fine Also can't compile utilities, it seems I'm missing zlib.h ... tried to get one, but it still wouldn't work (i.e. crc32 wasn't defined) Edit: what the hell? When I run the .bat, it creates a 'SettingsHandler.so' file in \bin\Modules (NOT \bin\Modules\SettingsHandler) Quote
Bak Posted December 30, 2009 Report Posted December 30, 2009 The instant crash is because the settings handler version MUST be updated if you change the interface, and therefore all modules which use the interface must be recompiled (changing the I_ version macro will ensure it does not try to load an old version, which would lead to lead to unexpected behavior since the modules expect the function pointers to have certain offsets within the interface class, but if you change the class and recompile those offsets may change). -|SDL_net' or -|SDL_image There are two types of directories, include directories (for header files) (gcc flag -I) and library directories (for static libraries) (gcc flag -L). Header files include the function headers... ever wonder where the implementation is? It's either precompiled into a static library file (.lib), or linked dynamically during runtime (.dll or .so). For sdl_net and sdl_image, they are linked statically at compile time, so you must add the static library search path into your project. You need to add the correct library directory to project, check Prject->Properties->C/C++ Build->Settings->Tool Settings->MinGW C++ Linker->Libraries->Library Search Path. For zlib, you want version 1.2.3 (from http://www.zlib.net/ ). When I run the .bat, it creates a 'SettingsHandler.so' file in \bin\Modules (NOT \bin\Modules\SettingsHandler) Yes that's on purpose and for a reason. The front end handles the updates, and the updates MAY include an update to SettingsHandler.so . Since you can't overwrite an .so file when it's in use, and the front end uses the settings handler module, the solution is to write the updated file to Modules/SettingsHandler/SettingsHandler.so. When the front end runs, it compares \bin\Modules\SettingsHandler.so and \bin\Modules\SettingsHandler\SettingsHandler.so and, if they differ, copies \bin\Modules\SettingsHandler\SettingsHandler.so to \bin\Modules\SettingsHandler.so and loads that one. You will also need to recompile the front end (cskinviewer) to reflect the new version of the SettingsHandler module. The directory with the eclipse project is disc_client\src\FrontEnd\cskinviewer Quote
Samapico Posted December 30, 2009 Author Report Posted December 30, 2009 hmm, and what about zdll? I managed to get everything working now, except that "cannot find -lzdll"I added the search path to C:\MinGW\lib\zlib-1.2.3 , where I unzipped the whole zlib 1.2.3 source bleh Edit: ok got it... now to aedGuiBak... Edit2: emm... added a search path to "D:\Sam\Prog Projects\Discretion\client\trunk\disc_client\deps\aedGUI-0.1.8a-bak\Release", still doesn't want to work... Quote
Bak Posted December 31, 2009 Report Posted December 31, 2009 Here's mine: http://img.photobucket.com/albums/v622/bak2007/cskin_settings.png I think with gcc/minGW you can even link directly to the .dll instead of using a library... also that stuff I said before about static libraries is true, but these ones are all dynamic (they have a corresponding .dll file), the library simply includes the offsets within the .dll, or something to that effect, not the actual source. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.