⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 images.cpp

📁 DOS游戏编程中处理Int 13的工具包
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// appears to be sliding onto the screen. This is done by starting with very
// narrow slices, which are grabbed from the center of the source, and disp-
// layed at the outside edges of the screen. As the slices get wider they re-
// main rooted to the edges of the screen, so that they appear to slide into
// the center. The outer loop iterates 160 times, or half the screen width.
// On each iteration the width of the frame (i_wid) is increased by one, and
// es:di, ds:si point to the top left corner of the source frame.
// **************************************************************************

void doSlideVerticalWipe(void far *pic_buf)
	{
	int i_wid, x0, putx;
	char ctrl;                   // controls branching

	asm	{
		mov i_wid, 0             // zero out the outer loop counter
		push ds                  // save the data segment
		mov es, GRAPH_SEG        // get the video segment into es
		}
	lefthalf:
	asm {
		mov ax, 160              // get center line into ax
		sub ax, i_wid            // i_wid is the offset from center
		mov x0, ax               // x0 is the top left of the source block
		mov putx, 0              // putx is the top left of the dest block
		mov ctrl, 0
		jmp doframe              // display the frame
		}

	righthalf:
	asm {
		mov ax, 160              // mostly same as above except for
		mov x0, ax               // right side
		mov ax, 319
		sub ax, i_wid
		mov putx, ax
		mov ctrl, 1
		jmp doframe
		}
	checkloop:
	asm {
		inc i_wid
		cmp i_wid, 160           // have 160 iterations
		jna lefthalf
		pop ds                   // restore data segment
		}
	return;                      // ** exit point **

	doframe:
	asm {
		mov di, putx             // di == top left corner of destination
		mov dx, input_status_1   // used to test for vbi below
		lds si, pic_buf          // get picture pointe into ds:si
		add si, x0               // set si == top left corner of source block
		}
	test_1:                      // these lines test for the vbi
	asm	{
		in al, dx                // first test, out of vbi
		test al,0x8
		jnz test_1
		}
	test_2:
	asm	{
		in al, dx                // second test, in vbi
		test al,0x8
		jz test_2
		mov dx, 200              // set dx up as loop counter
		cld                      // clear the direction flag
		}
	mainloop:                    // frame drawing loop
	asm	{
		mov cx, i_wid            // i_wid is equal to the block width
		push si                  // save the offsets
		push di
		shr cx, 1                // optimized copy technique, cx==number of
		rep movsw                // number of bytes/2
		rcl cx, 1                // now, if cx was odd, cx == 1, else cx ==0
		rep movsb                // catches any odd byte  (thanks to Gus S.)
		pop di                   // restore the offsets
		pop si
		add di, 320              // point to the next line
		add si, 320
		dec dx                   // adjust the outer loop counter
		jnz mainloop

		cmp ctrl, 0              // if last copy was lefthalf do righthalf
		je righthalf
		jmp checkloop
		}
	}

// **************************************************************************
// doSlideHorizWipe operates almost exactly like doSlideVerticalWipe above,
// except that the image slides in from top and bottom instead of from left
// and right. Like the other wipes it uses the wipe to clear the screen if
// called with pic_buf == NULL.
//
// This function operates almost exactly like the vertical version directly
// above.
// **************************************************************************

