#include #include #include "position.h" #include "level.h" #include "state.h" #include "pie/emu.h" #include "pill.h" static SDL_Surface *screen=NULL; static Dib24 vid_main( PacmanMachine::ScreenWidth, PacmanMachine::ScreenHeight ); static Dib24 vid_debug( PacmanMachine::ScreenWidth, PacmanMachine::ScreenHeight ); static unsigned int frame_hop=0; static bool show_debug=false; /** * Prepare emulator and load a snapshot */ level_t *emu_prepare(char *path, unsigned int fhop=1, bool debug=false) { show_debug = debug; /* Init emulator */ if ( ! emuInit() ) { fprintf(stderr, "Unable to init emulator. Aborting.\n"); exit(1); } /* Init display */ if ( SDL_Init(SDL_INIT_VIDEO | SDL_DOUBLEBUF) < 0 ) { fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError()); exit(1); } if ( debug ) screen = SDL_SetVideoMode(PacmanMachine::ScreenWidth*2, PacmanMachine::ScreenHeight, 32, SDL_SWSURFACE); else screen = SDL_SetVideoMode(PacmanMachine::ScreenWidth, PacmanMachine::ScreenHeight, 32, SDL_SWSURFACE); if ( screen == NULL ) { fprintf(stderr, "Unable to init video mode : %s\n", SDL_GetError()); exit(1); } SDL_WM_SetCaption("PACMAN Emu", "ICON"); emuActive( true ); /* Load a snapshot if user has specified a path */ level_t *lev = NULL; if ( path != NULL ) { char save[strlen(path)+5+1]; snprintf(save, strlen(path)+6, "%s.snap", path); emuRestoreSnapshot(save); /* Run one frame, so that we can guess level */ emuOneFrame(&vid_main); /* FIXME !! */ position_t pos = {0, 20}; lev = level_create(&vid_main, pos); if ( lev == NULL ) { fprintf(stderr, "Unable to guess level ! Check snapshot.\n"); exit(1); } } /* Set frame hop (= how often we should render) */ frame_hop = fhop; return lev; } /** * Set a position for the joystick */ void set_joystick_direction(direction_t d) { PacmanMachine::InputDeviceMode mode = PacmanMachine::DeviceOff; /* Cancel every command */ machine->setDeviceMode( PacmanMachine::Joy1_Up, mode ); machine->setDeviceMode( PacmanMachine::Joy1_Down, mode ); machine->setDeviceMode( PacmanMachine::Joy1_Left, mode ); machine->setDeviceMode( PacmanMachine::Joy1_Right, mode ); mode = PacmanMachine::DeviceOn; switch( d ) { case DIR_UP: machine->setDeviceMode( PacmanMachine::Joy1_Up, mode ); break; case DIR_DOWN: machine->setDeviceMode( PacmanMachine::Joy1_Down, mode ); break; case DIR_LEFT: machine->setDeviceMode( PacmanMachine::Joy1_Left, mode ); break; case DIR_RIGHT: machine->setDeviceMode( PacmanMachine::Joy1_Right, mode ); break; } } /** * Advance emulation for X iters */ game_state_t emu_advance(level_t *lev, unsigned int iters) { game_state_t gs; SDL_Rect debug_dest; debug_dest.x = PacmanMachine::ScreenWidth; debug_dest.y = 0; debug_dest.w = PacmanMachine::ScreenWidth; debug_dest.h = PacmanMachine::ScreenHeight; for(int i=0; igetFrameCount() % frame_hop == 0) emuOneFrame(&vid_main); else emuOneFrame(NULL); } if ( lev != NULL ) { gs.actors = guess_actors_state(lev); gs.pills = create_pill_table(); extract_pill_table(lev->graph, gs.pills); if ( is_game_preparing() ) gs.session = SESS_PREPARING; else if ( remaining_lifes() == 0 ) gs.session = SESS_GAMEOVER; else if ( remaining_pills(gs.pills) == 0 ) gs.session = SESS_WINNER; else gs.session = SESS_RUNNING; gs.score = current_score(); gs.lifes = remaining_lifes(); } if ( frame_hop != 0 ) { if ( show_debug && lev != NULL ) { draw_debug(lev, &gs.actors, &vid_debug); SDL_BlitSurface(vid_debug.getHandle(), NULL, screen, &debug_dest); } SDL_BlitSurface(vid_main.getHandle(), NULL, screen, NULL); SDL_Flip(screen); } return gs; }