RLE.C 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801
  1. /*
  2. THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  3. SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
  4. END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  5. ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  6. IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  7. SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  8. FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  9. CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
  10. AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
  11. COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
  12. */
  13. #pragma off (unreferenced)
  14. static char rcsid[] = "$Id: rle.c 1.27 1996/03/14 10:22:05 matt Exp $";
  15. #pragma on (unreferenced)
  16. #include <stdlib.h>
  17. #include <malloc.h>
  18. #include <stdio.h>
  19. #include <string.h>
  20. #include "pa_enabl.h" //$$POLY_ACC
  21. #include "mem.h"
  22. #include "mono.h"
  23. #include "gr.h"
  24. #include "grdef.h"
  25. #if !defined(MACINTOSH)
  26. #include "dpmi.h"
  27. #endif
  28. #include "error.h"
  29. #include "key.h"
  30. #if defined(POLY_ACC)
  31. #include "poly_acc.h"
  32. #endif
  33. //#define RLE_CODE 0xC0
  34. //#define NOT_RLE_CODE 63
  35. #define RLE_CODE 0xE0
  36. #define NOT_RLE_CODE 31
  37. ubyte *gr_rle_decode_asm( ubyte * src, ubyte * dest );
  38. #if !defined(MACINTOSH)
  39. #pragma aux gr_rle_decode_asm parm [esi] [edi] value [edi] modify exact [eax ebx ecx edx esi edi] = \
  40. " cld "\
  41. " xor ecx, ecx "\
  42. " cld "\
  43. " jmp NextByte "\
  44. " "\
  45. "Unique: "\
  46. " mov [edi],al "\
  47. " inc edi "\
  48. " "\
  49. "NextByte: "\
  50. " mov al,[esi] "\
  51. " inc esi "\
  52. " "\
  53. " mov ah, al "\
  54. " and ah, 0xE0 "\
  55. " cmp ah, 0xE0 "\
  56. " jne Unique "\
  57. " "\
  58. " mov cl, al "\
  59. " and cl, 31 "\
  60. " je done "\
  61. " "\
  62. " mov al,[esi] "\
  63. " inc esi "\
  64. " mov ah, al "\
  65. " shr ecx,1 "\
  66. " rep stosw "\
  67. " jnc NextByte "\
  68. " mov [edi],al "\
  69. " inc edi "\
  70. " "\
  71. " jmp NextByte "\
  72. " "\
  73. "done: ";
  74. void gr_rle_decode( ubyte * src, ubyte * dest, int dest_len )
  75. {
  76. ubyte *dest_end;
  77. dest_end = gr_rle_decode_asm( src, dest );
  78. Assert(dest_end-src < dest_len);
  79. }
  80. #else // !defined(MACINTOSH)
  81. void gr_rle_decode( ubyte * src, ubyte * dest )
  82. {
  83. int i;
  84. ubyte data, count = 0;
  85. while(1) {
  86. data = *src++;
  87. if ( (data & RLE_CODE) != RLE_CODE ) {
  88. *dest++ = data;
  89. } else {
  90. count = data & NOT_RLE_CODE;
  91. if (count==0) return;
  92. data = *src++;
  93. for (i=0; i<count; i++ )
  94. *dest++ = data;
  95. }
  96. }
  97. }
  98. #endif
  99. void rle_stosb(char *dest, int len, int color);
  100. #if !defined(MACINTOSH)
  101. #pragma aux rle_stosb = "cld rep stosb" parm [edi] [ecx] [eax] modify exact [edi ecx];
  102. #else
  103. void rle_stosb(char *dest, int len, int color)
  104. {
  105. int i;
  106. for (i=0; i<len; i++ )
  107. *dest++ = color;
  108. }
  109. #endif
  110. // Given pointer to start of one scanline of rle data, uncompress it to
  111. // dest, from source pixels x1 to x2.
  112. void gr_rle_expand_scanline_masked( ubyte *dest, ubyte *src, int x1, int x2 )
  113. {
  114. int i = 0;
  115. ubyte count;
  116. ubyte color;
  117. if ( x2 < x1 ) return;
  118. count = 0;
  119. while ( i < x1 ) {
  120. color = *src++;
  121. if ( color == RLE_CODE ) return;
  122. if ( (color & RLE_CODE)==RLE_CODE ) {
  123. count = color & (~RLE_CODE);
  124. color = *src++;
  125. } else {
  126. // unique
  127. count = 1;
  128. }
  129. i += count;
  130. }
  131. count = i - x1;
  132. i = x1;
  133. // we know have '*count' pixels of 'color'.
  134. if ( x1+count > x2 ) {
  135. count = x2-x1+1;
  136. if ( color != TRANSPARENCY_COLOR ) rle_stosb( dest, count, color );
  137. return;
  138. }
  139. if ( color != TRANSPARENCY_COLOR ) rle_stosb( dest, count, color );
  140. dest += count;
  141. i += count;
  142. while( i <= x2 ) {
  143. color = *src++;
  144. if ( color == RLE_CODE ) return;
  145. if ( (color & RLE_CODE) == (RLE_CODE) ) {
  146. count = color & (~RLE_CODE);
  147. color = *src++;
  148. } else {
  149. // unique
  150. count = 1;
  151. }
  152. // we know have '*count' pixels of 'color'.
  153. if ( i+count <= x2 ) {
  154. if ( color != TRANSPARENCY_COLOR )rle_stosb( dest, count, color );
  155. i += count;
  156. dest += count;
  157. } else {
  158. count = x2-i+1;
  159. if ( color != TRANSPARENCY_COLOR )rle_stosb( dest, count, color );
  160. i += count;
  161. dest += count;
  162. }
  163. }
  164. }
  165. void gr_rle_expand_scanline( ubyte *dest, ubyte *src, int x1, int x2 )
  166. {
  167. int i = 0;
  168. ubyte count;
  169. ubyte color;
  170. if ( x2 < x1 ) return;
  171. count = 0;
  172. while ( i < x1 ) {
  173. color = *src++;
  174. if ( color == RLE_CODE ) return;
  175. if ( (color & RLE_CODE)==RLE_CODE ) {
  176. count = color & (~RLE_CODE);
  177. color = *src++;
  178. } else {
  179. // unique
  180. count = 1;
  181. }
  182. i += count;
  183. }
  184. count = i - x1;
  185. i = x1;
  186. // we know have '*count' pixels of 'color'.
  187. if ( x1+count > x2 ) {
  188. count = x2-x1+1;
  189. rle_stosb( dest, count, color );
  190. return;
  191. }
  192. rle_stosb( dest, count, color );
  193. dest += count;
  194. i += count;
  195. while( i <= x2 ) {
  196. color = *src++;
  197. if ( color == RLE_CODE ) return;
  198. if ( (color & RLE_CODE)==RLE_CODE ) {
  199. count = color & (~RLE_CODE);
  200. color = *src++;
  201. } else {
  202. // unique
  203. count = 1;
  204. }
  205. // we know have '*count' pixels of 'color'.
  206. if ( i+count <= x2 ) {
  207. rle_stosb( dest, count, color );
  208. i += count;
  209. dest += count;
  210. } else {
  211. count = x2-i+1;
  212. rle_stosb( dest, count, color );
  213. i += count;
  214. dest += count;
  215. }
  216. }
  217. }
  218. int gr_rle_encode( int org_size, ubyte *src, ubyte *dest )
  219. {
  220. int i;
  221. ubyte c, oc;
  222. ubyte count;
  223. ubyte *dest_start;
  224. dest_start = dest;
  225. oc = *src++;
  226. count = 1;
  227. for (i=1; i<org_size; i++ ) {
  228. c = *src++;
  229. if ( c!=oc ) {
  230. if ( count ) {
  231. if ( (count==1) && ((oc & RLE_CODE)!=RLE_CODE) ) {
  232. *dest++ = oc;
  233. Assert( oc != RLE_CODE );
  234. } else {
  235. count |= RLE_CODE;
  236. *dest++ = count;
  237. *dest++ = oc;
  238. }
  239. }
  240. oc = c;
  241. count = 0;
  242. }
  243. count++;
  244. if ( count == NOT_RLE_CODE ) {
  245. count |= RLE_CODE;
  246. *dest++=count;
  247. *dest++=oc;
  248. count = 0;
  249. }
  250. }
  251. if (count) {
  252. if ( (count==1) && ((oc & RLE_CODE)!=RLE_CODE) ) {
  253. *dest++ = oc;
  254. Assert( oc != RLE_CODE );
  255. } else {
  256. count |= RLE_CODE;
  257. *dest++ = count;
  258. *dest++ = oc;
  259. }
  260. }
  261. *dest++ = RLE_CODE;
  262. return dest-dest_start;
  263. }
  264. int gr_rle_getsize( int org_size, ubyte *src )
  265. {
  266. int i;
  267. ubyte c, oc;
  268. ubyte count;
  269. int dest_size=0;
  270. oc = *src++;
  271. count = 1;
  272. for (i=1; i<org_size; i++ ) {
  273. c = *src++;
  274. if ( c!=oc ) {
  275. if ( count ) {
  276. if ( (count==1) && ((oc & RLE_CODE)!=RLE_CODE) ) {
  277. dest_size++;
  278. } else {
  279. dest_size++;
  280. dest_size++;
  281. }
  282. }
  283. oc = c;
  284. count = 0;
  285. }
  286. count++;
  287. if ( count == NOT_RLE_CODE ) {
  288. dest_size++;
  289. dest_size++;
  290. count = 0;
  291. }
  292. }
  293. if (count) {
  294. if ( (count==1) && ((oc & RLE_CODE)!=RLE_CODE) ) {
  295. dest_size++;
  296. } else {
  297. dest_size++;
  298. dest_size++;
  299. }
  300. }
  301. dest_size++;
  302. return dest_size;
  303. }
  304. int gr_bitmap_rle_compress( grs_bitmap * bmp )
  305. {
  306. int y, d1, d;
  307. int doffset;
  308. ubyte *rle_data;
  309. int large_rle = 0;
  310. // first must check to see if this is large bitmap.
  311. for (y=0; y<bmp->bm_h; y++ ) {
  312. d1= gr_rle_getsize( bmp->bm_w, &bmp->bm_data[bmp->bm_w*y] );
  313. if (d1 > 255) {
  314. large_rle = 1;
  315. break;
  316. }
  317. }
  318. rle_data=malloc( (bmp->bm_w+1)* bmp->bm_h );
  319. if (rle_data==NULL) return 0;
  320. if (!large_rle)
  321. doffset = 4 + bmp->bm_h;
  322. else
  323. doffset = 4 + (2 * bmp->bm_h); // each row of rle'd bitmap has short instead of byte offset now
  324. for (y=0; y<bmp->bm_h; y++ ) {
  325. d1= gr_rle_getsize( bmp->bm_w, &bmp->bm_data[bmp->bm_w*y] );
  326. if ( ((doffset+d1) > bmp->bm_w*bmp->bm_h) || (d1 > (large_rle?32767:255) ) ) {
  327. free(rle_data);
  328. return 0;
  329. }
  330. d = gr_rle_encode( bmp->bm_w, &bmp->bm_data[bmp->bm_w*y], &rle_data[doffset] );
  331. Assert( d==d1 );
  332. doffset += d;
  333. if (large_rle)
  334. *((short *)&(rle_data[(y*2)+4])) = (short)d;
  335. else
  336. rle_data[y+4] = d;
  337. }
  338. //mprintf( 0, "Bitmap of size %dx%d, (%d bytes) went down to %d bytes\n", bmp->bm_w, bmp->bm_h, bmp->bm_h*bmp->bm_w, doffset );
  339. memcpy( rle_data, &doffset, 4 );
  340. memcpy( bmp->bm_data, rle_data, doffset );
  341. free(rle_data);
  342. bmp->bm_flags |= BM_FLAG_RLE;
  343. if (large_rle)
  344. bmp->bm_flags |= BM_FLAG_RLE_BIG;
  345. return 1;
  346. }
  347. #define MAX_CACHE_BITMAPS 32
  348. typedef struct rle_cache_element {
  349. grs_bitmap * rle_bitmap;
  350. ubyte * rle_data;
  351. grs_bitmap * expanded_bitmap;
  352. int last_used;
  353. } rle_cache_element;
  354. int rle_cache_initialized = 0;
  355. int rle_counter = 0;
  356. int rle_next = 0;
  357. rle_cache_element rle_cache[MAX_CACHE_BITMAPS];
  358. int rle_hits = 0;
  359. int rle_misses = 0;
  360. void rle_cache_close()
  361. {
  362. if (rle_cache_initialized) {
  363. int i;
  364. rle_cache_initialized = 0;
  365. for (i=0; i<MAX_CACHE_BITMAPS; i++ ) {
  366. gr_free_bitmap(rle_cache[i].expanded_bitmap);
  367. }
  368. }
  369. }
  370. void rle_cache_init()
  371. {
  372. int i;
  373. for (i=0; i<MAX_CACHE_BITMAPS; i++ ) {
  374. rle_cache[i].rle_bitmap = NULL;
  375. rle_cache[i].expanded_bitmap = gr_create_bitmap( 64, 64 );
  376. rle_cache[i].last_used = 0;
  377. Assert( rle_cache[i].expanded_bitmap != NULL );
  378. }
  379. rle_cache_initialized = 1;
  380. atexit( rle_cache_close );
  381. }
  382. void rle_cache_flush()
  383. {
  384. int i;
  385. for (i=0; i<MAX_CACHE_BITMAPS; i++ ) {
  386. rle_cache[i].rle_bitmap = NULL;
  387. rle_cache[i].last_used = 0;
  388. }
  389. }
  390. void rle_expand_texture_sub( grs_bitmap * bmp, grs_bitmap * rle_temp_bitmap_1 )
  391. {
  392. unsigned char * dbits;
  393. unsigned char * sbits;
  394. int i;
  395. unsigned char * dbits1;
  396. sbits = &bmp->bm_data[4 + bmp->bm_h];
  397. dbits = rle_temp_bitmap_1->bm_data;
  398. rle_temp_bitmap_1->bm_flags = bmp->bm_flags & (~BM_FLAG_RLE);
  399. for (i=0; i < bmp->bm_h; i++ ) {
  400. #ifndef MACINTOSH
  401. dbits1=(unsigned char *)gr_rle_decode_asm( sbits, dbits );
  402. #else
  403. gr_rle_decode( sbits, dbits );
  404. #endif
  405. sbits += (int)bmp->bm_data[4+i];
  406. dbits += bmp->bm_w;
  407. #ifndef MACINTOSH
  408. Assert( dbits == dbits1 ); // Get John, bogus rle data!
  409. #endif
  410. }
  411. }
  412. #if defined(POLY_ACC)
  413. grs_bitmap *rle_get_id_sub(grs_bitmap *bmp)
  414. {
  415. int i;
  416. for (i=0;i<MAX_CACHE_BITMAPS;i++) {
  417. if (rle_cache[i].expanded_bitmap == bmp) {
  418. return rle_cache[i].rle_bitmap;
  419. }
  420. }
  421. return NULL;
  422. }
  423. #endif
  424. grs_bitmap * rle_expand_texture( grs_bitmap * bmp )
  425. {
  426. int i;
  427. int lowest_count, lc;
  428. int least_recently_used;
  429. if (!rle_cache_initialized) rle_cache_init();
  430. Assert( !(bmp->bm_flags & BM_FLAG_PAGED_OUT) );
  431. lc = rle_counter;
  432. rle_counter++;
  433. if ( rle_counter < lc ) {
  434. for (i=0; i<MAX_CACHE_BITMAPS; i++ ) {
  435. rle_cache[i].rle_bitmap = NULL;
  436. rle_cache[i].last_used = 0;
  437. }
  438. }
  439. // if (((rle_counter % 100)==1) && (rle_hits+rle_misses > 0))
  440. // mprintf(( 0, "RLE-CACHE %d%%, H:%d, M:%d\n", (rle_misses*100)/(rle_hits+rle_misses), rle_hits, rle_misses ));
  441. lowest_count = rle_cache[rle_next].last_used;
  442. least_recently_used = rle_next;
  443. rle_next++;
  444. if ( rle_next >= MAX_CACHE_BITMAPS )
  445. rle_next = 0;
  446. for (i=0; i<MAX_CACHE_BITMAPS; i++ ) {
  447. if (rle_cache[i].rle_bitmap == bmp) {
  448. rle_hits++;
  449. rle_cache[i].last_used = rle_counter;
  450. return rle_cache[i].expanded_bitmap;
  451. }
  452. if ( rle_cache[i].last_used < lowest_count ) {
  453. lowest_count = rle_cache[i].last_used;
  454. least_recently_used = i;
  455. }
  456. }
  457. Assert(bmp->bm_w<=64 && bmp->bm_h<=64); //dest buffer is 64x64
  458. rle_misses++;
  459. rle_expand_texture_sub( bmp, rle_cache[least_recently_used].expanded_bitmap );
  460. rle_cache[least_recently_used].rle_bitmap = bmp;
  461. rle_cache[least_recently_used].last_used = rle_counter;
  462. return rle_cache[least_recently_used].expanded_bitmap;
  463. }
  464. void gr_rle_expand_scanline_generic( grs_bitmap * dest, int dx, int dy, ubyte *src, int x1, int x2 )
  465. {
  466. int i = 0, j;
  467. int count;
  468. ubyte color;
  469. if ( x2 < x1 ) return;
  470. count = 0;
  471. while ( i < x1 ) {
  472. color = *src++;
  473. if ( color == RLE_CODE ) return;
  474. if ( (color & RLE_CODE) == RLE_CODE ) {
  475. count = color & NOT_RLE_CODE;
  476. color = *src++;
  477. } else {
  478. // unique
  479. count = 1;
  480. }
  481. i += count;
  482. }
  483. count = i - x1;
  484. i = x1;
  485. // we know have '*count' pixels of 'color'.
  486. if ( x1+count > x2 ) {
  487. count = x2-x1+1;
  488. for ( j=0; j<count; j++ )
  489. gr_bm_pixel( dest, dx++, dy, color );
  490. return;
  491. }
  492. for ( j=0; j<count; j++ )
  493. gr_bm_pixel( dest, dx++, dy, color );
  494. i += count;
  495. while( i <= x2 ) {
  496. color = *src++;
  497. if ( color == RLE_CODE ) return;
  498. if ( (color & RLE_CODE) == RLE_CODE ) {
  499. count = color & NOT_RLE_CODE;
  500. color = *src++;
  501. } else {
  502. // unique
  503. count = 1;
  504. }
  505. // we know have '*count' pixels of 'color'.
  506. if ( i+count <= x2 ) {
  507. for ( j=0; j<count; j++ )
  508. gr_bm_pixel( dest, dx++, dy, color );
  509. i += count;
  510. } else {
  511. count = x2-i+1;
  512. for ( j=0; j<count; j++ )
  513. gr_bm_pixel( dest, dx++, dy, color );
  514. i += count;
  515. }
  516. }
  517. }
  518. void gr_rle_expand_scanline_generic_masked( grs_bitmap * dest, int dx, int dy, ubyte *src, int x1, int x2 )
  519. {
  520. int i = 0, j;
  521. int count;
  522. ubyte color;
  523. if ( x2 < x1 ) return;
  524. count = 0;
  525. while ( i < x1 ) {
  526. color = *src++;
  527. if ( color == RLE_CODE ) return;
  528. if ( (color & RLE_CODE) == RLE_CODE ) {
  529. count = color & NOT_RLE_CODE;
  530. color = *src++;
  531. } else {
  532. // unique
  533. count = 1;
  534. }
  535. i += count;
  536. }
  537. count = i - x1;
  538. i = x1;
  539. // we know have '*count' pixels of 'color'.
  540. if ( x1+count > x2 ) {
  541. count = x2-x1+1;
  542. if (color != TRANSPARENCY_COLOR) {
  543. for ( j=0; j<count; j++ )
  544. gr_bm_pixel( dest, dx++, dy, color );
  545. }
  546. return;
  547. }
  548. if ( color != TRANSPARENCY_COLOR ) {
  549. for ( j=0; j<count; j++ )
  550. gr_bm_pixel( dest, dx++, dy, color );
  551. } else
  552. dx += count;
  553. i += count;
  554. while( i <= x2 ) {
  555. color = *src++;
  556. if ( color == RLE_CODE ) return;
  557. if ( (color & RLE_CODE) == RLE_CODE ) {
  558. count = color & NOT_RLE_CODE;
  559. color = *src++;
  560. } else {
  561. // unique
  562. count = 1;
  563. }
  564. // we know have '*count' pixels of 'color'.
  565. if ( i+count <= x2 ) {
  566. if ( color != TRANSPARENCY_COLOR ) {
  567. for ( j=0; j<count; j++ )
  568. gr_bm_pixel( dest, dx++, dy, color );
  569. } else
  570. dx += count;
  571. i += count;
  572. } else {
  573. count = x2-i+1;
  574. if ( color != TRANSPARENCY_COLOR ) {
  575. for ( j=0; j<count; j++ )
  576. gr_bm_pixel( dest, dx++, dy, color );
  577. } else
  578. dx += count;
  579. i += count;
  580. }
  581. }
  582. }
  583. void gr_rle_expand_scanline_svga_masked( grs_bitmap * dest, int dx, int dy, ubyte *src, int x1, int x2 )
  584. {
  585. int i = 0, j;
  586. int count;
  587. ubyte color;
  588. ubyte * vram = (ubyte *)0xA0000;
  589. int VideoLocation,page,offset;
  590. if ( x2 < x1 ) return;
  591. VideoLocation = (unsigned int)dest->bm_data + (dest->bm_rowsize * dy) + dx;
  592. page = VideoLocation >> 16;
  593. offset = VideoLocation & 0xFFFF;
  594. gr_vesa_setpage( page );
  595. if ( (offset + (x2-x1+1)) < 65536 ) {
  596. // We don't cross a svga page, so blit it fast!
  597. gr_rle_expand_scanline_masked( &vram[offset], src, x1, x2 );
  598. return;
  599. }
  600. count = 0;
  601. while ( i < x1 ) {
  602. color = *src++;
  603. if ( color == RLE_CODE ) return;
  604. if ( (color & RLE_CODE) == RLE_CODE ) {
  605. count = color & NOT_RLE_CODE;
  606. color = *src++;
  607. } else {
  608. // unique
  609. count = 1;
  610. }
  611. i += count;
  612. }
  613. count = i - x1;
  614. i = x1;
  615. // we know have '*count' pixels of 'color'.
  616. if ( x1+count > x2 ) {
  617. count = x2-x1+1;
  618. if (color != TRANSPARENCY_COLOR) {
  619. for ( j=0; j<count; j++ ) {
  620. vram[offset++] = color;
  621. if ( offset >= 65536 ) {
  622. offset -= 65536;
  623. page++;
  624. gr_vesa_setpage(page);
  625. }
  626. }
  627. }
  628. return;
  629. }
  630. if ( color != TRANSPARENCY_COLOR ) {
  631. for ( j=0; j<count; j++ ) {
  632. vram[offset++] = color;
  633. if ( offset >= 65536 ) {
  634. offset -= 65536;
  635. page++;
  636. gr_vesa_setpage(page);
  637. }
  638. }
  639. } else {
  640. offset += count;
  641. if ( offset >= 65536 ) {
  642. offset -= 65536;
  643. page++;
  644. gr_vesa_setpage(page);
  645. }
  646. }
  647. i += count;
  648. while( i <= x2 ) {
  649. color = *src++;
  650. if ( color == RLE_CODE ) return;
  651. if ( (color & RLE_CODE) == RLE_CODE ) {
  652. count = color & NOT_RLE_CODE;
  653. color = *src++;
  654. } else {
  655. // unique
  656. count = 1;
  657. }
  658. // we know have '*count' pixels of 'color'.
  659. if ( i+count <= x2 ) {
  660. if ( color != TRANSPARENCY_COLOR ) {
  661. for ( j=0; j<count; j++ ) {
  662. vram[offset++] = color;
  663. if ( offset >= 65536 ) {
  664. offset -= 65536;
  665. page++;
  666. gr_vesa_setpage(page);
  667. }
  668. }
  669. } else {
  670. offset += count;
  671. if ( offset >= 65536 ) {
  672. offset -= 65536;
  673. page++;
  674. gr_vesa_setpage(page);
  675. }
  676. }
  677. i += count;
  678. } else {
  679. count = x2-i+1;
  680. if ( color != TRANSPARENCY_COLOR ) {
  681. for ( j=0; j<count; j++ ) {
  682. vram[offset++] = color;
  683. if ( offset >= 65536 ) {
  684. offset -= 65536;
  685. page++;
  686. gr_vesa_setpage(page);
  687. }
  688. }
  689. } else {
  690. offset += count;
  691. if ( offset >= 65536 ) {
  692. offset -= 65536;
  693. page++;
  694. gr_vesa_setpage(page);
  695. }
  696. }
  697. i += count;
  698. }
  699. }
  700. }