MonochromeLib.c 29 KB

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