1 /*
2
3 Copyright (C) 2015-2018 Night Dive Studios, LLC.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 */
19 /*
20 * $Source: r:/prj/cit/src/RCS/hflip.c $
21 * $Revision: 1.6 $
22 * $Author: mahk $
23 * $Date: 1994/10/31 22:08:14 $
24 */
25
26 #include "gr2ss.h"
27 #include "cybmem.h"
28
29 // MLA #define REAL_HFLIP
30 #ifdef REAL_HFLIP
31 // asm is good
32 // tmp should be half a max row
33 // we copy to half row, then mirrow backwards, then copy half row in
34 void do_flip_in_place(uchar *bits, uchar *tmp, int w, int h, int row);
35 #pragma aux do_flip_in_place = \
36 /* end of the loop thing, so we need to do it to start out */ \
37 "mov eax, ecx" \
38 /* edi ptr tmp, esi ptr bits line, eax+ecx width, edx is height */ \
39 "per_line:" \
40 "shl edx, 16" /* get height back up there */ \
41 "mov ebx, esi" \
42 /* first copy half row */ \
43 "move_left_to_tmp:" \
44 "shr ecx, 1" \
45 "and ecx, 3" \
46 "rep movsb" \
47 "mov ecx, eax" \
48 "shr ecx, 3" \
49 "rep movsd" \
50 "dec edi" /* get back to end of tmp stream */ \
51 /* now mirror right half back to left */ \
52 "mov ecx, eax" \
53 "mov esi, ebx" /* get to left of bits */ \
54 "add esi, ecx" /* get to right of bits */ \
55 "dec esi" /* correct pixel is w-1 */ \
56 /* should inline this a bunch, eh? */ \
57 "rev_right_to_left_loop:" \
58 "mov dl,[esi]" \
59 "mov [ebx],dl" \
60 "dec esi" \
61 "inc ebx" \
62 "cmp esi, ebx" \
63 "jg rev_right_to_left_loop" \
64 /* now take back out of temp */ \
65 "jne even_size" \
66 "inc ebx" /* if odd, need do nothing to middle pixel */ \
67 "even_size:" /* ebx now points at next to fill */ \
68 "shr ecx, 1" /* note now edi is source, bx dest */ \
69 "rev_temp_to_right_loop:" \
70 "mov dl,[edi]" \
71 "mov [ebx],dl" \
72 "dec edi" \
73 "inc ebx" \
74 "dec ecx" \
75 "jnz rev_temp_to_right_loop" \
76 "inc edi" /* edi is left pointing one before start, thus inc */ \
77 "mov esi, ebx" /* store final pixel addr back into esi */ \
78 "add esi,[esp]" /* esi is pointing one past the end of line */ \
79 "mov ecx, eax" \
80 "shr edx, 16" \
81 "dec edx" \
82 "jnz per_line" \
83 "add esp, 4" /* get rid of the row_size on the stack */ \
84 parm [esi] [edi] [ecx] [edx] modify [eax ebx];
85
86 #pragma disable_message(202)
87 // row skip is used implicitly above
shock_hflip_in_place(grs_bitmap * bm)88 void shock_hflip_in_place(grs_bitmap *bm) {
89 int row_skip = bm->row - bm->w;
90 uchar tmp[320];
91
92 do_flip_in_place(bm->bits, tmp, bm->w, bm->h, row_skip);
93 }
94 #pragma enable_message(202)
95
_flip_in_place(uchar * bits,uchar * tmp,int w,int h,int row)96 void _flip_in_place(uchar *bits, uchar *tmp, int w, int h, int row) { do_flip_in_place(bits, tmp, w, h, row - w); }
97
98 #else // !REAL_HFLIP
99
shock_hflip_in_place(grs_bitmap * bm)100 void shock_hflip_in_place(grs_bitmap *bm) {
101 grs_canvas big_canvas;
102 grs_canvas bm_canvas;
103 gr_init_canvas(&big_canvas, big_buffer, BMT_FLAT8, bm->w, bm->h);
104 gr_init_canvas(&bm_canvas, bm->bits, BMT_FLAT8, bm->w, bm->h);
105 gr_push_canvas(&big_canvas);
106 gr_hflip_bitmap(bm, 0, 0);
107 gr_pop_canvas();
108 gr_push_canvas(&bm_canvas);
109 ss_bitmap(&big_canvas.bm, 0, 0);
110 gr_pop_canvas();
111 }
112
113 #endif
114