package example; import sega.dreamcast.holly.Background; import sega.dreamcast.holly.Core; import sega.dreamcast.holly.CoreBits; import sega.dreamcast.holly.Holly; import sega.dreamcast.holly.RegionArray; import sega.dreamcast.holly.TABits; import sega.dreamcast.holly.TAFIFOPolygonConverter; import sega.dreamcast.holly.TAParameter; import sega.dreamcast.holly.TextureMemoryAllocation; import sega.dreamcast.holly.ISPTSP; import sega.dreamcast.holly.TAVertexParameter; import sega.dreamcast.holly.TAGlobalParameter; import sega.dreamcast.MemoryMap; import model.UntitledModel; import model.Vec3; import model.Vec2; import model.FacePTN; import model.ModelObject; import java.misc.Memory; import java.misc.Resource; public class DreamcastVideo2 { static final int framebuffer_width = 640; static final int framebuffer_height = 480; static TAGlobalParameter.polygon_type_0[] gt0; static TAVertexParameter.polygon_type_3 vt0; static TAGlobalParameter.end_of_list eol; static Vec2[] quad; static Vec2[] quad_uv; static float theta; static int colors[] = { 5156825, 14787722, 9529551, 4729017, 10213073, 15956866, 5362273, 8377157, 9797796, 11479204, 4042586, 16676239 }; static { int parameter_control_word = TAParameter.para_control__para_type__polygon_or_modifier_volume | TAParameter.para_control__list_type__translucent | TAParameter.obj_control__col_type__packed_color | TAParameter.obj_control__texture; int isp_tsp_instruction_word = ISPTSP.isp_tsp_instruction_word__depth_compare_mode__greater | ISPTSP.isp_tsp_instruction_word__culling_mode__no_culling; int tsp_instruction_word = ISPTSP.tsp_instruction_word__src_alpha_instr__src_alpha | ISPTSP.tsp_instruction_word__dst_alpha_instr__inverse_src_alpha | ISPTSP.tsp_instruction_word__fog_control__no_fog | ISPTSP.tsp_instruction_word__texture_u_size__512 | ISPTSP.tsp_instruction_word__texture_v_size__1024 | ISPTSP.tsp_instruction_word__use_alpha; int texture_address = TextureMemoryAllocation.texture_regions[1][0] + 512; int texture_control_word = ISPTSP.texture_control_word__pixel_format__4444 | ISPTSP.texture_control_word__scan_order__non_twiddled | ISPTSP.texture_control_word__texture_address(texture_address / 8); int data_size_for_sort_dma = 0; int next_address_for_sort_dma = 0; gt0 = new TAGlobalParameter.polygon_type_0[2]; gt0[0] = new TAGlobalParameter.polygon_type_0(parameter_control_word, isp_tsp_instruction_word, tsp_instruction_word, texture_control_word, data_size_for_sort_dma, next_address_for_sort_dma); tsp_instruction_word = ISPTSP.tsp_instruction_word__src_alpha_instr__src_alpha | ISPTSP.tsp_instruction_word__dst_alpha_instr__inverse_src_alpha | ISPTSP.tsp_instruction_word__fog_control__no_fog | ISPTSP.tsp_instruction_word__texture_u_size__128 | ISPTSP.tsp_instruction_word__texture_v_size__64 | ISPTSP.tsp_instruction_word__use_alpha; texture_address = TextureMemoryAllocation.texture_regions[1][0] + 512 + (512 * 512 * 2 * 2); texture_control_word = ISPTSP.texture_control_word__pixel_format__4444 | ISPTSP.texture_control_word__scan_order__non_twiddled | ISPTSP.texture_control_word__texture_address(texture_address / 8); gt0[1] = new TAGlobalParameter.polygon_type_0(parameter_control_word, isp_tsp_instruction_word, tsp_instruction_word, texture_control_word, data_size_for_sort_dma, next_address_for_sort_dma); vt0 = new TAVertexParameter.polygon_type_3(0, // parameter_control_word 0.0f, // x 0.0f, // y 0.0f, // z 0.0f, // u 0.0f, // v 0, // color 0); // offset_color eol = new TAGlobalParameter.end_of_list(TAParameter.para_control__para_type__end_of_list); float x = 256.0f; float y = 208.0f; quad = new Vec2[4]; quad[0] = new Vec2(x + 0.0f, y + 0.0f); quad[1] = new Vec2(x + 128.0f, y + 0.0f); quad[2] = new Vec2(x + 128.0f, y + 64.0f); quad[3] = new Vec2(x + 0.0f, y + 64.0f); quad_uv = new Vec2[4]; quad_uv[0] = new Vec2(0.0f, 0.0f); quad_uv[1] = new Vec2(1.0f, 0.0f); quad_uv[2] = new Vec2(1.0f, 1.0f); quad_uv[3] = new Vec2(0.0f, 1.0f); } public static void transform_vertex(Vec3[] position, Vec2[] texture, FacePTN ptn) { float px = position[ptn.position].x; float py = position[ptn.position].y; float pz = position[ptn.position].z; float theta2 = theta * 2.0f; float scale = (Math.sin(theta2) + 3.0f) * 0.3f; px *= scale; py *= scale; pz *= scale; float x0 = px * Math.cos(theta) - py * Math.sin(theta); float y0 = px * Math.sin(theta) + py * Math.cos(theta); float z0 = pz; float theta05 = theta * 0.5f; float x1 = x0 * Math.cos(theta05) - z0 * Math.sin(theta05); float y1 = y0; float z1 = x0 * Math.sin(theta05) + z0 * Math.cos(theta05); // camera transform float z2 = 3f + z1; // perspective float x2 = x1 / z2; float y2 = y1 / z2; // screen space float x = x2 * 240f + 320f; float y = -y2 * 240f + 240f; float z = 1.0f / z2; vt0.x = x; vt0.y = y; vt0.z = z; vt0.u = texture[ptn.texture].x; vt0.v = texture[ptn.texture].y; } public static void transform_triangle(int n, Vec3[] position, Vec2[] texture, FacePTN[] face) { for (int i = 0; i < 3; i++) { vt0.parameter_control_word = TAParameter.para_control__para_type__vertex_parameter; if (i == 2) vt0.parameter_control_word |= TAParameter.para_control__end_of_strip; transform_vertex(position, texture, face[i]); vt0.base_color = colors[n]; Memory.putSQ1(vt0, MemoryMap.ta_fifo_polygon_converter); } } public static void transform_quad() { // strip order: // 0 1 3 2 vt0.z = 0.1f; vt0.parameter_control_word = TAParameter.para_control__para_type__vertex_parameter; vt0.x = quad[0].x; vt0.y = quad[0].y; vt0.u = quad_uv[0].x; vt0.v = quad_uv[0].y; Memory.putSQ1(vt0, MemoryMap.ta_fifo_polygon_converter); vt0.parameter_control_word = TAParameter.para_control__para_type__vertex_parameter; vt0.x = quad[1].x; vt0.y = quad[1].y; vt0.u = quad_uv[1].x; vt0.v = quad_uv[1].y; Memory.putSQ1(vt0, MemoryMap.ta_fifo_polygon_converter); vt0.parameter_control_word = TAParameter.para_control__para_type__vertex_parameter; vt0.x = quad[3].x; vt0.y = quad[3].y; vt0.u = quad_uv[3].x; vt0.v = quad_uv[3].y; Memory.putSQ1(vt0, MemoryMap.ta_fifo_polygon_converter); vt0.parameter_control_word = TAParameter.para_control__para_type__vertex_parameter | TAParameter.para_control__end_of_strip; vt0.x = quad[2].x; vt0.y = quad[2].y; vt0.u = quad_uv[2].x; vt0.v = quad_uv[2].y; Memory.putSQ1(vt0, MemoryMap.ta_fifo_polygon_converter); } public static void transfer_cube_scene() { // global parameters Memory.putSQ1(gt0[0], MemoryMap.ta_fifo_polygon_converter); // triangle parameters ModelObject obj = UntitledModel.objects[0]; for (int i = 0; i < obj.faces.length; i ++) { transform_triangle(i, UntitledModel.position, UntitledModel.texture, obj.faces[i]); } // end of list Memory.putSQ1(eol, MemoryMap.ta_fifo_polygon_converter); } public static void transfer_splash_scene() { // global parameters Memory.putSQ1(gt0[1], MemoryMap.ta_fifo_polygon_converter); // quad parameters transform_quad(); // end of list Memory.putSQ1(eol, MemoryMap.ta_fifo_polygon_converter); } public static void transfer_textures() { int texture = TextureMemoryAllocation.texture_regions[1][0] + 512; /* // java_cup int[] java_cup = Resource.getResource("images/java_cup"); int java_cup_length = (java_cup == null) ? 0 : java_cup.length; //System.out.print("images/java_cup length: "); //System.out.println(java_cup_length); for (int i = 0; i < java_cup_length; i++) { Memory.putU4(MemoryMap.texture_memory64 + texture, java_cup[i]); texture += 4; } // java_text int[] java_text = Resource.getResource("images/java_text"); int java_text_length = (java_text == null) ? 0 : java_text.length; //System.out.print("images/java_text length: "); //System.out.println(java_text_length); for (int i = 0; i < java_text_length; i++) { Memory.putU4(MemoryMap.texture_memory64 + texture, java_text[i]); texture += 4; } */ } public static void transfer_java_powered() { int texture = TextureMemoryAllocation.texture_regions[1][0] + 512 + (512 * 512 * 2 * 2); /* // java_powered int[] java_powered = Resource.getResource("images/java_powered"); int java_powered_length = (java_powered == null) ? 0 : java_powered.length; //System.out.print("images/java_powered length: "); //System.out.println(java_powered_length); for (int i = 0; i < java_powered_length; i++) { Memory.putU4(MemoryMap.texture_memory64 + texture, java_powered[i]); texture += 4; } */ } public static void boot_splash(int ta_alloc, int opb_size_total) { // unpipelined render loop TAFIFOPolygonConverter.init(TextureMemoryAllocation.isp_tsp_parameters_start[0], TextureMemoryAllocation.isp_tsp_parameters_end[0], TextureMemoryAllocation.object_list_start[0], TextureMemoryAllocation.object_list_end[0], opb_size_total, ta_alloc, framebuffer_width / 32, framebuffer_height / 32); transfer_splash_scene(); TAFIFOPolygonConverter.wait_translucent_list(); Core.start_render(TextureMemoryAllocation.region_array_start[0], TextureMemoryAllocation.isp_tsp_parameters_start[0], TextureMemoryAllocation.background_start[0], TextureMemoryAllocation.framebuffer_start[0], framebuffer_width); Core.wait_end_of_render_tsp(); while ((CoreBits.spg_status__vsync(Memory.getU4(Holly.SPG_STATUS)) == 0)); while (!(CoreBits.spg_status__vsync(Memory.getU4(Holly.SPG_STATUS)) == 0)); Core.fb_r_enable(); Memory.putU4(Holly.FB_R_SOF1, TextureMemoryAllocation.framebuffer_start[0]); } public static void main() { System.out.println(Memory.getU4(Holly.FB_R_SOF1)); int ta_alloc = TABits.ta_alloc_ctrl__opb_mode__increasing_addresses | TABits.ta_alloc_ctrl__pt_opb__no_list | TABits.ta_alloc_ctrl__tm_opb__no_list | TABits.ta_alloc_ctrl__t_opb__8x4byte | TABits.ta_alloc_ctrl__om_opb__no_list | TABits.ta_alloc_ctrl__o_opb__no_list ; RegionArray.OPBSize[] opb_size = { new RegionArray.OPBSize(0, // opaque 0, // opaque_modifier_volume 8 * 4, // translucent 0, // translucent_modifier_volume 0) // punch_through }; int opb_size_total = opb_size[0].total(); transfer_java_powered(); Background.background(TextureMemoryAllocation.background_start[0], 0x00c0c0c0); // sega white int num_render_passes = opb_size.length; RegionArray.region_array(framebuffer_width / 32, framebuffer_height / 32, opb_size, num_render_passes, TextureMemoryAllocation.region_array_start[0], TextureMemoryAllocation.object_list_start[0]); Core.init(); Core.fb_init(framebuffer_width, framebuffer_height); boot_splash(ta_alloc, opb_size_total); transfer_textures(); int background_color = 0xff100a00; Background.background(TextureMemoryAllocation.background_start[1], background_color); RegionArray.region_array(framebuffer_width / 32, framebuffer_height / 32, opb_size, num_render_passes, TextureMemoryAllocation.region_array_start[1], TextureMemoryAllocation.object_list_start[1]); int core = 0; int ta = 0; while (true) { // unpipelined render loop TAFIFOPolygonConverter.init(TextureMemoryAllocation.isp_tsp_parameters_start[ta], TextureMemoryAllocation.isp_tsp_parameters_end[ta], TextureMemoryAllocation.object_list_start[ta], TextureMemoryAllocation.object_list_end[ta], opb_size_total, ta_alloc, framebuffer_width / 32, framebuffer_height / 32); transfer_cube_scene(); TAFIFOPolygonConverter.wait_translucent_list(); Core.start_render(TextureMemoryAllocation.region_array_start[ta], TextureMemoryAllocation.isp_tsp_parameters_start[ta], TextureMemoryAllocation.background_start[1], TextureMemoryAllocation.framebuffer_start[core], framebuffer_width); Core.wait_end_of_render_tsp(); while (!(CoreBits.spg_status__vsync(Memory.getU4(Holly.SPG_STATUS)) != 0)); Memory.putU4(Holly.FB_R_SOF1, TextureMemoryAllocation.framebuffer_start[core]); while ((CoreBits.spg_status__vsync(Memory.getU4(Holly.SPG_STATUS)) != 0)); core = (core + 1) % 1; theta += Math.DEGREES_TO_RADIANS; } } }