void  doSlideHorizWipe(void far *pic_buf)
	{
	int i_wid, y0, puty;
	char ctrl;                   // controls branching

	asm	{
		mov i_wid, 1             // zero out the outer loop counter
		push ds                  // save the data segment
		mov es, GRAPH_SEG        // get the video segment into es
		}
	tophalf:
	asm {
		mov ax, 100              // get center line into ax
		sub ax, i_wid            // i_wid is the offset from center
		mov bx, 320
		mul bx
		mov y0, ax               // x0 is the top left of the source block
		mov puty, 0              // putx is the top left of the dest block
		mov ctrl, 0
		jmp doframe              // display the frame
		}

	bottomhalf:
	asm {
		mov ax, 99               // mostly same as above except for
		mov bx, 320
		mul bx
		mov y0, ax               // right side
		mov ax, 199
		sub ax, i_wid
		mul bx
		mov puty, ax
		mov ctrl, 1
		jmp doframe
		}
	checkloop:
	asm {
		inc i_wid
		cmp i_wid, 100           // have 160 iterations
		jna tophalf
		pop ds                   // restore data segment
		}
	return;                      // ** exit point **

	doframe:
	asm {
		mov di, puty             // di == top left corner of destination
		mov dx, input_status_1   // used to test for vbi below
		lds si, pic_buf          // get picture pointe into ds:si
		add si, y0               // set si == top left corner of source block
		}
	test_1:                      // these lines test for the vbi
	asm	{
		in al, dx                // first test, out of vbi
		test al,0x8
		jnz test_1
		}
	test_2:
	asm	{
		in al, dx                // second test, in vbi
		test al,0x8
		jz test_2
		mov dx, i_wid            // set dx up as loop counter
		cld                      // clear the direction flag
		}
	mainloop:                    // frame drawing loop
	asm	{
		mov cx, 160              // i_wid is equal to the block width
		push si                  // save the offsets
		push di
		rep movsw                // number of bytes/2
		pop di                   // restore the offsets
		pop si
		add di, 320              // point to the next line
		add si, 320
		dec dx                   // adjust the outer loop counter
		jnz mainloop

		cmp ctrl, 0              // if last copy was lefthalf do righthalf
		je bottomhalf
		jmp checkloop
		}
	}

// *************************************************************************
// doVerticalDissolve causes the image stored in pic_buf to be displayed by
// fading in multiple vertical slices. It is the vertical equivalent of the
// doHorizDissolve function. When called with a null pointer it clears the
// screen.
//
// The function moves the image data to the screen by iterating through
// 16 vertical slices. On each iteration two lines are drawn, at an equal
// distance on either side of the center mark for that section. The outer-
// most loop counts the lines; it takes 10 iterations to fill one slice. The
// innermost loop cycles through the 16 slices. So, the first slice gets two
// lines, the second gets two, on up to the 16th, and then the first gets
// two more, and so on. Keep an eye on si and di.
// *************************************************************************

void  doVerticalDissolve(void far *pic_buf)
	{
	int base_row;                //  base_row stores the line offset from x
	asm {
		mov es, GRAPH_SEG        // get the video segment into es
		mov base_row, 0          // start out drawing on the x pixel
		mov cx, 11               // outer loop, 11 pixels to each side of
		cld                      // the x pixel (in si and di) will be drawn
		push ds                  // save the ds register value
		lds si, pic_buf          // get the picture pointer into ds:si
		mov ax, ds               // check for a NULL pointer and jmp to
		cmp ax, 0                // clearscr if found
		je clearscr
		}
	mainloop:
	asm {
		push cx                  // save the outer loop counter
		push si                  // save original offset to byte 0 of pic
		mov cx, 16               // process 16 vertical slices
		add si, 9                // first x mark is on 9,0
		mov di, 9
		}
	drawloop:
	asm {
		push cx                  // save the inner loop counter
		push si                  // and the x mark, source and dest
		push di
		add di, base_row         // add in the offset from x for first line
		add si, base_row
		mov cx, 200              // plot 200 pixels
		}
	lineloop1:                   // this loop draws a vertical line
	asm {
		movsb                    // move one byte
		add si, 319              // move to next row
		add di, 319
		loop lineloop1           // do another

		pop di                   // restore the starting points
		pop si
		push si                  // save them again
		push di
		sub di, base_row         // drawing on the other side this time
		sub si, base_row
		mov cx, 200              // plot 200 pixels
		}
	lineloop2:
	asm {
		movsb                    // same as above
		add si, 319
		add di, 319
		loop lineloop2

		pop di                   // restore the starting point
		pop si
		pop cx                   // restore the inner loop counter
		add si, 20               // adjust pointer to the next slice
		add di, 20
		loop drawloop            // process it
		inc base_row             // increment the drawing offset
		pop si                   // restore the offset to byte 0 of pic
		pop cx                   // restore the outer loop counter
		loop mainloop            // do it all again
		jmp done
		}
	clearscr:                    // this block functions exactly as the
	asm {                        // previous one but clears the screen using
		push cx                  // palette register 0
		mov cx, 16
		mov di, 9
		}
	drawloop2:
	asm {
		push cx
		push di
		add di, base_row
		xor ax, ax
		mov cx, 200
		}
	lineloop21:
	asm {
		stosb
		add di, 319
		loop lineloop21

		pop di
		push di
		sub di, base_row
		xor ax, ax
		mov cx, 200
		}
	lineloop22:
	asm {
		stosb
		add di, 319
		loop lineloop22
		pop di
		pop cx
		add di, 20
		loop drawloop2
		inc base_row
		pop cx
		loop clearscr
		}
	done:
	asm pop ds;                  // restore the data segment
	}

