diff --git a/JGE/include/JRenderer.h b/JGE/include/JRenderer.h index ea2a2d38e..e2bda765e 100644 --- a/JGE/include/JRenderer.h +++ b/JGE/include/JRenderer.h @@ -41,7 +41,6 @@ #endif - #include "Vector2D.h" #define USING_MATH_TABLE @@ -532,7 +531,7 @@ private: }; void LoadJPG(TextureInfo &textureInfo, const char *filename, int mode = 0, int TextureFormat = TEXTURE_FORMAT); - void LoadPNG(TextureInfo &textureInfo, const char *filename, int mode = 0, int TextureFormat = TEXTURE_FORMAT); + int LoadPNG(TextureInfo &textureInfo, const char *filename, int mode = 0, int TextureFormat = TEXTURE_FORMAT); void LoadGIF(TextureInfo &textureInfo, const char *filename, int mode = 0, int TextureFormat = TEXTURE_FORMAT); int image_readgif(void * handle, TextureInfo &textureInfo, DWORD * bgcolor, InputFunc readFunc,int mode = 0, int TextureFormat = TEXTURE_FORMAT); diff --git a/JGE/include/JTypes.h b/JGE/include/JTypes.h index 82b9045e5..767c9009e 100644 --- a/JGE/include/JTypes.h +++ b/JGE/include/JTypes.h @@ -39,6 +39,13 @@ #define MAX_CHANNEL 128 +enum { + JGE_ERR_CANT_OPEN_FILE = -1, + JGE_ERR_PNG = -2, + JGE_ERR_MALLOC_FAILED = -4, + JGE_ERR_GENERIC = -5, +}; + #ifndef M_PI #define M_PI 3.14159265358979323846f diff --git a/JGE/src/JFileSystem.cpp b/JGE/src/JFileSystem.cpp index 6d04ef89d..6ba9320aa 100644 --- a/JGE/src/JFileSystem.cpp +++ b/JGE/src/JFileSystem.cpp @@ -14,6 +14,7 @@ #include "../include/JGE.h" #include "../include/JFileSystem.h" +#include "../include/JLogger.h" #include "tinyxml/tinyxml.h" #include "unzip/unzip.h" @@ -155,6 +156,8 @@ bool JFileSystem::OpenFile(const string &filename) { string path = mResourceRoot + filename; + JLOG("JFileSystem::OpenFile"); + JLOG(path.c_str()); if (mZipAvailable && mZipFile != NULL) { diff --git a/JGE/src/JGfx.cpp b/JGE/src/JGfx.cpp index c4296bd64..c8083a9a2 100644 --- a/JGE/src/JGfx.cpp +++ b/JGE/src/JGfx.cpp @@ -19,6 +19,7 @@ #include #include #include "../include/vram.h" +#include "../include/JLogger.h" #ifdef __cplusplus extern "C" { @@ -39,58 +40,6 @@ static unsigned int __attribute__((aligned(16))) list[262144]; extern void SwizzlePlot(u8* out, PIXEL_TYPE color, int i, int j, unsigned int width); -/* -//START PurpleScreen Debug -int JRenderer::debugged = 0; -typedef struct -{ - unsigned int* start; - unsigned int* current; - int parent_context; -} GuDisplayList; - -typedef struct -{ - GuDisplayList list; - int scissor_enable; - int scissor_start[2]; - int scissor_end[2]; - int near_plane; - int far_plane; - int depth_offset; - int fragment_2x; - int texture_function; - int texture_proj_map_mode; - int texture_map_mode; - int sprite_mode[4]; - unsigned int clear_color; - unsigned int clear_stencil; - unsigned int clear_depth; - int texture_mode; -} GuContext; - -typedef struct -{ - int pixel_size; - int frame_width; - void* frame_buffer; - void* disp_buffer; - void* depth_buffer; - int depth_width; - int width; - int height; - } GuDrawBuffer; - -extern int gu_curr_context; -extern GuDrawBuffer gu_draw_buffer; -extern GuContext gu_contexts[3]; -extern GuDisplayList* gu_list; - - -//END PurpleScreen Debug - -*/ - void Swap(float *a, float *b) { float n=*a; @@ -98,8 +47,6 @@ void Swap(float *a, float *b) *b = n; } - - JQuad::JQuad(JTexture *tex, float x, float y, float width, float height) :mTex(tex), mX(x), mY(y), mWidth(width), mHeight(height) { @@ -402,30 +349,6 @@ void JRenderer::EndScene() mCurrentTex = -1; mCurrentBlend = -1; - - /* -//START PurpleScreen Debug - if (!debugged){ - debugged = 1; - FILE * pFile; - pFile = fopen ("graphiclog.txt","w"); - char temp[4096]; - sprintf(temp,"fbp0:%p\nfbp1:%p\nBuffer Format:%d\nFrame Buffer Width:%d\nScreen Width:%d\nScreen Height:%d\n",fbp0,fbp1,BUFFER_FORMAT,FRAME_BUFFER_WIDTH,SCREEN_WIDTH,SCREEN_HEIGHT); - fputs(temp,pFile); - sprintf(temp,"\nDRAW BUFFER:\npixel_size:%d\nframe_width:%d\nframe_buffer:%p\n",gu_draw_buffer.pixel_size,gu_draw_buffer.frame_width,gu_draw_buffer.frame_buffer); - fputs(temp,pFile); - sprintf(temp,"disp_buffer:%p\ndepth_buffer:%p\ndepth_width:%d\nwidth:%d\nheight:%d\n",gu_draw_buffer.disp_buffer,gu_draw_buffer.depth_buffer,gu_draw_buffer.depth_width,gu_draw_buffer.width,gu_draw_buffer.height); - fputs(temp,pFile); - - GuContext gc = gu_contexts[gu_curr_context]; - - sprintf(temp,"\nGU CONTEXT:\nscissor_enable:%d\ndepth_offset:%d\nfragment_2x:%d\ntexture_function:%d\ntexture_mode:%d\n",gc.scissor_enable,gc.depth_offset,gc.fragment_2x,gc.texture_function,gc.texture_mode); - fputs(temp,pFile); - fclose (pFile); - } -//END PurpleScreen Debug -*/ - } @@ -1039,6 +962,7 @@ int JRenderer::PixelSize(int textureMode){ void JRenderer::LoadJPG(TextureInfo &textureInfo, const char *filename, int mode, int textureMode) { + JLOG("JRenderer::LoadJPG"); textureInfo.mBits = NULL; char filenamenew[4096]; #ifdef RESPATH @@ -1241,15 +1165,19 @@ void JRenderer::LoadJPG(TextureInfo &textureInfo, const char *filename, int mode jpeg_destroy_decompress(&cinfo); delete [] rawdata; + JLOG("-- OK -- JRenderer::LoadJPG"); } JTexture* JRenderer::LoadTexture(const char* filename, int mode, int textureMode) { + JLOG("JRenderer::LoadTexture"); TextureInfo textureInfo; textureInfo.mVRAM = false; textureInfo.mBits = NULL; + int ret = 0; + if (strstr(filename, ".jpg")!=NULL || strstr(filename, ".JPG")!=NULL) LoadJPG(textureInfo, filename, mode, textureMode); else if(strstr(filename, ".gif")!=NULL || strstr(filename, ".GIF")!=NULL) { @@ -1258,7 +1186,12 @@ JTexture* JRenderer::LoadTexture(const char* filename, int mode, int textureMode } else if(strstr(filename, ".png")!=NULL || strstr(filename, ".PNG")!=NULL) { textureMode = TEXTURE_FORMAT; //textureMode not supported in PNG yet - LoadPNG(textureInfo, filename, mode, textureMode); + ret = LoadPNG(textureInfo, filename, mode, textureMode); + if (ret < 0) { + char buf[512]; + sprintf(buf, "--LoadPNG sent error code: %i for file %s", ret, filename); + JLOG(buf); + } } if (textureInfo.mBits == NULL) @@ -1290,6 +1223,7 @@ JTexture* JRenderer::LoadTexture(const char* filename, int mode, int textureMode SAFE_DELETE(tex); } + JLOG("-- OK -- JRenderer::LoadTexture"); return tex; } @@ -1300,8 +1234,9 @@ JTexture* JRenderer::LoadTexture(const char* filename, int mode, int textureMode // http://svn.ps2dev.org/filedetails.php?repname=psp&path=/trunk/libpng/screenshot/main.c&rev=0&sc=0 // Load PNG as texture //------------------------------------------------------------------------------------------------ -void JRenderer::LoadPNG(TextureInfo &textureInfo, const char* filename, int mode, int textureMode) +int JRenderer::LoadPNG(TextureInfo &textureInfo, const char* filename, int mode, int textureMode) { + JLOG("JRenderer::LoadPNG"); textureInfo.mBits = NULL; bool useVideoRAM = (mode == TEX_TYPE_USE_VRAM); @@ -1317,19 +1252,19 @@ void JRenderer::LoadPNG(TextureInfo &textureInfo, const char* filename, int mode u32* line; JFileSystem* fileSystem = JFileSystem::GetInstance(); - if (!fileSystem->OpenFile(filename)) return; + if (!fileSystem->OpenFile(filename)) return JGE_ERR_CANT_OPEN_FILE; png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL) { fileSystem->CloseFile(); - return; + return JGE_ERR_PNG; } png_set_error_fn(png_ptr, (png_voidp) NULL, (png_error_ptr) NULL, PNGCustomWarningFn); info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { fileSystem->CloseFile(); png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL); - return; + return JGE_ERR_PNG; } png_init_io(png_ptr, NULL); png_set_read_fn(png_ptr, (png_voidp)fileSystem, PNGCustomReadDataFn); @@ -1347,7 +1282,7 @@ void JRenderer::LoadPNG(TextureInfo &textureInfo, const char* filename, int mode if (!line) { fileSystem->CloseFile(); png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL); - return; + return JGE_ERR_MALLOC_FAILED; } int texWidth = getNextPower2(width); @@ -1440,7 +1375,8 @@ void JRenderer::LoadPNG(TextureInfo &textureInfo, const char* filename, int mode textureInfo.mTexWidth = texWidth; textureInfo.mTexHeight = texHeight; textureInfo.mVRAM = videoRAMUsed; - + JLOG("-- OK -- JRenderer::LoadPNG"); + return 1; } else @@ -1452,6 +1388,7 @@ void JRenderer::LoadPNG(TextureInfo &textureInfo, const char* filename, int mode vfree(bits); else free(bits); + return JGE_ERR_GENERIC; } } diff --git a/JGE/src/main.cpp b/JGE/src/main.cpp index 7048d666a..4ba434636 100644 --- a/JGE/src/main.cpp +++ b/JGE/src/main.cpp @@ -361,6 +361,9 @@ void Run() // The main loop int main() { +#ifdef DOJLOG + remove(JGE_LOG_FILE); +#endif JLOG("SetupCallbacks()"); SetupCallbacks(); #ifdef DEVHOOK diff --git a/JGE/src/pc/JGfx.cpp b/JGE/src/pc/JGfx.cpp index 054c3e30c..02489d5db 100644 --- a/JGE/src/pc/JGfx.cpp +++ b/JGE/src/pc/JGfx.cpp @@ -813,7 +813,7 @@ JTexture* JRenderer::LoadTexture(const char* filename, int mode, int TextureForm return tex; } -void JRenderer::LoadPNG(TextureInfo &textureInfo, const char *filename, int mode __attribute__((unused)), int TextureFormat __attribute__((unused))) +int JRenderer::LoadPNG(TextureInfo &textureInfo, const char *filename, int mode __attribute__((unused)), int TextureFormat __attribute__((unused))) { //TextureInfo* textureInfo = new TextureInfo; @@ -836,7 +836,7 @@ void JRenderer::LoadPNG(TextureInfo &textureInfo, const char *filename, int mode //if ((fp = fopen(filename, "rb")) == NULL) return NULL; JFileSystem* fileSystem = JFileSystem::GetInstance(); - if (!fileSystem->OpenFile(filename)) return; + if (!fileSystem->OpenFile(filename)) return JGE_ERR_CANT_OPEN_FILE; png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL) @@ -844,7 +844,7 @@ void JRenderer::LoadPNG(TextureInfo &textureInfo, const char *filename, int mode //fclose(fp); fileSystem->CloseFile(); - return; + return JGE_ERR_PNG; } png_set_error_fn(png_ptr, (png_voidp) NULL, (png_error_ptr) NULL, PNGCustomWarningFn); @@ -856,7 +856,7 @@ void JRenderer::LoadPNG(TextureInfo &textureInfo, const char *filename, int mode png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL); - return; + return JGE_ERR_PNG; } png_init_io(png_ptr, NULL); png_set_read_fn(png_ptr, (png_voidp)fileSystem, PNGCustomReadDataFn); @@ -878,7 +878,7 @@ void JRenderer::LoadPNG(TextureInfo &textureInfo, const char *filename, int mode fileSystem->CloseFile(); png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL); - return; + return JGE_ERR_MALLOC_FAILED; } @@ -893,23 +893,9 @@ void JRenderer::LoadPNG(TextureInfo &textureInfo, const char *filename, int mode if (buffer) { -// tex->mFilter = TEX_FILTER_LINEAR; -// tex->mWidth = width; -// tex->mHeight = height; -// tex->mTexWidth = tw; -// tex->mTexHeight = th; -// GLuint texid; -// glGenTextures(1, &texid); -// tex->mTexId = texid; -// if (texid != 0) - { - - // OpenGL texture has (0,0) at lower-left - // Pay attention when doing texture mapping!!! - - p32 = (DWORD*) buffer;// + (height-1)*width; + p32 = (DWORD*) buffer; for (y = 0; y < (int)height; y++) { @@ -917,7 +903,6 @@ void JRenderer::LoadPNG(TextureInfo &textureInfo, const char *filename, int mode for (x = 0; x < (int)width; x++) { DWORD color32 = line[x]; - //u16 color16; int a = (color32 >> 24) & 0xff; int r = color32 & 0xff; int g = (color32 >> 8) & 0xff; @@ -931,40 +916,8 @@ void JRenderer::LoadPNG(TextureInfo &textureInfo, const char *filename, int mode } - -// glBindTexture(GL_TEXTURE_2D, texid); // Bind To The Texture ID -// -// -// if (mode == TEX_TYPE_MIPMAP) // generate mipmaps -// { -// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); -// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); -// glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); -// glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR); -// gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, tw, th, GL_RGBA, GL_UNSIGNED_BYTE, buffer); -// } -// else if (mode == TEX_TYPE_SKYBOX) // for skybox -// { -// #define GL_CLAMP_TO_EDGE 0x812F -// -// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); -// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); -// gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, tw, th, GL_RGBA, GL_UNSIGNED_BYTE, buffer); -// } -// else // single texture -// { -// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); -// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); -// glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); -// glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); -// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tw, th, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); -// } - -// ret = TRUE; - } -// delete buffer; } @@ -973,17 +926,8 @@ void JRenderer::LoadPNG(TextureInfo &textureInfo, const char *filename, int mode png_read_end(png_ptr, info_ptr); png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); - //fclose(fp); fileSystem->CloseFile(); -// if (!ret) -// { -// if (tex) -// delete tex; -// tex = NULL; -// } -// -// return tex; textureInfo.mBits = buffer; textureInfo.mWidth = width; @@ -991,6 +935,7 @@ void JRenderer::LoadPNG(TextureInfo &textureInfo, const char *filename, int mode textureInfo.mTexWidth = tw; textureInfo.mTexHeight = th; + return 1; //return textureInfo; } diff --git a/projects/mtg/bin/Res/campaigns/01.Where it all begins/story.xml b/projects/mtg/bin/Res/campaigns/01.Where it all begins/story.xml index 1273fd98c..215e46794 100644 --- a/projects/mtg/bin/Res/campaigns/01.Where it all begins/story.xml +++ b/projects/mtg/bin/Res/campaigns/01.Where it all begins/story.xml @@ -2,25 +2,26 @@ dialog -WELCOME YOUNG ADVENTURER... -_gfx/shopkeeper.jpg -So you want to become a sorcerer? -You've come to the right place. I'm myself just -a humble retailer, but I've met a lot of adventurers like you -in my life, enough to understand the basics of their craft... +WELCOME YOUNG ADVENTURER... +_gfx/shopkeeper.jpg +So you want to become a sorcerer? +You've come to the right place. I'm myself just +a humble retailer, but I've met a lot of adventurers like you +in my life, enough to understand the basics of their craft... -Interested? +I want to know more +Take me back to the menu dialog -TAPPING LANDS FOR MANA -In your quests you will have to fight against other wizards. -You will only have your brain and your spells to help you. -The basic Energy to cast your spells in Wagic is called mana. -The most frequent sources of Mana are called "Lands". -For a land to produce mana, -you just have to click on it with the action button (CIRCLE by default) +TAPPING LANDS FOR MANA +In your quests you will have to fight against other wizards. +You will only have your brain and your spells to help you. +The basic Energy to cast your spells in Wagic is called mana. +The most frequent sources of Mana are called "Lands". +For a land to produce mana, +you just have to click on it with the action button (CIRCLE by default) Go ahead and tap some mana! @@ -32,22 +33,22 @@ dialog -HMMM... -It seems you didn't get that right -Simply navigate (with the D-Pad) to the land that appears on your screen, -then click on the action button (CIRCLE by default) +HMMM... +It seems you didn't get that right +Simply navigate (with the D-Pad) to the land that appears on your screen, +then click on the action button (CIRCLE by default) Let's try again! dialog -WELL DONE...NOW LET'S CAST A SPELL -That was too easy for you! -Now let's see if you can cast a spell... -Spells have a cost represented by mana symbols on the top right corner -of the card. For example, 2 white mana icons on the top right of the card -means that you have to produce 2 white manas (by activating 2 plains) -in order to put it into play. +WELL DONE...NOW LET'S CAST A SPELL +That was too easy for you! +Now let's see if you can cast a spell... +Spells have a cost represented by mana symbols on the top right corner +of the card. For example, 2 white mana icons on the top right of the card +means that you have to produce 2 white manas (by activating 2 plains) +in order to put it into play. Try to produce 2 white mana and put a white knight in play @@ -59,24 +60,24 @@ dialog -HMMM... -It seems you didn't get that right -Simply navigate (with the D-Pad) to the lands that appear on your screen, -then click on the action button (CIRCLE by default) on each of them to produce 2 white mana. -Once this is done, navigate to the White Knight in your hand and click (CIRCLE by default) on it. -Depending on your configuration, you might need to display your hand (RTRIGGER by default) +HMMM... +It seems you didn't get that right +Simply navigate (with the D-Pad) to the lands that appear on your screen, +then click on the action button (CIRCLE by default) on each of them to produce 2 white mana. +Once this is done, navigate to the White Knight in your hand and click (CIRCLE by default) on it. +Depending on your configuration, you might need to display your hand (RTRIGGER by default) Let's try again! dialog -PERFECT...BUT THERE'S MORE TO IT -You did great, young adventurer! -But you will see that some spells have slighlty different costs. -Sometimes the cost contains a number with no mana color. It means you can -pay with mana of whatever color you want. -for example a card which cost has a number "1" and a green icon -needs you to pay 1 green mana + a mana of any color if you want to play it. +PERFECT...BUT THERE'S MORE TO IT +You did great, young adventurer! +But you will see that some spells have slighlty different costs. +Sometimes the cost contains a number with no mana color. It means you can +pay with mana of whatever color you want. +for example a card which cost has a number "1" and a green icon +needs you to pay 1 green mana + a mana of any color if you want to play it. Try to put a grizzly bear card in play. @@ -88,25 +89,25 @@ dialog -HMMM... -It seems you didn't get that right -Simply navigate (with the D-Pad) to the lands that appear on your screen, -then click on the action button (CIRCLE by default) on some of them to produce some mana. -Remember, you need 1 green mana and one other mana of any color. -Once this is done, navigate to the Grizzly Bears in your hand and click (CIRCLE by default) on it. +HMMM... +It seems you didn't get that right +Simply navigate (with the D-Pad) to the lands that appear on your screen, +then click on the action button (CIRCLE by default) on some of them to produce some mana. +Remember, you need 1 green mana and one other mana of any color. +Once this is done, navigate to the Grizzly Bears in your hand and click (CIRCLE by default) on it. Let's try again! dialog -GREAT. NOW LET'S TALK ABOUT PHASES -Once you put them into play, you will want your creatures to attack your opponent. -After all, they are here to help you defeat other sorcerers! -Your creatures can't attack anytime they want, however, -they must wait for the combat phase of your turn. -Your turn is divided into several phases. You can go through the phases by -clicking on LTRIGGER by default. The name of the current phase is displayed on the -top right corner of the screen. +GREAT. NOW LET'S TALK ABOUT PHASES +Once you put them into play, you will want your creatures to attack your opponent. +After all, they are here to help you defeat other sorcerers! +Your creatures can't attack anytime they want, however, +they must wait for the combat phase of your turn. +Your turn is divided into several phases. You can go through the phases by +clicking on LTRIGGER by default. The name of the current phase is displayed on the +top right corner of the screen. Go to the "Attackers" phase, then click on your White Knight to attack. @@ -119,31 +120,31 @@ dialog -HMMM... -It seems you didn't get that right -Go to the "Attackers" phase by clicking on LTRIGGER several times, -then click on your White Knight (with CIRCLE by default) to attack your opponent. +HMMM... +It seems you didn't get that right +Go to the "Attackers" phase by clicking on LTRIGGER several times, +then click on your White Knight (with CIRCLE by default) to attack your opponent. Let's try again! dialog -GOOD! -Let me tell you a bit more about phases. -Your turn is divided into several phases. The actions you can perform -Depend on the phase you're in. For now, let's say that you can: -- Play creatures during the "main phase 1" and the "main phase 2" phases of your turn. -- Attack with your creatures during the "Attackers" phase of your turn. -- Block your opponent's attacking creatures during the "blockers" phase of his turn. -There are lots of other phases but we'll discuss them later +GOOD! +Let me tell you a bit more about phases. +Your turn is divided into several phases. The actions you can perform +Depend on the phase you're in. For now, let's say that you can: +- Play creatures during the "main phase 1" and the "main phase 2" phases of your turn. +- Attack with your creatures during the "Attackers" phase of your turn. +- Block your opponent's attacking creatures during the "blockers" phase of his turn. +There are lots of other phases but we'll discuss them later Continue End -CONGRATULATIONS! -This is the end of this tutorial, -now time for you to fight some real ennemies! -Click on the action button to go back to the main menu +CONGRATULATIONS! +This is the end of this tutorial, +now time for you to fight some real ennemies! +Click on the action button to go back to the main menu diff --git a/projects/mtg/bin/Res/campaigns/README.txt b/projects/mtg/bin/Res/campaigns/README.txt new file mode 100644 index 000000000..9ab43a3fb --- /dev/null +++ b/projects/mtg/bin/Res/campaigns/README.txt @@ -0,0 +1,69 @@ +Documentation for the Basic campaign system in Wagic + +Each subfolder that contains a "story.xml" is considered as a "story". Stories appear in the menu and represent +a series of dialogs and duels. + +################################# + 1.Structure of story.xml: +################################# + +=========================================== +Elements of the root node +=========================================== + +page * + attributes: + id (compulsory) + +=========================================== +Elements of the page node +=========================================== + +type (dialog,duel,end) + + +=========================================== +Additional Elmts of the "page" node if type == dialog +=========================================== + +title * +img * +text * +answer * + +title, img, text, answer have the following common attributes: +x (optional - default 0) + 0 means auto + 0 < x < 1 means percentage of screen width + other value = absolute position +y (optional - default 0) + -1 means: go to previous line + 0 means: auto + 0 < y < 1 means: percentage of screen height + other value = absolute position +font (optional - default 0) + 0, 1, or 2 +align (optional - default left) + left, center, right + + +font and align not supported by title, which is equivalent to + +answer specific attributes: +goto + id of a page to go to + +=========================================== +Additional Elmts of the "page" node if type == dialog +=========================================== +onwin + id of a page to go to if duel lost +onlose + id of a page to go to if duel won + + + + +################################# + 2.Duel mode +################################# \ No newline at end of file diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index 7ce7bc7d8..e9ba6a179 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -8662,7 +8662,7 @@ name=Corpse Hatch target=creature[-black] auto=destroy auto=Token(-193507)*2 -text=Destroy target nonblack creature. -- Put two 0/1 colorless Eldrazi Spawn creature tokens onto the battlefield. They have “Sacrifice this creature: Add {1} to your mana pool.” +text=Destroy target nonblack creature. -- Put two 0/1 colorless Eldrazi Spawn creature tokens onto the battlefield. They have “Sacrifice this creature: Add {1} to your mana pool.E mana={3}{B}{B} type=Sorcery [/card] @@ -14631,30 +14631,30 @@ type=Creature subtype=Faerie Soldier power=3 toughness=2 -[/card] +[/card] -[card] +[card] name=Feral Hydra - + type=Creature - + subtype=Hydra Beast - + mana={X}{G} - + power=0 - -toughness=0 + +toughness=0 text=Feral Hydra enters the battlefield with X +1/+1 counters on it. -- {3}: Put a +1/+1 counter on Feral Hydra. Any player may play this ability - + auto=counter(1/1,X) - + auto={3}:counter(1/1) - + grade=borderline - + [/card] [card] name=Feral Instinct @@ -17052,6 +17052,8 @@ toughness=3 name=Giant Growth text=Target creature gets +3/+3 until end of turn. mana={G} +target=creature +auto=3/3 type=Instant [/card] [card] @@ -18876,7 +18878,7 @@ name=Grizzly Fate auto=token(Bear,creature bear, 2/2,green)*2 auto=aslongas(*|mygraveyard) token(Bear,creature bear, 2/2,green)*2 >6 autograveyard={5}{G}{G}:copy(this) && moveTo(mystack) asSorcery -text=Put two 2/2 green Bear creature tokens onto the battlefield. -- Threshold — Put four 2/2 green Bear creature tokens onto the battlefield instead if seven or more cards are in your graveyard. -- Flashback {2}{G}{G} (You may cast this card from your graveyard for its flashback cost. Then exile it.) +text=Put two 2/2 green Bear creature tokens onto the battlefield. -- Threshold EPut four 2/2 green Bear creature tokens onto the battlefield instead if seven or more cards are in your graveyard. -- Flashback {2}{G}{G} (You may cast this card from your graveyard for its flashback cost. Then exile it.) mana={3}{G}{G} type=Sorcery [/card] @@ -21713,7 +21715,7 @@ type=Enchantment name=Ior Ruin Expedition auto=@movedTo(land|myBattlefield):may counter(0/0,1,Quest) auto={C(0/0,-3,Quest)}{S}:draw:2 -text=Landfall — Whenever a land enters the battlefield under your control, you may put a quest counter on Ior Ruin Expedition. -- Remove three quest counters from Ior Ruin Expedition and sacrifice it: Draw two cards. +text=Landfall EWhenever a land enters the battlefield under your control, you may put a quest counter on Ior Ruin Expedition. -- Remove three quest counters from Ior Ruin Expedition and sacrifice it: Draw two cards. mana={1}{U} type=Enchantment [/card] @@ -43026,7 +43028,7 @@ toughness=1 name=Sunspring Expedition auto=@movedTo(land|myBattlefield):may counter(0/0,1,Quest) auto={C(0/0,-3,Quest)}{S}:life:8 -text=Landfall — Whenever a land enters the battlefield under your control, you may put a quest counter on Sunspring Expedition. -- Remove three quest counters from Sunspring Expedition and sacrifice it: You gain 8 life. +text=Landfall EWhenever a land enters the battlefield under your control, you may put a quest counter on Sunspring Expedition. -- Remove three quest counters from Sunspring Expedition and sacrifice it: You gain 8 life. mana={W} type=Enchantment [/card] @@ -46531,7 +46533,7 @@ auto=foreach(other creature[red]|myBattlefield) counter(1/1,1) auto=foreach(other creature[green]|myBattlefield) counter(1/1,1) auto={1}{C(1/1,-1)}:damage:1 target(creature) auto={1}{C(1/1,-1)}:token(Saproling,Creature Saproling,1/1,green) -text=Ulasht, the Hate Seed enters the battlefield with a +1/+1 counter on it for each other red creature you control and a +1/+1 counter on it for each other green creature you control. -- {1}, Remove a +1/+1 counter from Ulasht: Choose one — Ulasht deals 1 damage to target creature; or put a 1/1 green Saproling creature token onto the battlefield. +text=Ulasht, the Hate Seed enters the battlefield with a +1/+1 counter on it for each other red creature you control and a +1/+1 counter on it for each other green creature you control. -- {1}, Remove a +1/+1 counter from Ulasht: Choose one EUlasht deals 1 damage to target creature; or put a 1/1 green Saproling creature token onto the battlefield. mana={2}{R}{G} type=Legendary Creature subtype=Hellion Hydra @@ -46557,7 +46559,7 @@ auto=@damaged(creature,player) from(mytgt):counter(0/0,2,Charge) all(this) auto={C(0/0,-1,Charge)}:2/2 auto={C(0/0,-1,Charge)}:-1/-1 target(creature) auto={C(0/0,-1,Charge)}:life:2 controller -text=Whenever equipped creature deals combat damage, put two charge counters on Umezawa's Jitte. -- Remove a charge counter from Umezawa's Jitte: Choose one — Equipped creature gets +2/+2 until end of turn; or target creature gets -1/-1 until end of turn; or you gain 2 life. -- Equip {2} +text=Whenever equipped creature deals combat damage, put two charge counters on Umezawa's Jitte. -- Remove a charge counter from Umezawa's Jitte: Choose one EEquipped creature gets +2/+2 until end of turn; or target creature gets -1/-1 until end of turn; or you gain 2 life. -- Equip {2} mana={2} type=Legendary Artifact subtype=Equipment diff --git a/projects/mtg/bin/Res/test/_tests.txt b/projects/mtg/bin/Res/test/_tests.txt index a147869f4..f6788fb35 100644 --- a/projects/mtg/bin/Res/test/_tests.txt +++ b/projects/mtg/bin/Res/test/_tests.txt @@ -389,7 +389,6 @@ shivan_hellkite.txt shock.txt shock2.txt siege_gang_commander.txt -silent_arbiter.txt simic_initiate.txt slate_of_ancestry.txt sleeper_agent.txt diff --git a/projects/mtg/include/StoryFlow.h b/projects/mtg/include/StoryFlow.h index e9046d45c..1285540e8 100644 --- a/projects/mtg/include/StoryFlow.h +++ b/projects/mtg/include/StoryFlow.h @@ -11,42 +11,48 @@ class GameObserver; #define CAMPAIGNS_FOLDER "Res/campaigns/" -class StoryGraphicalElement:public JGuiObject { +class StoryDialogElement:public JGuiObject { public: float mX; float mY; - StoryGraphicalElement(float x, float y); + StoryDialogElement(float x, float y, int id = 0); + void Entering(){}; + bool Leaving(JButton key) {return false;}; + bool ButtonPressed() {return false;}; + bool hasFocus() {return false;}; + virtual float getHeight() = 0; }; -class StoryText:public StoryGraphicalElement { +class StoryText:public StoryDialogElement { public : string text; int align; -StoryText(string text, float mX, float mY, string align = "center"); + int font; +StoryText(string text, float mX, float mY, string align = "center", int font = 0, int id = 0); + void Render(); void Update(float dt); virtual ostream& toString(ostream& out) const; + float getHeight(); }; -class StoryImage:public StoryGraphicalElement { +class StoryImage:public StoryDialogElement { public : string img; StoryImage(string img, float mX, float mY); void Render(); void Update(float dt); virtual ostream& toString(ostream& out) const; + float getHeight(); }; -class StoryChoice:public JGuiObject { +class StoryChoice:public StoryText { public: string pageId; - string text; - float mX; - float mY; bool mHasFocus; float mScale; float mTargetScale; - StoryChoice(string id, string text, int JGOid, float mX, float mY, bool hasFocus); + StoryChoice(string id, string text, int JGOid, float mX, float mY, string _align, int _font, bool hasFocus); void Render(); void Update(float dt); @@ -55,11 +61,12 @@ public: bool ButtonPressed(); bool hasFocus(); virtual ostream& toString(ostream& out) const; + float getHeight(); }; class StoryFlow; class StoryPage { -public: +public: StoryFlow * mParent; StoryPage(StoryFlow * mParent); virtual void Update(float dt)=0; @@ -69,15 +76,18 @@ public: class StoryDialog:public StoryPage, public JGuiListener,public JGuiController { private: - vectorgraphics; + vectorgraphics; string safeAttribute(TiXmlElement* element, string attribute); - + void RenderElement(StoryDialogElement * elmt); public: StoryDialog(TiXmlElement* el,StoryFlow * mParent); ~StoryDialog(); void Update(float dt); void Render(); void ButtonPressed(int,int); + + static float currentY; + static float previousY; }; diff --git a/projects/mtg/src/GameStateMenu.cpp b/projects/mtg/src/GameStateMenu.cpp index 94113549a..7ecb37efa 100644 --- a/projects/mtg/src/GameStateMenu.cpp +++ b/projects/mtg/src/GameStateMenu.cpp @@ -472,7 +472,6 @@ void GameStateMenu::Update(float dt) currentState = MENU_STATE_MAJOR_SUBMENU; subMenuController = NEW SimpleMenu(102, this, Constants::MENU_FONT, 150,60); if (subMenuController){ - subMenuController->Add(SUBMENUITEM_STORY,"Story"); subMenuController->Add(SUBMENUITEM_CLASSIC,"Classic"); if (options[Options::MOMIR_MODE_UNLOCKED].number) subMenuController->Add(SUBMENUITEM_MOMIR, "Momir Basic"); @@ -480,6 +479,7 @@ void GameStateMenu::Update(float dt) subMenuController->Add(SUBMENUITEM_RANDOM1, "Random 1 Color"); subMenuController->Add(SUBMENUITEM_RANDOM2, "Random 2 Colors"); } + subMenuController->Add(SUBMENUITEM_STORY,"Story"); subMenuController->Add(SUBMENUITEM_CANCEL, "Cancel"); } }else{ diff --git a/projects/mtg/src/StoryFlow.cpp b/projects/mtg/src/StoryFlow.cpp index 1ae06466f..d1ae365ce 100644 --- a/projects/mtg/src/StoryFlow.cpp +++ b/projects/mtg/src/StoryFlow.cpp @@ -9,26 +9,42 @@ #include -StoryGraphicalElement::StoryGraphicalElement(float x, float y): JGuiObject(0), mX(x),mY(y) { +#define LINE_SPACE 2 +#define SPACE_BEFORE_CHOICES 10 + +float StoryDialog::currentY = 2; +float StoryDialog::previousY = 2; + +StoryDialogElement::StoryDialogElement(float x, float y, int id): JGuiObject(id), mX(x),mY(y) { } -StoryText::StoryText(string text, float _mX, float _mY, string _align):StoryGraphicalElement(_mX,_mY), text(text) { +StoryText::StoryText(string text, float _mX, float _mY, string _align, int _font, int id):StoryDialogElement(_mX,_mY, id), text(text), font(_font) { align = JGETEXT_LEFT; if (_align.compare("center") == 0) { align = JGETEXT_CENTER; + if (mX == 0) + mX = SCREEN_WIDTH/2; }else if (_align.compare("right") == 0) { align = JGETEXT_RIGHT; + if (mX == 0) + mX = SCREEN_WIDTH - 10; } - if (align == JGETEXT_CENTER && mX == 0){ - mX = SCREEN_WIDTH/2; + if (align == JGETEXT_LEFT && mX <= 0){ + mX += 10; //left margin } } void StoryText::Render() { - JLBFont * mFont = resources.GetJLBFont(Constants::MAIN_FONT); + JLBFont * mFont = resources.GetJLBFont(font); mFont->SetColor(ARGB(200,255,255,255)); mFont->SetScale(1.0); mFont->DrawString(text.c_str(), mX, mY, align); } + +float StoryText::getHeight() { + JLBFont * mFont = resources.GetJLBFont(font); + return mFont->GetHeight(); +} + void StoryText::Update(float dt){ //Nothing for now } @@ -38,7 +54,7 @@ void StoryText::Render() { return out << "StoryText ::: text : " << text; } - StoryImage::StoryImage(string img, float mX, float mY):StoryGraphicalElement(mX,mY), img(img) { + StoryImage::StoryImage(string img, float mX, float mY):StoryDialogElement(mX,mY), img(img) { } void StoryImage::Render() { @@ -52,6 +68,15 @@ void StoryImage::Render() { JRenderer::GetInstance()->RenderQuad(quad,x, mY); } } + +float StoryImage::getHeight() { +JQuad * quad = resources.RetrieveQuad(img); + if (quad) { + return quad->mHeight; + } + return 0; +} + void StoryImage::Update(float dt){ //Nothing for now } @@ -76,11 +101,16 @@ StoryFlow::StoryFlow(string folder): folder(folder){ void StoryChoice::Render() { - JLBFont * mFont = resources.GetJLBFont(Constants::MAIN_FONT); + JLBFont * mFont = resources.GetJLBFont(font); mFont->SetColor(ARGB(200,255,255,255)); if (mHasFocus) mFont->SetColor(ARGB(255,255,255,0)); mFont->SetScale(mScale); - mFont->DrawString(text.c_str(), mX, mY, JGETEXT_CENTER); + mFont->DrawString(text.c_str(), mX, mY, align); +} + +float StoryChoice::getHeight() { + JLBFont * mFont = resources.GetJLBFont(font); + return mFont->GetHeight() * mScale; } void StoryChoice::Update(float dt) @@ -133,7 +163,7 @@ ostream& StoryChoice::toString(ostream& out) const } -StoryChoice::StoryChoice(string pageId, string text, int JGOid, float mX, float mY, bool hasFocus):JGuiObject(JGOid),pageId(pageId),text(text),mX(mX),mY(mY),mHasFocus(hasFocus){ +StoryChoice::StoryChoice(string pageId, string text, int JGOid, float mX, float mY, string _align, int _font, bool hasFocus):StoryText(text, mX, mY, _align, _font, JGOid),pageId(pageId),mHasFocus(hasFocus){ mScale = 1.0f; mTargetScale = 1.0f; if(hasFocus) mTargetScale = 1.2f; @@ -221,39 +251,47 @@ string StoryDialog::safeAttribute(TiXmlElement* element, string attribute) { StoryDialog::StoryDialog(TiXmlElement* root, StoryFlow * mParent):StoryPage(mParent), JGuiListener(), JGuiController(1,NULL) { + currentY = 0; + for (TiXmlNode* node = root->FirstChild(); node; node = node->NextSibling()) { TiXmlElement* element = node->ToElement(); if (element) { + string sX = safeAttribute(element, "x"); + float x = atof(sX.c_str()); + if (x>0 && x < 1){ + x = SCREEN_WIDTH_F * x; + } + string sY = safeAttribute(element,"y"); + float y = atof(sY.c_str()); + if (y>0 && y < 1){ + y = SCREEN_HEIGHT_F * y; + } + string align = safeAttribute(element,"align"); + const char* textC = element->GetText(); + string text = textC; + string sFont = safeAttribute(element,"font"); + int font = atoi(sFont.c_str()); + if (strcmp(element->Value(), "text")==0) { - string sX = safeAttribute(element, "x"); - float x = atof(sX.c_str()); - string sY = safeAttribute(element,"y"); - float y = atof(sY.c_str()); - string align = safeAttribute(element,"align"); - const char* textC = element->GetText(); - string text = textC; - graphics.push_back(NEW StoryText(text,x,y,align)); + graphics.push_back(NEW StoryText(text,x,y,align, font)); + } + else if (strcmp(element->Value(), "title")==0) { + graphics.push_back(NEW StoryText(text,x,y,"center", Constants::MENU_FONT)); } else if (strcmp(element->Value(), "img")==0) { - string sX = safeAttribute(element,"x"); - float x = atof(sX.c_str()); //special case to force center if (sX.compare("") == 0 ){ x = -1; } - string sY = safeAttribute(element,"y"); - float y = atof(sY.c_str()); - const char* imgC = element->GetText(); - string img = imgC; - img = string("campaigns/").append(mParent->folder).append("/").append(img); + string img = string("campaigns/").append(mParent->folder).append("/").append(text); graphics.push_back(NEW StoryImage(img,x,y)); } else if (strcmp(element->Value(), "answer")==0){ string id = element->Attribute("goto"); - const char* answerC = element->GetText(); - string answer = answerC; + if (!align.size()) align = "center"; int i = mObjects.size(); - StoryChoice * sc = NEW StoryChoice(id,answer,i,SCREEN_WIDTH/2, SCREEN_HEIGHT-20 - i *20 , (i==0)); + StoryChoice * sc = NEW StoryChoice(id,text,i,x, y , align, font, (i==0)); + graphics.push_back(sc); Add(sc); }else { //Error @@ -265,18 +303,38 @@ StoryDialog::StoryDialog(TiXmlElement* root, StoryFlow * mParent):StoryPage(mPar } void StoryDialog::Update(float dt){ - JGuiController::Update(dt); for (size_t i = 0; i < graphics.size(); ++i){ graphics[i]->Update(dt); } + + JButton key = mEngine->ReadButton(); + CheckUserInput(key); + } +void StoryDialog::RenderElement(StoryDialogElement * elmt) { + float mYBackup = elmt->mY; + if (! elmt->mY) elmt->mY = currentY; + if (elmt->mY == -1) { + elmt->mY = previousY; + } + elmt->Render(); + previousY = currentY; + currentY = elmt->mY + elmt->getHeight() + LINE_SPACE; + elmt->mY = mYBackup; +} + void StoryDialog::Render() { + currentY = 2; + previousY = currentY; for (size_t i = 0; i < graphics.size(); ++i){ - graphics[i]->Render(); + StoryDialogElement * elmt = (StoryDialogElement *)(graphics[i]); + if (elmt == mObjects[0]) + currentY += SPACE_BEFORE_CHOICES; + RenderElement(elmt); } - JGuiController::Render(); + } void StoryDialog::ButtonPressed(int controllerid,int controlid) { @@ -284,7 +342,8 @@ void StoryDialog::ButtonPressed(int controllerid,int controlid) { } StoryDialog::~StoryDialog(){ - for (size_t i = 0; i < graphics.size(); ++i){ + mCount = 0; //avoid parent deleting + for (size_t i = 0; i < graphics.size(); ++i){ delete(graphics[i]); } }