/* _get_vtable: * Returns a pointer to the linear vtable for the specified color depth. */ GFX_VTABLE *_get_vtable(int color_depth) { GFX_VTABLE *vt; int i; ASSERT(system_driver); if (system_driver->get_vtable) { vt = system_driver->get_vtable(color_depth); if (vt) { LOCK_DATA(vt, sizeof(GFX_VTABLE)); LOCK_CODE(vt->draw_sprite, (long)vt->draw_sprite_end - (long)vt->draw_sprite); LOCK_CODE(vt->blit_from_memory, (long)vt->blit_end - (long)vt->blit_from_memory); return vt; } } for (i=0; _vtable_list[i].vtable; i++) { if (_vtable_list[i].color_depth == color_depth) { LOCK_DATA(_vtable_list[i].vtable, sizeof(GFX_VTABLE)); LOCK_CODE(_vtable_list[i].vtable->draw_sprite, (long)_vtable_list[i].vtable->draw_sprite_end - (long)_vtable_list[i].vtable->draw_sprite); LOCK_CODE(_vtable_list[i].vtable->blit_from_memory, (long)_vtable_list[i].vtable->blit_end - (long)_vtable_list[i].vtable->blit_from_memory); return _vtable_list[i].vtable; } } return NULL; }
/* InitMemory: * Initialisation de la carte mémoire et chargement des ROMS. */ static int InitMemory(void) { register int i; /* 128 ko de RAM */ for (i=0; i<mem.ram.nbank; i++) if ((mem.ram.bank[i] = calloc(mem.ram.size, sizeof(uint8))) == NULL) return ErrorMessage(TO7_BAD_ALLOC, NULL); /* 8 ko de ROM moniteur */ for (i=0; i<mem.mon.nbank; i++) if ((mem.mon.bank[i] = malloc(mem.mon.size*sizeof(uint8))) == NULL) return ErrorMessage(TO7_BAD_ALLOC, NULL); for (i=0; i<mem.mon.nbank; i++) { if (mem.mon.filename_low[i][0]) /* ROM contrôleur de disquettes? */ { if (LoadFile(mem.mon.filename_low[i], mem.mon.bank[i], 0x800) == TO7_ERROR){ show_error_and_exit("Unable to load cd90-640.rom file"); return TO7_ERROR; } } if (LoadFile(mem.mon.filename_high[i], mem.mon.bank[i]+0x800, mem.mon.size-0x800) == TO7_ERROR){ show_error_and_exit("Unable to load to770.rom file"); return TO7_ERROR; } } LOCK_DATA(mem.ram.bank[0], sizeof(uint8)*mem.ram.size); LOCK_DATA(mem.mon.bank[0], sizeof(uint8)*mem.mon.size); return TO7_OK; }
/* lock_bitmap: * Locks all the memory used by a bitmap structure. */ void lock_bitmap(BITMAP *bmp) { LOCK_DATA(bmp, sizeof(BITMAP) + sizeof(char *) * bmp->h); if (bmp->dat) { LOCK_DATA(bmp->dat, bmp->w * bmp->h * BYTES_PER_PIXEL(bitmap_color_depth(bmp))); } }
static APEG_LAYER *new_apeg_stream(void) { APEG_LAYER *layer; // Allocate the layer data, lock it, and hook it into the stream layer = calloc(1, sizeof(APEG_LAYER)); if(!layer) return NULL; LOCK_DATA(layer, sizeof(APEG_LAYER)); /* TODO: Should replace this with a dedicated function to clear the audio state */ _apeg_start_audio(layer, FALSE); return layer; }
/* _dos_irq_init: * Initialises this module. */ void _dos_irq_init(void) { int c; LOCK_VARIABLE(_irq_handler); LOCK_VARIABLE(_irq_stack); LOCK_FUNCTION(_irq_wrapper_0); for (c=0; c<MAX_IRQS; c++) { _irq_handler[c].handler = NULL; _irq_handler[c].number = 0; } for (c=0; c<IRQ_STACKS; c++) { _irq_stack[c] = _AL_MALLOC(STACK_SIZE); if (_irq_stack[c]) { LOCK_DATA(_irq_stack[c], STACK_SIZE); _irq_stack[c] += STACK_SIZE - 32; /* stacks grow downwards */ } } }
/* _make_bitmap: * Helper function for creating the screen bitmap. Sets up a bitmap * structure for addressing video memory at addr, and fills the bank * switching table using bank size/granularity information from the * specified graphics driver. */ BITMAP *_make_bitmap(int w, int h, uintptr_t addr, GFX_DRIVER *driver, int color_depth, int bpl) { GFX_VTABLE *vtable = _get_vtable(color_depth); int i, bank, size; BITMAP *b; if (!vtable) return NULL; size = sizeof(BITMAP) + sizeof(char *) * h; b = (BITMAP *)_AL_MALLOC(size); if (!b) return NULL; _gfx_bank = _AL_REALLOC(_gfx_bank, h * sizeof(int)); if (!_gfx_bank) { _AL_FREE(b); return NULL; } LOCK_DATA(b, size); LOCK_DATA(_gfx_bank, h * sizeof(int)); b->w = b->cr = w; b->h = b->cb = h; b->clip = TRUE; b->cl = b->ct = 0; b->vtable = &_screen_vtable; b->write_bank = b->read_bank = _stub_bank_switch; b->dat = NULL; b->id = BMP_ID_VIDEO; b->extra = NULL; b->x_ofs = 0; b->y_ofs = 0; b->seg = _video_ds(); memcpy(&_screen_vtable, vtable, sizeof(GFX_VTABLE)); LOCK_DATA(&_screen_vtable, sizeof(GFX_VTABLE)); _last_bank_1 = _last_bank_2 = -1; driver->vid_phys_base = addr; b->line[0] = (unsigned char *)addr; _gfx_bank[0] = 0; if (driver->linear) { for (i=1; i<h; i++) { b->line[i] = b->line[i-1] + bpl; _gfx_bank[i] = 0; } } else { bank = 0; for (i=1; i<h; i++) { b->line[i] = b->line[i-1] + bpl; if (b->line[i]+bpl-1 >= (unsigned char *)addr + driver->bank_size) { while (b->line[i] >= (unsigned char *)addr + driver->bank_gran) { b->line[i] -= driver->bank_gran; bank++; } } _gfx_bank[i] = bank; } } return b; }
/* _set_gfx_mode: * Called by set_gfx_mode(). Separated to make a clear difference between * the virtual GFX_SAFE driver and the rest. The allow_config parameter, * if true, allows the configuration to override the graphics card/driver * when using GFX_AUTODETECT. */ static int _set_gfx_mode(int card, int w, int h, int v_w, int v_h, int allow_config) { _DRIVER_INFO *driver_list; GFX_DRIVER *drv; char tmp1[64], tmp2[64]; AL_CONST char *dv; int flags = 0; int c; ASSERT(system_driver); ASSERT(card != GFX_SAFE); /* remember the current console state */ if (gfx_virgin) { TRACE(PREFIX_I "First call, remembering console state.\n"); LOCK_FUNCTION(_stub_bank_switch); LOCK_FUNCTION(blit); if (system_driver->save_console_state) system_driver->save_console_state(); _add_exit_func(shutdown_gfx, "shutdown_gfx"); gfx_virgin = FALSE; } timer_simulate_retrace(FALSE); _screen_split_position = 0; /* close down any existing graphics driver */ if (gfx_driver) { TRACE(PREFIX_I "Closing graphics driver (%p) ", gfx_driver); TRACE("%s.\n", gfx_driver->ascii_name); if (_al_linker_mouse) _al_linker_mouse->show_mouse(NULL); while (vram_bitmap_list) destroy_bitmap(vram_bitmap_list->bmp); bmp_read_line(screen, 0); bmp_write_line(screen, 0); bmp_unwrite_line(screen); if (gfx_driver->scroll) gfx_driver->scroll(0, 0); if (gfx_driver->exit) gfx_driver->exit(screen); destroy_bitmap(screen); gfx_driver = NULL; screen = NULL; gfx_capabilities = 0; } /* We probably don't want to do this because it makes * Allegro "forget" the color layout of previously set * graphics modes. But it should be retained if bitmaps * created in those modes are to be used in the new mode. */ #if 0 /* restore default truecolor pixel format */ _rgb_r_shift_15 = 0; _rgb_g_shift_15 = 5; _rgb_b_shift_15 = 10; _rgb_r_shift_16 = 0; _rgb_g_shift_16 = 5; _rgb_b_shift_16 = 11; _rgb_r_shift_24 = 0; _rgb_g_shift_24 = 8; _rgb_b_shift_24 = 16; _rgb_r_shift_32 = 0; _rgb_g_shift_32 = 8; _rgb_b_shift_32 = 16; _rgb_a_shift_32 = 24; #endif gfx_capabilities = 0; _set_current_refresh_rate(0); /* return to text mode? */ if (card == GFX_TEXT) { TRACE(PREFIX_I "Closing, restoring original console state.\n"); if (system_driver->restore_console_state) system_driver->restore_console_state(); if (_gfx_bank) { _AL_FREE(_gfx_bank); _gfx_bank = NULL; } TRACE(PREFIX_I "Graphic mode closed.\n"); return 0; } /* now to the interesting part: let's try to find a graphics driver */ usetc(allegro_error, 0); /* ask the system driver for a list of graphics hardware drivers */ if (system_driver->gfx_drivers) driver_list = system_driver->gfx_drivers(); else driver_list = _gfx_driver_list; /* filter specific fullscreen/windowed driver requests */ if (card == GFX_AUTODETECT_FULLSCREEN) { flags |= GFX_DRIVER_FULLSCREEN_FLAG; card = GFX_AUTODETECT; } else if (card == GFX_AUTODETECT_WINDOWED) { flags |= GFX_DRIVER_WINDOWED_FLAG; card = GFX_AUTODETECT; } if (card == GFX_AUTODETECT) { /* autodetect the driver */ int found = FALSE; tmp1[0] = '\0'; /* first try the config variables */ if (allow_config) { /* try the gfx_card variable if GFX_AUTODETECT or GFX_AUTODETECT_FULLSCREEN was selected */ if (!(flags & GFX_DRIVER_WINDOWED_FLAG)) found = get_config_gfx_driver(uconvert_ascii("gfx_card", tmp1), w, h, v_w, v_h, flags, driver_list); /* try the gfx_cardw variable if GFX_AUTODETECT or GFX_AUTODETECT_WINDOWED was selected */ if (!(flags & GFX_DRIVER_FULLSCREEN_FLAG) && !found) found = get_config_gfx_driver(uconvert_ascii("gfx_cardw", tmp1), w, h, v_w, v_h, flags, driver_list); } /* go through the list of autodetected drivers if none was previously found */ if (!found) { TRACE(PREFIX_I "Autodetecting graphic driver.\n"); for (c=0; driver_list[c].driver; c++) { if (driver_list[c].autodetect) { drv = driver_list[c].driver; if (gfx_driver_is_valid(drv, flags)) { screen = init_gfx_driver(drv, w, h, v_w, v_h); if (screen) break; } } } } else { TRACE(PREFIX_I "GFX_AUTODETECT overridden through configuration:" " %s.\n", tmp1); } } else { /* search the list for the requested driver */ drv = get_gfx_driver_from_id(card, driver_list); if (drv) screen = init_gfx_driver(drv, w, h, v_w, v_h); } /* gracefully handle failure */ if (!screen) { gfx_driver = NULL; /* set by init_gfx_driver() */ if (!ugetc(allegro_error)) ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unable to find a suitable graphics driver")); TRACE(PREFIX_E "Failed setting graphic driver %d.\n", card); return -1; } /* set the basic capabilities of the driver */ if ((VIRTUAL_W > SCREEN_W) || (VIRTUAL_H > SCREEN_H)) { if (gfx_driver->scroll) gfx_capabilities |= GFX_CAN_SCROLL; if ((gfx_driver->request_scroll) || (gfx_driver->request_video_bitmap)) gfx_capabilities |= GFX_CAN_TRIPLE_BUFFER; } /* check whether we are instructed to disable vsync */ dv = get_config_string(uconvert_ascii("graphics", tmp1), uconvert_ascii("disable_vsync", tmp2), NULL); if ((dv) && ((c = ugetc(dv)) != 0) && ((c == 'y') || (c == 'Y') || (c == '1'))) _wait_for_vsync = FALSE; else _wait_for_vsync = TRUE; TRACE(PREFIX_I "The driver %s wait for vsync.\n", (_wait_for_vsync) ? "will" : "won't"); /* Give the gfx driver an opportunity to set the drawing mode */ if ((gfx_driver->drawing_mode) && (!_dispsw_status)) gfx_driver->drawing_mode(); clear_bitmap(screen); /* set up the default colors */ for (c=0; c<256; c++) _palette_color8[c] = c; set_palette(default_palette); if (_al_linker_mouse) _al_linker_mouse->set_mouse_etc(); LOCK_DATA(gfx_driver, sizeof(GFX_DRIVER)); _register_switch_bitmap(screen, NULL); TRACE(PREFIX_I "set_gfx_card success for %dx%dx%d.\n", screen->w, screen->h, bitmap_color_depth(screen)); return 0; }
/* Opens the Ogg stream, searching for and initializing Theora and Vorbis media */ int alogg_open(APEG_LAYER *layer) { ALOGG_INFO *info; int vok = 0, aok = 0; int flag, cs, size; info = calloc(1, sizeof(ALOGG_INFO)); if(!info) return APEG_ERROR; LOCK_DATA(info, sizeof(ALOGG_INFO)); ogg_sync_init(&info->osync); theora_comment_init(&info->tcomment); theora_info_init(&info->tinfo); vorbis_info_init(&info->vinfo); vorbis_comment_init(&info->vcomment); flag = FALSE; while(!flag) { int ret = buffer_data(layer, info); if(ret == 0) break; while(ogg_sync_pageout(&info->osync, &info->opage) > 0) { ogg_stream_state test; /* is this a mandated initial header? If not, stop parsing */ if(!ogg_page_bos(&info->opage)) { if(vok > 0) ogg_stream_pagein(&info->ostream[0], &info->opage); if(aok > 0) ogg_stream_pagein(&info->ostream[1], &info->opage); flag = TRUE; break; } ogg_stream_init(&test, ogg_page_serialno(&info->opage)); ogg_stream_pagein(&test, &info->opage); ogg_stream_packetout(&test, &info->opkt); /* identify the codec: try theora */ if(!vok && theora_decode_header(&info->tinfo, &info->tcomment, &info->opkt) >= 0) { /* it is theora */ if(!_apeg_ignore_video) { memcpy(&info->ostream[0], &test, sizeof(test)); vok = 1; } else ogg_stream_clear(&test); } else if(!aok && vorbis_synthesis_headerin(&info->vinfo, &info->vcomment, &info->opkt) >= 0) { /* it is vorbis */ if(!_apeg_ignore_audio) { memcpy(&info->ostream[1], &test, sizeof(test)); aok = 1; } else ogg_stream_clear(&test); } /* whatever it is, we don't care about it */ else ogg_stream_clear(&test); } /* fall through to non-bos page parsing */ } /* look for further theora headers */ while((vok > 0 && vok < 3) || (aok > 0 && aok < 3)) { int ret; // Get the last two of three Theora headers while(vok > 0 && vok < 3 && (ret = ogg_stream_packetout(&info->ostream[0], &info->opkt))) { if(ret < 0) goto error; if(theora_decode_header(&info->tinfo, &info->tcomment, &info->opkt)) goto error; ++vok; } // Get the last two of three Vorbis headers while(aok > 0 && aok < 3 && (ret = ogg_stream_packetout(&info->ostream[1], &info->opkt))) { if(ret < 0) goto error; if(vorbis_synthesis_headerin(&info->vinfo, &info->vcomment, &info->opkt)) goto error; ++aok; } if(ogg_sync_pageout(&info->osync, &info->opage) <= 0) { /* need more data */ if(buffer_data(layer, info) == 0) break; } else { if(vok > 0) ogg_stream_pagein(&info->ostream[0], &info->opage); if(aok > 0) ogg_stream_pagein(&info->ostream[1], &info->opage); } } // Neither Vorbis or Theora fully initialized. Error. if(vok != 3 && aok != 3) goto error; layer->ogg_info = info; if(aok == 3) { vorbis_synthesis_init(&info->vdsp, &info->vinfo); vorbis_block_init(&info->vdsp, &info->vblock); if(info->vinfo.channels == 1) layer->stream.audio.down_channel = FALSE; layer->stream.audio.channels = info->vinfo.channels; layer->stream.audio.freq = info->vinfo.rate >> layer->stream.audio.down_sample; if(_apeg_audio_reset_parameters(layer) != APEG_OK) { vorbis_block_clear(&info->vblock); vorbis_dsp_clear(&info->vdsp); goto error; } // layer->audio.inited = TRUE; layer->stream.flags |= APEG_VORBIS_AUDIO; }