This addin is a Chip 8 Emulator.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

MonochromeLib.c 29KB

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