MonochromeLib.c 29 KB

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