/************************************ input.c *************************/ #include #include #include #include #include "sdi.h" /* * Copyright 1987 by Mark Weiser. * Permission to reproduce and use in any manner whatsoever on Suns is granted * so long as this copyright and other identifying marks of authorship * in the code and the game remain intact and visible. Use of this code * in other products is reserved to me--I'm working on Mac and IBM versions. */ /* * interrupt handling is here, including mousing, resizing, etc. */ extern Panel launchpanel; Notify_value update_icon(); void canvas_resize_proc(canvas, width, height) Canvas canvas; int width, height; { Pixwin *newpw;; #if 0 if (canvas == citycanvas || canvas == launchcanvas) { max_x = width-(2*FIELD_MARGIN)-4; max_y = height-(2*FIELD_MARGIN)-4; newpw = (Pixwin *)xv_create(citycanvas, CANVAS, XV_X, FIELD_MARGIN, XV_Y, FIELD_MARGIN, XV_WIDTH, max_x, XV_HEIGHT, max_y, WIN_CONSUME_EVENTS, WIN_UP_EVENTS, 0, WIN_EVENT_PROC, xv_get(canvas, WIN_EVENT_PROC), WIN_CURSOR, xv_get(canvas, WIN_CURSOR), CANVAS_RESIZE_PROC, xv_get(canvas, CANVAS_RESIZE_PROC), CANVAS_RETAINED, TRUE, WIN_ERROR_MSG, "Can't create window.", 0); } if (canvas == citycanvas) { citypw = newpw; num_cities = 0; init_cities(); } else if (canvas == launchcanvas) { launchpw = newpw; } #endif } int running_icon_pictures = 0; /* * This routine gets notifications even before SunView does. Almost the first * thing it does is all 'notify_next_event_func', which lets SunView do * its work. Resizes, opens, and closes are handled here. */ Notify_value synch_event_proc(frame, event, arg, type) Frame frame; Event *event; Notify_arg arg; Notify_event_type type; { int closed; static int oldclosed = 0; Notify_value value; /* send on the notification */ value = notify_next_event_func(frame, event, arg, type); /* start post-processing */ closed = (int) xv_get(frame, FRAME_CLOSED); if (frame == controlframe) { if ( closed && !oldclosed) { /* not many events come in while closed, * so if we are closed, we are probably * just now closing. Close everyone. */ xv_set(cityframe, WIN_SHOW, FALSE, 0); xv_set(launchframe, WIN_SHOW, FALSE, 0); if (running) suspend_proc(); if (!running_icon_pictures) { /* start the icon stuff */ running_icon_pictures = 1; do_with_delay(update_icon, 0, 1); } } else if (!closed) { /* opening control frame, and so show everybody */ if (! xv_get(cityframe, WIN_SHOW)) xv_set(cityframe, WIN_SHOW, TRUE, 0); if (! xv_get(launchframe, WIN_SHOW)) xv_set(launchframe, WIN_SHOW, TRUE, 0); if (running_icon_pictures) { /* stop the icon stuff */ running_icon_pictures = 0; } } oldclosed = closed; } return value; } /* * Handle mousing. */ #define PINX(x) (max(0,min(max_x,x))) #define PINY(y) (max(0,min(max_y,y))) static int rock_x = -1, rock_y; Event rock_down_event; void main_event_proc(window, event, arg) Xv_Window window; Event *event; caddr_t arg; { extern Panel_item rock_item; int times_around, offset, i; int id = event_id(event); int left; Xv_Window pw; if (! event_is_button(event)) return; if (suspended) return; if (window == citypw) { pw = citypw; } else if (window == launchpw) { pw = launchpw; } else { printf("sdi: input in unexpected window.\n"); fflush(stdout); } if (event_is_down(event)) { if (!running) { /* if not running, then try to start running. */ start_next_round(); } else { switch(id) { case MS_LEFT: { left = (int)xv_get(interceptor_item, PANEL_VALUE); if (left > 0) { if (event_meta_is_down(event)) { times_around = 2; offset = event_shift_is_down(event) ? -31 : -20; } else { times_around = 1; offset = 0; } for (i = 0; i < times_around; i += 1) { if (event_shift_is_down(event)) { start_blast(PINX(event_x(event)+offset), event_y(event), 0, 0, pw, bigblastcircles); } else { start_blast(PINX(event_x(event)+offset), event_y(event), 0, 0, pw, littleblastcircles); } offset = ABS(offset); } xv_set(interceptor_item, PANEL_VALUE, left-times_around, 0); update_cursor(); } else { need_a_bell = pw; } break; } case MS_RIGHT: { left = (int)xv_get(laser_item, PANEL_VALUE); if (left > 0) { if (event_meta_is_down(event)) { times_around = 2; offset = event_shift_is_down(event) ? -100 : -64; } else { times_around = 1; offset = 0; } for (i = 0; i < times_around; i += 1) { if (event_shift_is_down(event)) { start_laser(PINX(event_x(event)+offset), event_y(event), pw, 3, 256); } else { start_laser(PINX(event_x(event)+offset), event_y(event), pw, 6, 128); } offset = ABS(offset); } xv_set(laser_item, PANEL_VALUE, left-times_around, 0); update_cursor(); } else { need_a_bell = pw; } break; } case MS_MIDDLE: { left = (int)xv_get(rock_item, PANEL_VALUE); if (left > 0) { rock_x = event_x(event); rock_y = event_y(event); rock_down_event = *event; } else { rock_x = -1; need_a_bell = pw; } }} /* end of switch */ } } else if (/* implicit: event_is_up(event) && */ running && id == MS_MIDDLE && rock_x != -1) { /* throw some rocks */ if (event_meta_is_down(&rock_down_event)) { times_around = 2; offset = -20; } else { times_around = 1; offset = 0; } for (i = 0; i < times_around; i += 1) { if (event_shift_is_down(&rock_down_event)) { start_rocks(pw, rock_x, PINY(rock_y+offset), event_x(event), PINY(event_y(event)+offset), 3, bigrockcircles); } else { start_rocks(pw, rock_x, PINY(rock_y+offset), event_x(event)+offset, PINY(event_y(event)+offset), 5, littlerockcircles); } offset = ABS(offset); } rock_x = -1; xv_set(rock_item, PANEL_VALUE, xv_get(rock_item, PANEL_VALUE)-times_around, 0); update_cursor(); } }