kittycat768

Members
  • Content count

    85
  • Joined

  • Last visited

Community Reputation

102 Neutral

About kittycat768

  • Rank
    Member
  1. Quote:Original post by jyk Quote:I tried using ifstream to load my binary files and ifstream would cause my program to crash after so many reads. If you ever use binary files, I don't recommend ifstream. Also, ifstream doesn't afford the freedom that fscanf() does.@The OP: I would take the above advice with a grain of salt. Although it's not unheard of for there to be bugs in widely-used implementations of the standard C++ library, such claims should in general be viewed with a healthy does of skepticism (statistically speaking, the actual cause of the problem is more likely to be user error). @kittycat: Can you clarify in what way C IO functions offer more freedom than the SC++L 'stream' classes? You gotta be a little lenient with me. I just discovered an hour ago that cout is flexible... I now know that: int bob = 32; cout << "Bob is age: " << bob << ".\n" will yield: "Bob is age: 32." (new line) I actually have opened up a thread about why ifstream is spitting garbage at me. EDIT: I botched my export script.. lol /apologizes to ifstream. I'm trying really hard to learn the standard C++ classes and templates so I stop looking like a complete idiot on these forums... [rolleyes]
  2. NeHe Productions has a very nice OpenGL text tutorial. I don't think it even relies on FreeType2. On the other hand I'm pretty sure it uses Windows-only functions. I followed it and never had any funny defects. Check it out if you haven't already. If you aren't using Windows, I apologize for making that assumption. I also don't understand why you calculate your width and height by using pow2(). Is pow2() your own function? I only know about pow().
  3. Quote:Original post by hanrok Thx, 1. I think that I'm in your level at opengl and I did only rotate cube lol... 2. I said that I dont have imagination because I didnt find any exercises in google search and I dont think that I can do exercises to myself.. 3. Someone told me that better be if I start only with 2D game only to know how the game programming work, is this right? Thank U very much!.. :) If you want a fun exercise, attempt to make a Breakout clone. (2D of course). I had a lot of fun doing that. I didn't get very far at the time because I knew like 1/1000th of what I know now. Fun nonetheless. Not to mention that 9 years ago, DirectDraw was still cool. Microsoft stopped developing it past version 7. OpenGL can render very nice 2d graphics as well. Also, my OpenGL level is pretty decent. I recently stopped playing World of Warcraft after 4 years of not programming so my long term memory is getting a reality check. /runs off to make another breakout clone
  4. Quote:Original post by JPerry Hi gamedevers, I'm new to game programming and I hope you guys don't mind about my stupid question. I'm really having a hard time trying to figure out how to solve this problem. I hope you can help me. One way to enable color keying in OpenGL is creating an alpha channel on my image. Setting 0 for pixels to be ignored and 1 for colored ones. Then, using blending options. So far so good, pixels to be ignored are just ignored. However, when two colored ones intersect, a new brigther one comes up. That's a behaviour I wouldn't like to happen with my images. Appers to me that DEPTH_TEST is the solution. It turns out I didn't manage to make it work properly. Here's my image (they are brigther where they overlap) <br /><br /> Quickpost this image to Myspace, Digg, Facebook, and others! Thanks Please post your relevant rendering code between [ source ] and [ /source ] tags w/o the spaces so we can get a look at what you are actually doing.
  5. Are you loading a custom format? I use my own custom export script for Blender and it writes how many vertices there are before the actual vertex data. I recommend this method rather than wasting countless cycles counting your vertices. After reading the number of vertices I allocate my vertices. I then read them all from the file and move onto my materials section. All of the sections of my file are like this. I even go so far as to separate my triangles from quads so I don't have to call glBegin() a bajillion times. I tried using ifstream to load my binary files and ifstream would cause my program to crash after so many reads. If you ever use binary files, I don't recommend ifstream. Also, ifstream doesn't afford the freedom that fscanf() does. [Edited by - kittycat768 on January 16, 2009 8:39:56 PM]
  6. Quote:Original post by lordikon Quote:Original post by kittycat768 Quote:Original post by lordikon Because it is code from work I cannot copy and paste it, and I'm not currently at work so I don't have the code in front of me anyhow. Which comments do you mean, the only stuff I think I left out what the corner sizing. For the corner sizing if the user has resized the window more horizontally then I treat the movement the same as I would if they were dragging the the right or left, and so I adjust the width, otherwise I adjust the height. Okay, I understand why you can't post your code. I just can't offer any more information w/o actually seeing your code. I guess your code would probably be your companies code. Best of luck. WTB a programming job ;_; Here is what I'm doing inside the corner dragging cases, nothing special. if ( widthDiffGreaterThanHeightDiff ) { if ( fAspectRatio < MIN_ASPECT_RATIO ) // Not wide enough { // Make window shorter fHeight = (fWidth / MIN_ASPECT_RATIO) ; } // If window is too wide else if ( fAspectRatio > MAX_ASPECT_RATIO ) { // Make window taller fHeight = (fWidth / MAX_ASPECT_RATIO); } } else { // If window is not wide enough, make it wider if ( fAspectRatio < MIN_ASPECT_RATIO) { // Set height so that we reach MIN_ASPECT_RATIO fWidth = (fHeight * MIN_ASPECT_RATIO) + 0.5f; } // If window is too wide after shortening it, make it less wide else if ( fAspectRatio > MAX_ASPECT_RATIO ) { // Set width so that we reach MAX_ASPECT_RATIO fWidth = (fHeight * MAX_ASPECT_RATIO) + 0.5f; } } I understand what you're doing with this. I just today added this type of code and now my window can scale based on the x movement or y movement when being resized from a corner. before I would have to move the mouse on the x-axis. The way I snap my cursor is if I scale the height while dragging the bottom edge, I set the cursor y coordinate to the y of the bottome edge after I scale it. I can't help but keep coding on this idea. I've implemented a lot of what you've posted. I don't know if I'll ever stop playing with my code. I just hope that you can find some of my code as useful as I've found some of your code. [smile] case WMSZ_TOPLEFT: // The cursor move further or as much along the x axis as it did on the y axis if(abs((int)(p.x - pold.x)) >= abs((int)(p.y - pold.y))) { // Snap the corner to the cursor. rcWnd -> left = p.x; // Limit how far the left edge can go. constraint = rcWnd -> right - GetSystemMetrics(SM_CXMIN); if(p.x > constraint) p.x = rcWnd -> left = constraint; width = rcWnd -> right - rcWnd -> left - xborder; // Subtract the border from the width of the window. // Scale the height of the window using the aspect ratio of it's client area. rcWnd -> top = rcWnd -> bottom - yborder - ycaption - (long)((float)width * yaspect); // Snap the cursor to the corner. p.y = rcWnd -> top; } // The cursor moved further along the y axis than it did on the x axis else { // Snap the top edge to the cursor. rcWnd -> top = p.y; // Limit how far the top edge can go. SM_CXMIN includes the border, so subtract it when neccessary. constraint = rcWnd -> bottom - yborder - ycaption - (long)((float)(GetSystemMetrics(SM_CXMIN) - xborder) * yaspect); if(p.y > constraint) p.y = rcWnd -> top = constraint; // Subtract the border and caption from the height of the window. height = rcWnd -> bottom - rcWnd -> top - yborder - ycaption; // Scale the width of the window using the aspect ratio of it's client area. rcWnd -> left = rcWnd -> right - xborder - (long)((float)height * xaspect); // Snap the cursor to the corner. p.x = rcWnd -> left; } break; I throw this in at the end of WM_SIZING: pold = p; SetCursorPos(p.x, p.y); rcWnd = 0;
  7. Quote:Original post by lordikon Because it is code from work I cannot copy and paste it, and I'm not currently at work so I don't have the code in front of me anyhow. Which comments do you mean, the only stuff I think I left out what the corner sizing. For the corner sizing if the user has resized the window more horizontally then I treat the movement the same as I would if they were dragging the the right or left, and so I adjust the width, otherwise I adjust the height. Okay, I understand why you can't post your code. I just can't offer any more information w/o actually seeing your code. I guess your code would probably be your companies code. Best of luck. WTB a programming job ;_;
  8. OpenGL

    Are you using C/C++? If you are, get DevIL. If you are using GCC, use reimp to convert the coff libraries rather than compiling it yourself. This is a bit of the code I use. Also, in my experience, most 16-bit images are coded as 5-6-5 or 5-5-5-1, 1 being a useless bit. bool GLTexture :: LoadFromImage(LPSTR strFilename) { UINT nImage; char strBuffer[1024]; bool bEnabled; // Used to restore the state of GL_TEXTURE_2D at the end of the this function. ilInit(); ilGenImages(1, &nImage); ilBindImage(nImage); if(!ilLoadImage(strFilename)) { sprintf(strBuffer, "SOURCE: GLTexture::LoadFromImage()\nERROR: Could not load file %s. File likely does not exist.", strFilename); MessageBox(0, strBuffer, "Error! Application must terminate.", MB_ICONERROR); ilBindImage(0); ilDeleteImages(1, &nImage); return 0; } ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE); if(!(bEnabled = glIsEnabled(GL_TEXTURE_2D))) glEnable(GL_TEXTURE_2D); glGenTextures(1, &m_nTexture); glBindTexture(GL_TEXTURE_2D, m_nTexture); gluBuild2DMipmaps(GL_TEXTURE_2D, ilGetInteger(IL_IMAGE_BYTES_PER_PIXEL), ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT), ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, ilGetData()); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); if(!bEnabled) glDisable(GL_TEXTURE_2D); // If GL_TEXTURE_2D was originally disabled, disable it again. */ // Delete the DevIL image ilBindImage(0); ilDeleteImages(1, &nImage); return 1; }
  9. Quote:Original post by EasilyConfused Quote:Original post by kittycat768 I doubt it. GDI+ is very obscure. I read about it while browsing once, tried to use it myself and there was little to no usable information available. GDI+ just exists. There is a complete reference on MSDN. Quote:Original post by kittycat768 I don't think anybody actually uses it. If this is true for C or C++, it is more because very few people are using Win32 to develop GUI apps any more. I believe .NET uses GDI+ internally (the interface in C# is almost identical to the C++ version of the GDI+ library). To the OP - it is pretty effortless to get GDI+ working with C++ if you use the free Visual Studio Express. GDI+ uses gdiplus.dll, so you do need some kind of library file to statically link your project to it so you may have trouble with non-MS compilers. Having said that, I'd be suprised if it was impossible to use with MinGW. Really? I had such a hard time finding anything on GDI+ that I just shoved it aside. I think I'm going to try to get a hold of it and use reimp to convert the coff libraries. I don't normally give a hoot about GDI other than the fact that it contains a few OpenGL binding functions. GDI is the snail on the turles back going wohooo! Maybe GDI+ is better.
  10. Quote:Original post by lordikon I was snapping it to the corner, or at least I thought so. I've honestly only spent a little time on the mouse cursor issue among other things, chances are my calculations may be off by 1 pixel or so somewhere and it might be causing the strange behavior. This is a work project, and I just got moved to another system so I may not get to solve the cursor issue for a little while. Would you mind cutting and pasting your entire WM_SIZING message into your post. If I saw what your <do stuff> comments actually did it might help. err... your up-to-date code. I can clearly see that your previous code post just changes the window's aspect ratio and such.
  11. Quote:Original post by lordikon I haven't gotten around to messing with the cursor much. My first attempt a couple of days ago I got the cursor within about 1 pixel of where I needed it most of the time, but if I altered the position during the WM_SIZING message it would cause the cursor to move by about 1 pixel each time WM_SIZING would be called, which caused the window to move erratically. So my thought was to not try and move the cursor during the sizing itself, but rather to let the sizing message finish, which would cause the window to resize, and then on whatever message came next I could then calculate where to place the cursor. However, once I get to the next message I would no longer have information about which corner/side the cursor was moving because that info is within WM_SIZING, so I'd have to store that info during WM_SIZING to use later. I don't know what's causing that to happen. Are you literally snapping the cursor to the corners? (Which my code does) GetCursorPos(&p); rcWnd -> left = p.x; rcWnd -> top = p.y // Do stuff p.y = rcWnd -> top; // Update p.y because the top edge was scaled to fit the aspect ratio SetCursorPos(p.x, p.y); I've absolutely perfected my code. I've been hacking away at it for about 6 hours and I don't think I could make it look any nicer. I wish I could offer better assistance. I think there's a miscommunication going on. I can't figure out what your program does that mine doesn't. I'm not saying mine's better. I just can't figure out exactly what you're trying to do. I'd also like to thank you for inspiring me to write my resizing code :)
  12. Quote:Original post by lordikon Quote:Original post by kittycat768 Mmm... for me it's kind of the opposite. I don't confine the cursor to a rectangle. I try to keep it out of the rectangle that defines the window's minimum size. One major problem I'm running into is that the WM_SIZING message is getting called a bajillion times per second so when my window reaches it's minimum size the cursor sort of become trapped until I move the cursor a lot in one motion. I'm going to try to implement a timer in order to slow this down. If I can't slow it down I'm going to remove the code that limits the window's size. If the user wants a window that's 123 pixels by like 20 pixels, more power to them. kittycat768 casts Xfer on ApochPiQ's Lobo avatar. ApochPiQ's Lobo avatar dies. Edit: Acutally, I removed the "p.x = rcWnd.left" and "p.x = rcWnd.right" from my corner sections. It was an unnecessary bit of code that was causing the trapped cursor. I thought about enforcing the cursor position at the time the subsequent message that is called after WM_SIZING, which I believe is WM_WINDOWPOSCHANGED or something similar. But I would have to store which window size the cursor was on and then calculate where to snap the cursor. What does your program do differently that that makes it have to calculate all that stuff, or store it for that matter?
  13. Quote:Original post by ApochPiQ Sounds like a job for ClipCursor. Mmm... for me it's kind of the opposite. I don't confine the cursor to a rectangle. I try to keep it out of the rectangle that defines the window's minimum size. One major problem I'm running into is that the WM_SIZING message is getting called a bajillion times per second so when my window reaches it's minimum size the cursor sort of become trapped until I move the cursor a lot in one motion. I'm going to try to implement a timer in order to slow this down. If I can't slow it down I'm going to remove the code that limits the window's size. If the user wants a window that's 123 pixels by like 20 pixels, more power to them. kittycat768 casts Xfer on ApochPiQ's Lobo avatar. ApochPiQ's Lobo avatar dies. Edit: Acutally, I removed the "p.x = rcWnd.left" and "p.x = rcWnd.right" from my corner sections. It was an unnecessary bit of code that was causing the trapped cursor.
  14. Quote:Original post by EasilyConfused The default Windows behaviour is that the cursor keeps moving, even if the window is at its minimum or maximum size, but no longer stretches or shrinks the window. I'd say this is the more desired behaviour. It is very rare that manually changing the cursor position improves user experience. Consistency is the most important thing in interfaces so I'd always suggest mimicking the way the OS behaves where possible. You have to fight back against the default OS behavior in order to keep the window's aspect ratio. If you don't it looks really, really weird. I put in code that limits how fare each edge can go when the window reaches it's minimum size. I'm in the process of making my code less ugly. Windows may not like it, but the idea we're implementing is very nice looking in my opinion.
  15. I apologize for my code being a wall of text, but it covers everything that I could possibly implement as far as resizing on the go. It took me a few hours to code it. It's not w/o it's limitations, but it works well. Your code is very slimmed down. The way I see my code is that it looks at the situation from a very logical point of view. I'll more than likely remove a lot of my redundancies in the future. Trying to solve your problem has made me aware of how snazzy I can make my programs by implementing this. As far as restricting the mouse to the corner goes. What you do is get the mouse position. Set the corner to it. Fix the aspect ratio of the window and then set the mouse pointer as the corner of the window. In my case, my corner code sections all resize the height based on the aspect so so the mouse gets moved up or down. point p; float xaspect = 1.333333f; yaspect = 0.75f; case WM_SIZING: if(wParam == WMSZ_LEFT) { RECT *rcWnd = (RECT*)lParam; long xborder = GetSystemMetrics(SM_CXFRAME) * 2; long yborder = GetSystemMetrics(SM_CYFRAME) * 2; long ycaption = GetSystemMetrics(SM_CYCAPTION); long width = rcWnd -> right - rcWnd -> left - xborder; GetCursorPos(&p); // 123 is the minium window width on my system. I don't know how to calculate it. if((rcWnd -> right - rcWnd -> left) <= 123) { rcWnd -> left = rcWnd -> right - 123; if(p.x > rcWnd -> left) p.x = rcWnd -> left; } width = rcWnd -> right - rcWnd -> left; rcWnd -> bottom = (long)((float)width * yaspect) + rcWnd -> top + yborder + ycaption; if(p.y > rcWnd -> bottom) p.y = rcWnd -> bottom; else if(p.y < rcWnd -> top) p.y = rcWnd -> top; SetCursorPos(p.x, p.y); rcWnd = 0; } if(wParam == WMSZ_RIGHT) { RECT *rcWnd = (RECT*)lParam; long xborder = GetSystemMetrics(SM_CXFRAME) * 2; long yborder = GetSystemMetrics(SM_CYFRAME) * 2; long ycaption = GetSystemMetrics(SM_CYCAPTION); long width = rcWnd -> right - rcWnd -> left - xborder; GetCursorPos(&p); // 123 is the minium window width on my system. I don't know how to calculate it. if((rcWnd -> right - rcWnd -> left) <= 123) { rcWnd -> right = rcWnd -> left + 123; if(p.x < rcWnd -> right) p.x = rcWnd -> right; } width = rcWnd -> right - rcWnd -> left; rcWnd -> bottom = (long)((float)width * yaspect) + rcWnd -> top + yborder + ycaption; if(p.y > rcWnd -> bottom) p.y = rcWnd -> bottom; else if(p.y < rcWnd -> top) p.y = rcWnd -> top; SetCursorPos(p.x, p.y); rcWnd = 0; } if(wParam == WMSZ_TOP) { RECT *rcWnd = (RECT*)lParam; long xborder = GetSystemMetrics(SM_CXFRAME) * 2; long yborder = GetSystemMetrics(SM_CYFRAME) * 2; long ycaption = GetSystemMetrics(SM_CYCAPTION); long height = rcWnd -> bottom - rcWnd -> top - yborder - ycaption; GetCursorPos(&p); // 123 is the minium window width on my system. I don't know how to calculate it. rcWnd -> right = (long)((float)height * xaspect) + rcWnd -> left + xborder; if(rcWnd -> top >= (long)(rcWnd -> bottom - ((123 - xborder) * yaspect) - yborder - ycaption)) { rcWnd -> top = (long)(rcWnd -> bottom - ((123 - xborder) * yaspect) - yborder - ycaption); if(p.y > rcWnd -> top) p.y = rcWnd -> top; } if(p.x > rcWnd -> right) p.x = rcWnd -> right; else if(p.x < rcWnd -> left) p.x = rcWnd -> left; SetCursorPos(p.x, p.y); rcWnd = 0; } if(wParam == WMSZ_BOTTOM) { RECT *rcWnd = (RECT*)lParam; long xborder = GetSystemMetrics(SM_CXFRAME) * 2; long yborder = GetSystemMetrics(SM_CYFRAME) * 2; long ycaption = GetSystemMetrics(SM_CYCAPTION); long height = rcWnd -> bottom - rcWnd -> top - yborder - ycaption; GetCursorPos(&p); // 123 is the minium window width on my system. I don't know how to calculate it. rcWnd -> right = (long)((float)height * xaspect) + rcWnd -> left + xborder; if(rcWnd -> bottom <= (long)(((123 - xborder) * yaspect) + rcWnd -> top + yborder + ycaption)) { rcWnd -> bottom = (long)(((123 - xborder) * yaspect) + rcWnd -> top + yborder + ycaption); if(p.y < rcWnd -> bottom) p.y = rcWnd -> bottom; } if(p.x > rcWnd -> right) p.x = rcWnd -> right; else if(p.x < rcWnd -> left) p.x = rcWnd -> left; SetCursorPos(p.x, p.y); rcWnd = 0; } if(wParam == WMSZ_TOPLEFT) { RECT *rcWnd = (RECT*)lParam; long xborder = GetSystemMetrics(SM_CXFRAME) * 2; long yborder = GetSystemMetrics(SM_CYFRAME) * 2; long ycaption = GetSystemMetrics(SM_CYCAPTION); long width = rcWnd -> right - rcWnd -> left - xborder; //long height = rcWnd -> bottom - rcWnd -> top - yborder - ycaption; GetCursorPos(&p); rcWnd -> left = p.x; rcWnd -> top = p.y; // 123 is the minium window width on my system. I don't know how to calculate it. if((rcWnd -> right - rcWnd -> left) <= 123) { rcWnd -> left = rcWnd -> right - 123; if(p.x > rcWnd -> left) p.x = rcWnd -> left; } width = rcWnd -> right - rcWnd -> left; rcWnd -> top = rcWnd -> bottom - (long)((float)width * yaspect) - yborder - ycaption; p.x = rcWnd -> left; p.y = rcWnd -> top; SetCursorPos(p.x, p.y); rcWnd = 0; } if(wParam == WMSZ_BOTTOMLEFT) { RECT *rcWnd = (RECT*)lParam; long xborder = GetSystemMetrics(SM_CXFRAME) * 2; long yborder = GetSystemMetrics(SM_CYFRAME) * 2; long ycaption = GetSystemMetrics(SM_CYCAPTION); long width = rcWnd -> right - rcWnd -> left - xborder; GetCursorPos(&p); rcWnd -> left = p.x; rcWnd -> bottom = p.y; // 123 is the minium window width on my system. I don't know how to calculate it. if(rcWnd -> bottom <= (long)(((123 - xborder) * yaspect) + rcWnd -> top + yborder + ycaption)) { rcWnd -> bottom = (long)(((123 - xborder) * yaspect) + rcWnd -> top + yborder + ycaption); if(p.y < rcWnd -> bottom) p.y = rcWnd -> bottom; } // 123 is the minium window width on my system. I don't know how to calculate it. if((rcWnd -> right - rcWnd -> left) <= 123) { rcWnd -> left = rcWnd -> right - 123; if(p.x > rcWnd -> left) p.x = rcWnd -> left; } width = rcWnd -> right - rcWnd -> left; rcWnd -> bottom = (long)((float)width * yaspect) + rcWnd -> top + yborder + ycaption; p.x = rcWnd -> left; p.y = rcWnd -> bottom; SetCursorPos(p.x, p.y); rcWnd = 0; } if(wParam == WMSZ_TOPRIGHT) { RECT *rcWnd = (RECT*)lParam; long xborder = GetSystemMetrics(SM_CXFRAME) * 2; long yborder = GetSystemMetrics(SM_CYFRAME) * 2; long ycaption = GetSystemMetrics(SM_CYCAPTION); long width = rcWnd -> right - rcWnd -> left - xborder; GetCursorPos(&p); rcWnd -> right = p.x; rcWnd -> top = p.y; // 123 is the minium window width on my system. I don't know how to calculate it. if((rcWnd -> right - rcWnd -> left) <= 123) { rcWnd -> right = rcWnd -> left + 123; if(p.x < rcWnd -> right) p.x = rcWnd -> right; } width = rcWnd -> right - rcWnd -> left; rcWnd -> top = rcWnd -> bottom - (long)((float)width * yaspect) - yborder - ycaption; p.x = rcWnd -> right; p.y = rcWnd -> top; SetCursorPos(p.x, p.y); rcWnd = 0; } if(wParam == WMSZ_BOTTOMRIGHT) { RECT *rcWnd = (RECT*)lParam; long xborder = GetSystemMetrics(SM_CXFRAME) * 2; long yborder = GetSystemMetrics(SM_CYFRAME) * 2; long ycaption = GetSystemMetrics(SM_CYCAPTION); long width = rcWnd -> right - rcWnd -> left - xborder; GetCursorPos(&p); rcWnd -> right = p.x; rcWnd -> bottom = p.y; // 123 is the minium window width on my system. I don't know how to calculate it. if((rcWnd -> right - rcWnd -> left) <= 123) { rcWnd -> right = rcWnd -> left + 123; if(p.x < rcWnd -> right) p.x = rcWnd -> right; } width = rcWnd -> right - rcWnd -> left; rcWnd -> bottom = (long)((float)width * yaspect) + rcWnd -> top + yborder + ycaption; p.x = rcWnd -> right; p.y = rcWnd -> bottom; SetCursorPos(p.x, p.y); rcWnd = 0; } break;