// C Source File // Created 07/02/2004; 23:56:51 #include "mkhiblib.h" /* * General notes about scrolling * ----------------------------- * Scrolling down is like pressing the 'down key' in HibView, so the text goes to its * end, the screen goes up, and the buffer have to be filled at its bottom. * At the opposite, scrolling up is like pressing the 'up key' in HibView, so the text * goes to its begining, the screen goes down, and the buffer have to be filled at its * top. */ /** * Scroll the buffer down of the specified height * * @param height the height to scroll * @param hfile the file to scroll */ void hscrollhFileDown(short height, h_File * hfile) { short h_added, h_removed, nb_added, j; //calculate how many lines have to be added nb_added = 1; h_added = 0; //calculate the space for the new lines in the created space while (hfile->line_bot + nb_added < hfile->nb_scrlines && h_added < height) { h_added += hfile->hscrlines[hfile->line_bot + nb_added].height; nb_added++; } nb_added--; h_removed = 0; while (hfile->drawn_height - h_removed + h_added >= hfile->buffer.size.height) { h_removed += hfile->hscrlines[hfile->line_top++].height; } if (h_removed != 0) { //do the scroll register short nb = (hfile->drawn_height - h_removed) * hfile->buffer.mem.byte_width; register char * dest = hfile->buffer.mem.ptr; register char * src = dest + hfile->buffer.mem.byte_width * h_removed; while (nb-- > 0) { *(dest++) = *(src++); } hfile->buffer.pos.y -= h_removed; hfile->drawn_height -= h_removed; } memset(hfile->buffer.mem.ptr + hfile->drawn_height * hfile->buffer.mem.byte_width, 0, h_added * hfile->buffer.mem.byte_width); //fill with new lines in the created space for (j = 0; j < nb_added; j++) { hdrawLine(++hfile->line_bot, 0, hfile->drawn_height, hfile->buffer.size, hfile->buffer.mem, hfile); hfile->drawn_height += hfile->hscrlines[hfile->line_bot].height; } if (hfile->buffer.pos.y < 0) { hfile->buffer.pos.y = 0; } } /** * Scroll the buffer up of the specified height * * @param height the height to scroll * @param hfile the file to scroll */ void hscrollhFileUp(short height, h_File * hfile) { short h_added, h_removed, nb_added, h, j; //make space to insert "height" by deleting the bottoms lines nb_added = 1; h_added = 0; //calculate the space for the new lines in the created space while (hfile->line_top-nb_added >= 0 && h_added < height) { h_added += hfile->hscrlines[hfile->line_top - nb_added].height; nb_added++; } nb_added--; h_removed = 0; while (hfile->drawn_height - h_removed + h_added >= hfile->buffer.size.height) { h_removed += hfile->hscrlines[hfile->line_bot--].height; } hfile->drawn_height += h_added - h_removed; //do the scroll register short nb = (hfile->drawn_height - h_added) * hfile->buffer.mem.byte_width; register char * dest = hfile->buffer.mem.ptr + hfile->drawn_height * hfile->buffer.mem.byte_width - 1 ; register char * src = dest - hfile->buffer.mem.byte_width * h_added; while (nb-- > 0) { *(dest--) = *(src--); } hfile->buffer.pos.y += h_added; memset(hfile->buffer.mem.ptr, 0, h_added * hfile->buffer.mem.byte_width); //draw the lines h = 0; hfile->line_top -= nb_added; for (j = 0 ; j < nb_added; j++) { hdrawLine(hfile->line_top + j, 0, h, hfile->buffer.size, hfile->buffer.mem, hfile); h += hfile->hscrlines[hfile->line_top + j].height; } h = hfile->drawn_height - hfile->screen.size.height; if (hfile->buffer.pos.y > h) { hfile->buffer.pos.y = h; } } /** * Scroll the screen of one pixel up * * @param hfile the file to scroll * * This routine was adapted from Extgraph. Thank you the TICT Team */ void hl_goPixelUp(h_File * hfile) { register short* dst = hfile->screen_start; register short* src; register short nb = hfile->screen.size.height; dst += (nb << 4) - (nb); src = dst - 15; nb -= 2; asm volatile ("0:\n" "move.l -(%0),-(%1);move.l -(%0),-(%1);move.l -(%0),-(%1)\n" "move.l -(%0),-(%1);move.l -(%0),-(%1);move.l -(%0),-(%1)\n" "move.l -(%0),-(%1);move.w -(%0),-(%1)\n" "dbf %2,0b\n" : "=a" (src), "=a" (dst), "=d" (nb) : "0" (src), "1" (dst), "2" (nb)); hfile->buffer.pos.y--; if (hfile->buffer.pos.y < 0) { hscrollhFileUp(1, hfile); } unsigned char * src2 = hfile->buffer.mem.ptr + ((long) hfile->buffer.pos.y) * ((long) hfile->buffer.mem.byte_width) + (hfile->buffer.pos.x >> 3); unsigned char * dst2 = hfile->screen_start; short offset = hfile->buffer.pos.x & 7; // printf("%ld %d %d %d", hfile->buffer.mem.ptr, hfile->buffer.pos.y, nb); nb = hfile->screen.mem.byte_width; while (nb-- > 0) { // printf(" %ld %ld\n", src2, dst2); *dst2 = 0; *dst2 |= ((*src2) << offset); src2++; *dst2 |= ((*src2) >> (8 - offset)); dst2++; } } /** * Scroll the screen of one pixel down * * @param hfile the file to scroll * * This routine was adapted from Extgraph. Thank you the TICT Team */ void hl_goPixelDown(h_File * hfile) { register short* dst = hfile->screen_start; register short* src = dst + 15; register short nb = hfile->screen.size.height; nb -= 2; asm volatile ("0:\n" "move.l (%0)+,(%1)+;move.l (%0)+,(%1)+;move.l (%0)+,(%1)+\n" "move.l (%0)+,(%1)+;move.l (%0)+,(%1)+;move.l (%0)+,(%1)+\n" "move.l (%0)+,(%1)+;move.w (%0)+,(%1)+\n" "dbf %2,0b\n" : "=a" (src), "=a" (dst), "=d" (nb) : "0" (src), "1" (dst), "2" (nb)); hfile->buffer.pos.y++; if (hfile->buffer.pos.y + hfile->screen.size.height > hfile->drawn_height) { hscrollhFileDown(1, hfile); } unsigned char * src2 = hfile->buffer.mem.ptr + ((long)(hfile->buffer.pos.y + hfile->screen.size.height - 1)) * ((long) hfile->buffer.mem.byte_width) + (hfile->buffer.pos.x >> 3); unsigned char * dst2 = (char *) dst; short offset = hfile->buffer.pos.x & 7; // printf("%ld %d %d %d", hfile->buffer.mem.ptr, hfile->buffer.pos.y, hfile->screen.size.height, nb); // printf(" %ld %ld", src2, dst2); nb = hfile->screen.mem.byte_width; while (nb-- > 0) { // printf(" %ld %ld\n", src2, dst2); *dst2 = 0; *dst2 |= ((*src2) << offset); src2++; *dst2 |= ((*src2) >> (8 - offset)); dst2++; } } /** * Scroll the screen of one pixel right * * @param hfile the file to scroll * * This routine was adapted from Extgraph. Thank you the TICT Team */ void hl_goPixelRight(h_File * hfile) { register short* tmpbuffer = hfile->screen_start; register short nb = hfile->screen.size.height; tmpbuffer += (nb << 4) - (nb); nb--; asm volatile ("0:\n" "lsl.w -(%0);roxl.w -(%0);roxl.w -(%0);roxl.w -(%0);roxl.w -(%0)\n" "roxl.w -(%0);roxl.w -(%0);roxl.w -(%0);roxl.w -(%0);roxl.w -(%0)\n" "roxl.w -(%0);roxl.w -(%0);roxl.w -(%0);roxl.w -(%0);roxl.w -(%0)\n" "dbf %1,0b" : "=a" (tmpbuffer), "=d" (nb) : "0" (tmpbuffer), "1" (nb)); hfile->buffer.pos.x++; nb = hfile->screen.size.height; unsigned char * src2 = hfile->buffer.mem.ptr + ((long) hfile->buffer.pos.y * (long) hfile->buffer.mem.byte_width) + ((hfile->buffer.pos.x + hfile->screen.size.width - 1) >> 3); unsigned char * dst2 = hfile->screen.mem.ptr+((hfile->screen.size.width - 1) >> 3); short offset = (hfile->buffer.pos.x+hfile->screen.size.width - 1) & 7; short mask = (0xFF >> offset); offset = 7 - offset; while (nb-- > 0) { *dst2 |= ((*src2 & mask) >> offset); dst2 += hfile->screen.mem.byte_width; src2 += hfile->buffer.mem.byte_width; } } /** * Scroll the screen of one pixel left * * @param hfile the file to scroll * * This routine was adapted from Extgraph. Thank you the TICT Team */ void hl_goPixelLeft(h_File * hfile) { register short* tmpbuffer = hfile->screen_start; register short nb = hfile->screen.size.height; nb--; asm volatile ("0:\n" "lsr.w (%0)+;roxr.w (%0)+;roxr.w (%0)+;roxr.w (%0)+;roxr.w (%0)+\n" "roxr.w (%0)+;roxr.w (%0)+;roxr.w (%0)+;roxr.w (%0)+;roxr.w (%0)+\n" "roxr.w (%0)+;roxr.w (%0)+;roxr.w (%0)+;roxr.w (%0)+;roxr.w (%0)+\n" "dbf %1,0b" : "=a" (tmpbuffer), "=d" (nb) : "0" (tmpbuffer), "1" (nb)); hfile->buffer.pos.x--; nb = hfile->screen.size.height; unsigned char * src2 = hfile->buffer.mem.ptr + ((long) hfile->buffer.pos.y * (long) hfile->buffer.mem.byte_width) + (hfile->buffer.pos.x >> 3); unsigned char * dst2 = hfile->screen.mem.ptr; short offset = hfile->buffer.pos.x & 7; short mask = (0xFF << (7 - offset)); while (nb-- > 0) { *dst2 |= ((*src2 & mask) << offset); dst2 += hfile->screen.mem.byte_width; src2 += hfile->buffer.mem.byte_width; } } /** * Scroll the screen in teh specified direction * * @param dx the x shift * @param dy the y shift * @param hfile the file to scroll */ //void hl_scrollhFile(short dx, short dy, h_File * hfile) { // hfile->buffer.pos.y += dy; // hfile->buffer.pos.x += dx; // hl_refreshScreen(hfile); //} /** * Scroll the screen in teh specified direction * * @param dx the x shift * @param dy the y shift * @param hfile the file to scroll */ void hl_updateBuffers(h_File * hfile) { short h = hfile->buffer.pos.y + hfile->screen.size.height - hfile->drawn_height; if (h > 0) { //we are above the screen bottom //try to scroll hscrollhFileDown(h, hfile); h = hfile->buffer.pos.y + hfile->screen.size.height - hfile->drawn_height; if (h > 0) { //in fact we are at the end of the text //scroll in the other way hfile->buffer.pos.y -= h; } } if (hfile->buffer.pos.y < 0) { //we are above the screen top //try to scroll hscrollhFileUp(-hfile->buffer.pos.y, hfile); if (hfile->buffer.pos.y < 0) { //in fact we are at the beginning of the text hfile->buffer.pos.y = 0; } } h = hfile->buffer.size.width - hfile->screen.size.width; if (hfile->buffer.pos.x > h) { hfile->buffer.pos.x = h; } if (hfile->buffer.pos.x < 0) { hfile->buffer.pos.x = 0; } } /** * Goes to the specified position in the text. * The position is specified by a number or a bookmark number. If the line * number is -1, then it goes to the bookmark number. Else if goes to the * specified line. * * @param num_line the line to go to * @param bookmark the number of the bookmark to go to * @param hfile the file to draw */ void hl_goTo(short num_line, short bookmark, h_File * hfile) { if (num_line < 0) { //a bookmark to begin with has been defined unsigned short pos_txt = hfile->hbkmks[bookmark].pos_txt; num_line = 0; while (pos_txt >= hfile->hscrlines[num_line].pos_txt) num_line++; num_line--; } hl_drawPage(num_line, hfile); hl_updateBuffers(hfile); }