// **************************************************************************
// doHorizDissolve causes the image in pic_buf to be displayed by dissolving
// it in in 10 horizontal bands. If called with pic_buf==NULL it clears the
// screen by the same method.
//
// This function processes the data much like the Vertcal Dissolve funtion
// above. The screen in this case is divided into 10 horizontal slices. The
// center line starting points of these slices begin at 2880 bytes into the
// video buffer, and every 6400 bytes after that. Like the function above it
// cycles through the slices drawing two lines at each, progressively further
// from the center line with each iteration of the outer loop. Like the func-
// tion above, you have to keep a carefull eye on di and si to understand it.
// **************************************************************************

void  doHorizDissolve(void far *pic_buf)
	{
	int base_line;
	asm {
		mov base_line, 0          // base_line is an offset from each line
		mov es, GRAPH_SEG         // get video segment into es
		mov bx, 320               // bx * base_line == adjust value for si,di
		mov cx, 20                // outer loop 20 iterations
		cld                       // clear the direction flag
		push ds                   // save the ds register value
		lds si, pic_buf           // get pic_buf into ds:si
		mov ax, ds                // if pic_buf == NULL jump to clearscr
		cmp ax, 0
		je clearscr
		}
	mainloop1:                    // main drawing loop, 20 iterations...
	asm {                         // the number of offset lines to draw
		push cx                   // save the counter
		mov cx, 10                // inner loop, 10 iterations, draws lines
		push si                   // save the offset of the pic_buf pointer
		add si, 60480             // 60480, address of first line processed
		mov di, 60480
		mov dx, input_status_1    // used below to test for vbi
		}
	test_11:                      // these lines test for the vbi
	asm	{
		in al, dx                 // first test, out of vbi
		test al,0x8
		jnz test_11
		}
	test_12:
	asm	{
		in al, dx                 // second test, in vbi
		test al,0x8
		jz test_12
		}
	drawloop1:                    // drawloop processes the 10 base lines,
	asm {                         // drawing 2 lines at offset ax from base
		push cx                   // save the counter
		push si                   // save the offset to the current base
		push di
		mov ax, base_line         // calculate the pointer offset from base
		mul bx                    // by multiplying base_line * 320
		sub si, ax                // subtract the offset from source and
		sub di, ax                // dest base pointers, and
		mov cx, 160               // draw the first line
		rep movsw
		pop di                    // restore the base pointers
		pop si
		push si                   // save em again
		push di
		add si, ax                // add the offset to the source and dest
		add di, ax                // base pointers and
		mov cx, 160               // draw the second line
		rep movsw
		pop di                    // restore the base pointers
		pop si
		pop cx                    // restore the inner loop counter
		sub si, 6400              // adjust base pointers to point to the
		sub di, 6400              // next base, 20 lines up the screen
		loop drawloop1            // process the next section
		inc base_line             // increment the base offset factor
		pop si                    // restore the original pic_buf offset
		pop cx                    // restore the outer loop counter
		loop mainloop1            // do it all over again
		jmp done                  // finished
		}
	clearscr:                     // this section executes if pic_buf==NULL
	asm {
		push cx                   // save the outer loop counter
		mov cx, 10
		mov di, 60480             // we can ignore ds:si since no source
		mov dx, input_status_1    // used to test for vbi below
		}
	test_21:                      // these lines test for the vbi
	asm	{
		in al, dx                 // first test, out of vbi
		test al,0x8
		jnz test_21
		}
	test_22:
	asm	{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -