void glMaterialfv (GLenum face, GLenum pname, const GLfloat *params) { switch (pname) { case GL_AMBIENT: pspgl_curctx->material.ambient = COLOR4(params); /* material ambient is overloaded by glColor() */ if (getReg(CMD_ENA_LIGHTING) & 0xff) { sendCommandi(CMD_MATERIAL_AMB_C, pspgl_curctx->material.ambient); sendCommandi(CMD_MATERIAL_AMB_A, pspgl_curctx->material.ambient >> 24); } break; case GL_EMISSION: sendCommandi(CMD_MATERIAL_EMS_C, COLOR3(params)); break; case GL_DIFFUSE: sendCommandi(CMD_MATERIAL_DIF_C, COLOR3(params)); break; case GL_AMBIENT_AND_DIFFUSE: glMaterialfv(face, GL_AMBIENT, params); glMaterialfv(face, GL_DIFFUSE, params); break; case GL_SPECULAR: sendCommandi(CMD_MATERIAL_SPC_C, COLOR3(params)); break; case GL_SHININESS: sendCommandf(CMD_MATERIAL_SPEC_POW, params[0]); break; default: GLERROR(GL_INVALID_ENUM); return; }
void sceGuModelColor(unsigned int emissive, unsigned int ambient, unsigned int diffuse, unsigned int specular) { sendCommandi(84, emissive & 0xffffff); sendCommandi(86, diffuse & 0xffffff); sendCommandi(85, ambient & 0xffffff); sendCommandi(87, specular & 0xffffff); }
void sceGuDrawArrayN(int primitive_type, int vertex_type, int count, int a3, const void* indices, const void* vertices) { if (vertex_type) sendCommandi(18,vertex_type); if (indices) { sendCommandi(16,(((unsigned int)indices) >> 8) & 0xf0000); sendCommandi(2,((unsigned int)indices) & 0xffffff); } if (vertices) { sendCommandi(16,(((unsigned int)vertices) >> 8) & 0xf0000); sendCommandi(1,((unsigned int)vertices) & 0xffffff); } if (a3 > 0) { // TODO: not sure about this loop, might be off. review int i; for (i = a3-1; i > 0; --i) sendCommandi(4,(primitive_type << 16)|count); sendCommandiStall(4,(primitive_type << 16)|count); } }
void sceGuMaterial(int mode, int color) { if (mode & 0x01) sendCommandi(85, color & 0xffffff); if (mode & 0x02) sendCommandi(86, color & 0xffffff); if (mode & 0x04) sendCommandi(87, color & 0xffffff); }
void sceGuTexFunc(int tfx, int tcc) { GuContext* context = &gu_contexts[gu_curr_context]; context->texture_function = (tcc << 8) | tfx; sendCommandi(201,((tcc << 8)|tfx)|context->unknown_state); }
void sceGuTexProjMapMode(int mode) { GuContext* context = &gu_contexts[gu_curr_context]; context->texture_proj_map_mode = ((mode & 0x03) << 8); sendCommandi(192,((mode & 0x03) << 8) | context->texture_map_mode); }
void glLightModelfv (GLenum pname, const GLfloat *params) { switch (pname) { case GL_LIGHT_MODEL_AMBIENT: sendCommandi(CMD_AMBIENT_COLOR, COLOR3(params)); sendCommandi(CMD_AMBIENT_ALPHA, (int) (255.0 * CLAMPF(params[3]))); break; case GL_LIGHT_MODEL_COLOR_CONTROL: sendCommandi(CMD_LIGHTMODEL, (params[0] == GL_SEPARATE_SPECULAR_COLOR) ? 1 : 0); break; default: GLERROR(GL_INVALID_ENUM); return; } }
void sceGuMaterial(int mode, int color) { if (mode & 0x01) { sendCommandi(85, color & 0xffffff); sendCommandi(88, color >> 24); }
static void update_color(unsigned long c) { pspgl_curctx->current.color = c; /* only apply when lighting is disabled */ if ((getReg(CMD_ENA_LIGHTING) & 0xff) == 0) { sendCommandi(CMD_MATERIAL_AMB_C, c); sendCommandi(CMD_MATERIAL_AMB_A, c>>24); }
void sceGuDrawBezier(int vertex_type, int ucount, int vcount, const void* indices, const void* vertices) { if (vertex_type) sendCommandi(18,vertex_type); if (indices) { sendCommandi(16,(((unsigned int)indices) >> 8) & 0xf0000); sendCommandi(2,((unsigned int)indices) & 0xffffff); } if (vertices) { sendCommandi(16,(((unsigned int)vertices) >> 8) & 0xf0000); sendCommandi(1,((unsigned int)vertices) & 0xffffff); } sendCommandi(5,(vcount << 8)|ucount); }
void glShadeModel (GLenum mode) { switch (mode) { case GL_FLAT: case GL_SMOOTH: sendCommandi(CMD_SHADEMODEL, (mode & 1)); break; default: GLERROR(GL_INVALID_ENUM); } }
void __pspgl_set_scissor(void) { int t,b,l,r; struct pspgl_context *c = pspgl_curctx; if (c->scissor_test.enabled) { b = c->draw->height - c->scissor_test.y; t = b - c->scissor_test.height; l = c->scissor_test.x; r = l + c->scissor_test.width; } else { b = c->draw->height; t = 0; l = 0; r = c->draw->width; } sendCommandi(CMD_SCISSOR1, (t << 10) | l); sendCommandi(CMD_SCISSOR2, ((b - 1) << 10) | (r - 1)); }
void glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { unsigned long mask = red ? 0xffff00 : 0xffffff; if (green) mask &= 0xff00ff; if (blue) mask &= 0x00ffff; pspgl_curctx->write_mask.alpha = alpha ? pspgl_curctx->draw->alpha_mask : 0x00; sendCommandi(CMD_RGB_MASK, mask); /** * Alpha Channel and Stencil are shared. Only update Alpha mask register * if stencil test is disabled. */ if ((pspgl_curctx->hw.ge_reg[CMD_ENA_STENCIL_TEST] & 1) == 0) sendCommandi(CMD_ALPHA_MASK, ~pspgl_curctx->write_mask.alpha); }
void sceGuEndObject(void) { // rewrite commands from sceGuBeginObject() unsigned int* current = gu_list->current; gu_list->current = gu_object_stack[gu_object_stack_depth-1]; sendCommandi(16, (((unsigned int)current) >> 8) & 0xf0000); sendCommandi(9, ((unsigned int)current) & 0xffffff); gu_list->current = current; gu_object_stack_depth--; }
void sceGuStart(int cid, void* list) { GuContext* context = &gu_contexts[cid]; unsigned int* local_list = (unsigned int*)(((unsigned int)list) | 0x40000000); // setup display list context->list.start = local_list; context->list.current = local_list; context->list.parent_context = gu_curr_context; gu_list = &context->list; // store current context gu_curr_context = cid; if (!cid) { ge_list_executed[0] = sceGeListEnQueue(local_list,local_list,gu_settings.ge_callback_id,0); gu_settings.signal_offset = 0; } if (!gu_init) { static int dither_matrix[16] = { -4, 0,-3, 1, 2,-2, 3,-1, -3, 1,-4, 0, 3,-1, 2,-2 }; sceGuSetDither((ScePspIMatrix4*)dither_matrix); sceGuPatchDivide(16,16); sceGuColorMaterial(GU_AMBIENT|GU_DIFFUSE|GU_SPECULAR); sceGuSpecular(1.0f); sceGuTexScale(1.0f,1.0f); gu_init = 1; } if (!gu_curr_context) { if (gu_draw_buffer.frame_width) { sendCommandi(156, ((unsigned int)gu_draw_buffer.frame_buffer) & 0xffffff); sendCommandi(157, ((((unsigned int)gu_draw_buffer.frame_buffer) & 0xff000000) >> 8) | gu_draw_buffer.frame_width); } }
void sceGuLight(int light, int type, int components, const ScePspFVector3* position) { GuLightSettings* settings = &light_settings[light]; sendCommandf(settings->row0[2],position->x); sendCommandf(settings->row0[3],position->y); sendCommandf(settings->row1[0],position->z); int kind = 2; if (components != 8) kind = (components^6) < 1 ? 1 : 0; sendCommandi(settings->row0[1],((type & 0x03) << 8)|kind); }
void glStencilFunc( GLenum func, GLint ref, GLuint mask) { unsigned char sref = (unsigned char) ref; if (unlikely(func < GL_NEVER) || unlikely(func > GL_ALWAYS)) goto out_error; func &= 0x0007; sendCommandi(CMD_STENCIL_FUNC, (mask << 16) | (sref << 8) | stenciltestfunc_mapping[func]); return; out_error: GLERROR(GL_INVALID_ENUM); }
void glCullFace (GLenum mode) { switch (mode) { case GL_BACK: case GL_FRONT: pspgl_curctx->polygon.cull_front = (mode == GL_FRONT); /* Because the PSP uses a right-handed screen coord system, the cull face direction is reversed with respect to the normal sense of CMD_CULL_FACE. */ sendCommandi(CMD_CULL_FACE, (pspgl_curctx->polygon.front_cw ^ pspgl_curctx->polygon.cull_front)); break; case GL_FRONT_AND_BACK: default: GLERROR(GL_INVALID_ENUM); } }
void sceGuAmbientColor(unsigned int color) { sendCommandi(85,color & 0xffffff); sendCommandi(88,color >> 24); }
void sceGuOffset(unsigned int x, unsigned int y) { sendCommandi(76,x << 4); sendCommandi(77,y << 4); }
void glBindTexture(GLenum target, GLuint id) { struct pspgl_texobj *tobj, *bound; struct hashtable *hash = &pspgl_curctx->shared->texture_objects; unsigned i; GLenum error; bound = pspgl_curctx->texture.bound; tobj = __pspgl_hash_lookup(hash, id); if (likely(tobj != NULL)) { error = GL_INVALID_OPERATION; if (unlikely(tobj->target == 0)) tobj->target = target; else if (unlikely(tobj->target != target)) goto out_error; } else { /* if this is a new id, create the texture */ tobj = __pspgl_texobj_new(id, target); psp_log("id %u unknown; creating new texture %p\n", id, tobj); error = GL_OUT_OF_MEMORY; if (unlikely(tobj == NULL)) goto out_error; __pspgl_hash_insert(hash, id, tobj); } if (bound == tobj) return; if (bound != NULL) { int i; psp_log("unbinding previous texture %p\n", bound); /* save per-texture state in texture object */ for(i = TEXSTATE_START; i <= TEXSTATE_END; i++) bound->ge_texreg[i - TEXSTATE_START] = getReg(i); __pspgl_texobj_free(bound); } psp_log("binding to %u (%p)\n", id, tobj); tobj->refcount++; pspgl_curctx->texture.bound = tobj; /* restore texture state */ psp_log("updating register state\n"); for(i = TEXSTATE_START; i <= TEXSTATE_END; i++) if (i != CMD_CLUT_LOAD) sendCommandi(i, tobj->ge_texreg[i - TEXSTATE_START]); if (__pspgl_texobj_cmap(tobj) != NULL) pspgl_curctx->hw.dirty |= HWD_CLUT; __pspgl_update_texenv(tobj); sendCommandi(CMD_TEXCACHE_FLUSH, getReg(CMD_TEXCACHE_FLUSH)+1); return; out_error: GLERROR(error); }
void sceGuBlendFunc(int op, int src, int dest, unsigned int srcfix, unsigned int destfix) { sendCommandi(223,src | (dest << 4) | (op << 8)); sendCommandi(224,srcfix & 0xffffff); sendCommandi(225,destfix & 0xffffff); }
void glClear (GLbitfield mask) { struct clear_vertex *vbuf; struct pspgl_surface *s = pspgl_curctx->draw; unsigned long clearmask = pspgl_curctx->clear.color; unsigned long clearmode = 0; unsigned x, y, width, height; if (mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) goto out_error; /* make room for 2 embedded vertices in cmd_buf, aligned to 16byte boundary */ vbuf = __pspgl_dlist_insert_space(2 * sizeof(struct clear_vertex)); if (mask & GL_COLOR_BUFFER_BIT) { clearmode |= GU_COLOR_BUFFER_BIT; if (s->alpha_mask) clearmode |= GU_STENCIL_BUFFER_BIT; /* really alpha */ } if (s->stencil_mask && (mask & GL_STENCIL_BUFFER_BIT)) { static const unsigned char stencil_shift [] = { 32-1, 32-4, 32-8 }; clearmask &= 0x00ffffff; clearmask |= (pspgl_curctx->clear.stencil) << stencil_shift[s->pixfmt-1]; clearmode |= GU_STENCIL_BUFFER_BIT; } if (s->depth_buffer && (mask & GL_DEPTH_BUFFER_BIT)) clearmode |= GU_DEPTH_BUFFER_BIT; if (pspgl_curctx->scissor_test.enabled) { x = pspgl_curctx->scissor_test.x; y = pspgl_curctx->scissor_test.y; width = pspgl_curctx->scissor_test.width; height = pspgl_curctx->scissor_test.height; } else { x = 0; y = 0; width = s->width; height = s->height; } vbuf[0].color = clearmask; vbuf[0].x = x; vbuf[0].y = s->height - y; vbuf[0].z = pspgl_curctx->clear.depth; vbuf[1].color = clearmask; vbuf[1].x = x + width; vbuf[1].y = s->height - (y + height); vbuf[1].z = pspgl_curctx->clear.depth; /* enable clear mode */ sendCommandi(CMD_CLEARMODE, (clearmode << 8) | 1); /* draw array */ __pspgl_context_render_prim(pspgl_curctx, GE_SPRITES, 2, GE_COLOR_8888 | GE_VERTEX_16BIT | GE_TRANSFORM_2D, vbuf, NULL); /* leave clear mode */ sendCommandi(CMD_CLEARMODE, 0); return; out_error: GLERROR(GL_INVALID_VALUE); }
void sceGuClutLoad(int num_blocks, const void* cbp) { sendCommandi(176,((unsigned int)cbp) & 0xffffff); sendCommandi(177,(((unsigned int)cbp) >> 8) & 0xf0000); sendCommandi(196,num_blocks); }
void sceGuDrawBufferList(int psm, void* fbp, int fbw) { sendCommandi(210,psm); sendCommandi(156,((unsigned int)fbp) & 0xffffff); sendCommandi(157,((((unsigned int)fbp) & 0xff000000) >> 8) | fbw); }
void sceGuAmbient(unsigned int color) { sendCommandi(92,(color & 0xffffff)); sendCommandi(93,(color >> 24)); }
void sceGuDisable(int state) { switch(state) { case 0: sendCommandi(34,0); break; case 1: sendCommandi(35,0); break; case 2: { GuContext* context = &gu_contexts[gu_curr_context]; context->scissor_enable = 0; sendCommandi(212,0); sendCommandi(213,((gu_draw_buffer.height-1) << 10)|(gu_draw_buffer.width-1)); } break; case 3: sendCommandi(36,0); break; case 4: sendCommandi(33,0); break; case 5: sendCommandi(29,0); break; case 6: sendCommandi(32,0); break; case 7: sendCommandi(31,0); break; case 8: sendCommandi(28,0); break; case 9: sendCommandi(30,0); break; case 10: sendCommandi(23,0); break; case 11: sendCommandi(24,0); break; case 12: sendCommandi(25,0); break; case 13: sendCommandi(26,0); break; case 14: sendCommandi(27,0); break; case 15: sendCommandi(37,0); break; case 16: sendCommandi(38,0); break; case 17: sendCommandi(39,0); break; case 18: sendCommandi(40,0); break; case 19: sendCommandi(81,0); break; case 20: sendCommandi(56,0); break; case 21: { GuContext* context = &gu_contexts[gu_curr_context]; context->unknown_state = 0; sendCommandi(201,context->texture_function); } break; } if (state < 22) gu_states &= ~(1 << state); }
void sceGuLightMode(int mode) { sendCommandi(94,mode); }
void glStencilOp (GLenum fail, GLenum zfail, GLenum zpass) { sendCommandi(CMD_STENCIL_OP, (map_sfunc(zpass) << 16) | (map_sfunc(zfail) << 8) | map_sfunc(fail)); }
void drawRegion(int x, int y, int width, int height) { sendCommandi(21,(y << 10) | x); sendCommandi(22,(((y + height)-1) << 10) | ((x + width)-1)); }