MonochromeLib.c 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282
  1. /*************************************************************/
  2. /** MonochromeLib - monochrome graphic library for fx-9860G **/
  3. /** MonochromeLib is free software **/
  4. /** **/
  5. /** @author Pierre "PierrotLL" Le Gall **/
  6. /** @contact legallpierre89@gmail.com **/
  7. /** **/
  8. /** @file MonochromeLib.c **/
  9. /** Code file of MonochromeLib **/
  10. /** **/
  11. /** @date 06-17-2011 **/
  12. /*************************************************************/
  13. #include "MonochromeLib.h"
  14. #include <stdlib.h>
  15. /******************************/
  16. /** Dependencies management **/
  17. /******************************/
  18. #ifdef ML_ALL
  19. #define ML_CLEAR_VRAM
  20. #define ML_CLEAR_SCREEN
  21. #define ML_DISPLAY_VRAM
  22. #define ML_SET_CONTRAST
  23. #define ML_GET_CONTRAST
  24. #define ML_PIXEL
  25. #define ML_POINT
  26. #define ML_PIXEL_TEST
  27. #define ML_LINE
  28. #define ML_HORIZONTAL_LINE
  29. #define ML_VERTICAL_LINE
  30. #define ML_RECTANGLE
  31. #define ML_POLYGONE
  32. #define ML_FILLED_POLYGONE
  33. #define ML_CIRCLE
  34. #define ML_FILLED_CIRCLE
  35. #define ML_ELLIPSE
  36. #define ML_ELLIPSE_IN_RECT
  37. #define ML_FILLED_ELLIPSE
  38. #define ML_FILLED_ELLIPSE_IN_RECT
  39. #define ML_HORIZONTAL_SCROLL
  40. #define ML_VERTICAL_SCROLL
  41. #define ML_BMP_OR
  42. #define ML_BMP_AND
  43. #define ML_BMP_XOR
  44. #define ML_BMP_OR_CL
  45. #define ML_BMP_AND_CL
  46. #define ML_BMP_XOR_CL
  47. #define ML_BMP_8_OR
  48. #define ML_BMP_8_AND
  49. #define ML_BMP_8_XOR
  50. #define ML_BMP_8_OR_CL
  51. #define ML_BMP_8_AND_CL
  52. #define ML_BMP_8_XOR_CL
  53. #define ML_BMP_16_OR
  54. #define ML_BMP_16_AND
  55. #define ML_BMP_16_XOR
  56. #define ML_BMP_16_OR_CL
  57. #define ML_BMP_16_AND_CL
  58. #define ML_BMP_16_XOR_CL
  59. #endif
  60. #ifdef ML_POLYGONE
  61. #define ML_LINE
  62. #endif
  63. #ifdef ML_LINE
  64. #define ML_PIXEL
  65. #endif
  66. #ifdef ML_POINT
  67. #define ML_PIXEL
  68. #define ML_RECTANGLE
  69. #endif
  70. #ifdef ML_RECTANGLE
  71. #define ML_HORIZONTAL_LINE
  72. #endif
  73. #ifdef ML_FILLED_POLYGONE
  74. #define ML_HORIZONTAL_LINE
  75. #endif
  76. #ifdef ML_CIRCLE
  77. #define ML_PIXEL
  78. #endif
  79. #ifdef ML_FILLED_CIRCLE
  80. #define ML_HORIZONTAL_LINE
  81. #endif
  82. #ifdef ML_ELLIPSE_IN_RECT
  83. #define ML_ELLIPSE
  84. #endif
  85. #ifdef ML_ELLIPSE
  86. #define ML_PIXEL
  87. #endif
  88. #ifdef ML_FILLED_ELLIPSE_IN_RECT
  89. #define ML_FILLED_ELLIPSE
  90. #endif
  91. #ifdef ML_FILLED_ELLIPSE
  92. #define ML_HORIZONTAL_LINE
  93. #endif
  94. /***************/
  95. /** Functions **/
  96. /***************/
  97. #define sgn(x) (x<0?-1:1)
  98. #define rnd(x) ((int)(x+0.5))
  99. const static unsigned int sc0135[] = { 0xD201D002, 0x422B0009, 0x80010070, 0x0135 };
  100. typedef char*(*sc_cpv)(void);
  101. char* ML_vram_adress() {
  102. return (*(sc_cpv)sc0135)();
  103. }
  104. #ifdef ML_CLEAR_VRAM
  105. void ML_clear_vram()
  106. {
  107. int i, end, *pointer_long, vram;
  108. char *pointer_byte;
  109. vram = (int)ML_vram_adress();
  110. end = 4-vram&3;
  111. pointer_byte = (char*)vram;
  112. for(i=0 ; i<end ; i++) pointer_byte[i] = 0;
  113. pointer_long = (int*) (vram+end);
  114. for(i=0 ; i<255 ; i++) pointer_long[i] = 0;
  115. pointer_byte += 1020+end;
  116. end = vram&3;
  117. for(i=0 ; i<end ; i++) pointer_byte[i] = 0;
  118. }
  119. #endif
  120. #ifdef ML_CLEAR_SCREEN
  121. void ML_clear_screen()
  122. {
  123. char *LCD_register_selector = (char*)0xB4000000, *LCD_data_register = (char*)0xB4010000;
  124. int i, j;
  125. for(i=0 ; i<64 ; i++) {
  126. *LCD_register_selector = 4;
  127. *LCD_data_register = i|192;
  128. *LCD_register_selector = 4;
  129. *LCD_data_register = 0;
  130. *LCD_register_selector = 7;
  131. for(j=0 ; j<16 ; j++) *LCD_data_register = 0;
  132. }
  133. }
  134. #endif
  135. #ifdef ML_DISPLAY_VRAM
  136. void ML_display_vram()
  137. {
  138. char *LCD_register_selector = (char*)0xB4000000, *LCD_data_register = (char*)0xB4010000, *vram;
  139. int i, j;
  140. vram = ML_vram_adress();
  141. for(i=0 ; i<64 ; i++) {
  142. *LCD_register_selector = 4;
  143. *LCD_data_register = i|192;
  144. *LCD_register_selector = 4;
  145. *LCD_data_register = 0;
  146. *LCD_register_selector = 7;
  147. for(j=0 ; j<16 ; j++) *LCD_data_register = *vram++;
  148. }
  149. }
  150. #endif
  151. #ifdef ML_SET_CONTRAST
  152. void ML_set_contrast(unsigned char contrast)
  153. {
  154. char *LCD_register_selector = (char*)0xB4000000, *LCD_data_register = (char*)0xB4010000;
  155. *LCD_register_selector = 6;
  156. *LCD_data_register = contrast;
  157. }
  158. #endif
  159. #ifdef ML_GET_CONTRAST
  160. unsigned char ML_get_contrast()
  161. {
  162. char *LCD_register_selector = (char*)0xB4000000, *LCD_data_register = (char*)0xB4010000;
  163. *LCD_register_selector = 6;
  164. return *LCD_data_register;
  165. }
  166. #endif
  167. #ifdef ML_PIXEL
  168. void ML_pixel(int x, int y, ML_Color color)
  169. {
  170. char* vram = ML_vram_adress();
  171. if(x<0 || x>127 || y<0 || y>63) return;
  172. switch(color)
  173. {
  174. case BLACK:
  175. vram[(y<<4)+(x>>3)] |= 128>>(x&7);
  176. break;
  177. case WHITE:
  178. vram[(y<<4)+(x>>3)] &= ~(128>>(x&7));
  179. break;
  180. case XOR:
  181. vram[(y<<4)+(x>>3)] ^= 128>>(x&7);
  182. break;
  183. case CHECKER:
  184. if(y&1^x&1) vram[(y<<4)+(x>>3)] &= ~(128>>(x&7));
  185. else vram[(y<<4)+(x>>3)] |= 128>>(x&7);
  186. break;
  187. }
  188. }
  189. #endif
  190. #ifdef ML_POINT
  191. void ML_point(int x, int y, int width, ML_Color color)
  192. {
  193. if(width < 1) return;
  194. if(width == 1) ML_pixel(x, y, color);
  195. else
  196. {
  197. int padding, pair;
  198. padding = width>>1;
  199. pair = !(width&1);
  200. ML_rectangle(x-padding+pair, y-padding+pair, x+padding, y+padding, 0, 0, color);
  201. }
  202. }
  203. #endif
  204. #ifdef ML_PIXEL_TEST
  205. ML_Color ML_pixel_test(int x, int y)
  206. {
  207. char *vram, byte;
  208. if(x<0 || x>127 || y<0 || y>63) return TRANSPARENT;
  209. vram = ML_vram_adress();
  210. byte = 1<<(7-(x&7));
  211. return (vram[(y<<4)+(x>>3)] & byte ? BLACK : WHITE);
  212. }
  213. #endif
  214. #ifdef ML_LINE
  215. void ML_line(int x1, int y1, int x2, int y2, ML_Color color)
  216. {
  217. int i, x, y, dx, dy, sx, sy, cumul;
  218. x = x1;
  219. y = y1;
  220. dx = x2 - x1;
  221. dy = y2 - y1;
  222. sx = sgn(dx);
  223. sy = sgn(dy);
  224. dx = abs(dx);
  225. dy = abs(dy);
  226. ML_pixel(x, y, color);
  227. if(dx > dy)
  228. {
  229. cumul = dx / 2;
  230. for(i=1 ; i<dx ; i++)
  231. {
  232. x += sx;
  233. cumul += dy;
  234. if(cumul > dx)
  235. {
  236. cumul -= dx;
  237. y += sy;
  238. }
  239. ML_pixel(x, y, color);
  240. }
  241. }
  242. else
  243. {
  244. cumul = dy / 2;
  245. for(i=1 ; i<dy ; i++)
  246. {
  247. y += sy;
  248. cumul += dx;
  249. if(cumul > dy)
  250. {
  251. cumul -= dy;
  252. x += sx;
  253. }
  254. ML_pixel(x, y, color);
  255. }
  256. }
  257. }
  258. #endif
  259. #ifdef ML_HORIZONTAL_LINE
  260. void ML_horizontal_line(int y, int x1, int x2, ML_Color color)
  261. {
  262. int i;
  263. char checker;
  264. char* vram = ML_vram_adress();
  265. if(y<0 || y>63 || (x1<0 && x2<0) || (x1>127 && x2>127)) return;
  266. if(x1 > x2)
  267. {
  268. i = x1;
  269. x1 = x2;
  270. x2 = i;
  271. }
  272. if(x1 < 0) x1 = 0;
  273. if(x2 > 127) x2 = 127;
  274. switch(color)
  275. {
  276. case BLACK:
  277. if(x1>>3 != x2>>3)
  278. {
  279. vram[(y<<4)+(x1>>3)] |= 255 >> (x1&7);
  280. vram[(y<<4)+(x2>>3)] |= 255 << 7-(x2&7);
  281. for(i=(x1>>3)+1 ; i<x2>>3 ; i++)
  282. vram[(y<<4) + i] = 255;
  283. }
  284. else vram[(y<<4)+(x1>>3)] |= (255>>(x1%8 + 7-x2%8))<<(7-(x2&7));
  285. break;
  286. case WHITE:
  287. if(x1>>3 != x2>>3)
  288. {
  289. vram[(y<<4)+(x1>>3)] &= 255 << 8-(x1&7);
  290. vram[(y<<4)+(x2>>3)] &= 255 >> 1+(x2&7);
  291. for(i=(x1>>3)+1 ; i<x2>>3 ; i++)
  292. vram[(y<<4) + i] = 0;
  293. }
  294. else vram[(y<<4)+(x1>>3)] &= (255<<8-(x1&7)) | (255>>1+(x2&7));
  295. break;
  296. case XOR:
  297. if(x1>>3 != x2>>3)
  298. {
  299. vram[(y<<4)+(x1>>3)] ^= 255 >> (x1&7);
  300. vram[(y<<4)+(x2>>3)] ^= 255 << 7-(x2&7);
  301. for(i=(x1>>3)+1 ; i<(x2>>3) ; i++)
  302. vram[(y<<4) + i] ^= 255;
  303. }
  304. else vram[(y<<4)+(x1>>3)] ^= (255>>((x1&7) + 7-(x2&7)))<<(7-(x2&7));
  305. break;
  306. case CHECKER:
  307. checker = (y&1 ? 85 : 170);
  308. if(x1>>3 != x2>>3)
  309. {
  310. vram[(y<<4)+(x1>>3)] &= 255 << 8-(x1&7);
  311. vram[(y<<4)+(x2>>3)] &= 255 >> 1+(x2&7);
  312. vram[(y<<4)+(x1>>3)] |= checker & 255>>(x1&7);
  313. vram[(y<<4)+(x2>>3)] |= checker & 255<<7-(x2&7);
  314. for(i=(x1>>3)+1 ; i<x2>>3 ; i++)
  315. vram[(y<<4) + i] = checker;
  316. }
  317. else
  318. {
  319. vram[(y<<4)+(x1>>3)] &= (255<<8-(x1&7)) | (255>>1+(x2&7));
  320. vram[(y<<4)+(x1>>3)] |= checker & (255>>(x1%8 + 7-x2%8))<<(7-(x2&7));
  321. }
  322. break;
  323. }
  324. }
  325. #endif
  326. #ifdef ML_VERTICAL_LINE
  327. void ML_vertical_line(int x, int y1, int y2, ML_Color color)
  328. {
  329. int i, j;
  330. char checker, byte, *vram = ML_vram_adress();
  331. if(x<0 || x>127 || (y1<0 && y2<0) || (y1>63 && y2>63)) return;
  332. if(y1 > y2)
  333. {
  334. int tmp = y1;
  335. y1 = y2;
  336. y2 = tmp;
  337. }
  338. if(y1 < 0) y1 = 0;
  339. if(y2 > 63) y2 = 63;
  340. i = (y1<<4)+(x>>3);
  341. j = (y2<<4)+(x>>3);
  342. switch(color)
  343. {
  344. case BLACK:
  345. byte = 128>>(x&7);
  346. for( ; i<=j ; i+=16)
  347. vram[i] |= byte;
  348. break;
  349. case WHITE:
  350. byte = ~(128>>(x&7));
  351. for( ; i<=j ; i+=16)
  352. vram[i] &= byte;
  353. break;
  354. case XOR:
  355. byte = 128>>(x&7);
  356. for( ; i<=j ; i+=16)
  357. vram[i] ^= byte;
  358. break;
  359. case CHECKER:
  360. byte = 128>>(x&7);
  361. checker = y1&1^x&1;
  362. for( ; i<=j ; i+=16)
  363. {
  364. if(checker) vram[i] &= ~byte;
  365. else vram[i] |= byte;
  366. checker = !checker;
  367. }
  368. break;
  369. }
  370. }
  371. #endif
  372. #ifdef ML_RECTANGLE
  373. void ML_rectangle(int x1, int y1, int x2, int y2, int border_width, ML_Color border_color, ML_Color fill_color)
  374. {
  375. int i;
  376. if(x1 > x2)
  377. {
  378. i = x1;
  379. x1 = x2;
  380. x2 = i;
  381. }
  382. if(y1 > y2)
  383. {
  384. i = y1;
  385. y1 = y2;
  386. y2 = i;
  387. }
  388. if(border_width > (x2-x1)/2+1) border_width = (x2-x1)/2+1;
  389. if(border_width > (y2-y1)/2+1) border_width = (y2-y1)/2+1;
  390. if(border_color != TRANSPARENT && border_width > 0)
  391. {
  392. for(i=0 ; i<border_width ; i++)
  393. {
  394. ML_horizontal_line(y1+i, x1, x2, border_color);
  395. ML_horizontal_line(y2-i, x1, x2, border_color);
  396. }
  397. for(i=y1+border_width ; i<=y2-border_width ; i++)
  398. {
  399. ML_horizontal_line(i, x1, x1+border_width-1, border_color);
  400. ML_horizontal_line(i, x2-border_width+1, x2, border_color);
  401. }
  402. }
  403. if(fill_color != TRANSPARENT)
  404. {
  405. for(i=y1+border_width ; i<=y2-border_width ; i++)
  406. ML_horizontal_line(i, x1+border_width, x2-border_width, fill_color);
  407. }
  408. }
  409. #endif
  410. #ifdef ML_POLYGONE
  411. void ML_polygone(int *x, int *y, int nb_vertices, ML_Color color)
  412. {
  413. int i;
  414. if(nb_vertices < 1) return;
  415. for(i=0 ; i<nb_vertices-1 ; i++)
  416. ML_line(x[i], y[i], x[i+1], y[i+1], color);
  417. ML_line(x[i], y[i], x[0], y[0], color);
  418. }
  419. #endif
  420. #ifdef ML_FILLED_POLYGONE
  421. int ML_filled_polygone_quicksord_partition(int *t, int p, int r)
  422. {
  423. int i, j, x, tmp;
  424. j = p - 1;
  425. x = t[r];
  426. for(i=p ; i<r ; i++)
  427. {
  428. if(x > t[i])
  429. {
  430. j++;
  431. tmp = t[j];
  432. t[j] = t[i];
  433. t[i] = tmp;
  434. }
  435. }
  436. t[r] = t[j+1];
  437. t[j+1] = x;
  438. return j + 1;
  439. }
  440. void ML_filled_polygone_quicksord(int* t, int p, int r)
  441. {
  442. int q;
  443. if(p < r)
  444. {
  445. q = ML_filled_polygone_quicksord_partition(t, p, r);
  446. ML_filled_polygone_quicksord(t, p, q-1);
  447. ML_filled_polygone_quicksord(t, q+1, r);
  448. }
  449. }
  450. void ML_filled_polygone(int *x, int *y, int nb_vertices, ML_Color color)
  451. {
  452. int i, j, dx, dy, ymin, ymax;
  453. int *cut_in_line, nb_cut;
  454. if(nb_vertices < 3) return;
  455. cut_in_line = malloc(nb_vertices*sizeof(int));
  456. if(!cut_in_line) return;
  457. ymin = ymax = y[0];
  458. for(i=1 ; i<nb_vertices ; i++)
  459. {
  460. if(y[i] < ymin) ymin = y[i];
  461. if(y[i] > ymax) ymax = y[i];
  462. }
  463. for(i=ymin ; i<=ymax ; i++)
  464. {
  465. nb_cut = 0;
  466. for(j=0 ; j<nb_vertices ; j++)
  467. {
  468. if((y[j]<=i && y[(j+1)%nb_vertices]>=i) || (y[j]>=i && y[(j+1)%nb_vertices]<=i))
  469. {
  470. dy = abs(y[j]-y[(j+1)%nb_vertices]);
  471. if(dy)
  472. {
  473. dx = x[(j+1)%nb_vertices]-x[j];
  474. cut_in_line[nb_cut] = x[j] + rnd(abs(i-y[j]+sgn(i-y[j])/2)*dx/dy);
  475. nb_cut++;
  476. }
  477. }
  478. }
  479. ML_filled_polygone_quicksord(cut_in_line, 0, nb_cut-1);
  480. j = 0;
  481. while(j<nb_cut-2 && cut_in_line[j]==cut_in_line[j+1]) j++;
  482. while(j < nb_cut)
  483. {
  484. if(j == nb_cut-1) ML_horizontal_line(i, cut_in_line[j-1]+1, cut_in_line[j], color);
  485. else
  486. {
  487. dx = 1;
  488. while(j+dx<nb_cut-1 && cut_in_line[j+dx]==cut_in_line[j+dx+1]) dx++;
  489. ML_horizontal_line(i, cut_in_line[j], cut_in_line[j+dx], color);
  490. j += dx;
  491. }
  492. j++;
  493. }
  494. }
  495. free(cut_in_line);
  496. }
  497. #endif
  498. #ifdef ML_CIRCLE
  499. void ML_circle(int x, int y, int radius, ML_Color color)
  500. {
  501. int plot_x, plot_y, d;
  502. if(radius < 0) return;
  503. plot_x = 0;
  504. plot_y = radius;
  505. d = 1 - radius;
  506. ML_pixel(x, y+plot_y, color);
  507. if(radius)
  508. {
  509. ML_pixel(x, y-plot_y, color);
  510. ML_pixel(x+plot_y, y, color);
  511. ML_pixel(x-plot_y, y, color);
  512. }
  513. while(plot_y > plot_x)
  514. {
  515. if(d < 0)
  516. d += 2*plot_x+3;
  517. else
  518. {
  519. d += 2*(plot_x-plot_y)+5;
  520. plot_y--;
  521. }
  522. plot_x++;
  523. if(plot_y >= plot_x)
  524. {
  525. ML_pixel(x+plot_x, y+plot_y, color);
  526. ML_pixel(x-plot_x, y+plot_y, color);
  527. ML_pixel(x+plot_x, y-plot_y, color);
  528. ML_pixel(x-plot_x, y-plot_y, color);
  529. }
  530. if(plot_y > plot_x)
  531. {
  532. ML_pixel(x+plot_y, y+plot_x, color);
  533. ML_pixel(x-plot_y, y+plot_x, color);
  534. ML_pixel(x+plot_y, y-plot_x, color);
  535. ML_pixel(x-plot_y, y-plot_x, color);
  536. }
  537. }
  538. }
  539. #endif
  540. #ifdef ML_FILLED_CIRCLE
  541. void ML_filled_circle(int x, int y, int radius, ML_Color color)
  542. {
  543. int plot_x, plot_y, d;
  544. if(radius < 0) return;
  545. plot_x = 0;
  546. plot_y = radius;
  547. d = 1 - radius;
  548. ML_horizontal_line(y, x-plot_y, x+plot_y, color);
  549. while(plot_y > plot_x)
  550. {
  551. if(d < 0)
  552. d += 2*plot_x+3;
  553. else {
  554. d += 2*(plot_x-plot_y)+5;
  555. plot_y--;
  556. ML_horizontal_line(y+plot_y+1, x-plot_x, x+plot_x, color);
  557. ML_horizontal_line(y-plot_y-1, x-plot_x, x+plot_x, color);
  558. }
  559. plot_x++;
  560. if(plot_y >= plot_x)
  561. {
  562. ML_horizontal_line(y+plot_x, x-plot_y, x+plot_y, color);
  563. ML_horizontal_line(y-plot_x, x-plot_y, x+plot_y, color);
  564. }
  565. }
  566. }
  567. #endif
  568. #ifdef ML_ELLIPSE
  569. void ML_ellipse(int x, int y, int radius1, int radius2, ML_Color color)
  570. {
  571. int plot_x, plot_y;
  572. float d1, d2;
  573. if(radius1 < 1 || radius2 < 1) return;
  574. plot_x = 0;
  575. plot_y = radius2;
  576. d1 = radius2*radius2 - radius1*radius1*radius2 + radius1*radius1/4;
  577. ML_pixel(x, y+plot_y, color);
  578. ML_pixel(x, y-plot_y, color);
  579. while(radius1*radius1*(plot_y-.5) > radius2*radius2*(plot_x+1))
  580. {
  581. if(d1 < 0)
  582. {
  583. d1 += radius2*radius2*(2*plot_x+3);
  584. plot_x++;
  585. } else {
  586. d1 += radius2*radius2*(2*plot_x+3) + radius1*radius1*(-2*plot_y+2);
  587. plot_x++;
  588. plot_y--;
  589. }
  590. ML_pixel(x+plot_x, y+plot_y, color);
  591. ML_pixel(x-plot_x, y+plot_y, color);
  592. ML_pixel(x+plot_x, y-plot_y, color);
  593. ML_pixel(x-plot_x, y-plot_y, color);
  594. }
  595. d2 = radius2*radius2*(plot_x+.5)*(plot_x+.5) + radius1*radius1*(plot_y-1)*(plot_y-1) - radius1*radius1*radius2*radius2;
  596. while(plot_y > 0)
  597. {
  598. if(d2 < 0)
  599. {
  600. d2 += radius2*radius2*(2*plot_x+2) + radius1*radius1*(-2*plot_y+3);
  601. plot_y--;
  602. plot_x++;
  603. } else {
  604. d2 += radius1*radius1*(-2*plot_y+3);
  605. plot_y--;
  606. }
  607. ML_pixel(x+plot_x, y+plot_y, color);
  608. ML_pixel(x-plot_x, y+plot_y, color);
  609. if(plot_y > 0)
  610. {
  611. ML_pixel(x+plot_x, y-plot_y, color);
  612. ML_pixel(x-plot_x, y-plot_y, color);
  613. }
  614. }
  615. }
  616. #endif
  617. #ifdef ML_ELLIPSE_IN_RECT
  618. void ML_ellipse_in_rect(int x1, int y1, int x2, int y2, ML_Color color)
  619. {
  620. int radius1, radius2;
  621. if(x1 > x2)
  622. {
  623. int tmp = x1;
  624. x1 = x2;
  625. x2 = tmp;
  626. }
  627. if(y1 > y2)
  628. {
  629. int tmp = y1;
  630. y1 = y2;
  631. y2 = tmp;
  632. }
  633. radius1 = (x2-x1)/2;
  634. radius2 = (y2-y1)/2;
  635. ML_ellipse(x1+radius1, y1+radius2, radius1, radius2, color);
  636. }
  637. #endif
  638. #ifdef ML_FILLED_ELLIPSE
  639. void ML_filled_ellipse(int x, int y, int radius1, int radius2, ML_Color color)
  640. {
  641. int plot_x, plot_y;
  642. float d1, d2;
  643. if(radius1 < 1 || radius2 < 1) return;
  644. plot_x = 0;
  645. plot_y = radius2;
  646. d1 = radius2*radius2 - radius1*radius1*radius2 + radius1*radius1/4;
  647. while(radius1*radius1*(plot_y-.5) > radius2*radius2*(plot_x+1))
  648. {
  649. if(d1 < 0)
  650. {
  651. d1 += radius2*radius2*(2*plot_x+3);
  652. plot_x++;
  653. } else {
  654. d1 += radius2*radius2*(2*plot_x+3) + radius1*radius1*(-2*plot_y+2);
  655. ML_horizontal_line(y+plot_y, x-plot_x, x+plot_x, color);
  656. ML_horizontal_line(y-plot_y, x-plot_x, x+plot_x, color);
  657. plot_x++;
  658. plot_y--;
  659. }
  660. }
  661. ML_horizontal_line(y+plot_y, x-plot_x, x+plot_x, color);
  662. ML_horizontal_line(y-plot_y, x-plot_x, x+plot_x, color);
  663. d2 = radius2*radius2*(plot_x+.5)*(plot_x+.5) + radius1*radius1*(plot_y-1)*(plot_y-1) - radius1*radius1*radius2*radius2;
  664. while(plot_y > 0)
  665. {
  666. if(d2 < 0)
  667. {
  668. d2 += radius2*radius2*(2*plot_x+2) + radius1*radius1*(-2*plot_y+3);
  669. plot_y--;
  670. plot_x++;
  671. } else {
  672. d2 += radius1*radius1*(-2*plot_y+3);
  673. plot_y--;
  674. }
  675. ML_horizontal_line(y+plot_y, x-plot_x, x+plot_x, color);
  676. if(plot_y > 0)
  677. ML_horizontal_line(y-plot_y, x-plot_x, x+plot_x, color);
  678. }
  679. }
  680. #endif
  681. #ifdef ML_FILLED_ELLIPSE_IN_RECT
  682. void ML_filled_ellipse_in_rect(int x1, int y1, int x2, int y2, ML_Color color)
  683. {
  684. int radius1, radius2;
  685. if(x1 > x2)
  686. {
  687. int tmp = x1;
  688. x1 = x2;
  689. x2 = tmp;
  690. }
  691. if(y1 > y2)
  692. {
  693. int tmp = y1;
  694. y1 = y2;
  695. y2 = tmp;
  696. }
  697. radius1 = (x2-x1)/2;
  698. radius2 = (y2-y1)/2;
  699. ML_filled_ellipse(x1+radius1, y1+radius2, radius1, radius2, color);
  700. }
  701. #endif
  702. #ifdef ML_HORIZONTAL_SCROLL
  703. void ML_horizontal_scroll(int scroll)
  704. {
  705. int i, j;
  706. unsigned char line[16], Bshift, next, *vram;
  707. unsigned short word;
  708. vram = ML_vram_adress();
  709. scroll %= 128;
  710. Bshift = 8-(scroll&7);
  711. for(i=0 ; i<64 ; i++)
  712. {
  713. for(j=0 ; j<16 ; j++) line[j] = vram[(i<<4)+((j-(scroll>>3)+15)&15)];
  714. next = line[15];
  715. vram[(i<<4)+15] = 0;
  716. for(j=15 ; j>0 ; j--)
  717. {
  718. word = next << Bshift;
  719. next = line[j-1];
  720. vram[(i<<4)+j] |= *((char*)&word+1);
  721. vram[(i<<4)+j-1] = *((char*)&word);
  722. }
  723. word = next << Bshift;
  724. vram[(i<<4)] |= *((char*)&word+1);
  725. vram[(i<<4)+15] |= *((char*)&word);
  726. }
  727. }
  728. #endif
  729. #ifdef ML_VERTICAL_SCROLL
  730. void ML_vertical_scroll(int scroll)
  731. {
  732. int i, j;
  733. char column[64], *vram = ML_vram_adress();
  734. scroll %= 64;
  735. for(i=0 ; i<16 ; i++)
  736. {
  737. for(j=0 ; j<64 ; j++) column[j] = vram[(j<<4)+i];
  738. for(j=0 ; j<64 ; j++) vram[(j<<4)+i] = column[(j-scroll+64)&63];
  739. }
  740. }
  741. #endif
  742. #ifdef ML_BMP_OR
  743. void ML_bmp_or(unsigned char *bmp, int x, int y, int width, int height)
  744. {
  745. unsigned short line;
  746. char shift, *screen, *p=(char*)&line;
  747. int i, j, begin=0, end=height, real_width=(width-1>>3<<3)+8;
  748. if(!bmp || x<0 || x>128-width || y<1-height || y>63 || width<1 || height<1) return;
  749. if(y < 0) begin = -y;
  750. if(y+height > 64) end = 64-y;
  751. shift = 8-(x&7);
  752. screen = ML_vram_adress()+(y+begin<<4)+(x>>3);
  753. for(i=begin ; i<end ; i++)
  754. {
  755. for(j=0 ; j<width-1>>3 ; j++)
  756. {
  757. line = bmp[i*(real_width>>3)+j]<<shift;
  758. screen[j] |= *p;
  759. if(shift!=8) screen[j+1] |= *(p+1);
  760. }
  761. line = (bmp[i*(real_width>>3)+j] & -1<<(real_width-width))<<shift;
  762. screen[j] |= *p;
  763. if(shift!=8 && x+real_width<129) screen[j+1] |= *(p+1);
  764. screen += 16;
  765. }
  766. }
  767. #endif
  768. #ifdef ML_BMP_AND
  769. void ML_bmp_and(unsigned char *bmp, int x, int y, int width, int height)
  770. {
  771. unsigned short line;
  772. char shift, *screen, *p=(char*)&line;
  773. int i, j, begin=0, end=height, real_width=(width-1>>3<<3)+8;
  774. if(!bmp || x<0 || x>128-width || y<1-height || y>63 || width<1 || height<1) return;
  775. if(y < 0) begin = -y;
  776. if(y+height > 64) end = 64-y;
  777. shift = 8-(x&7);
  778. screen = ML_vram_adress()+(y+begin<<4)+(x>>3);
  779. for(i=begin ; i<end ; i++)
  780. {
  781. for(j=0 ; j<width-1>>3 ; j++)
  782. {
  783. line = ~((unsigned char)~bmp[i*(real_width>>3)+j]<<shift);
  784. screen[j] &= *p;
  785. if(shift!=8) screen[j+1] &= *(p+1);
  786. }
  787. line = ~((unsigned char)~(bmp[i*(real_width>>3)+j] | (unsigned char)-1>>8-(width&7))<<shift);
  788. screen[j] &= *p;
  789. if(shift!=8 && x+real_width<129) screen[j+1] &= *(p+1);
  790. screen += 16;
  791. }
  792. }
  793. #endif
  794. #ifdef ML_BMP_XOR
  795. void ML_bmp_xor(unsigned char *bmp, int x, int y, int width, int height)
  796. {
  797. unsigned short line;
  798. char shift, *screen, *p=(char*)&line;
  799. int i, j, begin=0, end=height, real_width=(width-1>>3<<3)+8;
  800. if(!bmp || x<0 || x>128-width || y<1-height || y>63 || width<1 || height<1) return;
  801. if(y < 0) begin = -y;
  802. if(y+height > 64) end = 64-y;
  803. shift = 8-(x&7);
  804. screen = ML_vram_adress()+(y+begin<<4)+(x>>3);
  805. for(i=begin ; i<end ; i++)
  806. {
  807. for(j=0 ; j<width-1>>3 ; j++)
  808. {
  809. line = bmp[i*(real_width>>3)+j]<<shift;
  810. screen[j] ^= *p;
  811. if(shift!=8) screen[j+1] ^= *(p+1);
  812. }
  813. line = (bmp[i*(real_width>>3)+j] & -1<<(real_width-width))<<shift;
  814. screen[j] ^= *p;
  815. if(shift!=8 && x+real_width<129) screen[j+1] ^= *(p+1);
  816. screen += 16;
  817. }
  818. }
  819. #endif
  820. #ifdef ML_BMP_OR_CL
  821. void ML_bmp_or_cl(unsigned char *bmp, int x, int y, int width, int height)
  822. {
  823. unsigned short line;
  824. char shift, *screen, *p;
  825. int i, j, real_width, begin_x, end_x, begin_y, end_y;
  826. char bool1=1, bool2=1, bool3;
  827. if(!bmp || x<1-width || x>127 || y<1-height || y>63 || height<1 || width<1) return;
  828. p = (char*)&line;
  829. real_width = (width-1>>3<<3)+8;
  830. if(y < 0) begin_y = -y;
  831. else begin_y = 0;
  832. if(y+height > 64) end_y = 64-y;
  833. else end_y = height;
  834. shift = 8-(x&7);
  835. if(x<0)
  836. {
  837. begin_x = -x>>3;
  838. if(shift != 8) bool1 = 0;
  839. } else begin_x = 0;
  840. if(x+real_width > 128) end_x = 15-(x>>3), bool2 = 0;
  841. else end_x = real_width-1>>3;
  842. bool3 = (end_x == real_width-1>>3);
  843. screen = ML_vram_adress()+(y+begin_y<<4)+(x>>3);
  844. for(i=begin_y ; i<end_y ; i++)
  845. {
  846. if(begin_x < end_x)
  847. {
  848. line = bmp[i*(real_width>>3)+begin_x] << shift;
  849. if(bool1) screen[begin_x] |= *p;
  850. if(shift!=8) screen[begin_x+1] |= *(p+1);
  851. for(j=begin_x+1 ; j<end_x ; j++)
  852. {
  853. line = bmp[i*(real_width>>3)+j] << shift;
  854. screen[j] |= *p;
  855. if(shift!=8) screen[j+1] |= *(p+1);
  856. }
  857. }
  858. line = bmp[i*(real_width>>3)+end_x];
  859. if(bool3) line &= -1<<real_width-width;
  860. line <<= shift;
  861. if(begin_x < end_x || bool1) screen[end_x] |= *p;
  862. if(bool2) screen[end_x+1] |= *(p+1);
  863. screen += 16;
  864. }
  865. }
  866. #endif
  867. #ifdef ML_BMP_AND_CL
  868. void ML_bmp_and_cl(unsigned char *bmp, int x, int y, int width, int height)
  869. {
  870. unsigned short line;
  871. char shift, *screen, *p;
  872. int i, j, real_width, begin_x, end_x, begin_y, end_y;
  873. char bool1=1, bool2=1, bool3;
  874. if(!bmp || x<1-width || x>127 || y<1-height || y>63 || height<1 || width<1) return;
  875. p = (char*)&line;
  876. real_width = (width-1>>3<<3)+8;
  877. if(y < 0) begin_y = -y;
  878. else begin_y = 0;
  879. if(y+height > 64) end_y = 64-y;
  880. else end_y = height;
  881. shift = 8-(x&7);
  882. if(x<0)
  883. {
  884. begin_x = -x>>3;
  885. if(shift != 8) bool1 = 0;
  886. } else begin_x = 0;
  887. if(x+real_width > 128) end_x = 15-(x>>3), bool2 = 0;
  888. else end_x = real_width-1>>3;
  889. bool3 = (end_x == real_width-1>>3);
  890. screen = ML_vram_adress()+(y+begin_y<<4)+(x>>3);
  891. for(i=begin_y ; i<end_y ; i++)
  892. {
  893. if(begin_x < end_x)
  894. {
  895. line = ~((unsigned char)~bmp[i*(real_width>>3)+begin_x]<<shift);
  896. if(bool1) screen[begin_x] &= *p;
  897. if(shift!=8) screen[begin_x+1] &= *(p+1);
  898. for(j=begin_x+1 ; j<end_x ; j++)
  899. {
  900. line = ~((unsigned char)~bmp[i*(real_width>>3)+j]<<shift);
  901. screen[j] &= *p;
  902. if(shift!=8) screen[j+1] &= *(p+1);
  903. }
  904. }
  905. line = (unsigned char)~bmp[i*(real_width>>3)+end_x];
  906. if(bool3) line &= -1<<real_width-width;
  907. line = ~(line << shift);
  908. if(begin_x < end_x || bool1) screen[end_x] &= *p;
  909. if(bool2) screen[end_x+1] &= *(p+1);
  910. screen += 16;
  911. }
  912. }
  913. #endif
  914. #ifdef ML_BMP_XOR_CL
  915. void ML_bmp_xor_cl(unsigned char *bmp, int x, int y, int width, int height)
  916. {
  917. unsigned short line;
  918. char shift, *screen, *p;
  919. int i, j, real_width, begin_x, end_x, begin_y, end_y;
  920. char bool1=1, bool2=1, bool3;
  921. if(!bmp || x<1-width || x>127 || y<1-height || y>63 || height<1 || width<1) return;
  922. p = (char*)&line;
  923. real_width = (width-1>>3<<3)+8;
  924. if(y < 0) begin_y = -y;
  925. else begin_y = 0;
  926. if(y+height > 64) end_y = 64-y;
  927. else end_y = height;
  928. shift = 8-(x&7);
  929. if(x<0)
  930. {
  931. begin_x = -x>>3;
  932. if(shift != 8) bool1 = 0;
  933. } else begin_x = 0;
  934. if(x+real_width > 128) end_x = 15-(x>>3), bool2 = 0;
  935. else end_x = real_width-1>>3;
  936. bool3 = (end_x == real_width-1>>3);
  937. screen = ML_vram_adress()+(y+begin_y<<4)+(x>>3);
  938. for(i=begin_y ; i<end_y ; i++)
  939. {
  940. if(begin_x < end_x)
  941. {
  942. line = bmp[i*(real_width>>3)+begin_x] << shift;
  943. if(bool1) screen[begin_x] ^= *p;
  944. if(shift!=8) screen[begin_x+1] ^= *(p+1);
  945. for(j=begin_x+1 ; j<end_x ; j++)
  946. {
  947. line = bmp[i*(real_width>>3)+j] << shift;
  948. screen[j] ^= *p;
  949. if(shift!=8) screen[j+1] ^= *(p+1);
  950. }
  951. }
  952. line = bmp[i*(real_width>>3)+end_x];
  953. if(bool3) line &= -1<<real_width-width;
  954. line <<= shift;
  955. if(begin_x < end_x || bool1) screen[end_x] ^= *p;
  956. if(bool2) screen[end_x+1] ^= *(p+1);
  957. screen += 16;
  958. }
  959. }
  960. #endif
  961. #ifdef ML_BMP_8_OR
  962. void ML_bmp_8_or(unsigned char *bmp, int x, int y)
  963. {
  964. unsigned short line;
  965. char i, shift, begin=0, end=8, *screen, *p=(char*)&line;
  966. if(!bmp || x<0 || x>120 || y<-7 || y>63) return;
  967. if(y < 0) begin = -y;
  968. if(y > 56) end = 64-y;
  969. shift = 8-(x&7);
  970. screen = ML_vram_adress()+(y+begin<<4)+(x>>3);
  971. for(i=begin ; i<end ; i++)
  972. {
  973. line = bmp[i]<<shift;
  974. screen[0] |= *p;
  975. if(shift!=8) screen[1] |= *(p+1);
  976. screen += 16;
  977. }
  978. }
  979. #endif
  980. #ifdef ML_BMP_8_AND
  981. void ML_bmp_8_and(unsigned char *bmp, int x, int y)
  982. {
  983. unsigned short line;
  984. char i, shift, begin=0, end=8, *screen, *p=(char*)&line;
  985. if(!bmp || x<0 || x>120 || y<-7 || y>63) return;
  986. if(y < 0) begin = -y;
  987. if(y > 56) end = 64-y;
  988. shift = 8-(x&7);
  989. screen = ML_vram_adress()+(y+begin<<4)+(x>>3);
  990. for(i=begin ; i<end ; i++)
  991. {
  992. line = ~((unsigned char)~bmp[i]<<shift);
  993. screen[0] &= *p;
  994. if(shift!=8) screen[1] &= *(p+1);
  995. screen += 16;
  996. }
  997. }
  998. #endif
  999. #ifdef ML_BMP_8_XOR
  1000. void ML_bmp_8_xor(unsigned char *bmp, int x, int y)
  1001. {
  1002. unsigned short line;
  1003. char i, shift, begin=0, end=8, *screen, *p=(char*)&line;
  1004. if(!bmp || x<0 || x>120 || y<-7 || y>63) return;
  1005. if(y < 0) begin = -y;
  1006. if(y > 56) end = 64-y;
  1007. shift = 8-(x&7);
  1008. screen = ML_vram_adress()+(y+begin<<4)+(x>>3);
  1009. for(i=begin ; i<end ; i++)
  1010. {
  1011. line = bmp[i]<<shift;
  1012. screen[0] ^= *p;
  1013. if(shift<8) screen[1] ^= *(p+1);
  1014. screen += 16;
  1015. }
  1016. }
  1017. #endif
  1018. #ifdef ML_BMP_8_OR_CL
  1019. void ML_bmp_8_or_cl(unsigned char *bmp, int x, int y)
  1020. {
  1021. unsigned short line;
  1022. char i, shift, begin=0, end=8, bool1=1, bool2=1, *screen, *p=(char*)&line;
  1023. if(!bmp || x<-7 || x>127 || y<-7 || y>63) return;
  1024. if(y < 0) begin = -y;
  1025. if(y > 56) end = 64-y;
  1026. shift = 8-(x&7);
  1027. if(x < 0) bool1 = 0;
  1028. if(x>120 || shift==8) bool2 = 0;
  1029. screen = ML_vram_adress()+(y+begin<<4)+(x>>3);
  1030. for(i=begin ; i<end ; i++)
  1031. {
  1032. line = bmp[i]<<shift;
  1033. if(bool1) screen[0] |= *p;
  1034. if(bool2) screen[1] |= *(p+1);
  1035. screen += 16;
  1036. }
  1037. }
  1038. #endif
  1039. #ifdef ML_BMP_8_AND_CL
  1040. void ML_bmp_8_and_cl(unsigned char *bmp, int x, int y)
  1041. {
  1042. unsigned short line;
  1043. char i, shift, begin=0, end=8, bool1=1, bool2=1, *screen, *p=(char*)&line;
  1044. if(!bmp || x<-7 || x>127 || y<-7 || y>63) return;
  1045. if(y < 0) begin = -y;
  1046. if(y > 56) end = 64-y;
  1047. shift = 8-(x&7);
  1048. if(x < 0) bool1 = 0;
  1049. if(x>120 || shift==8) bool2 = 0;
  1050. screen = ML_vram_adress()+(y+begin<<4)+(x>>3);
  1051. for(i=begin ; i<end ; i++)
  1052. {
  1053. line = ~((unsigned char)~bmp[i]<<shift);
  1054. if(bool1) screen[0] &= *p;
  1055. if(bool2) screen[1] &= *(p+1);
  1056. screen += 16;
  1057. }
  1058. }
  1059. #endif
  1060. #ifdef ML_BMP_8_XOR_CL
  1061. void ML_bmp_8_xor_cl(unsigned char *bmp, int x, int y)
  1062. {
  1063. unsigned short line;
  1064. char i, shift, begin=0, end=8, bool1=1, bool2=1, *screen, *p=(char*)&line;
  1065. if(!bmp || x<-7 || x>127 || y<-7 || y>63) return;
  1066. if(y < 0) begin = -y;
  1067. if(y > 56) end = 64-y;
  1068. shift = 8-(x&7);
  1069. if(x < 0) bool1 = 0;
  1070. if(x>120 || shift==8) bool2 = 0;
  1071. screen = ML_vram_adress()+(y+begin<<4)+(x>>3);
  1072. for(i=begin ; i<end ; i++)
  1073. {
  1074. line = bmp[i]<<shift;
  1075. if(bool1) screen[0] ^= *p;
  1076. if(bool2) screen[1] ^= *(p+1);
  1077. screen += 16;
  1078. }
  1079. }
  1080. #endif
  1081. #ifdef ML_BMP_16_OR
  1082. void ML_bmp_16_or(unsigned short *bmp, int x, int y)
  1083. {
  1084. unsigned long line;
  1085. char i, shift, begin=0, end=16, *screen, *p=(char*)&line+1;
  1086. if(!bmp || x<0 || x>112 || y<-15 || y>63) return;
  1087. if(y < 0) begin = -y;
  1088. if(y > 48) end = 64-y;
  1089. shift = 8-(x&7);
  1090. screen = ML_vram_adress()+(y+begin<<4)+(x>>3);
  1091. for(i=begin ; i<end ; i++)
  1092. {
  1093. line = bmp[i]<<shift;
  1094. screen[0] |= *p;
  1095. screen[1] |= *(p+1);
  1096. if(shift!=8) screen[2] |= *(p+2);
  1097. screen += 16;
  1098. }
  1099. }
  1100. #endif
  1101. #ifdef ML_BMP_16_AND
  1102. void ML_bmp_16_and(unsigned short *bmp, int x, int y)
  1103. {
  1104. unsigned long line;
  1105. char i, shift, begin=0, end=16, *screen, *p=(char*)&line+1;
  1106. if(!bmp || x<0 || x>112 || y<-15 || y>63) return;
  1107. if(y < 0) begin = -y;
  1108. if(y > 48) end = 64-y;
  1109. shift = 8-(x&7);
  1110. screen = ML_vram_adress()+(y+begin<<4)+(x>>3);
  1111. for(i=begin ; i<end ; i++)
  1112. {
  1113. line = ~((unsigned short)~bmp[i]<<shift);
  1114. screen[0] &= *p;
  1115. screen[1] &= *(p+1);
  1116. if(shift!=8) screen[2] &= *(p+2);
  1117. screen += 16;
  1118. }
  1119. }
  1120. #endif
  1121. #ifdef ML_BMP_16_XOR
  1122. void ML_bmp_16_xor(unsigned short *bmp, int x, int y)
  1123. {
  1124. unsigned long line;
  1125. char i, shift, begin=0, end=16, *screen, *p=(char*)&line+1;
  1126. if(!bmp || x<0 || x>112 || y<-15 || y>63) return;
  1127. if(y < 0) begin = -y;
  1128. if(y > 48) end = 64-y;
  1129. shift = 8-(x&7);
  1130. screen = ML_vram_adress()+(y+begin<<4)+(x>>3);
  1131. for(i=begin ; i<end ; i++)
  1132. {
  1133. line = bmp[i]<<shift;
  1134. screen[0] ^= *p;
  1135. screen[1] ^= *(p+1);
  1136. if(shift!=8) screen[2] ^= *(p+2);
  1137. screen += 16;
  1138. }
  1139. }
  1140. #endif
  1141. #ifdef ML_BMP_16_OR_CL
  1142. void ML_bmp_16_or_cl(unsigned short *bmp, int x, int y)
  1143. {
  1144. unsigned long line;
  1145. char i, shift, begin=0, end=16, bool1=1, bool2=1, bool3=1, *screen, *p=(char*)&line+1;
  1146. if(!bmp || x<-15 || x>127 || y<-15 || y>63) return;
  1147. if(y < 0) begin = -y;
  1148. if(y > 48) end = 64-y;
  1149. shift = 8-(x&7);
  1150. if(x < 0) bool1 = 0;
  1151. if(x<-8 || x>119) bool2 = 0;
  1152. if(x>111 || shift==8) bool3 = 0;
  1153. screen = ML_vram_adress()+(y+begin<<4)+(x>>3);
  1154. for(i=begin ; i<end ; i++)
  1155. {
  1156. line = bmp[i]<<shift;
  1157. if(bool1) screen[0] |= *p;
  1158. if(bool2) screen[1] |= *(p+1);
  1159. if(bool3) screen[2] |= *(p+2);
  1160. screen += 16;
  1161. }
  1162. }
  1163. #endif
  1164. #ifdef ML_BMP_16_AND_CL
  1165. void ML_bmp_16_and_cl(unsigned short *bmp, int x, int y)
  1166. {
  1167. unsigned long line;
  1168. char i, shift, begin=0, end=16, bool1=1, bool2=1, bool3=1, *screen, *p=(char*)&line+1;
  1169. if(!bmp || x<-15 || x>127 || y<-15 || y>63) return;
  1170. if(y < 0) begin = -y;
  1171. if(y > 48) end = 64-y;
  1172. shift = 8-(x&7);
  1173. if(x < 0) bool1 = 0;
  1174. if(x<-8 || x>119) bool2 = 0;
  1175. if(x>111 || shift==8) bool3 = 0;
  1176. screen = ML_vram_adress()+(y+begin<<4)+(x>>3);
  1177. for(i=begin ; i<end ; i++)
  1178. {
  1179. line = ~((unsigned short)~bmp[i]<<shift);
  1180. if(bool1) screen[0] &= *p;
  1181. if(bool2) screen[1] &= *(p+1);
  1182. if(bool3) screen[2] &= *(p+2);
  1183. screen += 16;
  1184. }
  1185. }
  1186. #endif
  1187. #ifdef ML_BMP_16_XOR_CL
  1188. void ML_bmp_16_xor_cl(unsigned short *bmp, int x, int y)
  1189. {
  1190. unsigned long line;
  1191. char i, shift, begin=0, end=16, bool1=1, bool2=1, bool3=1, *screen, *p=(char*)&line+1;
  1192. if(!bmp || x<-15 || x>127 || y<-15 || y>63) return;
  1193. if(y < 0) begin = -y;
  1194. if(y > 48) end = 64-y;
  1195. shift = 8-(x&7);
  1196. if(x < 0) bool1 = 0;
  1197. if(x<-8 || x>119) bool2 = 0;
  1198. if(x>111 || shift==8) bool3 = 0;
  1199. screen = ML_vram_adress()+(y+begin<<4)+(x>>3);
  1200. for(i=begin ; i<end ; i++)
  1201. {
  1202. line = bmp[i]<<shift;
  1203. if(bool1) screen[0] ^= *p;
  1204. if(bool2) screen[1] ^= *(p+1);
  1205. if(bool3) screen[2] ^= *(p+2);
  1206. screen += 16;
  1207. }
  1208. }
  1209. #endif