/**********************************************************************
This file is part of Crack dot Com's free source code release of
Golgotha.
for
information about compiling & licensing issues visit this URL
If that doesn't help, contact Jonathan Clark at golgotha_source@usa.net (Subject should have "GOLG" in it) ***********************************************************************/ #include#include #include "draw_sprocket.hh" #include "device/event.hh" #include "device/keys.hh" enum mac_modnum { MAC_COMMAND = 0x37, MAC_LSHIFT, MAC_CAPSLOCK, MAC_LOPTION, MAC_LCONTROL, MAC_RSHIFT, MAC_ROPTION, MAC_RCONTROL, MAC_LAST }; const int mac_map[8] = { I4_COMMAND, I4_SHIFT_L, I4_CAPS, I4_ALT_L, I4_CTRL_L, I4_SHIFT_R, I4_ALT_R, I4_CTRL_R, }; // save area for old event mask short OldEventMask; // new event mask for i4 system const short MACEVENTS = mUpMask | mDownMask | keyUpMask | keyDownMask | autoKeyMask; draw_sprocket_class draw_sprocket; w32 draw_sprocket_class::device_manager_class::request_device(i4_event_handler_class *for_who, w32 event_types) //{{{ { if ((event_types&i4_device_class::FLAG_MOUSE_BUTTON_UP) || (event_types&i4_device_class::FLAG_MOUSE_BUTTON_DOWN) || (event_types&i4_device_class::FLAG_MOUSE_MOVE) || (event_types&i4_device_class::FLAG_KEY_PRESS) || (event_types&i4_device_class::FLAG_KEY_RELEASE) || (event_types&i4_device_class::FLAG_DISPLAY_CLOSE)) { if (event_types&i4_device_class::FLAG_KEY_PRESS) add_agent(for_who,i4_device_class::FLAG_KEY_PRESS); if (event_types&i4_device_class::FLAG_KEY_RELEASE) add_agent(for_who,i4_device_class::FLAG_KEY_RELEASE); if (event_types&i4_device_class::FLAG_MOUSE_BUTTON_UP) add_agent(for_who,i4_device_class::FLAG_MOUSE_BUTTON_UP); if (event_types&i4_device_class::FLAG_MOUSE_BUTTON_DOWN) add_agent(for_who,i4_device_class::FLAG_MOUSE_BUTTON_DOWN); if (event_types&i4_device_class::FLAG_MOUSE_MOVE) add_agent(for_who,i4_device_class::FLAG_MOUSE_MOVE); if (event_types&i4_device_class::FLAG_DISPLAY_CLOSE) add_agent(for_who,i4_device_class::FLAG_DISPLAY_CLOSE); return (i4_device_class::FLAG_KEY_PRESS| i4_device_class::FLAG_KEY_RELEASE| i4_device_class::FLAG_MOUSE_BUTTON_UP| i4_device_class::FLAG_MOUSE_BUTTON_DOWN| i4_device_class::FLAG_MOUSE_MOVE| i4_device_class::FLAG_DISPLAY_CLOSE)&event_types; } return 0; } //}}} void draw_sprocket_class::device_manager_class::release_device(i4_event_handler_class *for_who, w32 event_types) //{{{ { if (event_types&i4_device_class::FLAG_KEY_PRESS) remove_agent(for_who,i4_device_class::FLAG_KEY_PRESS); if (event_types&i4_device_class::FLAG_KEY_RELEASE) remove_agent(for_who,i4_device_class::FLAG_KEY_RELEASE); if (event_types&i4_device_class::FLAG_MOUSE_BUTTON_UP) remove_agent(for_who,i4_device_class::FLAG_MOUSE_BUTTON_UP); if (event_types&i4_device_class::FLAG_MOUSE_BUTTON_DOWN) remove_agent(for_who,i4_device_class::FLAG_MOUSE_BUTTON_DOWN); if (event_types&i4_device_class::FLAG_MOUSE_MOVE) remove_agent(for_who,i4_device_class::FLAG_MOUSE_MOVE); if (event_types&i4_device_class::FLAG_DISPLAY_CLOSE) remove_agent(for_who,i4_device_class::FLAG_DISPLAY_CLOSE); } //}}} i4_bool draw_sprocket_class::device_manager_class::process_events() //{{{ { i4_bool ret = i4_F; Point p; // Update mouse position omx = mx; omy = my; ::GetMouse(&p); mx = p.h; my = p.v; if (mx!=omx || my!=omy) { i4_mouse_move_event_class ev(mx,my); send_event_to_agents(&ev,i4_device_class::FLAG_MOUSE_MOVE); ret = i4_T; } #if 0 if (Button()) { i4_display_close_event_class quit(&draw_sprocket); send_event_to_agents(&quit,FLAG_DISPLAY_CLOSE); return i4_T; } return i4_F; #endif // get mac modifiers unsigned char km[16]; int i; GetKeys((unsigned long*)&km); for (i=0; i > 3 ] >> ((i+MAC_COMMAND) & 7)) & 1; if (mac_modifier[i] != last) { w16 key, key_code; key_code = mac_map[i]; if (mac_modifier[i]) { key = i4_key_translate(key_code,1,shift_state); i4_key_press_event_class ev(key, key_code); send_event_to_agents(&ev,FLAG_KEY_PRESS); ret = i4_T; } else { key = i4_key_translate(key_code,0,shift_state); i4_key_release_event_class ev(key, key_code); send_event_to_agents(&ev,FLAG_KEY_RELEASE); ret = i4_T; } } } EventRecord MacEv; // process mac events while (GetOSEvent(MACEVENTS,&MacEv)) { switch (MacEv.what) { case keyDown : case keyUp : case autoKey : { // process key events w16 key, key_code; switch ((MacEv.message & keyCodeMask)>>8) { case 0x7d: key_code=I4_DOWN; break; case 0x7e: key_code=I4_UP; break; case 0x7b: key_code=I4_LEFT; break; case 0x7c: key_code=I4_RIGHT; break; case 0x47: key_code=I4_NUM_LOCK; break; case 0x73: key_code=I4_HOME; break; case 0x77: key_code=I4_END; break; case 0x33: key_code=I4_BACKSPACE; break; case 0x30: key_code=I4_TAB; break; case 0x24: key_code=I4_ENTER; break; case 0x39: key_code=I4_CAPS; break; case 0x35: key_code=I4_ESC; break; case 0x7a: key_code=I4_F1; break; case 0x78: key_code=I4_F2;break; case 0x63: key_code=I4_F3; break; case 0x76: key_code=I4_F4; break; case 0x60: key_code=I4_F5; break; case 0x61: key_code=I4_F6; break; case 0x62: key_code=I4_F7; break; case 0x64: key_code=I4_F8; break; case 0x65: key_code=I4_F9; break; case 0x6d: key_code=I4_F10; break; case 0x67: key_code=I4_F11; break; case 0x6f: key_code=I4_F12; break; case 0x69: key_code=I4_F13; break; case 0x6b: key_code=I4_F14; break; case 0x71: key_code=I4_F15; break; case 0x72: key_code=I4_INSERT; break; case 0x75: key_code=I4_DEL; break; case 0x74: key_code=I4_PAGEUP; break; case 0x79: key_code=I4_PAGEDOWN; break; case 0x52: key_code=I4_KP0; break; case 0x53: key_code=I4_KP1; break; case 0x54: key_code=I4_KP2; break; case 0x55: key_code=I4_KP3; break; case 0x56: key_code=I4_KP4; break; case 0x57: key_code=I4_KP5; break; case 0x58: key_code=I4_KP6; break; case 0x59: key_code=I4_KP7; break; case 0x5b: key_code=I4_KP8; break; case 0x5c: key_code=I4_KP9; break; case 0x51: key_code=I4_KPEQUAL; break; case 0x4b: key_code=I4_KPSLASH; break; case 0x43: key_code=I4_KPSTAR; break; case 0x4e: key_code=I4_KPMINUS; break; case 0x45: key_code=I4_KPPLUS; break; case 0x4c: key_code=I4_KPENTER; break; case 0x41: key_code=I4_KPPERIOD; break; case 0x00: key_code='A'; break; case 0x0b: key_code='B'; break; case 0x08: key_code='C'; break; case 0x02: key_code='D'; break; case 0x0e: key_code='E'; break; case 0x03: key_code='F'; break; case 0x05: key_code='G'; break; case 0x04: key_code='H'; break; case 0x22: key_code='I'; break; case 0x26: key_code='J'; break; case 0x28: key_code='K'; break; case 0x25: key_code='L'; break; case 0x2e: key_code='M'; break; case 0x2d: key_code='N'; break; case 0x1f: key_code='O'; break; case 0x23: key_code='P'; break; case 0x0c: key_code='Q'; break; case 0x0f: key_code='R'; break; case 0x01: key_code='S'; break; case 0x11: key_code='T'; break; case 0x20: key_code='U'; break; case 0x09: key_code='V'; break; case 0x0d: key_code='W'; break; case 0x07: key_code='X'; break; case 0x10: key_code='Y'; break; case 0x06: key_code='Z'; break; case 0x32: key_code='`'; break; case 0x12: key_code='1'; break; case 0x13: key_code='2'; break; case 0x14: key_code='3'; break; case 0x15: key_code='4'; break; case 0x17: key_code='5'; break; case 0x16: key_code='6'; break; case 0x1a: key_code='7'; break; case 0x1c: key_code='8'; break; case 0x19: key_code='9'; break; case 0x1d: key_code='0'; break; case 0x1b: key_code='-'; break; case 0x18: key_code='='; break; case 0x21: key_code='['; break; case 0x1e: key_code=']'; break; case 0x2a: key_code='\\'; break; case 0x29: key_code=';'; break; case 0x27: key_code='\''; break; case 0x2b: key_code=','; break; case 0x2f: key_code='.'; break; case 0x2c: key_code='/'; break; case 0x31: key_code=' '; break; default: key_code = 0; break; } if (key_code) { if (MacEv.what!=keyUp) { key = i4_key_translate(key_code,1,shift_state); i4_key_press_event_class ev(key, key_code); send_event_to_agents(&ev,FLAG_KEY_PRESS); ret = i4_T; } else { key = i4_key_translate(key_code,0,shift_state); i4_key_release_event_class ev(key, key_code); send_event_to_agents(&ev,FLAG_KEY_RELEASE); ret = i4_T; } } } break; case mouseUp : { i4_mouse_button_up_event_class down(i4_mouse_button_up_event_class::LEFT); send_event_to_agents(&down,FLAG_MOUSE_BUTTON_UP); ret = i4_T; } break; case mouseDown : { i4_mouse_button_down_event_class down(i4_mouse_button_down_event_class::LEFT); send_event_to_agents(&down,FLAG_MOUSE_BUTTON_DOWN); ret = i4_T; } break; } } return ret; } //}}} draw_sprocket_class::device_manager_class::device_manager_class() : shift_state(0) //{{{ { int i; for (i=0; i<8; i++) mac_modifier[i] = 0; } //}}} draw_sprocket_class::draw_sprocket_class() : i4_display_class(), context(0), screen(0) //{{{ { /* tell SIOUX(stdio simulator) to shut up */ // SIOUXSettings.autocloseonquit = true; SIOUXSettings.asktosaveonclose = false; DSpStartup(); // open window & initialize toolbox routines to allow DrawSprockets to work? printf("Draw Sprocket Initialization\n"); // save & set event mask OldEventMask = LMGetSysEvtMask(); SetEventMask(MACEVENTS); } //}}} draw_sprocket_class::~draw_sprocket_class() //{{{ { // restore event mask SetEventMask(OldEventMask); DSpShutdown(); } //}}} draw_sprocket_class::draw_sprocket_mode_class *draw_sprocket_class::new_mode(DSpContextReference context) // create new video mode info struct from draw sprocket context //{{{ { DSpContextAttributes attr; OSErr err; err = DSpContext_GetAttributes( context, &attr ); if (err != noErr) return 0; if (attr.displayBestDepth != (8*I4_BYTES_PER_PIXEL)) return 0; draw_sprocket_mode_class *m = new draw_sprocket_mode_class(context); m->xres = attr.displayWidth; m->yres = attr.displayHeight; m->bits_per_pixel = attr.displayBestDepth; m->bits_per_color = 8; m->flags = mode::PAGE_FLIPPED; m->name[0] = 0; return m; } //}}} draw_sprocket_class::mode *draw_sprocket_class::get_first_mode() //{{{ { return get_next_mode(0); } //}}} draw_sprocket_class::mode *draw_sprocket_class::get_next_mode(mode *last_mode) //{{{ { DSpContextReference cont; CAST_PTR(dsm, draw_sprocket_mode_class, last_mode); draw_sprocket_mode_class *ret; OSErr err; if (dsm == 0) { // get first screen through Display Manager gd = DMGetFirstScreenDevice(0); err = DMGetDisplayIDByGDevice( gd, &display_id, 0); if (err != noErr) return 0; // start screen enumeration through Display Manager err = DSpGetFirstContext( display_id, &cont ); if (err != noErr) return 0; } else { // iterate screen enumeration through Display Manager err = DSpGetNextContext( dsm->ref, &cont ); if (err != noErr) return 0; } while (cont && (ret = new_mode(cont))==0) { // continue to get valid modes err = DSpGetNextContext( cont, &cont ); if (err != noErr) return 0; } return ret; } //}}} void draw_sprocket_class::setup_back_buffer() // get memory pointer to back buffer for direct drawing & page flipping //{{{ { CGrafPtr back; w8 *data; w32 rowbytes; // get CGrafPtr to back buffer DSpContext_GetBackBuffer(DSp_ref, kDSpBufferKind_Normal, &back); // get pixmap of port PMH = back->portPixMap; // ensure pixels stay in memory LockPixels(PMH); // get number of physical bytes per row rowbytes = (*PMH)->rowBytes & 0x3FFF; // get pointer to screen memory data = (w8 *)GetPixBaseAddr(PMH); i4_pal_handle_class pal; //#if (I4_SCREEN_DEPTH==15) //pal.set_type(i4_pal_handle_class::ID_15BIT); //#elif (I4_SCREEN_DEPTH==16) pal.set_type(i4_pal_handle_class::ID_16BIT); //#else //#error add code here //#endif // setup screen with pointer into pixmap if (!screen) { screen=new I4_SCREEN_TYPE(wx,wy, pal, rowbytes, // bytes per line (w8 *)data); } else screen->local_set_data((w8*)data); #if 0 //{{{ Debugging under 16 bit to show colors int i,j; for (j=0; j<1<<(16 - 8); j++) for (i=0; i<1<<8; i++) *((w16 *)(data + (j*rowbytes) + i*2)) = (j<<8) + i; for (j=0; j<100; j++) for (i=0; i<20; i++) { *((w16 *)(data + (j*rowbytes) + (i+340)*2)) = 0x001f; *((w16 *)(data + (j*rowbytes) + (i+320)*2)) = 0x03e0; *((w16 *)(data + (j*rowbytes) + (i+300)*2)) = 0x7c00; } //}}} #endif } //}}} i4_bool draw_sprocket_class::initialize_mode(mode *m) //{{{ { OSErr err; DSpContextAttributes attr; CAST_PTR(dsm, draw_sprocket_mode_class, m); DSp_ref = dsm->ref; err = DSpContext_GetAttributes( DSp_ref, &attr ); if (err != noErr) return i4_F; // enable page flipping option attr.contextOptions |= kDSpContextOption_PageFlip; err = DSpContext_Reserve(DSp_ref, &attr); if (err != noErr) return i4_F; // fade out mac scrren err = DSpContext_FadeGammaOut(0, 0); if (err != noErr) return i4_F; // change mode err = DSpContext_SetState(DSp_ref, kDSpContextState_Active); if (err != noErr) return i4_F; // fade game in err = DSpContext_FadeGammaIn(0, 0); if (err != noErr) return i4_F; wx = attr.displayWidth; wy = attr.displayHeight; setup_back_buffer(); if (context) delete context; // setup context for window context=new i4_draw_context_class(0,0,wx-1,wy-1); context->both_dirty=new i4_rect_list_class; context->single_dirty=new i4_rect_list_class; return i4_T; } //}}} i4_bool draw_sprocket_class::close() //{{{ { OSErr err; if (PMH) // free pixels to Mac Heap UnlockPixels(PMH); err = DSpContext_FadeGammaOut(0, 0); // return to normal mode err = DSpContext_SetState(DSp_ref, kDSpContextState_Inactive); err = DSpContext_FadeGammaIn(0, 0); if (context) delete context; context = 0; if (screen) delete screen; screen = 0; return i4_T; } //}}} void draw_sprocket_class::flush() //{{{ { OSErr err; PixMapHandle PMH2 = PMH; w8 *data; w32 rowbytes; Rect r; // save off pointers to current screen rowbytes = (*PMH2)->rowBytes & 0x3FFF; data = (w8 *)GetPixBaseAddr(PMH2); // swap screens err = DSpContext_SwapBuffers(DSp_ref, 0, 0); setup_back_buffer(); // copy areas that changed i4_rect_list_class::area_iter a=context->both_dirty->list.begin(); for (;a!=context->both_dirty->list.end();++a) { r.left = a->x1; r.top = a->y1; r.right = a->x2+1; r.bottom = a->y2+1; CopyBits((BitMap *)*PMH2, (BitMap *)*PMH, &r, &r, srcCopy, 0); } // free memory for old screen if (PMH2) UnlockPixels(PMH2); context->single_dirty->delete_list(); context->both_dirty->delete_list(); } //}}} i4_bool draw_sprocket_class::available() //{{{ { // should do more checks return i4_T; } //}}} i4_bool draw_sprocket_class::realize_palette(i4_pal_handle_class pal_id) //{{{ { return i4_F; } //}}} i4_bool draw_sprocket_class::set_mouse_shape(i4_cursor_class *cursor) //{{{ { // not implemented yet return i4_F; } //}}} //{{{ Emacs Locals // Local Variables: // folded-file: t // End: //}}}