00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifdef HAVE_CONFIG_H
00023 # include <config.h>
00024 #endif
00025
00026 #ifndef ALPHA_LINUX_CXX
00027 # include <cstring>
00028 #endif
00029 #include "utils.h"
00030 #include "rect.h"
00031 #include "ibuf8.h"
00032 #include "vgafile.h"
00033 #include "databuf.h"
00034 #include "Flex.h"
00035 #include "exceptions.h"
00036
00037 #include <cassert>
00038
00039 #ifndef UNDER_CE
00040 using std::cerr;
00041 using std::cout;
00042 using std::endl;
00043 using std::ifstream;
00044 using std::ios;
00045 using std::memcpy;
00046 using std::memset;
00047 using std::ostream;
00048 #endif
00049
00050 GL_manager *Shape_frame::glman = 0;
00051 Image_buffer8 *Shape_frame::scrwin = 0;
00052
00053 #if 1
00054 #include <iomanip>
00055 #include "items.h"
00056 #endif
00057
00058
00059
00060
00061 inline void Check_file
00062 (
00063 ifstream& shapes
00064 )
00065 {
00066 if (!shapes.good())
00067 {
00068 cout << "VGA file is bad!" << endl;
00069 shapes.clear();
00070 }
00071 }
00072
00073
00074
00075
00076
00077
00078
00079 Shape_frame *Shape_frame::reflect
00080 (
00081 )
00082 {
00083 if (!data)
00084 return 0;
00085 int w = get_width(), h = get_height();
00086 if (w < h)
00087 w = h;
00088 else
00089 h = w;
00090 Shape_frame *reflected = new Shape_frame();
00091 reflected->rle = true;
00092 reflected->xleft = yabove;
00093 reflected->yabove = xleft;
00094 reflected->xright = ybelow;
00095 reflected->ybelow = xright;
00096
00097 Image_buffer8 *ibuf = new Image_buffer8(h, w);
00098 ibuf->fill8(255);
00099
00100 int xoff = reflected->xleft, yoff = reflected->yabove;
00101 uint8 *in = data;
00102 int scanlen;
00103 while ((scanlen = Read2(in)) != 0)
00104 {
00105
00106 int encoded = scanlen&1;
00107 scanlen = scanlen>>1;
00108 short scanx = Read2(in);
00109 short scany = Read2(in);
00110 if (!encoded)
00111 {
00112 ibuf->copy8(in, 1, scanlen,
00113 xoff + scany, yoff + scanx);
00114 in += scanlen;
00115 continue;
00116 }
00117 for (int b = 0; b < scanlen; )
00118 {
00119 unsigned char bcnt = *in++;
00120
00121 int repeat = bcnt&1;
00122 bcnt = bcnt>>1;
00123 if (repeat)
00124 {
00125 unsigned char pix = *in++;
00126 ibuf->fill8(pix, 1, bcnt,
00127 xoff + scany, yoff + scanx + b);
00128 }
00129 else
00130 {
00131 ibuf->copy8(in, 1, bcnt,
00132 xoff + scany, yoff + scanx + b);
00133 in += bcnt;
00134 }
00135 b += bcnt;
00136 }
00137 }
00138 reflected->create_rle(ibuf->get_bits(), w, h);
00139 delete ibuf;
00140 return (reflected);
00141 }
00142
00143
00144
00145
00146
00147
00148
00149
00150 static int Skip_transparent
00151 (
00152 unsigned char *& pixels,
00153 int x,
00154 int w
00155 )
00156 {
00157 while (x < w && *pixels == 255)
00158 {
00159 x++;
00160 pixels++;
00161 }
00162 return (x);
00163 }
00164
00165
00166
00167
00168
00169
00170
00171
00172 static int Find_runs
00173 (
00174 short *runs,
00175
00176
00177 unsigned char *pixels,
00178 int x,
00179 int w
00180 )
00181 {
00182 int runcnt = 0;
00183 while (x < w && *pixels != 255)
00184 {
00185 int run = 0;
00186 while (x < w - 1 && pixels[0] == pixels[1])
00187 {
00188 x++;
00189 pixels++;
00190 run++;
00191 }
00192 if (run)
00193 {
00194 run = ((run + 1)<<1)|1;
00195 x++;
00196 pixels++;
00197 }
00198 else do
00199 {
00200 x++;
00201 pixels++;
00202 run += 2;
00203 }
00204 while (x < w && *pixels != 255 &&
00205 (x == w - 1 || pixels[0] != pixels[1]));
00206
00207 runs[runcnt++] = run;
00208 }
00209 runs[runcnt] = 0;
00210 return (x);
00211 }
00212
00213
00214
00215
00216
00217
00218
00219 void Shape_frame::create_rle
00220 (
00221 unsigned char *pixels,
00222 int w, int h
00223 )
00224 {
00225 delete [] data;
00226 data = encode_rle(pixels, w, h, xleft, yabove, datalen);
00227 }
00228
00229
00230
00231
00232
00233
00234
00235 unsigned char *Shape_frame::encode_rle
00236 (
00237 unsigned char *pixels,
00238 int w, int h,
00239 int xoff, int yoff,
00240 int& datalen
00241 )
00242 {
00243
00244 uint8 *buf = new uint8[w*h*2 + 16*h];
00245 uint8 *out = buf;
00246 int newx;
00247 for (int y = 0; y < h; y++)
00248 for (int x = 0; (x = Skip_transparent(pixels, x, w)) < w;
00249 x = newx)
00250 {
00251 short runs[100];
00252 newx = Find_runs(runs, pixels, x, w);
00253
00254 if (!runs[1] && !(runs[0]&1))
00255 {
00256 int len = runs[0] >> 1;
00257 Write2(out, runs[0]);
00258
00259 Write2(out, x - xoff);
00260 Write2(out, y - yoff);
00261 memcpy(out, pixels, len);
00262 pixels += len;
00263 out += len;
00264 continue;
00265 }
00266
00267 Write2(out, ((newx - x)<<1)|1);
00268
00269 Write2(out, x - xoff);
00270 Write2(out, y - yoff);
00271
00272 for (int i = 0; runs[i]; i++)
00273 {
00274 int len = runs[i]>>1;
00275
00276 if (runs[i]&1)
00277 {
00278 while (len)
00279 {
00280 int c = len > 127
00281 ? 127 : len;
00282 *out++ = (c<<1)|1;
00283 *out++ = *pixels;
00284 pixels += c;
00285 len -= c;
00286 }
00287 }
00288 else while (len > 0)
00289 {
00290 int c = len > 127 ? 127 : len;
00291 *out++ = c<<1;
00292 memcpy(out, pixels, c);
00293 out += c;
00294 pixels += c;
00295 len -= c;
00296 }
00297 }
00298 }
00299 Write2(out, 0);
00300 datalen = out - buf;
00301 #ifdef DEBUG
00302 if(datalen > w*h*2 + 16*h)
00303 cout << "create_rle: datalen: " << datalen << " w: " << w
00304 << " h: " << h << endl;
00305 #endif
00306 unsigned char *data = new unsigned char[datalen];
00307 memcpy(data, buf, datalen);
00308 delete [] buf;
00309 return data;
00310 }
00311
00312
00313
00314
00315
00316 Shape_frame::Shape_frame
00317 (
00318 unsigned char *pixels,
00319 int w, int h,
00320 int xoff, int yoff,
00321 bool setrle
00322 ) : xleft(xoff), yabove(yoff), xright(w - xoff - 1),
00323 ybelow(h - yoff - 1), rle(setrle)
00324 #ifdef HAVE_OPENGL
00325 , glshape(0)
00326 #endif
00327 {
00328 if (!rle)
00329 {
00330 assert(w == 8 && h == 8);
00331 datalen = 64;
00332 data = new unsigned char[64];
00333 memcpy(data, pixels, 64);
00334 }
00335 else
00336 data = encode_rle(pixels, w, h, xleft, yabove, datalen);
00337 }
00338
00339
00340
00341
00342
00343
00344
00345 unsigned char Shape_frame::read
00346 (
00347 DataSource* shapes,
00348 uint32 shapeoff,
00349 uint32 shapelen,
00350 int frnum
00351 )
00352 {
00353 int framenum = frnum;
00354 rle = false;
00355 if (!shapelen && !shapeoff) return 0;
00356
00357 shapes->seek(shapeoff);
00358 uint32 dlen = shapes->read4();
00359 uint32 hdrlen = shapes->read4();
00360 if (dlen == shapelen)
00361 {
00362 rle = true;
00363
00364 int nframes = (hdrlen - 4)/4;
00365 if (framenum >= nframes)
00366 return (nframes);
00367
00368 uint32 frameoff, framelen;
00369 if (framenum == 0)
00370 {
00371 frameoff = hdrlen;
00372 framelen = nframes > 1 ? shapes->read4() - frameoff :
00373 dlen - frameoff;
00374 }
00375 else
00376 {
00377 shapes->skip((framenum - 1) * 4);
00378 frameoff = shapes->read4();
00379
00380 if (framenum == nframes - 1)
00381 framelen = dlen - frameoff;
00382 else
00383 framelen = shapes->read4() - frameoff;
00384 }
00385
00386 get_rle_shape(shapes, shapeoff + frameoff, framelen);
00387
00388 return (nframes);
00389 }
00390 framenum &= 31;
00391 xleft = yabove = 8;
00392 xright= ybelow = -1;
00393 shapes->seek(shapeoff + framenum*64);
00394 data = new unsigned char[64];
00395 datalen = 64;
00396 shapes->read((char *) data, 64);
00397 return (shapelen/64);
00398 }
00399
00400
00401
00402
00403
00404 void Shape_frame::get_rle_shape
00405 (
00406 DataSource* shapes,
00407 long filepos,
00408 long len
00409 )
00410 {
00411 shapes->seek(filepos);
00412 xright = shapes->read2();
00413 xleft = shapes->read2();
00414 yabove = shapes->read2();
00415 ybelow = shapes->read2();
00416 len -= 8;
00417 data = new unsigned char[len + 2];
00418 datalen = len+2;
00419 shapes->read((char*)data, len);
00420 data[len] = 0;
00421 data[len + 1] = 0;
00422 rle = true;
00423 }
00424
00425
00426
00427
00428
00429 void Shape_frame::paint_rle
00430 (
00431 Image_buffer8 *win,
00432 int xoff, int yoff
00433 )
00434 {
00435 assert(rle);
00436
00437 int w = get_width(), h = get_height();
00438 if (w >= 8 || h >= 8)
00439 if (!win->is_visible(xoff - xleft, yoff - yabove, w, h))
00440 return;
00441
00442 win->paint_rle (xoff, yoff, data);
00443 return;
00444 }
00445
00446
00447
00448
00449
00450 void Shape_frame::paint
00451 (
00452 Image_buffer8 *win,
00453 int xoff, int yoff
00454 )
00455 {
00456 if (rle)
00457 paint_rle(win, xoff, yoff);
00458 else
00459 win->copy8(data, 8, 8, xoff - 8, yoff - 8);
00460 }
00461
00462
00463
00464
00465
00466 void Shape_frame::paint_rle_translucent
00467 (
00468 Image_buffer8 *win,
00469 int xoff, int yoff,
00470 Xform_palette *xforms,
00471 int xfcnt
00472 )
00473 {
00474 assert(rle);
00475
00476 int w = get_width(), h = get_height();
00477 if (w >= 8 || h >= 8)
00478 if (!win->is_visible(xoff - xleft,
00479 yoff - yabove, w, h))
00480 return;
00481
00482 const int xfstart = 0xff - xfcnt;
00483 uint8 *in = data;
00484 int scanlen;
00485 while ((scanlen = Read2(in)) != 0)
00486 {
00487
00488 int encoded = scanlen&1;
00489 scanlen = scanlen>>1;
00490 short scanx = Read2(in);
00491 short scany = Read2(in);
00492 if (!encoded)
00493 {
00494 win->copy_line_translucent8(in, scanlen,
00495 xoff + scanx, yoff + scany,
00496 xfstart, 0xfe, xforms);
00497 in += scanlen;
00498 continue;
00499 }
00500 for (int b = 0; b < scanlen; )
00501 {
00502 unsigned char bcnt = *in++;
00503
00504 int repeat = bcnt&1;
00505 bcnt = bcnt>>1;
00506 if (repeat)
00507 {
00508 unsigned char pix = *in++;
00509 if (pix >= xfstart && pix <= 0xfe)
00510 win->fill_line_translucent8(pix, bcnt,
00511 xoff + scanx + b, yoff + scany,
00512 xforms[pix - xfstart]);
00513 else
00514 win->fill_line8(pix, bcnt,
00515 xoff + scanx + b, yoff + scany);
00516 }
00517 else
00518 {
00519 win->copy_line_translucent8(in, bcnt,
00520 xoff + scanx + b, yoff + scany,
00521 xfstart, 0xfe, xforms);
00522 in += bcnt;
00523 }
00524 b += bcnt;
00525 }
00526 }
00527 }
00528
00529
00530
00531
00532
00533
00534 void Shape_frame::paint_rle_transformed
00535 (
00536 Image_buffer8 *win,
00537 int xoff, int yoff,
00538 Xform_palette& xform
00539 )
00540 {
00541 assert(rle);
00542
00543 int w = get_width(), h = get_height();
00544 if (w >= 8 || h >= 8)
00545 if (!win->is_visible(xoff - xleft,
00546 yoff - yabove, w, h))
00547 return;
00548 uint8 * in = data;
00549 int scanlen;
00550 while ((scanlen = Read2(in)) != 0)
00551 {
00552
00553 int encoded = scanlen&1;
00554 scanlen = scanlen>>1;
00555 short scanx = Read2(in);
00556 short scany = Read2(in);
00557 if (!encoded)
00558 {
00559 win->fill_line_translucent8(0, scanlen,
00560 xoff + scanx, yoff + scany, xform);
00561 in += scanlen;
00562 continue;
00563 }
00564 for (int b = 0; b < scanlen; )
00565 {
00566 unsigned char bcnt = *in++;
00567
00568 int repeat = bcnt&1;
00569 bcnt = bcnt>>1;
00570 in += repeat ? 1 : bcnt;
00571 win->fill_line_translucent8(0, bcnt,
00572 xoff + scanx + b, yoff + scany, xform);
00573 b += bcnt;
00574 }
00575 }
00576 }
00577
00578
00579
00580
00581
00582 void Shape_frame::paint_rle_outline
00583 (
00584 Image_buffer8 *win,
00585 int xoff, int yoff,
00586 unsigned char color
00587 )
00588 {
00589 assert(rle);
00590
00591 int w = get_width(), h = get_height();
00592 if (w >= 8 || h >= 8)
00593 if (!win->is_visible(xoff - xleft,
00594 yoff - yabove, w, h))
00595 return;
00596 int firsty = -10000;
00597 int lasty;
00598 uint8 * in = data;
00599 int scanlen;
00600 while ((scanlen = Read2(in)) != 0)
00601 {
00602
00603 int encoded = scanlen&1;
00604 scanlen = scanlen>>1;
00605 short scanx = Read2(in);
00606 short scany = Read2(in);
00607 int x = xoff + scanx;
00608 int y = yoff + scany;
00609 if (firsty == -10000)
00610 {
00611 firsty = y;
00612 lasty = y + h - 1;
00613 }
00614
00615 win->put_pixel8(color, x, y);
00616 win->put_pixel8(color, x + scanlen - 1, y);
00617
00618 if (!encoded)
00619 {
00620 if (y == firsty ||
00621 y == lasty)
00622 win->fill_line8(color, scanlen, x, y);
00623 in += scanlen;
00624 continue;
00625 }
00626 for (int b = 0; b < scanlen; )
00627 {
00628 unsigned char bcnt = *in++;
00629
00630 int repeat = bcnt&1;
00631 bcnt = bcnt>>1;
00632 if (repeat)
00633 in++;
00634 else
00635 in += bcnt;
00636 if (y == firsty ||
00637 y == lasty)
00638 win->fill_line8(color, bcnt, x + b, y);
00639 b += bcnt;
00640 }
00641 }
00642 }
00643
00644
00645
00646
00647
00648
00649 int Shape_frame::has_point
00650 (
00651 int x, int y
00652 )
00653 {
00654 if (!rle)
00655 {
00656 return x >= -xleft && x < xright &&
00657 y >= -yabove && y < ybelow;
00658 }
00659 uint8 *in = data;
00660 int scanlen;
00661 while ((scanlen = Read2(in)) != 0)
00662 {
00663
00664 int encoded = scanlen&1;
00665 scanlen = scanlen>>1;
00666 short scanx = Read2(in);
00667 short scany = Read2(in);
00668
00669 if (y == scany && x >= scanx - 1 && x <= scanx + scanlen)
00670 return (1);
00671 if (!encoded)
00672 {
00673 in += scanlen;
00674 continue;
00675 }
00676 for (int b = 0; b < scanlen; )
00677 {
00678 unsigned char bcnt = *in++;
00679
00680 int repeat = bcnt&1;
00681 bcnt = bcnt>>1;
00682 if (repeat)
00683 in++;
00684 else
00685 in += bcnt;
00686 b += bcnt;
00687 }
00688 }
00689 return (0);
00690 }
00691
00692
00693
00694
00695
00696 void Shape_frame::set_offset
00697 (
00698 int new_xright, int new_ybelow
00699 )
00700 {
00701 if (!rle)
00702 return;
00703 int w = get_width(), h = get_height();
00704 if (new_xright > w)
00705 new_xright = w;
00706 if (new_ybelow > h)
00707 new_ybelow = h;
00708 int deltax = new_xright - xright;
00709 int deltay = new_ybelow - ybelow;
00710 xright = new_xright;
00711 ybelow = new_ybelow;
00712 xleft = w - xright - 1;
00713 yabove = h - ybelow - 1;
00714 uint8 *in = data;
00715 int scanlen;
00716 while ((scanlen = Read2(in)) != 0)
00717 {
00718
00719 int encoded = scanlen&1;
00720 scanlen = scanlen>>1;
00721 short scanx = Read2(in);
00722 in -= 2;
00723 Write2(in, scanx + deltax);
00724 short scany = Read2(in);
00725 in -= 2;
00726 Write2(in, scany + deltay);
00727
00728 if (!encoded)
00729 in += scanlen;
00730 else for (int b = 0; b < scanlen; )
00731 {
00732 unsigned char bcnt = *in++;
00733
00734 int repeat = bcnt&1;
00735 bcnt = bcnt>>1;
00736 if (repeat)
00737 in++;
00738 else
00739 in += bcnt;
00740 b += bcnt;
00741 }
00742 }
00743 }
00744
00745
00746
00747
00748
00749 Shape_frame *Shape::reflect
00750 (
00751 DataSource* shapes,
00752 int shapenum,
00753 int framenum
00754 )
00755 {
00756
00757 Shape_frame *normal = get(shapes, shapenum, framenum);
00758 if (!normal)
00759 return (0);
00760
00761 Shape_frame *reflected = normal->reflect();
00762 if (!reflected)
00763 return (0);
00764 framenum |= 32;
00765 if (framenum >= frames_size - 1)
00766 enlarge(framenum + 1);
00767 frames[framenum] = reflected;
00768 return reflected;
00769 }
00770
00771
00772
00773
00774
00775 void Shape::enlarge
00776 (
00777 int newsize
00778 )
00779 {
00780 Shape_frame **newframes = new Shape_frame *[newsize];
00781 int i;
00782 for (i = 0; i < frames_size; i++)
00783 newframes[i] = frames[i];
00784 frames_size = newsize;
00785 for ( ; i < frames_size; i++)
00786 newframes[i] = 0;
00787 delete [] frames;
00788 frames = newframes;
00789 }
00790
00791
00792
00793
00794
00795 void Shape::resize
00796 (
00797 int newsize
00798 )
00799 {
00800 if (newsize == frames_size)
00801 return;
00802 if (newsize > frames_size)
00803 enlarge(newsize);
00804 else
00805 {
00806 Shape_frame **newframes = new Shape_frame *[newsize];
00807 int i;
00808 for (i = 0; i < newsize; i++)
00809 newframes[i] = frames[i];
00810
00811 for ( ; i < frames_size; i++)
00812 delete frames[i];
00813 frames_size = newsize;
00814 delete [] frames;
00815 frames = newframes;
00816 }
00817 num_frames = newsize;
00818 }
00819
00820
00821
00822
00823
00824 inline void Shape::create_frames_list
00825 (
00826 int nframes
00827 )
00828 {
00829 num_frames = frames_size = nframes;
00830 frames = new Shape_frame *[frames_size];
00831 memset((char *) frames, 0, frames_size * sizeof(Shape_frame *));
00832 }
00833
00834
00835
00836
00837
00838
00839
00840
00841 Shape_frame *Shape::read
00842 (
00843 DataSource *shapes1,
00844 int shapenum,
00845 int framenum,
00846 DataSource *shapes2,
00847 int count1,
00848 int count2
00849 )
00850 {
00851 DataSource *shapes = 0;
00852 Shape_frame *frame = new Shape_frame();
00853
00854 uint32 shapeoff = 0x80 + shapenum*8;
00855 uint32 shapelen = 0;
00856
00857
00858 if (shapes2 && (count2 == -1 || shapenum < count2))
00859 {
00860 shapes2->seek(shapeoff);
00861
00862 int s = shapes2->read4();
00863 shapelen = shapes2->read4();
00864
00865 if (s && shapelen)
00866 {
00867 shapeoff = s;
00868 shapes = shapes2;
00869 }
00870 }
00871 if (shapes == 0)
00872 {
00873 shapes = shapes1;
00874 if (count1 != -1 && shapenum >= count1)
00875 {
00876 std::cerr << "Shape num out of range: " << shapenum << std::endl;
00877 return 0;
00878 }
00879
00880 shapes->seek(shapeoff);
00881
00882 shapeoff = shapes->read4();
00883 shapelen = shapes->read4();
00884 }
00885 if (!shapelen)
00886 return 0;
00887
00888 int nframes = frame->read(shapes, shapeoff, shapelen, framenum);
00889 if (!num_frames)
00890 create_frames_list(nframes);
00891 if (!frame->rle)
00892 framenum &= 31;
00893 if (framenum >= nframes &&
00894 (framenum&32))
00895 {
00896 delete frame;
00897 return (reflect(shapes, shapenum, framenum&0x1f));
00898 }
00899 return store_frame(frame, framenum);
00900 }
00901
00902
00903
00904
00905
00906
00907
00908
00909 void Shape::write
00910 (
00911 ostream& out
00912 )
00913 {
00914 int frnum;
00915 if (!num_frames)
00916 return;
00917 assert(frames != 0 && *frames != 0);
00918 bool flat = !frames[0]->is_rle();
00919
00920 unsigned long startpos = out.tellp();
00921
00922 if (!flat)
00923 {
00924 Write4(out, 0);
00925
00926 for (frnum = 0; frnum < num_frames; frnum++)
00927 Write4(out, 0);
00928 }
00929 for (frnum = 0; frnum < num_frames; frnum++)
00930 {
00931 Shape_frame *frame = frames[frnum];
00932 assert(frame != 0);
00933 assert(flat == !frame->is_rle());
00934 if (frame->is_rle())
00935 {
00936
00937 unsigned long pos = out.tellp();
00938 out.seekp(startpos + (frnum + 1)*4);
00939 Write4(out, pos - startpos);
00940 out.seekp(pos);
00941 Write2(out, frame->xright);
00942 Write2(out, frame->xleft);
00943 Write2(out, frame->yabove);
00944 Write2(out, frame->ybelow);
00945 }
00946 out.write(reinterpret_cast<char *>(frame->data), frame->datalen);
00947 }
00948 if (!flat)
00949 {
00950 unsigned long pos = out.tellp();
00951 out.seekp(startpos);
00952 Write4(out, pos - startpos);
00953 out.seekp(pos);
00954 }
00955 }
00956
00957
00958
00959
00960
00961
00962
00963 Shape_frame *Shape::store_frame
00964 (
00965 Shape_frame *frame,
00966 int framenum
00967 )
00968 {
00969 if (framenum >= frames_size)
00970 {
00971 delete frame;
00972 cerr << "Shape::store_frame: framenum >= frames_size"
00973 << endl;
00974 return (0);
00975 }
00976 if (!frames)
00977 {
00978 frames = new Shape_frame *[num_frames];
00979 memset((char *) frames, 0, num_frames * sizeof(Shape_frame *));
00980 }
00981 frames[framenum] = frame;
00982 return (frame);
00983 }
00984
00985
00986
00987
00988
00989 Shape::Shape(Shape_frame* fr)
00990 {
00991 num_frames = frames_size = 1;
00992 frames = new Shape_frame*[1];
00993 frames[0] = fr;
00994 }
00995
00996
00997
00998
00999
01000 Shape::Shape
01001 (
01002 int n
01003 )
01004 {
01005 create_frames_list(n);
01006 }
01007
01008 void Shape::reset()
01009 {
01010 if (frames)
01011 {
01012 for(int i = 0; i < frames_size; i++)
01013 delete frames[i];
01014 delete [] frames;
01015 frames = 0;
01016 }
01017 else if (frames_size)
01018 cerr << "Shape::~Shape(): 'frames' is null, while frames_size="
01019 << (int) frames_size << endl;
01020 }
01021
01022
01023
01024
01025
01026 void Shape::take
01027 (
01028 Shape *sh2
01029 )
01030 {
01031 reset();
01032 frames = sh2->frames;
01033 sh2->frames = 0;
01034 frames_size = sh2->frames_size;
01035 num_frames = sh2->num_frames;
01036 sh2->num_frames = sh2->frames_size = 0;
01037 }
01038
01039
01040
01041
01042
01043 void Shape::load
01044 (
01045 DataSource* shape_source
01046 )
01047 {
01048 reset();
01049 Shape_frame *frame = new Shape_frame();
01050 uint32 shapelen = shape_source->read4();
01051
01052 create_frames_list(frame->read(shape_source, 0L, shapelen, 0));
01053 store_frame(frame, 0);
01054
01055 for (int i = 1; i < num_frames; i++)
01056 {
01057 frame = new Shape_frame();
01058 frame->read(shape_source, 0L, shapelen, i);
01059 store_frame(frame, i);
01060 }
01061 }
01062
01063 Shape::~Shape()
01064 {
01065 reset();
01066 }
01067
01068
01069
01070
01071
01072 void Shape::set_frame
01073 (
01074 Shape_frame *frame,
01075 int framenum
01076 )
01077 {
01078 assert (framenum < num_frames);
01079 delete frames[framenum];
01080 frames[framenum] = frame;
01081 }
01082
01083
01084
01085
01086
01087 void Shape::add_frame
01088 (
01089 Shape_frame *frame,
01090 int framenum
01091 )
01092 {
01093 assert (framenum <= num_frames);
01094 enlarge(frames_size + 1);
01095 for (int i = frames_size - 1; i > framenum; i--)
01096 frames[i] = frames[i - 1];
01097 frames[framenum] = frame;
01098 num_frames++;
01099 }
01100
01101
01102
01103
01104
01105 void Shape::del_frame
01106 (
01107 int framenum
01108 )
01109 {
01110 assert (framenum < num_frames);
01111 delete frames[framenum];
01112
01113 for (int i = framenum + 1; i < frames_size; i++)
01114 frames[i - 1] = frames[i];
01115 frames[frames_size - 1] = 0;
01116 num_frames--;
01117 }
01118
01119
01120
01121
01122
01123 Shape_file::Shape_file() : Shape()
01124 {
01125
01126 }
01127
01128
01129
01130
01131
01132 Shape_file::Shape_file
01133 (
01134 const char *nm
01135 ) : Shape()
01136 {
01137 load(nm);
01138 }
01139
01140
01141
01142
01143
01144 void Shape_file::load
01145 (
01146 const char *nm
01147 )
01148 {
01149 ifstream file;
01150 U7open(file, nm);
01151 StreamDataSource shape_source(&file);
01152 Shape::load(&shape_source);
01153 }
01154
01155
01156
01157
01158
01159 Shape_file::Shape_file
01160 (
01161 DataSource* shape_source
01162 ) : Shape()
01163 {
01164 Shape::load(shape_source);
01165 }
01166
01167
01168
01169
01170 int Shape_file::get_size()
01171 {
01172 int size = 4;
01173 for (int i=0; i<num_frames; i++)
01174 size += frames[i]->get_size() + 4 + 8;
01175 return size;
01176 }
01177
01178
01179 void Shape_file::save(DataSource* shape_source)
01180 {
01181 int* offsets = new int[num_frames];
01182 int size;
01183 offsets[0] = 4 + num_frames * 4;
01184 int i;
01185 for (i=1; i<num_frames; i++)
01186 offsets[i] = offsets[i-1] + frames[i-1]->get_size() + 8;
01187 size = offsets[num_frames-1] + frames[num_frames-1]->get_size() + 8;
01188 shape_source->write4(size);
01189 for (i=0; i<num_frames; i++)
01190 shape_source->write4(offsets[i]);
01191 for (i=0; i<num_frames; i++) {
01192 shape_source->write2(frames[i]->xright);
01193 shape_source->write2(frames[i]->xleft);
01194 shape_source->write2(frames[i]->yabove);
01195 shape_source->write2(frames[i]->ybelow);
01196 shape_source->write((char*)(frames[i]->data), frames[i]->get_size());
01197 }
01198 delete [] offsets;
01199 }
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209 Vga_file::Vga_file
01210 (
01211 const char *nm,
01212 int u7drag,
01213 const char *nm2
01214 ) : shape_source(0), shape_source2(0),
01215 num_shapes(0), num_shapes1(0), num_shapes2(0),
01216 shapes(0), u7drag_type(u7drag), flex(true)
01217 {
01218 load(nm, nm2);
01219 }
01220
01221 Vga_file::Vga_file
01222 (
01223 ) : shape_source(0), shape_source2(0),
01224 num_shapes(0), num_shapes1(0), num_shapes2(0),
01225 shapes(0), u7drag_type(-1), flex(true)
01226 {
01227
01228 }
01229
01230
01231
01232
01233
01234
01235 void Vga_file::load
01236 (
01237 const char *nm,
01238 const char *nm2
01239 )
01240 {
01241 reset();
01242 if (U7exists(nm))
01243 {
01244 U7open(file, nm);
01245 shape_source = new StreamDataSource(&file);
01246 StreamDataSource ds(&file);
01247 flex = Flex::is_flex(&ds);
01248 }
01249 if (nm2 && U7exists(nm2))
01250 {
01251 U7open(file2, nm2);
01252 shape_source2 = new StreamDataSource(&file2);
01253 StreamDataSource ds(&file2);
01254 flex = Flex::is_flex(&ds);
01255 }
01256 if (!shape_source && !shape_source2)
01257 throw file_open_exception(get_system_path(nm));
01258 if (!flex)
01259 {
01260 num_shapes = num_shapes1 = num_shapes2 = 1;
01261 shapes = new Shape[1];
01262 shapes[0].load(shape_source2 ? shape_source2 : shape_source);
01263 return;
01264 }
01265 if (shape_source)
01266 {
01267 shape_source->seek(0x54);
01268 num_shapes = num_shapes1 = shape_source->read4();
01269 }
01270 if (shape_source2)
01271 {
01272 shape_source2->seek(0x54);
01273 num_shapes2 = shape_source2->read4();
01274 if (num_shapes2 > num_shapes) num_shapes = num_shapes2;
01275 }
01276
01277 shapes = new Shape[num_shapes];
01278 }
01279
01280 void Vga_file::reset()
01281 {
01282 if( shapes )
01283 delete [] shapes;
01284 if( shape_source )
01285 delete shape_source;
01286 file.close();
01287
01288 if( shape_source2 )
01289 delete shape_source2;
01290
01291 if (file2.is_open()) file2.close();
01292
01293 num_shapes = 0;
01294 num_shapes1 = 0;
01295 num_shapes2 = 0;
01296 shape_source = 0;
01297 shape_source2 = 0;
01298 shapes = 0;
01299 }
01300
01301 Vga_file::~Vga_file()
01302 {
01303 reset();
01304 }
01305
01306
01307
01308
01309
01310
01311
01312 Shape *Vga_file::new_shape
01313 (
01314 int shapenum
01315 )
01316 {
01317 if (shapenum < 0 || shapenum >= 2048)
01318 return 0;
01319 if (shapenum < num_shapes)
01320 {
01321 shapes[shapenum].reset();
01322 shapes[shapenum].num_frames = shapes[shapenum].frames_size = 0;
01323 }
01324 else
01325 {
01326 if (!flex)
01327 return 0;
01328 Shape *newshapes = new Shape[shapenum + 1];
01329 for (int i = 0; i < num_shapes; i++)
01330 newshapes[i].take(&shapes[i]);
01331 delete [] shapes;
01332 shapes = newshapes;
01333 num_shapes = shapenum + 1;
01334 }
01335 return &shapes[shapenum];
01336 }
01337