aboutsummaryrefslogtreecommitdiff
path: root/pkg/images/tv/iis/iism70/zsnap.x
blob: c0f9b23035fc2dc5cc9d9153fd3254f4a1f421c5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.

include <mach.h>
include <fset.h>
include "iis.h"
include "../lib/ids.h"

# DO_SNAP -- Return a line of the active image display, as seen
# by the viewer.

procedure do_snap (buf, nchar, xpos, ypos)

short	buf[ARB]			# buffer to read into
int	nchar				# how many to read
int	xpos, ypos			# and from where

int	y, yindex, xs, xe
int	line, previous
int	i,j
int	yedge
int	zm, count
bool	first

include "../lib/ids.com"
include "iis.com"
include "zsnap.com"

begin
	# Check if read is for one line only

	if (nchar > IIS_XDIM) {
	    call eprintf("ZSNAP -- too many pixels (%d) requested.\n")
	        call pargi (nchar)
	    call aclrs (buf, nchar)
	    return
	}

	# Determine x and y coordinates on screen.

	y = IIS_YDIM - 1 - ypos
	xs = xpos
	xe = xs + nchar - 1
	count = nchar

	# See if we are dealing with (a part of only) one line

	if (xe >= IIS_XDIM) {
	    call eprintf("ZSNAP -- line overlap error (xend is %d).\n")
		call pargi (xe)
	    call aclrs (buf, nchar)
	    return
	}

	# Determine whether above or below split point.

	if (y < ysplit)
	    yindex = 1
	else
	    yindex = 2

	# Clear accumulators

	do j = sn_start, sn_end
	    call aclrs (Mems[result[j]], IIS_XDIM)

	# Fetch and massage data for each active frame

	first = true
	previous = -1		# a bit of safety if no frames on
	do i = 1, i_maxframes {
	    if (on[i]) {
		# If frame not active in any color for this half of screen,
		# ignore it
		if (sn_start != sn_end) {
		    if ((left[BLU, yindex, i] == -1) &&
		        (left[GR , yindex, i] == -1) &&
		        (left[RD , yindex, i] == -1) )
		         next
		} else if (left[sn_start, yindex, i] == -1)
		    next

		zm = zoom[i]
		iplane = 377B			# all bit planes
		iframe = 2**(i-1)

		# y edge of frame (top) [ see zcursor_set for more information]
		yedge = IIS_YCEN - yscroll[i] + IIS_YCEN_INV - IIS_YCEN_INV/zm
		if (yedge < 0)
		    yedge = yedge + IIS_YDIM

		# Desired y (screen) coordinate
		line = yedge + y/zm
		if (line >= IIS_YDIM)
	    	    line = line - IIS_YDIM
	        # If have done this line before, just return the same answer

		if (first) {
		    if (line == prev_y) {
	    	        call amovs (Mems[answer], buf, nchar)
	    	        return
		    }
		    previous = line
		    first = false
		}

		# Turn line into file position.
		line = IIS_YDIM - 1 - line
		if (multi_frame)
		    call fseti (sn_fd, F_CANCEL, OK)
		call zseek (sn_fd, xs, line)
		call read (sn_fd, Mems[input], count)
		call zmassage (zm, xscroll[i], yindex, i, xs, xe)
	    }
	}

	# Apply scaling

	do j = sn_start, sn_end {
	    # Note...xs, xe are zero-based indices
	    if ( offset[j] != 0)
	        call aaddks (Mems[result[j]+xs], offset[j],
		             Mems[result[j]+xs], count)
	    if ( range[j] != 1)
	        call adivks (Mems[result[j]+xs], range[j],
	   		     Mems[result[j]+xs], count)
	    call aluts (Mems[result[j]+xs], Mems[result[j]+xs], count,
			Mems[ofmp[j]])
	}

	# Or in the graphics ... use of "select" (asel) depends on design
	# decision in zdisplay_g.x

	if (gr_in_use) {
	    iframe = GRCHAN
	    iplane = 177B		# ignore cursor plane
	    zm = zoom[GRCHNUM]

	    yedge = IIS_YCEN - yscroll[GRCHNUM] + IIS_YCEN_INV - IIS_YCEN_INV/zm
	    if (yedge < 0)
	        yedge = yedge + IIS_YDIM

	    line = yedge + y/zm
	    if (line >= IIS_YDIM)
	        line = line - IIS_YDIM
	    line = IIS_YDIM - 1 - line

	    if (multi_frame)
		call fseti (sn_fd, F_CANCEL, OK)

	    call zseek (sn_fd, xs, line)
	    call read (sn_fd, Mems[input], count)
	    call zmassage (zm, xscroll[GRCHNUM], yindex, GRCHNUM, xs, xe)

	    do j = sn_start, sn_end {
	        call aluts (Mems[input+xs], Mems[zs], count, Mems[grp[j]])

	        # Build boolean which says if have graphics on
	        call abneks (Mems[zs], short(0), Memi[grbit_on], count) 

	        # With INSERT on: replace data with graphics.
	        call asels (Mems[zs], Mems[result[j]+xs], Mems[result[j]+xs],
		    Memi[grbit_on], count)
	    }
	}

	# The answer is:

	if (sn_start != sn_end) {
	    call aadds (Mems[result[BLU]], Mems[result[GR]],
	        Mems[answer], IIS_XDIM)
	    call aadds (Mems[answer], Mems[result[RD]], Mems[answer], IIS_XDIM)
	    call adivks (Mems[answer], short(3), Mems[answer], IIS_XDIM)
	} else {
	    # Put in "answer" so repeated lines are in known location
	    call amovs (Mems[result[sn_start]], Mems[answer], nchar)
	}

	# Set the previous line and return the answer

	prev_y = previous
	call amovs (Mems[answer], buf, nchar)
