477 lines
14 KiB
C
477 lines
14 KiB
C
/****************************************************************************
|
|
*
|
|
* Open Watcom Project
|
|
*
|
|
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
|
|
*
|
|
* ========================================================================
|
|
*
|
|
* This file contains Original Code and/or Modifications of Original
|
|
* Code as defined in and that are subject to the Sybase Open Watcom
|
|
* Public License version 1.0 (the 'License'). You may not use this file
|
|
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
|
|
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
|
|
* provided with the Original Code and Modifications, and is also
|
|
* available at www.sybase.com/developer/opensource.
|
|
*
|
|
* The Original Code and all software distributed under the License are
|
|
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
|
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
|
|
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
|
|
* NON-INFRINGEMENT. Please see the License for the specific language
|
|
* governing rights and limitations under the License.
|
|
*
|
|
* ========================================================================
|
|
*
|
|
* Description: Drawing routines for OS/2.
|
|
*
|
|
****************************************************************************/
|
|
|
|
|
|
#define INCL_PM
|
|
|
|
#include <os2.h>
|
|
#include <string.h>
|
|
#include "drawmenu.h"
|
|
#include "button.h"
|
|
#include "room.h"
|
|
#include "threed.h"
|
|
|
|
static HWND hwnd;
|
|
|
|
static HAB Main_hab;
|
|
|
|
static HMQ Main_hmq;
|
|
|
|
static three_d_handle hThree_d;
|
|
|
|
static RECTL Draw_area;
|
|
|
|
#ifdef DRAW_ALL_AT_ONCE
|
|
static HDC Hdc;
|
|
static HPS Mem_dc;
|
|
static HBITMAP Draw_bitmap = NULLHANDLE;
|
|
static HBITMAP Old_bitmap = NULLHANDLE;
|
|
#endif
|
|
|
|
|
|
static int Button_height;
|
|
|
|
static int Auto_run = 0;
|
|
|
|
static void add_wrap( three_d_attr attr, int add, int minimum, int maximum )
|
|
{
|
|
int start;
|
|
|
|
start = three_d_get( hThree_d, attr );
|
|
start += add;
|
|
while( start >= maximum ) {
|
|
start -= maximum - minimum;
|
|
}
|
|
while( start < minimum ) {
|
|
start += maximum - minimum;
|
|
}
|
|
three_d_set( hThree_d, attr, start );
|
|
}
|
|
|
|
static void add_range( three_d_attr attr, int add, int minimum, int maximum )
|
|
{
|
|
int start;
|
|
|
|
start = three_d_get( hThree_d, attr );
|
|
start += add;
|
|
if( start >= maximum ) {
|
|
three_d_set( hThree_d, attr, maximum );
|
|
} else if( start <= minimum ) {
|
|
three_d_set( hThree_d, attr, minimum );
|
|
} else {
|
|
three_d_set( hThree_d, attr, start );
|
|
}
|
|
}
|
|
|
|
void draw_box(
|
|
float x1,
|
|
float x2,
|
|
float y1,
|
|
float y2,
|
|
float z1,
|
|
float z2,
|
|
unsigned red,
|
|
unsigned green,
|
|
unsigned blue )
|
|
{
|
|
three_d_box( hThree_d, x1, x2, y1, y2, z1, z2, red, green, blue );
|
|
}
|
|
|
|
void new_display( void )
|
|
{
|
|
#ifdef DRAW_ALL_AT_ONCE
|
|
GpiSetBitmap( Mem_dc, Old_bitmap );
|
|
GpiDeleteBitmap( Draw_bitmap );
|
|
Draw_bitmap = NULLHANDLE;
|
|
GpiDestroyPS( Mem_dc );
|
|
DevCloseDC( Hdc );
|
|
#endif
|
|
}
|
|
|
|
static void draw_stuff( HWND hwnd )
|
|
{
|
|
HPS win_dc;
|
|
RECTL paint;
|
|
RECTL intersect;
|
|
#ifdef DRAW_ALL_AT_ONCE
|
|
int old_top;
|
|
int width, height;
|
|
SIZEL sizl = { 0, 0 };
|
|
BITMAPINFOHEADER2 bmih;
|
|
LONG formats[24];
|
|
POINTL pts[3];
|
|
LONG old_cursor;
|
|
LONG hour_glass_cur;
|
|
RECTL interior;
|
|
DEVOPENSTRUC dop = { 0L, "DISPLAY", NULL, 0L,
|
|
0L, 0L, 0L, 0L, 0L };
|
|
#endif
|
|
|
|
|
|
win_dc = WinBeginPaint( hwnd, 0, &paint );
|
|
GpiCreateLogColorTable( win_dc, 0L, LCOLF_RGB, 0L, 0L, NULL );
|
|
#ifdef DRAW_ALL_AT_ONCE
|
|
old_top = paint.yBottom;
|
|
paint.yBottom = Draw_area.yTop;
|
|
#endif
|
|
WinFillRect( win_dc, &paint, SYSCLR_WINDOW );
|
|
#ifdef DRAW_ALL_AT_ONCE
|
|
paint.yBottom = old_top;
|
|
#endif
|
|
if( WinIntersectRect( Main_hab, &intersect, &paint, &Draw_area ) ) {
|
|
|
|
#ifdef DRAW_ALL_AT_ONCE
|
|
width = Draw_area.xRight - Draw_area.xLeft;
|
|
height = Draw_area.yTop - Draw_area.yBottom;
|
|
interior.xLeft = 0;
|
|
interior.yBottom = 0;
|
|
interior.xRight = width;
|
|
interior.yTop = height;
|
|
if( Draw_bitmap == NULLHANDLE ) {
|
|
Hdc = DevOpenDC( Main_hab, OD_MEMORY, "*", 5L,
|
|
(PDEVOPENDATA)&dop, NULLHANDLE );
|
|
Mem_dc = GpiCreatePS( Main_hab, Hdc, &sizl, PU_PELS | GPIA_ASSOC );
|
|
memset( &bmih, 0, sizeof( BITMAPINFOHEADER2 ) );
|
|
GpiQueryDeviceBitmapFormats( Mem_dc, 24L, formats );
|
|
bmih.cbFix = sizeof( BITMAPINFOHEADER2 );
|
|
bmih.cx = width;
|
|
bmih.cy = height;
|
|
bmih.cPlanes = (USHORT) formats[0];
|
|
bmih.cBitCount = (USHORT) formats[1];
|
|
Draw_bitmap = GpiCreateBitmap( Mem_dc, &bmih, 0L, NULL, NULL );
|
|
Old_bitmap = GpiSetBitmap( Mem_dc, Draw_bitmap );
|
|
GpiCreateLogColorTable( Mem_dc, 0, LCOLF_RGB, 0, 0, NULL );
|
|
WinFillRect( Mem_dc, &interior, SYSCLR_WINDOW );
|
|
|
|
hour_glass_cur = WinQuerySysPointer( HWND_DESKTOP, SPTR_WAIT, FALSE );
|
|
old_cursor = WinQueryPointer( HWND_DESKTOP );
|
|
WinSetPointer( HWND_DESKTOP, hour_glass_cur );
|
|
|
|
hThree_d = three_d_begin( Mem_dc, &interior );
|
|
draw_room();
|
|
three_d_draw( hThree_d );
|
|
three_d_end( hThree_d );
|
|
|
|
WinSetPointer( HWND_DESKTOP, old_cursor );
|
|
}
|
|
|
|
pts[0].x = Draw_area.xLeft;
|
|
pts[0].y = Draw_area.yBottom;
|
|
pts[1].x = Draw_area.xLeft + width;
|
|
pts[1].y = Draw_area.yBottom + height;
|
|
pts[2].x = 0;
|
|
pts[2].y = 0;
|
|
GpiBitBlt( win_dc, Mem_dc, 3, pts, ROP_SRCCOPY, BBO_IGNORE );
|
|
#else
|
|
hThree_d = three_d_begin( win_dc, &Draw_area );
|
|
draw_room();
|
|
three_d_draw( hThree_d );
|
|
three_d_end( hThree_d );
|
|
#endif
|
|
|
|
}
|
|
WinEndPaint( win_dc );
|
|
}
|
|
|
|
static void make_buttons( HWND hwnd )
|
|
{
|
|
int offset;
|
|
int max_height;
|
|
int btn_width;
|
|
int btn_height;
|
|
static int buttons[] = {
|
|
IDM_ROTATE_UP,
|
|
IDM_MOVE_IN,
|
|
IDM_ROTATE_LEFT,
|
|
IDM_ROTATE_RIGHT,
|
|
IDM_MOVE_OUT,
|
|
IDM_ROTATE_DOWN,
|
|
IDM_MORE_BRIGHTNESS,
|
|
IDM_LESS_BRIGHTNESS,
|
|
0 };
|
|
int index;
|
|
|
|
Draw_area.yTop -= 2;
|
|
offset = Draw_area.xLeft + 2;
|
|
max_height= 0;
|
|
for( index = 0; buttons[index]; ++ index, offset += btn_width - 1 ) {
|
|
#if 0
|
|
if( index == 0 ) {
|
|
add_button( hwnd, Draw_area.yTop, offset, buttons[index], NULL, &btn_height );
|
|
} else
|
|
#endif
|
|
add_button( hwnd, Draw_area.yTop, offset, buttons[index], &btn_width, &btn_height );
|
|
if( max_height < btn_height ) max_height = btn_height;
|
|
}
|
|
// Remove buttons from drawing area
|
|
Draw_area.yTop -= max_height + 2;
|
|
Button_height = max_height + 4;
|
|
}
|
|
|
|
MRESULT EXPENTRY main_proc(
|
|
HWND hwnd,
|
|
ULONG msg,
|
|
MPARAM mp1,
|
|
MPARAM mp2
|
|
) {
|
|
if( msg == WM_CREATE ) {
|
|
|
|
PCREATESTRUCT pcreate;
|
|
|
|
pcreate = ( CREATESTRUCT * ) mp2;
|
|
Draw_area.xRight = pcreate->x + pcreate->cx;
|
|
Draw_area.yTop = pcreate->y + pcreate->cy;
|
|
Draw_area.yBottom = pcreate->y;
|
|
Draw_area.xLeft = pcreate->x;
|
|
// WinQueryWindowRect( hwnd, &Draw_area );
|
|
|
|
} else if( msg == WM_COMMAND || ( msg == WM_CONTROL &&
|
|
SHORT2FROMMP( mp1 ) != BN_PAINT ) ) {
|
|
|
|
switch( SHORT1FROMMP( mp1 ) ) {
|
|
|
|
case IDM_EXIT:
|
|
new_display();
|
|
WinPostMsg( hwnd, WM_QUIT, 0L, 0L );
|
|
return( NULL );
|
|
|
|
case IDM_ROTATE_LEFT:
|
|
new_display();
|
|
add_wrap( THREE_D_HORZ_ANGLE, -15, 0, 360 );
|
|
break;
|
|
case IDM_ROTATE_RIGHT:
|
|
new_display();
|
|
add_wrap( THREE_D_HORZ_ANGLE, 15, 0, 360 );
|
|
break;
|
|
case IDM_ROTATE_UP:
|
|
new_display();
|
|
add_range( THREE_D_VERT_ANGLE, 5, -90, 90 );
|
|
break;
|
|
case IDM_ROTATE_DOWN:
|
|
new_display();
|
|
add_range( THREE_D_VERT_ANGLE, -5, -90, 90 );
|
|
break;
|
|
case IDM_MOVE_IN:
|
|
new_display();
|
|
add_range(THREE_D_ZOOM, 10, 5, 200 );
|
|
break;
|
|
case IDM_MOVE_OUT:
|
|
new_display();
|
|
add_range( THREE_D_ZOOM, -10, 5, 200 );
|
|
break;
|
|
case IDM_MORE_PERSPECTIVE:
|
|
new_display();
|
|
add_range( THREE_D_PERSPECTIVE, 10, 5, 200 );
|
|
break;
|
|
case IDM_LESS_PERSPECTIVE:
|
|
new_display();
|
|
add_range( THREE_D_PERSPECTIVE, -10, 5, 200 );
|
|
break;
|
|
case IDM_MORE_CONTRAST:
|
|
new_display();
|
|
add_range( THREE_D_CONTRAST, 10, 0, 100 );
|
|
break;
|
|
case IDM_LESS_CONTRAST:
|
|
new_display();
|
|
add_range( THREE_D_CONTRAST, -10, 0, 100 );
|
|
break;
|
|
case IDM_MORE_BRIGHTNESS:
|
|
new_display();
|
|
add_range( THREE_D_BRIGHTNESS, 10, 0, 100 );
|
|
break;
|
|
case IDM_LESS_BRIGHTNESS:
|
|
new_display();
|
|
add_range( THREE_D_BRIGHTNESS, -10, 0, 100 );
|
|
break;
|
|
case IDM_LIGHT_HORZ_LEFT:
|
|
new_display();
|
|
three_d_set( hThree_d, THREE_D_LIGHT_HORZ, 1 );
|
|
break;
|
|
case IDM_LIGHT_HORZ_MIDDLE:
|
|
new_display();
|
|
three_d_set( hThree_d, THREE_D_LIGHT_HORZ, 2 );
|
|
break;
|
|
case IDM_LIGHT_HORZ_RIGHT:
|
|
new_display();
|
|
three_d_set( hThree_d, THREE_D_LIGHT_HORZ, 3 );
|
|
break;
|
|
case IDM_LIGHT_VERT_TOP:
|
|
new_display();
|
|
three_d_set( hThree_d, THREE_D_LIGHT_VERT, 1 );
|
|
break;
|
|
case IDM_LIGHT_VERT_MIDDLE:
|
|
new_display();
|
|
three_d_set( hThree_d, THREE_D_LIGHT_VERT, 2 );
|
|
break;
|
|
case IDM_LIGHT_VERT_BOTTOM:
|
|
new_display();
|
|
three_d_set( hThree_d, THREE_D_LIGHT_VERT, 3 );
|
|
break;
|
|
case IDM_LIGHT_DEPTH_FRONT:
|
|
new_display();
|
|
three_d_set( hThree_d, THREE_D_LIGHT_DEPTH, 1 );
|
|
break;
|
|
case IDM_LIGHT_DEPTH_MIDDLE:
|
|
new_display();
|
|
three_d_set( hThree_d, THREE_D_LIGHT_DEPTH, 2 );
|
|
break;
|
|
case IDM_LIGHT_DEPTH_BACK:
|
|
new_display();
|
|
three_d_set( hThree_d, THREE_D_LIGHT_DEPTH, 3 );
|
|
break;
|
|
default:
|
|
;
|
|
}
|
|
WinInvalidateRect( hwnd, &Draw_area,
|
|
SHORT1FROMMP( mp1 ) >= IDM_FIRST_REQUIRING_CLEAR );
|
|
|
|
} else if( msg == WM_DESTROY ) {
|
|
WinPostMsg( hwnd, WM_QUIT, 0L, 0L );
|
|
return( 0 );
|
|
|
|
} else if( msg == WM_PAINT ) {
|
|
draw_stuff( hwnd );
|
|
if( Auto_run ) {
|
|
if( Auto_run == 5 ) {
|
|
WinPostMsg( hwnd, WM_QUIT, 0L, 0L );
|
|
} else {
|
|
long count;
|
|
int will_be_one;
|
|
will_be_one = 1;
|
|
for(count = 0; count < 1000000; ++ count ) will_be_one ^= 1;
|
|
|
|
Auto_run += will_be_one;
|
|
WinPostMsg( hwnd, WM_COMMAND,
|
|
MPFROMSHORT( IDM_ROTATE_LEFT ), 0L );
|
|
}
|
|
}
|
|
return( 0 );
|
|
|
|
} else if( msg == WM_SIZE ) {
|
|
WinQueryWindowRect( hwnd, &Draw_area );
|
|
Draw_area.yTop -= Button_height;
|
|
WinInvalidateRect( hwnd, NULL, TRUE );
|
|
return( 0 );
|
|
|
|
} else if( msg == WM_MEASUREITEM ) {
|
|
return( (MRESULT) measure_button( hwnd, mp1, mp2 ) );
|
|
|
|
} else if( msg == WM_CONTROL && SHORT2FROMMP( mp1 ) == BN_PAINT ) {
|
|
draw_button( mp1, mp2 );
|
|
return( (MRESULT) TRUE );
|
|
|
|
}
|
|
|
|
return( (MRESULT) WinDefWindowProc( hwnd, msg, mp1, mp2 ) );
|
|
}
|
|
|
|
static BOOL init_instance( int show )
|
|
{
|
|
HWND frame_hwnd;
|
|
ULONG flags = FCF_SIZEBORDER | FCF_TITLEBAR
|
|
| FCF_SYSMENU | FCF_MENU | FCF_MINMAX | FCF_SHELLPOSITION;
|
|
|
|
frame_hwnd = WinCreateStdWindow( HWND_DESKTOP, WS_VISIBLE,
|
|
&flags, "DrawDemo", "Draw a Picture", WS_VISIBLE,
|
|
0, 200, &hwnd );
|
|
|
|
/* If window could not be created, return "failure" */
|
|
|
|
if( hwnd == 0 || frame_hwnd == 0 ) {
|
|
return (FALSE);
|
|
}
|
|
|
|
/* Make the window visible; update its client area; and return "success" */
|
|
|
|
WinSetWindowPos( frame_hwnd, HWND_TOP, 50, 50, 200, 200, show );
|
|
|
|
make_buttons( hwnd );
|
|
|
|
WinShowWindow( frame_hwnd, TRUE );
|
|
WinUpdateWindow( frame_hwnd );
|
|
return( TRUE );
|
|
}
|
|
|
|
BOOL init_app( HAB hab )
|
|
{
|
|
/* Register the window class and return success/failure code. */
|
|
return( WinRegisterClass( hab, "DrawDemo", (PFNWP) main_proc, NULL, 0 ) );
|
|
}
|
|
|
|
int main(
|
|
/*******/
|
|
void
|
|
) {
|
|
QMSG qmsg;
|
|
|
|
Main_hab = WinInitialize( 0 );
|
|
if( !Main_hab ) {
|
|
return( FALSE );
|
|
}
|
|
|
|
Main_hmq = WinCreateMsgQueue( Main_hab, 0 );
|
|
if( !Main_hmq ) {
|
|
return( FALSE );
|
|
}
|
|
|
|
if( !init_app( Main_hab ) ) {
|
|
return( FALSE );
|
|
}
|
|
|
|
/* Perform initializations that apply to a specific instance */
|
|
|
|
three_d_init();
|
|
define_room();
|
|
if (!init_instance( SWP_SHOW | SWP_ACTIVATE ) ) {
|
|
finish_room();
|
|
three_d_fini();
|
|
return( FALSE );
|
|
}
|
|
|
|
/* Acquire and dispatch messages until a WM_QUIT message is received. */
|
|
|
|
while( WinGetMsg( Main_hab, &qmsg, NULL, NULL, NULL) ) {
|
|
WinDispatchMsg( Main_hab, &qmsg );
|
|
}
|
|
finish_room();
|
|
three_d_fini();
|
|
|
|
if( Main_hmq ) {
|
|
WinDestroyMsgQueue( Main_hmq );
|
|
}
|
|
if( Main_hab ) {
|
|
WinTerminate( Main_hab );
|
|
}
|
|
|
|
DosExit( EXIT_PROCESS, 0);
|
|
|
|
return( SHORT1FROMMP( qmsg.mp1 ) );
|
|
}
|