#include "mx.h" SDL_Surface *front = 0; struct SDL_Font *font = 0, *menu_font = 0; SDL_Surface *menu_wall = 0, *menu_bg = 0; SDL_Joystick *stick = 0; int dim_offset = 0; int cur_dim = 0; int axis[4] = {0}; struct mxMenu menu; struct mxCursor cur; struct mxWinDim dimensions[10]; struct mxKeyboard keyboard; int menu_count = 0; #ifdef FOR_PSP int platform_plus = 10; #else int platform_plus = 1; #endif SDL_Surface *key_back = 0; int GetFX(int w,int x, int nw) { float xp = (float)x * (float)w / (float)nw; return (int)xp; } int GetFZ(int h, int y, int nh) { float yp = (float)y * (float)h / (float)nh; return (int)yp; } int add_new_dim(const char *title, struct mxWin *first, int (*keyevent)(struct mxEvent*)) { sprintf(dimensions[dim_offset].title, "%s", title); dimensions[dim_offset].first_windows = first; dimensions[dim_offset].wall = 0; dimensions[dim_offset].event = keyevent; return dim_offset++; } void stretch_blt(SDL_Surface *surf, SDL_Rect *rc, SDL_Surface *where, SDL_Rect *rc2) { int i,z; void *buf, *buf2; buf = lock(surf, surf->format->BitsPerPixel); buf2 = lock(where, surf->format->BitsPerPixel); for(i = 0; i < rc2->w; i++) { for(z = 0; z < rc2->h; z++) { static unsigned long color = 0; static int cx, cy; cx = GetFX(rc->w, i, rc2->w); cy = GetFZ(rc->h, z, rc2->h); color = getpixel(surf, cx,cy,surf->format->BitsPerPixel, surf->pitch); setpixel(buf2, i, z, color, where->format->BitsPerPixel, where->pitch); } } unlock(where); unlock(surf); } void init_menu() { int i; menu.menu_cords.x = front->w-65; menu.menu_cords.y = front->h-24; menu.menu_cords.w = 63; menu.menu_cords.h = 24; menu_wall = SDL_LoadBMP("startmenu.bmp"); menu_bg = SDL_LoadBMP("menu_bg.bmp"); menu.menu_up = 0; for(i = 0; i < 10; i++) menu.items[i].icon = 0; } void setcur_dim(int cur) { cur_dim = cur; keyboard.event = dimensions[cur_dim].event; keyboard.keybuffer[0] = 0; keyboard.key_offset = 0; } void init_cursor(struct mxCursor *cursor) { cursor->bmp_cursor = SDL_LoadBMP("cursor.bmp"); cursor->hand_cursor = SDL_LoadBMP("hand.bmp"); cursor->x = 480/2; cursor->y = 272/2; cursor->button = 0; cursor->cur_cursor = 0; SDL_ShowCursor(SDL_DISABLE); init_menu(); } void draw_cursor(struct mxCursor *cursor) { SDL_Rect c = { cursor->x, cursor->y, cursor->bmp_cursor->w, cursor->bmp_cursor->h }; if(cursor->cur_cursor == 0) { SDL_SetColorKey(cursor->bmp_cursor, SDL_SRCCOLORKEY, 0x0); SDL_BlitSurface(cursor->bmp_cursor, 0, front, &c); } else { SDL_SetColorKey(cursor->hand_cursor, SDL_SRCCOLORKEY, 0x0); SDL_BlitSurface(cursor->hand_cursor, 0, front, &c); } } void proc_event(struct mxWin *first, struct mxEvent *e) { if(first != 0 && first->left != 0) proc_event(first->left,e); if(first != 0 && first->right != 0) proc_event(first->right,e); if(first->active == 1 && first->show == 1 ) { SDL_Rect rc4 = {first->rc.x+first->rc.w-25, first->rc.y-20, 24,18}; if(cursor_in_rect(&rc4, cur.x, cur.y) && first->full == 0 ) { if(cur.button) { first->active = 0; first->show = 0; } } e->cur_surface = first->surface; first->event(e); } } void add_menu_item(struct mxMenu *menu, char *icon, char *title, struct mxWin *window, int cur_dim) { menu->items[menu_count].icon = SDL_LoadBMP(icon); sprintf(menu->items[menu_count].name ,"%s", title); menu->items[menu_count].the_window = window; menu->items[menu_count].selected = 0; menu->items[menu_count].dim = cur_dim; menu_count++; } void remove_menu_items(struct mxMenu *menu) { int i; for(i = 0; i < menu_count; i++) if(menu->items[i].icon) SDL_FreeSurface(menu->items[i].icon); } void trans_event(struct mxEvent *e, SDL_Event *se) { switch(se->type) { case SDL_JOYBUTTONDOWN: e->type = se->type; e->button = se->jbutton.button; cur.button = e->button; if(e->button == 4) { if(cur_dim > 0) cur_dim--; } else if(e->button == 5) { if(cur_dim < dim_offset-1) cur_dim++; } else if(e->button == 10) { move_keyboard_up(); set_scroll(0); keyboard.event(e); } else { } break; case SDL_JOYBUTTONUP: e->type = se->type; e->button = 0; cur.button = e->button; break; case SDL_JOYAXISMOTION: { if(se->jaxis.axis < 2) axis[se->jaxis.axis]=se->jaxis.value>>8; } break; case SDL_MOUSEMOTION: { cur.x = se->motion.x; cur.y = se->motion.y; } break; case SDL_MOUSEBUTTONDOWN: { if(se->button.button == 3) move_keyboard_up(); e->type = SDL_JOYBUTTONDOWN; cur.button = 1; cur.x = se->button.x; cur.y = se->button.y; } break; case SDL_MOUSEBUTTONUP : { cur.button = 0; e->type = SDL_JOYBUTTONUP; e->button = 0; } break; #ifndef FOR_PSP case SDL_KEYDOWN: { e->type = SDL_JOYBUTTONDOWN; switch(se->key.keysym.sym) { case SDLK_LEFT: e->button = 7; break; case SDLK_RIGHT: e->button = 9; break; case SDLK_UP: e->button = 8; break; case SDLK_DOWN: e->button = 6; break; case SDLK_a: e->button = 0; break; case SDLK_s: e->button = 1; break; case SDLK_z: e->button = 2; break; case SDLK_x: e->button = 3; break; case SDLK_q: e->button = 4; break; case SDLK_w: e->button = 5; break; } } break; #endif case SDL_KEYUP: { e->type = SDL_JOYBUTTONUP; cur.button = 0; } break; } proc_event(dimensions[cur_dim].first_windows, e); } struct mxWin *init_windows(struct mxWin *first, SDL_Rect *rc, unsigned long back_color, unsigned long title_color,unsigned long font_color,const char *title, int (*event)(struct mxEvent*) ) { struct mxWin **pnode, *node; if(first == 0) { first = (struct mxWin*) malloc ( sizeof(struct mxWin) ); first->left = first->right = 0; first->rc.x = rc->x; first->rc.y = rc->y; first->rc.w = rc->w; first->rc.h = rc->h; first->back_color = back_color; first->title_color = title_color; first->font_color = font_color; first->event = event; first->active = first->show = 0; sprintf(first->title, "%s", title); first->surface = SDL_CreateRGBSurface(SDL_HWSURFACE, rc->w, rc->h, front->format->BitsPerPixel,front->format->Rmask, front->format->Gmask, front->format->Bmask, front->format->Amask); SDL_FillRect(first->surface, 0, 0x0); first->full = 0; return first; } pnode = &first; while ((node = *pnode) != 0) { int cmp = strcmp(first->title, title); pnode = (cmp > 0) ? &first->left : &first->right; } node = (struct mxWin*) malloc ( sizeof(struct mxWin) ); node->left = node->right = 0; node->back_color = back_color; node->rc.x = rc->x; node->rc.y = rc->y; node->rc.w = rc->w; node->rc.h = rc->h; node->title_color = title_color; node->font_color = font_color; node->event = event; node->active = 0; node->show = 0; node->full = 0; node->event = event; node->surface = SDL_CreateRGBSurface(SDL_HWSURFACE, rc->w, rc->h, front->format->BitsPerPixel,front->format->Rmask, front->format->Gmask, front->format->Bmask, front->format->Amask); SDL_FillRect(node->surface, 0, 0); sprintf(node->title, "%s", title); *pnode = node; return node; } void mxwin_draw(struct mxWin *what) { SDL_Rect rc2 = {what->rc.x, what->rc.y-20, what->rc.w, 20}; SDL_Rect rc3 = {what->rc.x-2,what->rc.y-22, what->rc.w+4, what->rc.h+24}; SDL_Rect rc4 = {what->rc.x+what->rc.w-25, what->rc.y-20, 24,18}; if(what->full == 0) { SDL_FillRect(front, &rc3, SDL_MapRGB(front->format, 255,255,255)); SDL_BlitSurface(what->surface, 0,front, &what->rc); SDL_FillRect(front, &rc2, what->title_color); SDL_PrintText(front, font, what->rc.x+2,what->rc.y-22,what->font_color, what->title); SDL_FillRect(front, &rc4, SDL_MapRGB(front->format, 200,200,200)); SDL_PrintText(front, font, what->rc.x+what->rc.w-20,what->rc.y-21, SDL_MapRGB(front->format, 255, 0,0), "X"); } else { SDL_BlitSurface(what->surface, 0, front, 0); } } void print_windows(struct mxWin *first) { if(first->left != 0) print_windows(first->left); if(first->right != 0) print_windows(first->right); printf("%s\n", first->title); } void draw_line(int x, int y, int x2, unsigned long color) { void *buf = lock(front, front->format->BitsPerPixel); int i; for(i = x; i < x2; i++) if(i >= 0 && i < front->w && y > 0 && y < front->h) setpixel(buf, i,y, color, front->format->BitsPerPixel, front->pitch); unlock(front); } void draw_menu_items() { int i; int offset_y = menu.up_menu.y; for(i = 0; i < menu_count; i++) { SDL_Rect cords = { menu.up_menu.x + 5, offset_y, menu.items[i].icon->w, menu.items[i].icon->h }; SDL_SetColorKey(menu.items[i].icon, SDL_SRCCOLORKEY, SDL_MapRGB(menu.items[i].icon->format, 255,255,255)); SDL_BlitSurface(menu.items[i].icon, 0, front, &cords); SDL_PrintTextScaled(front, menu_font, menu.up_menu.x+menu.items[i].icon->w+6, offset_y+5, 10, 14, SDL_MapRGB(front->format, 255,255,255), menu.items[i].name); cords.w = 100; if(menu.up_menu.y <= 25 && cursor_in_rect(&cords,cur.x,cur.y)) { draw_line(menu.up_menu.x+menu.items[i].icon->w+6, offset_y+18, menu.up_menu.x+menu.items[i].icon->w+6+65, SDL_MapRGB(front->format, 255, 255, 255)); cur.cur_cursor = 1; if(cur.button) { struct mxEvent e = { 0 }; cur.button = 0; menu.items[i].the_window->active = 1; menu.items[i].the_window->show = 1; e.type = SDL_MENU_CLICKED; menu.items[i].the_window->event(&e); setcur_dim(menu.items[i].dim); menu.menu_up = 0; } } offset_y += menu.items[i].icon->h+5; } } void draw_menu() { if(menu.menu_up == 0) { SDL_FillRect(front, &menu.menu_cords, SDL_MapRGB(front->format, 100,100,100)); SDL_PrintText(front, font, menu.menu_cords.x+4, menu.menu_cords.y+2, SDL_MapRGB(front->format, 0xBD, 0,0), "Start"); } else { SDL_Rect rc3 = { 0,0,menu.up_menu.w, menu.up_menu.h }; SDL_Rect rc4 = { menu.up_menu.x+2, menu.menu_cords.y+2, menu.menu_cords.w+48, menu.menu_cords.h-6}; SDL_BlitSurface(menu_bg, &rc3, front, &menu.up_menu); if(menu.up_menu.y > 25) { menu.up_menu.y -= platform_plus+10; menu.up_menu.h += platform_plus+10; } SDL_FillRect(front, &rc4, SDL_MapRGB(front->format, 150,150,150)); SDL_PrintText(front, font, menu.menu_cords.x-45, menu.menu_cords.y, SDL_MapRGB(front->format, 0,0,255), "Programs"); draw_menu_items(); } } void show_menu() { menu.menu_up = 1; menu.up_menu.x = menu.menu_cords.x-50; menu.up_menu.w = menu.menu_cords.w+50; menu.up_menu.y = menu.menu_cords.y; menu.up_menu.h = menu.menu_cords.h; } void draw_windows(struct mxWin *first) { if(first->left != 0) draw_windows(first->left); if(first->right != 0) draw_windows(first->right); if(first->show) mxwin_draw(first); } void draw_dim() { int i,offset_x = 10; SDL_Rect rc = { 0,front->h-25,front->w, front->h }; if(dimensions[cur_dim].wall != 0) SDL_BlitSurface(dimensions[cur_dim].wall, 0, front, 0); draw_windows(dimensions[cur_dim].first_windows); draw_keyboard(); SDL_FillRect(front, &rc, SDL_MapRGB(front->format, 0xBD,0, 0)); SDL_BlitSurface(menu_wall, 0, front, &rc); for(i = 0; i < dim_offset; i++) { SDL_Rect rc2 = { offset_x-2, front->h-24, 80,24}; dimensions[i].rc.x = rc2.x; dimensions[i].rc.y = rc2.y; dimensions[i].rc.w = rc2.w; dimensions[i].rc.h = rc2.h; SDL_PrintText(front, font, offset_x, front->h-24, i == cur_dim ? SDL_MapRGB(front->format, 255, 100,200) : SDL_MapRGB(front->format, 255,255,255), dimensions[i].title); offset_x += 80; } draw_menu(); } int col_detect(SDL_Rect *rc2, SDL_Rect *rc1) { if(rc1->x <= rc2->w && rc1->x >= rc2->x && rc1->y <= rc2->h && rc1->y >= rc2->y) { return 1; } return 0; } int cursor_in_rect(SDL_Rect *rc, int x, int y) { SDL_Rect rc1 = { rc->x, rc->y, rc->x+rc->w, rc->h+rc->y }; SDL_Rect rc2 = { x,y,x+16,y+16 }; return col_detect(&rc1,&rc2); } void proccess_render(struct mxWin *window) { if(window->left) proccess_render(window->left); if(window->right) proccess_render(window->right); if(window->active && window->show) { struct mxEvent e; e.button = cur.button; e.mouse_x = cur.x; e.mouse_y = cur.y; e.type = SDL_RENDER; e.cur_surface = window->surface; window->event(&e); } } int get_cur_dim() { return cur_dim; } void proccess_idle_events() { static int counter = 0; static Uint8 *keys = 0; static int button = 0; int cur_dim = 0; SDL_Rect rc5; keys = SDL_GetKeyState(0); #ifndef FOR_PSP if(++counter % 2 == 0) { #endif keys = SDL_GetKeyState(0); if(keys[SDLK_LEFT]) { if(cur.x > 0) cur.x--; } if(keys[SDLK_RIGHT]) if(cur.x < front->w-cur.bmp_cursor->w/2) cur.x++; if(keys[SDLK_UP]) if(cur.y > 0) cur.y--; if(keys[SDLK_DOWN]) if(cur.y < front->h-cur.bmp_cursor->h/2) cur.y++; if(keys[SDLK_s]) { int cur_dim = 0; for(cur_dim = 0; cur_dim < dim_offset; cur_dim++) if(cursor_in_rect(&dimensions[cur_dim].rc, cur.x, cur.y)) { setcur_dim(cur_dim); break; } } // axis[0] = SDL_JoystickGetAxis(stick, 0); // axis[1] = SDL_JoystickGetAxis(stick, 1); button = cur.button; if(axis[0] > 35 && cur.x < front->w-cur.bmp_cursor->w/2) cur.x += platform_plus; if(axis[0] < -35 && cur.x > 0) cur.x -= platform_plus; if(axis[1] > 35 && cur.y < front->h-cur.bmp_cursor->h/2) cur.y += platform_plus; if(axis[1] < -5 && cur.y > 0) cur.y -= platform_plus; cur_dim = 0; rc5.x = menu.menu_cords.x-50; rc5.y = menu.menu_cords.y; rc5.w = menu.menu_cords.w+50; rc5.h = menu.menu_cords.h; for(cur_dim = 0; cur_dim < dim_offset; cur_dim++) if(cursor_in_rect(&dimensions[cur_dim].rc, cur.x, cur.y)) { if(button == 1) setcur_dim(cur_dim); else { cur.cur_cursor = 1; } break; } else if(cursor_in_rect(&menu.menu_cords, cur.x, cur.y)) { cur.cur_cursor = 1; if(button == 1) { show_menu(); cur.button = 0; } } else cur.cur_cursor = 0; if(!cursor_in_rect(&menu.up_menu, cur.x, cur.y)) { if(cur.button) menu.menu_up = 0, cur.button = 0; } #ifndef FOR_PSP } #endif proccess_render(dimensions[get_cur_dim()].first_windows); } void free_windows(struct mxWin *first) { if(first->left != 0) free_windows(first->left); if(first->right != 0) free_windows(first->right); if(first) { SDL_FreeSurface(first->surface); free(first); } } void free_dim() { int i = 0; for(i = 0; i < dim_offset; i++) { if(dimensions[i].wall != 0) SDL_FreeSurface(dimensions[i].wall); if(dimensions[i].first_windows) free_windows(dimensions[i].first_windows); } remove_menu_items(&menu); SDL_FreeSurface(menu_bg); SDL_FreeSurface(menu_wall); SDL_FreeSurface(key_back); } void trans_cords(struct mxWin *win,SDL_Rect *rc) { } static SDL_Rect rc; int offset = 0; void move_keyboard_up() { if(keyboard.keyboard_up == 0) { rc.x = 0; rc.y = 272; rc.w = 480; rc.h = 0; keyboard.keyboard_up = 1; } else keyboard.keyboard_up = 0; } void draw_keys() { if(keyboard.keyboard_up != -1) { int i, offset_x = 0, offset_y = rc.y; for(i = 0; i < offset; i++) { static char key[2]; SDL_Rect rc = {offset_x, offset_y, 20,20 }; SDL_FillRect(front, &rc, SDL_MapRGB(front->format, 100,100,100)); key[0] = keyboard.keys[i]; key[1] = 0; SDL_PrintText(front, font, offset_x+4,offset_y-1, (i == keyboard.cur_sel) ? SDL_MapRGB(front->format,255,0,0) : SDL_MapRGB(front->format, 255,255,255), key); offset_x += 22; if(offset_x > front->w) { offset_x = 0; offset_y += 22; } } proc_key_cords(); } } void add_key_to_buffer(char i) { struct mxEvent e; if(i == '<') { if(keyboard.key_offset > 0) keyboard.keybuffer[--keyboard.key_offset] = 0; } else if(i == '>') keyboard.keybuffer[0] = 0, keyboard.key_offset = 0; else if(i == '=') {} else { keyboard.keybuffer[keyboard.key_offset++] = i; keyboard.keybuffer[keyboard.key_offset] = 0; } e.type = SDL_KBPRESS; e.key = i; keyboard.event(&e); } void proc_key_cords() { if(keyboard.keyboard_up == 1) { int i, offset_x = 0, offset_y = rc.y; for(i = 0; i < offset; i++) { static char key[2]; SDL_Rect rc = {offset_x, offset_y, 20,20 }; key[0] = keyboard.keys[i]; key[1] = 0; if(cursor_in_rect(&rc,cur.x,cur.y)) { if(cur.button == 1) { add_key_to_buffer(keyboard.keys[i]); cur.button = 0; } keyboard.cur_sel = i; } offset_x += 22; if(offset_x > front->w) { offset_x = 0; offset_y += 22; } } } } void draw_keyboard() { #ifdef FOR_PSP static int platform_wait = 20; #else static int platform_wait = 1; #endif if(keyboard.keyboard_up == 1) { if(rc.y > 272-100) rc.y-=platform_wait, rc.h+=platform_wait; SDL_BlitSurface(key_back, 0, front, &rc); draw_keys(); } else if(keyboard.keyboard_up == 0) { if(rc.y < 272-25) { rc.y+=platform_wait,rc.h+=platform_wait; SDL_BlitSurface(key_back, 0, front, &rc); } draw_keys(); } else if(keyboard.keyboard_up == -1) { keyboard.rc.x = 0; keyboard.rc.y = 0; keyboard.rc.w = 0; keyboard.rc.h = 0; } } void init_keyboard(int (*event)(struct mxEvent*)) { char i = 0; for(i = 0; i < 127; i++) { if(isalpha(i) || isdigit(i)) { keyboard.keys[offset++] = i; } } keyboard.event = event; keyboard.keys[offset++] = '<'; keyboard.keys[offset++] = '>'; keyboard.keys[offset++] = '='; keyboard.keys[offset++] = ' '; keyboard.rc.x = 0; keyboard.rc.y = 272; keyboard.rc.w = 480; keyboard.rc.h = 0; keyboard.active = 0; keyboard.cur_sel = 0; keyboard.keyboard_up = -1; key_back = SDL_LoadBMP("keyback.bmp"); keyboard.key_offset = 0; keyboard.keybuffer[0] = 0; move_keyboard_up(); } void def_key(char c) { }