end


# ZMASSAGE --- do all the boring massaging of the data: zoom, scroll, look
# up tables.

procedure zmassage (zm, xscr, yi, i, xstart, xend)

int	zm			# zoom factor
short	xscr			# x scroll
int	yi			# y-index
int	i			# frame index
int	xstart, xend		# indices for line start and end

int	lb, count		# left bound, count of number of items
int	j, x1, x2, itemp
include	"zsnap.com"

begin
	if ( (xscr != IIS_XCEN) || (zm != 1)) {
	    if (xscr == IIS_XCEN)
		# Scrolling not needed
		call amovs (Mems[input], Mems[zs], IIS_XDIM)
	    else {
		# Scroll the data
		lb = xscr - IIS_XCEN
		if ( lb < 0 )
		    lb = lb + IIS_XDIM
		count = IIS_XDIM - lb
		call amovs (Mems[input+lb], Mems[zs], count)
		call amovs (Mems[input], Mems[zs+count], lb)
	    }
	    # Now zoom it
	    if (zm == 1)
		call amovs (Mems[zs], Mems[input], IIS_XDIM)
	    else
		call ids_blockit (Mems[zs+IIS_XCEN-IIS_XCEN/zm], Mems[input],
		              IIS_XDIM, real(zm))
	}

	if (i == GRCHNUM)
	    return

	# With the aligned data, perform the lookup.  Note that left is
	# 0 based, right is (0-based) first excluded value.

	do j = sn_start, sn_end {
	    if (left[j, yi, i] == -1)
		next
	    itemp = left[j,yi,i]
	    x1 = max (itemp, xstart)
	    itemp = right[j,yi,i]
	    x2 = min (itemp - 1, xend)
	    call aluts (Mems[input+x1], Mems[zs], x2-x1+1, Mems[lutp[j,i]])
	    call aadds (Mems[zs], Mems[result[j]+x1], Mems[result[j]+x1],
	   		x2-x1+1)
	}
end